// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/blockedemail/create.go package blockedemail import ( "context" "strings" "go.uber.org/zap" "github.com/gocql/gocql" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config/constants" uc_blockedemail "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/blockedemail" uc_user "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/user" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/validation" ) type CreateBlockedEmailService interface { Execute(ctx context.Context, req *CreateBlockedEmailRequestDTO) (*BlockedEmailResponseDTO, error) } type createBlockedEmailServiceImpl struct { config *config.Configuration logger *zap.Logger createBlockedEmailUseCase uc_blockedemail.CreateBlockedEmailUseCase userGetByEmailUseCase uc_user.UserGetByEmailUseCase } func NewCreateBlockedEmailService( config *config.Configuration, logger *zap.Logger, createBlockedEmailUseCase uc_blockedemail.CreateBlockedEmailUseCase, userGetByEmailUseCase uc_user.UserGetByEmailUseCase, ) CreateBlockedEmailService { logger = logger.Named("CreateBlockedEmailService") return &createBlockedEmailServiceImpl{ config: config, logger: logger, createBlockedEmailUseCase: createBlockedEmailUseCase, userGetByEmailUseCase: userGetByEmailUseCase, } } func (svc *createBlockedEmailServiceImpl) Execute(ctx context.Context, req *CreateBlockedEmailRequestDTO) (*BlockedEmailResponseDTO, error) { // // STEP 1: Validation // if req == nil { svc.logger.Warn("Failed validation with nil request") return nil, httperror.NewBadRequestError("Request is required") } e := make(map[string]string) if strings.TrimSpace(req.Email) == "" { e["email"] = "Email is required" } if len(e) != 0 { svc.logger.Warn("Failed validation", zap.Any("error", e)) return nil, httperror.NewValidationError(e) } // // STEP 2: Get user ID from context // userID, ok := ctx.Value(constants.SessionUserID).(gocql.UUID) if !ok { svc.logger.Error("Failed getting user ID from context") return nil, httperror.NewInternalServerError("Authentication context error") } // // STEP 3: Check if blocked email belongs to a registered user // var blockedUserID gocql.UUID blockedUser, err := svc.userGetByEmailUseCase.Execute(ctx, req.Email) if err != nil { svc.logger.Debug("Blocked email user not found, continuing without user ID", zap.String("email", validation.MaskEmail(req.Email)), zap.Any("error", err)) // User not found is fine - we still allow blocking non-existent emails } else if blockedUser != nil { blockedUserID = blockedUser.ID } // // STEP 4: Create blocked email // blockedEmail, err := svc.createBlockedEmailUseCase.Execute(ctx, userID, req.Email, blockedUserID, req.Reason) if err != nil { svc.logger.Error("Failed to create blocked email", zap.Any("error", err), zap.Any("user_id", userID), zap.String("email", validation.MaskEmail(req.Email))) return nil, err } // // STEP 5: Map to response DTO // response := &BlockedEmailResponseDTO{ UserID: blockedEmail.UserID, BlockedEmail: blockedEmail.BlockedEmail, BlockedUserID: blockedEmail.BlockedUserID, Reason: blockedEmail.Reason, CreatedAt: blockedEmail.CreatedAt, } return response, nil }