316 lines
8.2 KiB
Go
316 lines
8.2 KiB
Go
package profile
|
|
|
|
import (
|
|
"context"
|
|
"github.com/google/uuid"
|
|
"github.com/rs/zerolog"
|
|
"github.com/samber/lo"
|
|
"go.uber.org/fx"
|
|
|
|
"base/internal/domain/profile"
|
|
"base/internal/dto"
|
|
)
|
|
|
|
type Service interface {
|
|
Create(ctx context.Context, req dto.CreateProfileRequest) (*dto.ProfileResponse, error)
|
|
Update(ctx context.Context, req dto.UpdateProfileRequest) (*dto.ProfileResponse, error)
|
|
GetByID(ctx context.Context, id uuid.UUID) (*dto.ProfileResponse, error)
|
|
GetByHandle(ctx context.Context, handle string) (*dto.ProfileResponse, error)
|
|
List(ctx context.Context, req dto.ListProfilesRequest) (*dto.ListProfilesResponse, error)
|
|
Delete(ctx context.Context, id uuid.UUID) error
|
|
}
|
|
|
|
type service struct {
|
|
logger zerolog.Logger
|
|
profileRepo profile.Repository
|
|
}
|
|
|
|
type Param struct {
|
|
Logger zerolog.Logger
|
|
ProfileRepo profile.Repository
|
|
|
|
fx.In
|
|
}
|
|
|
|
func New(param Param) Service {
|
|
return &service{
|
|
logger: param.Logger,
|
|
profileRepo: param.ProfileRepo,
|
|
}
|
|
}
|
|
|
|
func (s *service) Create(ctx context.Context, req dto.CreateProfileRequest) (*dto.ProfileResponse, error) {
|
|
domainProfile := &profile.Profile{
|
|
ID: uuid.New(),
|
|
Handle: req.Handle,
|
|
PageSectionOrder: req.PageSectionOrder,
|
|
Hero: profile.Hero{
|
|
Role: &profile.Role{
|
|
ID: lo.FromPtr(req.Hero.RoleID),
|
|
Level: req.Hero.RoleLevel,
|
|
},
|
|
FirstName: req.Hero.FirstName,
|
|
LastName: req.Hero.LastName,
|
|
Company: req.Hero.Company,
|
|
ShortDescription: req.Hero.ShortDescription,
|
|
ResumeLink: req.Hero.ResumeLink,
|
|
CTAEnabled: req.Hero.CTAEnabled,
|
|
Avatar: req.Hero.Avatar,
|
|
},
|
|
About: profile.About{
|
|
ProfilePicture: req.About.ProfilePicture,
|
|
About: req.About.About,
|
|
},
|
|
Contact: profile.Contact{
|
|
Email: req.Contact.Email,
|
|
Phone: req.Contact.Phone,
|
|
},
|
|
PageSetting: profile.PageSetting{
|
|
VisibilityLevel: req.PageSetting.VisibilityLevel,
|
|
},
|
|
}
|
|
|
|
if req.Hero.RoleID != nil {
|
|
domainProfile.Hero.Role = &profile.Role{
|
|
ID: *req.Hero.RoleID,
|
|
}
|
|
}
|
|
|
|
for _, skill := range req.Skills {
|
|
domainProfile.Skills = append(domainProfile.Skills, profile.Skill{
|
|
SkillName: skill.SkillName,
|
|
Level: skill.Level,
|
|
})
|
|
}
|
|
|
|
for _, achievement := range req.About.Achievements {
|
|
domainProfile.About.Achievements = append(domainProfile.About.Achievements, profile.Achievement{
|
|
Title: achievement.Title,
|
|
Value: achievement.Value,
|
|
Enabled: achievement.Enabled,
|
|
})
|
|
}
|
|
|
|
for _, socialLink := range req.Contact.SocialLinks {
|
|
domainProfile.Contact.SocialLinks = append(domainProfile.Contact.SocialLinks, profile.SocialLink{
|
|
LinkType: socialLink.LinkType,
|
|
Link: socialLink.Link,
|
|
})
|
|
}
|
|
|
|
if err := s.profileRepo.Create(ctx, domainProfile); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.toProfileResponse(domainProfile), nil
|
|
}
|
|
|
|
func (s *service) Update(ctx context.Context, req dto.UpdateProfileRequest) (*dto.ProfileResponse, error) {
|
|
id, err := uuid.Parse(req.ID)
|
|
if err != nil {
|
|
return nil, profile.ErrProfileNotFound
|
|
}
|
|
|
|
// First, get the existing profile to ensure it exists
|
|
existingProfile, err := s.profileRepo.FindByID(ctx, id)
|
|
if err != nil {
|
|
return nil, profile.ErrProfileNotFound
|
|
}
|
|
|
|
domainProfile := &profile.Profile{
|
|
ID: id,
|
|
Handle: req.Handle,
|
|
PageSectionOrder: req.PageSectionOrder,
|
|
Hero: profile.Hero{
|
|
FirstName: req.Hero.FirstName,
|
|
Role: &profile.Role{
|
|
ID: lo.FromPtr(req.Hero.RoleID),
|
|
Level: req.Hero.RoleLevel,
|
|
},
|
|
LastName: req.Hero.LastName,
|
|
Company: req.Hero.Company,
|
|
ShortDescription: req.Hero.ShortDescription,
|
|
ResumeLink: req.Hero.ResumeLink,
|
|
CTAEnabled: req.Hero.CTAEnabled,
|
|
Avatar: req.Hero.Avatar,
|
|
},
|
|
About: profile.About{
|
|
ProfilePicture: req.About.ProfilePicture,
|
|
About: req.About.About,
|
|
},
|
|
Contact: profile.Contact{
|
|
Email: req.Contact.Email,
|
|
Phone: req.Contact.Phone,
|
|
},
|
|
PageSetting: profile.PageSetting{
|
|
VisibilityLevel: req.PageSetting.VisibilityLevel,
|
|
},
|
|
}
|
|
|
|
if req.Hero.RoleID != nil {
|
|
domainProfile.Hero.Role = &profile.Role{
|
|
ID: *req.Hero.RoleID,
|
|
}
|
|
} else if existingProfile != nil && existingProfile.Hero.Role != nil {
|
|
domainProfile.Hero.Role = existingProfile.Hero.Role
|
|
}
|
|
|
|
if req.Hero.RoleLevel == "" && existingProfile != nil {
|
|
domainProfile.Hero.Role.Level = existingProfile.Hero.Role.Level
|
|
}
|
|
|
|
for _, skill := range req.Skills {
|
|
domainProfile.Skills = append(domainProfile.Skills, profile.Skill{
|
|
SkillName: skill.SkillName,
|
|
Level: skill.Level,
|
|
})
|
|
}
|
|
|
|
for _, achievement := range req.About.Achievements {
|
|
domainProfile.About.Achievements = append(domainProfile.About.Achievements, profile.Achievement{
|
|
Title: achievement.Title,
|
|
Value: achievement.Value,
|
|
Enabled: achievement.Enabled,
|
|
})
|
|
}
|
|
|
|
for _, socialLink := range req.Contact.SocialLinks {
|
|
domainProfile.Contact.SocialLinks = append(domainProfile.Contact.SocialLinks, profile.SocialLink{
|
|
LinkType: socialLink.LinkType,
|
|
Link: socialLink.Link,
|
|
})
|
|
}
|
|
|
|
if err := s.profileRepo.Update(ctx, domainProfile); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.toProfileResponse(domainProfile), nil
|
|
}
|
|
|
|
func (s *service) GetByID(ctx context.Context, id uuid.UUID) (*dto.ProfileResponse, error) {
|
|
profileData, err := s.profileRepo.FindByID(ctx, id)
|
|
if err != nil {
|
|
return nil, profile.ErrProfileNotFound
|
|
}
|
|
|
|
return s.toProfileResponse(profileData), nil
|
|
}
|
|
|
|
func (s *service) GetByHandle(ctx context.Context, handle string) (*dto.ProfileResponse, error) {
|
|
profileData, err := s.profileRepo.FindByHandle(ctx, handle)
|
|
if err != nil {
|
|
return nil, profile.ErrProfileNotFound
|
|
}
|
|
|
|
return s.toProfileResponse(profileData), nil
|
|
}
|
|
|
|
func (s *service) List(ctx context.Context, req dto.ListProfilesRequest) (*dto.ListProfilesResponse, error) {
|
|
filter := profile.Filter{
|
|
FirstName: req.FirstName,
|
|
LastName: req.LastName,
|
|
Company: req.Company,
|
|
SkillName: req.SkillName,
|
|
Page: req.Page,
|
|
PageSize: req.PageSize,
|
|
SortedBy: req.SortedBy,
|
|
Ascending: req.Ascending,
|
|
}
|
|
|
|
if req.Page == 0 {
|
|
filter.Page = 1
|
|
}
|
|
if req.PageSize == 0 {
|
|
filter.PageSize = 10
|
|
}
|
|
|
|
if req.RoleID != nil {
|
|
filter.RoleID = *req.RoleID
|
|
}
|
|
|
|
profiles, total, err := s.profileRepo.FindAll(ctx, filter)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
response := &dto.ListProfilesResponse{
|
|
Profiles: make([]dto.ProfileResponse, len(profiles)),
|
|
Total: total,
|
|
Page: filter.Page,
|
|
PageSize: filter.PageSize,
|
|
}
|
|
|
|
for i, p := range profiles {
|
|
response.Profiles[i] = *s.toProfileResponse(p)
|
|
}
|
|
|
|
return response, nil
|
|
}
|
|
|
|
func (s *service) Delete(ctx context.Context, id uuid.UUID) error {
|
|
// Get profile first to ensure it exists
|
|
profileData, err := s.profileRepo.FindByID(ctx, id)
|
|
if err != nil {
|
|
return profile.ErrProfileNotFound
|
|
}
|
|
|
|
return s.profileRepo.Delete(ctx, profileData)
|
|
}
|
|
|
|
func (s *service) toProfileResponse(p *profile.Profile) *dto.ProfileResponse {
|
|
resp := &dto.ProfileResponse{
|
|
ID: p.ID,
|
|
Handle: p.Handle,
|
|
PageSectionOrder: p.PageSectionOrder,
|
|
Hero: dto.HeroDTO{
|
|
FirstName: p.Hero.FirstName,
|
|
LastName: p.Hero.LastName,
|
|
Company: p.Hero.Company,
|
|
ShortDescription: p.Hero.ShortDescription,
|
|
ResumeLink: p.Hero.ResumeLink,
|
|
CTAEnabled: p.Hero.CTAEnabled,
|
|
Avatar: p.Hero.Avatar,
|
|
},
|
|
About: dto.AboutDTO{
|
|
ProfilePicture: p.About.ProfilePicture,
|
|
About: p.About.About,
|
|
},
|
|
Contact: dto.ContactDTO{
|
|
Email: p.Contact.Email,
|
|
Phone: p.Contact.Phone,
|
|
},
|
|
PageSetting: dto.PageSettingDTO{
|
|
VisibilityLevel: p.PageSetting.VisibilityLevel,
|
|
},
|
|
}
|
|
|
|
if p.Hero.Role != nil {
|
|
resp.Hero.RoleID = &p.Hero.Role.ID
|
|
}
|
|
|
|
for _, skill := range p.Skills {
|
|
resp.Skills = append(resp.Skills, dto.SkillDTO{
|
|
SkillName: skill.SkillName,
|
|
Level: skill.Level,
|
|
})
|
|
}
|
|
|
|
for _, achievement := range p.About.Achievements {
|
|
resp.About.Achievements = append(resp.About.Achievements, dto.AchievementDTO{
|
|
Title: achievement.Title,
|
|
Value: achievement.Value,
|
|
Enabled: achievement.Enabled,
|
|
})
|
|
}
|
|
|
|
for _, socialLink := range p.Contact.SocialLinks {
|
|
resp.Contact.SocialLinks = append(resp.Contact.SocialLinks, dto.SocialLinkDTO{
|
|
LinkType: socialLink.LinkType,
|
|
Link: socialLink.Link,
|
|
})
|
|
}
|
|
|
|
return resp
|
|
}
|