package processor import ( "context" "fmt" "apskel-pos-be/internal/contract" "apskel-pos-be/internal/entities" "apskel-pos-be/internal/mappers" "apskel-pos-be/internal/models" "apskel-pos-be/internal/repository" ) type CampaignProcessor interface { CreateCampaign(ctx context.Context, req *contract.CreateCampaignRequest) (*models.CampaignResponse, error) GetCampaign(ctx context.Context, id string) (*models.CampaignResponse, error) ListCampaigns(ctx context.Context, req *contract.ListCampaignsRequest) (*models.ListCampaignsResponse, error) UpdateCampaign(ctx context.Context, req *contract.UpdateCampaignRequest) (*models.CampaignResponse, error) DeleteCampaign(ctx context.Context, id string) error GetActiveCampaigns(ctx context.Context) ([]models.CampaignResponse, error) GetCampaignsForApp(ctx context.Context) ([]models.CampaignResponse, error) } type campaignProcessor struct { campaignRepo repository.CampaignRepository } func NewCampaignProcessor(campaignRepo repository.CampaignRepository) CampaignProcessor { return &campaignProcessor{ campaignRepo: campaignRepo, } } func (p *campaignProcessor) CreateCampaign(ctx context.Context, req *contract.CreateCampaignRequest) (*models.CampaignResponse, error) { // Convert request to entity entity := mappers.ToCampaignEntity(req) if entity == nil { return nil, fmt.Errorf("invalid request data") } // Create in repository if err := p.campaignRepo.Create(ctx, entity); err != nil { return nil, fmt.Errorf("failed to create campaign: %w", err) } // Convert entity to response response := mappers.ToCampaignResponse(entity) return response, nil } func (p *campaignProcessor) GetCampaign(ctx context.Context, id string) (*models.CampaignResponse, error) { // Get from repository entity, err := p.campaignRepo.GetByID(ctx, id) if err != nil { return nil, fmt.Errorf("failed to get campaign: %w", err) } if entity == nil { return nil, fmt.Errorf("campaign not found") } // Convert entity to response response := mappers.ToCampaignResponse(entity) return response, nil } func (p *campaignProcessor) ListCampaigns(ctx context.Context, req *contract.ListCampaignsRequest) (*models.ListCampaignsResponse, error) { // Convert request to entity request entityReq := &entities.ListCampaignsRequest{ Page: req.Page, Limit: req.Limit, Search: req.Search, Type: req.Type, IsActive: req.IsActive, ShowOnApp: req.ShowOnApp, StartDate: req.StartDate, EndDate: req.EndDate, } // Get from repository entities, total, err := p.campaignRepo.List(ctx, entityReq) if err != nil { return nil, fmt.Errorf("failed to list campaigns: %w", err) } // Convert entities to response campaigns := mappers.ToCampaignResponseSlice(entities) response := &models.ListCampaignsResponse{ Campaigns: campaigns, Total: total, Page: req.Page, Limit: req.Limit, } return response, nil } func (p *campaignProcessor) UpdateCampaign(ctx context.Context, req *contract.UpdateCampaignRequest) (*models.CampaignResponse, error) { // Convert request to entity entity := mappers.ToCampaignEntityFromUpdate(req) if entity == nil { return nil, fmt.Errorf("invalid request data") } // Update in repository if err := p.campaignRepo.Update(ctx, entity); err != nil { return nil, fmt.Errorf("failed to update campaign: %w", err) } // Get updated entity updatedEntity, err := p.campaignRepo.GetByID(ctx, req.ID.String()) if err != nil { return nil, fmt.Errorf("failed to get updated campaign: %w", err) } // Convert entity to response response := mappers.ToCampaignResponse(updatedEntity) return response, nil } func (p *campaignProcessor) DeleteCampaign(ctx context.Context, id string) error { // Delete from repository if err := p.campaignRepo.Delete(ctx, id); err != nil { return fmt.Errorf("failed to delete campaign: %w", err) } return nil } func (p *campaignProcessor) GetActiveCampaigns(ctx context.Context) ([]models.CampaignResponse, error) { // Get from repository entities, err := p.campaignRepo.GetActiveCampaigns(ctx) if err != nil { return nil, fmt.Errorf("failed to get active campaigns: %w", err) } // Convert entities to response campaigns := mappers.ToCampaignResponseSlice(entities) return campaigns, nil } func (p *campaignProcessor) GetCampaignsForApp(ctx context.Context) ([]models.CampaignResponse, error) { // Get from repository entities, err := p.campaignRepo.GetCampaignsForApp(ctx) if err != nil { return nil, fmt.Errorf("failed to get campaigns for app: %w", err) } // Convert entities to response campaigns := mappers.ToCampaignResponseSlice(entities) return campaigns, nil } // Campaign Rule Processor type CampaignRuleProcessor interface { CreateCampaignRule(ctx context.Context, req *contract.CreateCampaignRuleRequest) (*models.CampaignRuleResponse, error) GetCampaignRule(ctx context.Context, id string) (*models.CampaignRuleResponse, error) ListCampaignRules(ctx context.Context, req *contract.ListCampaignRulesRequest) (*models.ListCampaignRulesResponse, error) UpdateCampaignRule(ctx context.Context, req *contract.UpdateCampaignRuleRequest) (*models.CampaignRuleResponse, error) DeleteCampaignRule(ctx context.Context, id string) error GetCampaignRulesByCampaignID(ctx context.Context, campaignID string) ([]models.CampaignRuleResponse, error) } type campaignRuleProcessor struct { campaignRuleRepo repository.CampaignRuleRepository } func NewCampaignRuleProcessor(campaignRuleRepo repository.CampaignRuleRepository) CampaignRuleProcessor { return &campaignRuleProcessor{ campaignRuleRepo: campaignRuleRepo, } } func (p *campaignRuleProcessor) CreateCampaignRule(ctx context.Context, req *contract.CreateCampaignRuleRequest) (*models.CampaignRuleResponse, error) { // Convert request to entity entity := &entities.CampaignRule{ CampaignID: req.CampaignID, RuleType: entities.RuleType(req.RuleType), ConditionValue: req.ConditionValue, RewardType: entities.CampaignRewardType(req.RewardType), RewardValue: req.RewardValue, RewardSubtype: (*entities.RewardSubtype)(req.RewardSubtype), RewardRefID: req.RewardRefID, Metadata: req.Metadata, } // Create in repository if err := p.campaignRuleRepo.Create(ctx, entity); err != nil { return nil, fmt.Errorf("failed to create campaign rule: %w", err) } // Convert entity to response response := mappers.ToCampaignRuleResponse(entity) return response, nil } func (p *campaignRuleProcessor) GetCampaignRule(ctx context.Context, id string) (*models.CampaignRuleResponse, error) { // Get from repository entity, err := p.campaignRuleRepo.GetByID(ctx, id) if err != nil { return nil, fmt.Errorf("failed to get campaign rule: %w", err) } if entity == nil { return nil, fmt.Errorf("campaign rule not found") } // Convert entity to response response := mappers.ToCampaignRuleResponse(entity) return response, nil } func (p *campaignRuleProcessor) ListCampaignRules(ctx context.Context, req *contract.ListCampaignRulesRequest) (*models.ListCampaignRulesResponse, error) { // Convert request to entity request entityReq := &entities.ListCampaignRulesRequest{ Page: req.Page, Limit: req.Limit, CampaignID: req.CampaignID, RuleType: req.RuleType, RewardType: req.RewardType, } // Get from repository entities, total, err := p.campaignRuleRepo.List(ctx, entityReq) if err != nil { return nil, fmt.Errorf("failed to list campaign rules: %w", err) } // Convert entities to response rules := mappers.ToCampaignRuleResponseSlice(entities) response := &models.ListCampaignRulesResponse{ Rules: rules, Total: total, Page: req.Page, Limit: req.Limit, } return response, nil } func (p *campaignRuleProcessor) UpdateCampaignRule(ctx context.Context, req *contract.UpdateCampaignRuleRequest) (*models.CampaignRuleResponse, error) { // Convert request to entity entity := &entities.CampaignRule{ ID: req.ID, CampaignID: req.CampaignID, RuleType: entities.RuleType(req.RuleType), ConditionValue: req.ConditionValue, RewardType: entities.CampaignRewardType(req.RewardType), RewardValue: req.RewardValue, RewardSubtype: (*entities.RewardSubtype)(req.RewardSubtype), RewardRefID: req.RewardRefID, Metadata: req.Metadata, } // Update in repository if err := p.campaignRuleRepo.Update(ctx, entity); err != nil { return nil, fmt.Errorf("failed to update campaign rule: %w", err) } // Get updated entity updatedEntity, err := p.campaignRuleRepo.GetByID(ctx, req.ID.String()) if err != nil { return nil, fmt.Errorf("failed to get updated campaign rule: %w", err) } // Convert entity to response response := mappers.ToCampaignRuleResponse(updatedEntity) return response, nil } func (p *campaignRuleProcessor) DeleteCampaignRule(ctx context.Context, id string) error { // Delete from repository if err := p.campaignRuleRepo.Delete(ctx, id); err != nil { return fmt.Errorf("failed to delete campaign rule: %w", err) } return nil } func (p *campaignRuleProcessor) GetCampaignRulesByCampaignID(ctx context.Context, campaignID string) ([]models.CampaignRuleResponse, error) { // Get from repository entities, err := p.campaignRuleRepo.GetByCampaignID(ctx, campaignID) if err != nil { return nil, fmt.Errorf("failed to get campaign rules by campaign ID: %w", err) } // Convert entities to response rules := mappers.ToCampaignRuleResponseSlice(entities) return rules, nil }