package campaign import ( "context" "errors" // For standard errors "time" "your_project/domain" "your_project/pkg/richerror" "your_project/repository" ) type ID = unit64 type EntityCampaign = domain.Campaign type CampaignServiceImp interface { CreateCampaign(ctx context.Context, req CampaignRepository) (types.ID, error) } type CampaignService struct { repo repository.CampaignRepository } func NewCampaignService( campaignRepo repository.CampaignRepository, ) *CampaignService { return &CampaignService{ repo: campaignRepo, } } func (s *CampaignService) CreateCampaign(ctx context.Context, req CreateCampaignRequest) (ID, error) { const Op = "service.campaign.create_campaign" if req.Title == "" { return 0, richerror.New(Op).WithMessage("title is required") } if req.GoalAmount <= 0 { return 0, richerror.New(Op).WithMessage("goal_amount must be greater than 0") } if req.AdminID == 0 { return 0, richerror.New(Op).WithMessage("admin_id is required") } validStatuses := map[string]bool{ "draft": true, "active": true, "completed": true, "cancelled": true, "paused": true } if !validStatuses[req.Status] { return 0, richerror.New(Op).WithMessage("invalid status provided") } newCampaign := &EntityCampaign{ Title: req.Title, Description: req.Description, GoalAmount: req.GoalAmount, RaisedAmount: 0, // Initially 0 Status: EntityCampaign.Status(req.Status), DeadlineAt: req.DeadlineAt, AdminID: req.AdminID, CreatedAt: time.Now(), } createdCampaignID, err := s.repo.CreateAndSave(ctx, newCampaign) if err != nil { return 0, richerror.New(Op).WithErr(err) } return createdCampaignID, nil }