turash/bugulma/backend/internal/domain/subscription.go

201 lines
8.0 KiB
Go

package domain
import (
"context"
"time"
)
// SubscriptionPlan represents a subscription plan tier
type SubscriptionPlan string
const (
SubscriptionPlanFree SubscriptionPlan = "free"
SubscriptionPlanBasic SubscriptionPlan = "basic"
SubscriptionPlanProfessional SubscriptionPlan = "professional"
SubscriptionPlanEnterprise SubscriptionPlan = "enterprise"
)
// SubscriptionStatus represents the status of a subscription
type SubscriptionStatus string
const (
SubscriptionStatusActive SubscriptionStatus = "active"
SubscriptionStatusCanceled SubscriptionStatus = "canceled"
SubscriptionStatusPastDue SubscriptionStatus = "past_due"
SubscriptionStatusTrialing SubscriptionStatus = "trialing"
SubscriptionStatusExpired SubscriptionStatus = "expired"
SubscriptionStatusNone SubscriptionStatus = "none"
)
// BillingPeriod represents the billing frequency
type BillingPeriod string
const (
BillingPeriodMonthly BillingPeriod = "monthly"
BillingPeriodYearly BillingPeriod = "yearly"
)
// Subscription represents a user's subscription
type Subscription struct {
ID string `gorm:"primaryKey;type:text"`
UserID string `gorm:"type:text;not null;index"`
Plan SubscriptionPlan `gorm:"type:varchar(50);not null;default:'free'"`
Status SubscriptionStatus `gorm:"type:varchar(20);not null;default:'none'"`
BillingPeriod BillingPeriod `gorm:"type:varchar(20);not null;default:'monthly'"`
CurrentPeriodStart time.Time `gorm:"not null"`
CurrentPeriodEnd time.Time `gorm:"not null"`
CancelAtPeriodEnd bool `gorm:"default:false"`
TrialEnd *time.Time `gorm:"index"`
StripeSubscriptionID string `gorm:"type:text;index"`
StripeCustomerID string `gorm:"type:text;index"`
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"`
// Associations
User *User `gorm:"foreignKey:UserID"`
}
// TableName specifies the table name for GORM
func (Subscription) TableName() string {
return "subscriptions"
}
// PaymentMethodType represents the type of payment method
type PaymentMethodType string
const (
PaymentMethodTypeCard PaymentMethodType = "card"
PaymentMethodTypeBankAccount PaymentMethodType = "bank_account"
)
// PaymentMethod represents a payment method for a user
type PaymentMethod struct {
ID string `gorm:"primaryKey;type:text"`
UserID string `gorm:"type:text;not null;index"`
Type PaymentMethodType `gorm:"type:varchar(20);not null"`
StripePaymentMethodID string `gorm:"type:text;index"`
Last4 string `gorm:"type:varchar(4)"`
Brand string `gorm:"type:varchar(50)"`
ExpiryMonth *int `gorm:"type:integer"`
ExpiryYear *int `gorm:"type:integer"`
IsDefault bool `gorm:"default:false"`
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"`
// Associations
User *User `gorm:"foreignKey:UserID"`
}
// TableName specifies the table name for GORM
func (PaymentMethod) TableName() string {
return "payment_methods"
}
// InvoiceStatus represents the status of an invoice
type InvoiceStatus string
const (
InvoiceStatusDraft InvoiceStatus = "draft"
InvoiceStatusOpen InvoiceStatus = "open"
InvoiceStatusPaid InvoiceStatus = "paid"
InvoiceStatusVoid InvoiceStatus = "void"
InvoiceStatusUncollectible InvoiceStatus = "uncollectible"
)
// Invoice represents a subscription invoice
type Invoice struct {
ID string `gorm:"primaryKey;type:text"`
UserID string `gorm:"type:text;not null;index"`
SubscriptionID string `gorm:"type:text;not null;index"`
StripeInvoiceID string `gorm:"type:text;index"`
Status InvoiceStatus `gorm:"type:varchar(20);not null;default:'draft'"`
Amount int64 `gorm:"type:bigint;not null"` // Amount in cents
Currency string `gorm:"type:varchar(3);default:'USD'"`
PeriodStart time.Time `gorm:"not null"`
PeriodEnd time.Time `gorm:"not null"`
PaidAt *time.Time `gorm:"index"`
DueDate time.Time `gorm:"not null"`
InvoicePDF string `gorm:"type:text"` // URL to invoice PDF
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"`
// Associations
User *User `gorm:"foreignKey:UserID"`
Subscription *Subscription `gorm:"foreignKey:SubscriptionID"`
}
// TableName specifies the table name for GORM
func (Invoice) TableName() string {
return "invoices"
}
// UsageLimitType represents the type of usage limit
type UsageLimitType string
const (
UsageLimitTypeOrganizations UsageLimitType = "organizations"
UsageLimitTypeUsers UsageLimitType = "users"
UsageLimitTypeStorage UsageLimitType = "storage"
UsageLimitTypeAPICalls UsageLimitType = "api_calls"
UsageLimitTypeCustomDomains UsageLimitType = "custom_domains"
)
// UsageTracking represents usage tracking for subscription limits
type UsageTracking struct {
ID string `gorm:"primaryKey;type:text"`
UserID string `gorm:"type:text;not null;index"`
LimitType UsageLimitType `gorm:"type:varchar(50);not null;index"`
CurrentUsage int64 `gorm:"type:bigint;default:0"`
PeriodStart time.Time `gorm:"not null;index"`
PeriodEnd time.Time `gorm:"not null;index"`
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"`
// Associations
User *User `gorm:"foreignKey:UserID"`
}
// TableName specifies the table name for GORM
func (UsageTracking) TableName() string {
return "usage_tracking"
}
// SubscriptionRepository defines the interface for subscription operations
type SubscriptionRepository interface {
Create(ctx context.Context, subscription *Subscription) error
GetByID(ctx context.Context, id string) (*Subscription, error)
GetByUserID(ctx context.Context, userID string) (*Subscription, error)
GetActiveByUserID(ctx context.Context, userID string) (*Subscription, error)
Update(ctx context.Context, subscription *Subscription) error
UpdateStatus(ctx context.Context, id string, status SubscriptionStatus) error
Delete(ctx context.Context, id string) error
}
// PaymentMethodRepository defines the interface for payment method operations
type PaymentMethodRepository interface {
Create(ctx context.Context, paymentMethod *PaymentMethod) error
GetByID(ctx context.Context, id string) (*PaymentMethod, error)
GetByUserID(ctx context.Context, userID string) ([]*PaymentMethod, error)
GetDefaultByUserID(ctx context.Context, userID string) (*PaymentMethod, error)
Update(ctx context.Context, paymentMethod *PaymentMethod) error
SetDefault(ctx context.Context, userID string, paymentMethodID string) error
Delete(ctx context.Context, id string) error
}
// InvoiceRepository defines the interface for invoice operations
type InvoiceRepository interface {
Create(ctx context.Context, invoice *Invoice) error
GetByID(ctx context.Context, id string) (*Invoice, error)
GetByUserID(ctx context.Context, userID string, limit, offset int) ([]*Invoice, int64, error)
GetBySubscriptionID(ctx context.Context, subscriptionID string) ([]*Invoice, error)
Update(ctx context.Context, invoice *Invoice) error
}
// UsageTrackingRepository defines the interface for usage tracking operations
type UsageTrackingRepository interface {
Create(ctx context.Context, usage *UsageTracking) error
GetByUserIDAndType(ctx context.Context, userID string, limitType UsageLimitType, periodStart time.Time) (*UsageTracking, error)
UpdateUsage(ctx context.Context, userID string, limitType UsageLimitType, periodStart time.Time, amount int64) error
GetCurrentPeriodUsage(ctx context.Context, userID string, limitType UsageLimitType) (*UsageTracking, error)
}