github.com/k0marov/go-socnet@v0.0.0-20220715154813-90d07867c782/features/profiles/domain/service/service.go (about) 1 package service 2 3 import ( 4 "fmt" 5 "github.com/k0marov/go-socnet/core/abstract/likeable" 6 "github.com/k0marov/go-socnet/core/general/client_errors" 7 "github.com/k0marov/go-socnet/core/general/core_entities" 8 "github.com/k0marov/go-socnet/core/general/core_err" 9 "github.com/k0marov/go-socnet/core/general/core_values" 10 "github.com/k0marov/go-socnet/core/general/static_store" 11 "github.com/k0marov/go-socnet/core/helpers" 12 13 "github.com/k0marov/go-socnet/features/profiles/domain/contexters" 14 "github.com/k0marov/go-socnet/features/profiles/domain/models" 15 16 "github.com/k0marov/go-socnet/features/profiles/domain/entities" 17 "github.com/k0marov/go-socnet/features/profiles/domain/store" 18 "github.com/k0marov/go-socnet/features/profiles/domain/validators" 19 "github.com/k0marov/go-socnet/features/profiles/domain/values" 20 ) 21 22 type ( 23 ProfileGetter func(id, caller core_values.UserId) (entities.ContextedProfile, error) 24 ProfileUpdater func(core_entities.User, values.ProfileUpdateData) (entities.ContextedProfile, error) 25 AvatarUpdater func(core_entities.User, values.AvatarData) (core_values.FileURL, error) 26 ProfileCreator func(core_entities.User) (entities.Profile, error) 27 FollowToggler func(target, follower core_values.UserId) error 28 FollowsGetter func(target, caller core_values.UserId) ([]entities.ContextedProfile, error) 29 ) 30 31 func NewProfileGetter(getProfile store.StoreProfileGetter, addContext contexters.ProfileContextAdder) ProfileGetter { 32 return func(id core_values.UserId, caller core_values.UserId) (entities.ContextedProfile, error) { 33 profile, err := getProfile(id) 34 if err != nil { 35 if err == core_err.ErrNotFound { 36 return entities.ContextedProfile{}, client_errors.NotFound 37 } 38 return entities.ContextedProfile{}, core_err.Rethrow("getting profile in a service", err) 39 } 40 contextedProfile, err := addContext(profile, caller) 41 if err != nil { 42 return entities.ContextedProfile{}, core_err.Rethrow("adding context to profile", err) 43 } 44 return contextedProfile, nil 45 } 46 } 47 48 func NewFollowToggler(toggleLike likeable.LikeToggler) FollowToggler { 49 return FollowToggler(toggleLike) 50 } 51 52 func NewFollowsGetter(getUserLikes likeable.UserLikesGetter, getProfile ProfileGetter) FollowsGetter { 53 return func(target, caller core_values.UserId) ([]entities.ContextedProfile, error) { 54 followIds, err := getUserLikes(target) 55 if err != nil { 56 return []entities.ContextedProfile{}, core_err.Rethrow("getting a list of profile ids that target follows", err) 57 } 58 follows, err := helpers.MapForEachWithErr(followIds, func(followId string) (entities.ContextedProfile, error) { 59 return getProfile(followId, caller) 60 }) 61 if err != nil { 62 return []entities.ContextedProfile{}, core_err.Rethrow("getting profiles of follows", err) 63 } 64 return follows, nil 65 } 66 } 67 68 func NewProfileUpdater(validate validators.ProfileUpdateValidator, update store.StoreProfileUpdater, get ProfileGetter) ProfileUpdater { 69 return func(user core_entities.User, updateData values.ProfileUpdateData) (entities.ContextedProfile, error) { 70 if clientError, ok := validate(updateData); !ok { 71 return entities.ContextedProfile{}, clientError 72 } 73 err := update(user.Id, updateData) 74 if err != nil { 75 return entities.ContextedProfile{}, fmt.Errorf("got an error while updating profile in a service: %w", err) 76 } 77 updatedProfile, err := get(user.Id, user.Id) 78 if err != nil { 79 return entities.ContextedProfile{}, err 80 } 81 return updatedProfile, nil 82 } 83 } 84 85 const DefaultAbout = "" 86 const DefaultAvatarPath = "" 87 88 // NewProfileCreator this should be invoked when a new user is registered 89 func NewProfileCreator(storeProfileCreator store.StoreProfileCreator) ProfileCreator { 90 return func(user core_entities.User) (entities.Profile, error) { 91 newProfile := models.ProfileModel{ 92 Id: user.Id, 93 Username: user.Username, 94 About: DefaultAbout, 95 AvatarPath: DefaultAvatarPath, 96 } 97 err := storeProfileCreator(newProfile) 98 if err != nil { 99 return entities.Profile{}, fmt.Errorf("got an error while creating a profile in a service: %w", err) 100 } 101 createdProfile := entities.Profile{ 102 ProfileModel: newProfile, 103 Follows: 0, 104 Followers: 0, 105 } 106 return createdProfile, nil 107 } 108 } 109 110 func NewAvatarUpdater(validator validators.AvatarValidator, storeAvatar store.StoreAvatarUpdater) AvatarUpdater { 111 return func(user core_entities.User, avatar values.AvatarData) (core_values.FileURL, error) { 112 if clientError, ok := validator(avatar); !ok { 113 return "", clientError 114 } 115 116 avatarPath, err := storeAvatar(user.Id, avatar) 117 if err != nil { 118 return "", fmt.Errorf("got an error while storing updated avatar: %w", err) 119 } 120 121 return static_store.PathToURL(avatarPath), nil 122 } 123 }