Files
worker/app/models/plan.go
Gleb Tv 2c884c5612
Некоторые проверки не удались
CI / test (push) Successful in 2m5s
Docker / Build and publish worker image (push) Failing after 31s
refactor: adopt worker module path
2026-07-13 17:56:12 +03:00

109 строки
4.4 KiB
Go

package models
import (
"log"
"github.com/google/uuid"
"github.com/lib/pq"
"gorm.io/gorm"
"rocketgit.ru/rsmon/worker/app/models/concerns"
)
var canonicalPlanCodes = []string{"free", "solo", "team", "enterprise"}
// CanonicalPlanCodes returns the supported public catalog codes.
func CanonicalPlanCodes() []string {
return append([]string(nil), canonicalPlanCodes...)
}
// Plan is a versioned-by-code catalog entry. A zero cap means unlimited.
type Plan struct {
concerns.Model
Code string `gorm:"size:32;not null" json:"code"`
NameRU string `gorm:"size:64;not null" json:"name_ru"`
NameEN string `gorm:"size:64;not null" json:"name_en"`
PriceMonthlyMinor int64 `gorm:"not null;default:0" json:"price_monthly_minor"`
PriceAnnualMinor int64 `gorm:"not null;default:0" json:"price_annual_minor"`
Currency string `gorm:"size:3;not null;default:'RUB'" json:"currency"`
MonitorCap int64 `gorm:"not null;default:0" json:"monitor_cap"`
IntervalMinSeconds int `gorm:"not null;default:30" json:"interval_min_seconds"`
StatusPagesCap int64 `gorm:"not null;default:0" json:"status_pages_cap"`
MaintenanceCap int64 `gorm:"not null;default:0" json:"maintenance_cap"`
LoginSeatsIncluded int64 `gorm:"not null;default:0" json:"login_seats_included"`
NotifySeatsIncluded int64 `gorm:"not null;default:0" json:"notify_seats_included"`
UnlimitedSeats bool `gorm:"not null;default:false" json:"unlimited_seats"`
Integrations pq.StringArray `gorm:"type:text[];not null;default:'{}'" json:"integrations"`
CheckKinds pq.StringArray `gorm:"type:text[];not null;default:'{}'" json:"check_kinds"`
DataRetentionMonths int `gorm:"not null;default:3" json:"data_retention_months"`
DistributedWorkers bool `gorm:"not null;default:false" json:"distributed_workers"`
Confirmations bool `gorm:"not null;default:false" json:"confirmations"`
AllowHardAlerts bool `gorm:"not null;default:false" json:"allow_hard_alerts"`
ConfirmTimeoutSec int `gorm:"not null;default:90" json:"confirm_timeout_sec"`
HealthWindowSec int `gorm:"not null;default:300" json:"health_window_sec"`
HealthRateThreshold float64 `gorm:"not null;default:0.5" json:"health_rate_threshold"`
HealthMinAttempts int `gorm:"not null;default:10" json:"health_min_attempts"`
SOC2 bool `gorm:"not null;default:false" json:"soc2"`
GDPRDPA bool `gorm:"not null;default:false" json:"gdpr_dpa"`
IsDefault bool `gorm:"not null;default:false" json:"is_default"`
Archived bool `gorm:"not null;default:false" json:"archived"`
// Deprecated source-compatibility fields. The legacy plans table is retained
// as plans_legacy; these values are never written to the canonical catalog.
Default bool `gorm:"-" json:"Default,omitempty"`
Name string `gorm:"-" json:"Name,omitempty"`
HTTPMonitors *int64 `gorm:"-" json:"HTTPMonitors,omitempty"`
DNSMonitors *int64 `gorm:"-" json:"DNSMonitors,omitempty"`
WHOISMonitors *int64 `gorm:"-" json:"WHOISMonitors,omitempty"`
TotalMonitors *int64 `gorm:"-" json:"TotalMonitors,omitempty"`
Price int `gorm:"-" json:"Price,omitempty"`
TrialPeriod int `gorm:"-" json:"TrialPeriod,omitempty"`
concerns.Timestamped
Audited
}
func (p *Plan) BeforeCreate(_ *gorm.DB) error {
if p.Code == "" {
p.Code = "legacy-" + uuid.NewString()[:24]
}
if p.NameRU == "" {
p.NameRU = p.Name
}
if p.NameEN == "" {
p.NameEN = p.NameRU
}
if p.Currency == "" {
p.Currency = "RUB"
}
if p.IntervalMinSeconds == 0 {
p.IntervalMinSeconds = 30
}
return nil
}
func (p *Plan) AfterFind(_ *gorm.DB) error {
p.Name = p.NameRU
p.Price = int(p.PriceMonthlyMinor / 100)
p.Default = p.IsDefault
p.TotalMonitors = &p.MonitorCap
return nil
}
// DefaultPlan returns the canonical free plan.
func DefaultPlan() Plan {
pl := Plan{}
if err := DB().Where("code = ? AND archived = FALSE", "free").First(&pl).Error; err != nil {
log.Println("unable to find default plan")
panic(err)
}
return pl
}
// AllowsDistributed keeps legacy callers working while using the canonical
// entitlement flag for catalog plans.
func (p *Plan) AllowsDistributed() bool {
return p != nil && (p.DistributedWorkers || p.Price > 0)
}