package models import ( "time" ) // SubscriptionTier represents the subscription tier type SubscriptionTier string const ( TierFree SubscriptionTier = "free" TierPro SubscriptionTier = "pro" ) // SubscriptionSettings represents the subscription_subscriptionsettings table (singleton) type SubscriptionSettings struct { ID uint `gorm:"primaryKey" json:"id"` EnableLimitations bool `gorm:"column:enable_limitations;default:false" json:"enable_limitations"` } // TableName returns the table name for GORM func (SubscriptionSettings) TableName() string { return "subscription_subscriptionsettings" } // UserSubscription represents the subscription_usersubscription table type UserSubscription struct { BaseModel UserID uint `gorm:"column:user_id;uniqueIndex;not null" json:"user_id"` Tier SubscriptionTier `gorm:"column:tier;size:10;default:'free'" json:"tier"` // In-App Purchase data AppleReceiptData *string `gorm:"column:apple_receipt_data;type:text" json:"-"` GooglePurchaseToken *string `gorm:"column:google_purchase_token;type:text" json:"-"` // Subscription dates SubscribedAt *time.Time `gorm:"column:subscribed_at" json:"subscribed_at"` ExpiresAt *time.Time `gorm:"column:expires_at" json:"expires_at"` AutoRenew bool `gorm:"column:auto_renew;default:true" json:"auto_renew"` // Tracking CancelledAt *time.Time `gorm:"column:cancelled_at" json:"cancelled_at"` Platform string `gorm:"column:platform;size:10" json:"platform"` // ios, android } // TableName returns the table name for GORM func (UserSubscription) TableName() string { return "subscription_usersubscription" } // IsActive returns true if the subscription is active (pro tier and not expired) func (s *UserSubscription) IsActive() bool { if s.Tier != TierPro { return false } if s.ExpiresAt != nil && time.Now().UTC().After(*s.ExpiresAt) { return false } return true } // IsPro returns true if the user has a pro subscription func (s *UserSubscription) IsPro() bool { return s.Tier == TierPro && s.IsActive() } // UpgradeTrigger represents the subscription_upgradetrigger table type UpgradeTrigger struct { BaseModel TriggerKey string `gorm:"column:trigger_key;uniqueIndex;size:50;not null" json:"trigger_key"` Title string `gorm:"column:title;size:200;not null" json:"title"` Message string `gorm:"column:message;type:text;not null" json:"message"` PromoHTML string `gorm:"column:promo_html;type:text" json:"promo_html"` ButtonText string `gorm:"column:button_text;size:50;default:'Upgrade to Pro'" json:"button_text"` IsActive bool `gorm:"column:is_active;default:true" json:"is_active"` } // TableName returns the table name for GORM func (UpgradeTrigger) TableName() string { return "subscription_upgradetrigger" } // FeatureBenefit represents the subscription_featurebenefit table type FeatureBenefit struct { BaseModel FeatureName string `gorm:"column:feature_name;size:200;not null" json:"feature_name"` FreeTierText string `gorm:"column:free_tier_text;size:200;not null" json:"free_tier_text"` ProTierText string `gorm:"column:pro_tier_text;size:200;not null" json:"pro_tier_text"` DisplayOrder int `gorm:"column:display_order;default:0" json:"display_order"` IsActive bool `gorm:"column:is_active;default:true" json:"is_active"` } // TableName returns the table name for GORM func (FeatureBenefit) TableName() string { return "subscription_featurebenefit" } // Promotion represents the subscription_promotion table type Promotion struct { BaseModel PromotionID string `gorm:"column:promotion_id;uniqueIndex;size:50;not null" json:"promotion_id"` Title string `gorm:"column:title;size:200;not null" json:"title"` Message string `gorm:"column:message;type:text;not null" json:"message"` Link *string `gorm:"column:link;size:200" json:"link"` StartDate time.Time `gorm:"column:start_date;not null" json:"start_date"` EndDate time.Time `gorm:"column:end_date;not null" json:"end_date"` TargetTier SubscriptionTier `gorm:"column:target_tier;size:10;default:'free'" json:"target_tier"` IsActive bool `gorm:"column:is_active;default:true" json:"is_active"` } // TableName returns the table name for GORM func (Promotion) TableName() string { return "subscription_promotion" } // IsCurrentlyActive returns true if the promotion is currently active func (p *Promotion) IsCurrentlyActive() bool { if !p.IsActive { return false } now := time.Now().UTC() return now.After(p.StartDate) && now.Before(p.EndDate) } // TierLimits represents the subscription_tierlimits table type TierLimits struct { BaseModel Tier SubscriptionTier `gorm:"column:tier;uniqueIndex;size:10;not null" json:"tier"` PropertiesLimit *int `gorm:"column:properties_limit" json:"properties_limit"` TasksLimit *int `gorm:"column:tasks_limit" json:"tasks_limit"` ContractorsLimit *int `gorm:"column:contractors_limit" json:"contractors_limit"` DocumentsLimit *int `gorm:"column:documents_limit" json:"documents_limit"` } // TableName returns the table name for GORM func (TierLimits) TableName() string { return "subscription_tierlimits" } // GetDefaultFreeLimits returns the default limits for the free tier func GetDefaultFreeLimits() TierLimits { one := 1 ten := 10 zero := 0 return TierLimits{ Tier: TierFree, PropertiesLimit: &one, TasksLimit: &ten, ContractorsLimit: &zero, DocumentsLimit: &zero, } } // GetDefaultProLimits returns the default limits for the pro tier (unlimited) func GetDefaultProLimits() TierLimits { return TierLimits{ Tier: TierPro, PropertiesLimit: nil, // nil = unlimited TasksLimit: nil, ContractorsLimit: nil, DocumentsLimit: nil, } }