package service import ( "context" "errors" "time" "git.gocasts.ir/ebhomengo/niki/campaign/entity" "git.gocasts.ir/ebhomengo/niki/repository" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" "git.gocasts.ir/ebhomengo/niki/types" ) type CampaignService struct { repo repository.CampaignRepository } type CampaignServiceInterface interface { CreateCampaign(ctx context.Context, req CampaignRepository) (types.ID, error) } // NewCampaignService creates a new campaign service func NewCampaignService( repo repository.CampaignRepository, participantRepo repository.CampaignParticipantRepository, ) *CampaignService { return &CampaignService{ repo: repo, participantRepo: participantRepo, } } // CreateCampaign creates a new campaign func (s *CampaignService) CreateCampaign(ctx context.Context, req CreateCampaignRequest) (types.ID, error) { const Op = "service.campaign.create_campaign" // Business Logic: Validation if req.Title == "" { return 0, richerror.New(Op).WithErr(errors.New("title is required")) } if req.GoalAmount <= 0 { return 0, richerror.New(Op).WithErr(errors.New("goal_amount must be greater than 0")) } if req.AdminID == 0 { return 0, richerror.New(Op).WithErr(errors.New("admin_id is required")) } // Business Logic: Validate status validStatuses := map[string]bool{ "draft": true, "active": true, "completed": true, "cancelled": true, } if !validStatuses[req.Status] { return 0, richerror.New(Op).WithErr(errors.New("invalid status")) } // Create campaign entity campaign := entity.Campaign{ Title: req.Title, Description: req.Description, GoalAmount: req.GoalAmount, RaisedAmount: 0, // Initially 0 Status: entity.CampaignStatus(req.Status), DeadlineAt: req.DeadlineAt, AdminID: req.AdminID, CreatedAt: time.Now(), } // Call repository campaignID, err := s.repo.CreateCampaign(ctx, campaign) if err != nil { return 0, richerror.New(Op).WithErr(err) } return campaignID, nil }