Files
worker/app/models/subscription.go
Gleb Tv 2c7a0236da feat: publish standalone worker
Separate worker packaging and service lifecycle from the control plane.
2026-07-13 17:55:14 +03:00

62 строки
3.2 KiB
Go

package models
import (
"time"
"gorm.io/datatypes"
"rsgit.ru/rsmon/rsmon/app/models/concerns"
)
const (
SubscriptionStatusTrialing = "trialing"
SubscriptionStatusActive = "active"
SubscriptionStatusPastDue = "past_due"
SubscriptionStatusPaused = "paused"
SubscriptionStatusCanceled = "canceled"
SubscriptionStatusExpired = "expired"
)
// Subscription is the current billable entitlement for one account. M0 only
// writes manual subscriptions; provider flows are deliberately deferred.
type Subscription struct {
concerns.Model
AccountID int64 `gorm:"not null;index" json:"account_id"`
Account *Account `json:"-"`
PlanID int64 `gorm:"not null;index" json:"plan_id"`
Plan *Plan `json:"plan,omitempty"`
Provider string `gorm:"size:16;not null;default:'manual'" json:"provider"`
ProviderSubscriptionID *string `gorm:"size:128" json:"provider_subscription_id,omitempty"`
ProviderCustomerID *string `gorm:"size:128" json:"provider_customer_id,omitempty"`
Status string `gorm:"size:24;not null;default:'active';index" json:"status"`
BillingCycle string `gorm:"size:8;not null;default:'monthly'" json:"billing_cycle"`
CurrentPeriodStart *time.Time `json:"current_period_start,omitempty"`
CurrentPeriodEnd *time.Time `gorm:"index" json:"current_period_end,omitempty"`
TrialEndsAt *time.Time `json:"trial_ends_at,omitempty"`
CancelAtPeriodEnd bool `gorm:"not null;default:false" json:"cancel_at_period_end"`
CanceledAt *time.Time `json:"canceled_at,omitempty"`
Currency string `gorm:"size:3;not null" json:"currency"`
AmountMinor int64 `gorm:"not null;default:0" json:"amount_minor"`
MetadataJSON datatypes.JSON `gorm:"type:jsonb;not null;default:'{}'" json:"metadata_json"`
concerns.Timestamped
}
// SubscriptionEvent is an append-only audit record for entitlement changes
// and provider deliveries. ProviderEventID makes future webhook processing
// idempotent without coupling the ledger to a specific PSP.
type SubscriptionEvent struct {
concerns.Model
SubscriptionID int64 `gorm:"not null;index" json:"subscription_id"`
AccountID int64 `gorm:"not null;index" json:"account_id"`
Provider string `gorm:"size:16;not null;default:'manual';uniqueIndex:idx_subscription_events_provider_event,priority:1" json:"provider"`
Kind string `gorm:"size:32;not null" json:"kind"`
FromPlanID *int64 `json:"from_plan_id,omitempty"`
ToPlanID *int64 `json:"to_plan_id,omitempty"`
AmountMinor *int64 `json:"amount_minor,omitempty"`
Currency string `gorm:"size:3" json:"currency,omitempty"`
ActorUserID *int64 `json:"actor_user_id,omitempty"`
ProviderEventID *string `gorm:"size:128;uniqueIndex:idx_subscription_events_provider_event,priority:2" json:"provider_event_id,omitempty"`
PayloadJSON datatypes.JSON `gorm:"type:jsonb;not null;default:'{}'" json:"payload_json"`
CreatedAt time.Time `json:"created_at"`
}