Yimaru-BackEnd/internal/domain/subscriptions.go
Yared Yemane 79fb95ce36 Add category-based subscription controls for LMS and exam prep.
Introduce plan and content categories across programs and exam-prep catalog roots, wire category-aware checkout and access checks, and keep learner gating temporarily bypassed until data migration is ready.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 06:20:49 -07:00

116 lines
2.8 KiB
Go

package domain
import (
"time"
)
type SubscriptionCategory string
const (
SubscriptionCategoryLearnEnglish SubscriptionCategory = "LEARN_ENGLISH"
SubscriptionCategoryIELTS SubscriptionCategory = "IELTS"
SubscriptionCategoryDuolingo SubscriptionCategory = "DUOLINGO"
)
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
Category 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
}
type CreateSubscriptionPlanInput struct {
Name string
Description *string
Category string
DurationValue int32
DurationUnit string
Price float64
Currency string
IsActive *bool
}
type UpdateSubscriptionPlanInput struct {
Name *string
Description *string
Category *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
}
}