package processor import ( "context" "eslogad-be/internal/entities" "eslogad-be/internal/repository" "github.com/google/uuid" ) type RecipientProcessor interface { CreateDefaultRecipients(ctx context.Context, letterID uuid.UUID) ([]entities.LetterIncomingRecipient, error) CreateRecipients(ctx context.Context, letterID uuid.UUID, departmentIDs []uuid.UUID) ([]entities.LetterIncomingRecipient, error) CreateSingleRecipient(ctx context.Context, recipient *entities.LetterIncomingRecipient) error } type RecipientProcessorImpl struct { recipientRepo *repository.LetterIncomingRecipientRepository settingRepo *repository.AppSettingRepository departmentRepo *repository.DepartmentRepository userDeptRepo *repository.UserDepartmentRepository } func NewRecipientProcessor( recipientRepo *repository.LetterIncomingRecipientRepository, settingRepo *repository.AppSettingRepository, departmentRepo *repository.DepartmentRepository, userDeptRepo *repository.UserDepartmentRepository, ) *RecipientProcessorImpl { return &RecipientProcessorImpl{ recipientRepo: recipientRepo, settingRepo: settingRepo, departmentRepo: departmentRepo, userDeptRepo: userDeptRepo, } } func (p *RecipientProcessorImpl) CreateDefaultRecipients(ctx context.Context, letterID uuid.UUID) ([]entities.LetterIncomingRecipient, error) { departmentIDs, err := p.settingRepo.GetDepartmentRecipients(ctx) if err != nil { return []entities.LetterIncomingRecipient{}, nil } if len(departmentIDs) == 0 { return []entities.LetterIncomingRecipient{}, nil } return p.CreateRecipients(ctx, letterID, departmentIDs) } func (p *RecipientProcessorImpl) CreateRecipients(ctx context.Context, letterID uuid.UUID, departmentIDs []uuid.UUID) ([]entities.LetterIncomingRecipient, error) { if len(departmentIDs) == 0 { return []entities.LetterIncomingRecipient{}, nil } userMemberships, err := p.userDeptRepo.ListActiveByDepartmentIDs(ctx, departmentIDs) if err != nil { return nil, err } recipients := p.buildUniqueRecipients(letterID, userMemberships) if len(recipients) > 0 { if err := p.recipientRepo.CreateBulk(ctx, recipients); err != nil { return nil, err } } return recipients, nil } func (p *RecipientProcessorImpl) buildUniqueRecipients(letterID uuid.UUID, userMemberships []repository.UserDepartmentRow) []entities.LetterIncomingRecipient { var recipients []entities.LetterIncomingRecipient userMap := make(map[string]bool) for _, membership := range userMemberships { userIDStr := membership.UserID.String() if !userMap[userIDStr] { recipients = append(recipients, entities.LetterIncomingRecipient{ LetterID: letterID, RecipientUserID: &membership.UserID, RecipientDepartmentID: &membership.DepartmentID, Status: entities.RecipientStatusNew, }) userMap[userIDStr] = true } } return recipients } func (p *RecipientProcessorImpl) CreateSingleRecipient(ctx context.Context, recipient *entities.LetterIncomingRecipient) error { return p.recipientRepo.Create(ctx, recipient) }