@@ -0,0 +1,96 @@
|
||||
// Package demos : cœur métier — cycle de vie des démos client déployées
|
||||
// dans le cluster (une démo = un namespace isolé, TTL 30 jours).
|
||||
package demos
|
||||
|
||||
import "time"
|
||||
|
||||
// Paramètres capacité / durée de vie.
|
||||
const (
|
||||
TTL = 30 * 24 * time.Hour // durée de vie d'une démo
|
||||
MaxConcurrentDemos = 5 // capacité cible
|
||||
PoolSizePerService = 5 // slots par service externe poolé
|
||||
)
|
||||
|
||||
// Services externes gérés par pool pré-provisionné (non auto-créables par API).
|
||||
// TomTom n'y figure pas : ses clés sont créées à la volée par le worker.
|
||||
const (
|
||||
ServiceTelegram = "telegram"
|
||||
ServiceNowPayments = "nowpayments"
|
||||
)
|
||||
|
||||
// PooledServices : services nécessitant un slot de pool par démo.
|
||||
var PooledServices = []string{ServiceTelegram, ServiceNowPayments}
|
||||
|
||||
// Status : état d'une démo.
|
||||
type Status string
|
||||
|
||||
const (
|
||||
StatusPending Status = "pending" // créée, pas encore prise par le worker
|
||||
StatusProvisioning Status = "provisioning" // worker en train de déployer
|
||||
StatusReady Status = "ready" // démo accessible
|
||||
StatusExpiring Status = "expiring" // teardown en cours
|
||||
StatusExpired Status = "expired" // détruite / TTL atteint
|
||||
StatusFailed Status = "failed" // échec de provisioning
|
||||
)
|
||||
|
||||
func (s Status) Valid() bool {
|
||||
switch s {
|
||||
case StatusPending, StatusProvisioning, StatusReady, StatusExpiring, StatusExpired, StatusFailed:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Active indique si la démo occupe des ressources (compte dans la capacité).
|
||||
func (s Status) Active() bool {
|
||||
switch s {
|
||||
case StatusPending, StatusProvisioning, StatusReady, StatusExpiring:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Extendable : on ne prolonge que des démos encore vivantes.
|
||||
func (s Status) Extendable() bool {
|
||||
switch s {
|
||||
case StatusProvisioning, StatusReady:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Demo : modèle GORM d'une démo.
|
||||
type Demo struct {
|
||||
ID string `gorm:"type:uuid;primaryKey" json:"id"`
|
||||
Username string `gorm:"type:varchar(64);index" json:"username,omitempty"`
|
||||
LeadID string `gorm:"type:varchar(36);index" json:"lead_id,omitempty"`
|
||||
Status Status `gorm:"size:20;not null;index" json:"status"`
|
||||
Namespace string `gorm:"size:63;uniqueIndex" json:"namespace"`
|
||||
URL string `gorm:"size:255" json:"url"`
|
||||
TypeAbo string `gorm:"type:varchar(35)" json:"type_abonnement"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
}
|
||||
|
||||
func (Demo) TableName() string { return "demos" }
|
||||
|
||||
// ResourceStatus : état d'un slot de pool.
|
||||
type ResourceStatus string
|
||||
|
||||
const (
|
||||
ResourceFree ResourceStatus = "free"
|
||||
ResourceBorrowed ResourceStatus = "borrowed"
|
||||
)
|
||||
|
||||
// ExternalResource : slot pré-provisionné (table external_pool).
|
||||
// On stocke une *référence* au secret (SecretRef), jamais le secret en clair.
|
||||
type ExternalResource struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Service string `gorm:"size:20;not null;index:idx_service_status" json:"service"`
|
||||
Label string `gorm:"size:120" json:"label"` // ex. "@omnex_demo_bot_1"
|
||||
SecretRef string `gorm:"size:200;not null" json:"-"` // clé dans le secret manager
|
||||
Status ResourceStatus `gorm:"size:20;not null;index:idx_service_status" json:"status"`
|
||||
DemoID string `gorm:"type:varchar(36);index" json:"demo_id,omitempty"` // FK optionnelle (vide si libre)
|
||||
}
|
||||
|
||||
func (ExternalResource) TableName() string { return "external_pool" }
|
||||
Reference in New Issue
Block a user