package domain import ( "time" ) type DurationUnit string const ( DurationUnitDay DurationUnit = "DAY" DurationUnitWeek DurationUnit = "WEEK" DurationUnitMonth DurationUnit = "MONTH" DurationUnitYear DurationUnit = "YEAR" ) type SubscriptionStatus string const ( SubscriptionStatusPending SubscriptionStatus = "PENDING" SubscriptionStatusActive SubscriptionStatus = "ACTIVE" SubscriptionStatusExpired SubscriptionStatus = "EXPIRED" SubscriptionStatusCancelled SubscriptionStatus = "CANCELLED" ) type SubscriptionPlan struct { ID int64 Name string Description *string DurationValue int32 DurationUnit string Price float64 Currency string IsActive bool CreatedAt time.Time UpdatedAt *time.Time } type UserSubscription struct { ID int64 UserID int64 PlanID int64 StartsAt time.Time ExpiresAt time.Time Status string PaymentReference *string PaymentMethod *string AutoRenew bool CancelledAt *time.Time CreatedAt time.Time UpdatedAt *time.Time // Joined fields from plan PlanName *string DurationValue *int32 DurationUnit *string Price *float64 Currency *string } // UserSubscriptionSummary is the active subscription attached to admin user list responses (GET /users). type UserSubscriptionSummary struct { ID int64 `json:"id"` PlanID int64 `json:"plan_id"` PlanName string `json:"plan_name"` Status string `json:"status"` StartsAt time.Time `json:"starts_at"` ExpiresAt time.Time `json:"expires_at"` AutoRenew bool `json:"auto_renew"` PaymentMethod *string `json:"payment_method,omitempty"` DurationValue int32 `json:"duration_value"` DurationUnit string `json:"duration_unit"` Price float64 `json:"price"` Currency string `json:"currency"` } // Summary returns a copy safe for JSON embedding; nil if receiver is nil. func (us *UserSubscription) Summary() *UserSubscriptionSummary { if us == nil { return nil } s := &UserSubscriptionSummary{ ID: us.ID, PlanID: us.PlanID, Status: us.Status, StartsAt: us.StartsAt, ExpiresAt: us.ExpiresAt, AutoRenew: us.AutoRenew, PaymentMethod: us.PaymentMethod, } if us.PlanName != nil { s.PlanName = *us.PlanName } if us.DurationValue != nil { s.DurationValue = *us.DurationValue } if us.DurationUnit != nil { s.DurationUnit = *us.DurationUnit } if us.Price != nil { s.Price = *us.Price } if us.Currency != nil { s.Currency = *us.Currency } return s } type CreateSubscriptionPlanInput struct { Name string Description *string DurationValue int32 DurationUnit string Price float64 Currency string IsActive *bool } type UpdateSubscriptionPlanInput struct { Name *string Description *string DurationValue *int32 DurationUnit *string Price *float64 Currency *string IsActive *bool } type CreateUserSubscriptionInput struct { UserID int64 PlanID int64 StartsAt *time.Time ExpiresAt time.Time Status *string PaymentReference *string PaymentMethod *string AutoRenew *bool } // CalculateExpiryDate calculates the expiry date based on plan duration func CalculateExpiryDate(startTime time.Time, durationValue int32, durationUnit string) time.Time { switch durationUnit { case string(DurationUnitDay): return startTime.AddDate(0, 0, int(durationValue)) case string(DurationUnitWeek): return startTime.AddDate(0, 0, int(durationValue)*7) case string(DurationUnitMonth): return startTime.AddDate(0, int(durationValue), 0) case string(DurationUnitYear): return startTime.AddDate(int(durationValue), 0, 0) default: return startTime.AddDate(0, int(durationValue), 0) // Default to months } }