package models import ( "encoding/json" "time" "gorm.io/gorm" ) type App struct { ID int64 `gorm:"column:rowid;primaryKey;autoIncrement" json:"id"` // Unique identifier Name string `json:"name" gorm:"not null"` Description string `json:"description"` Version string `json:"version" gorm:"index"` // Configuration as JSON string in DB ConfigJSON string `json:"-" gorm:"column:config;type:text"` // Virtual field for ORM serialization/deserialization Config AppConfig `json:"config" gorm:"-"` CreatedAt time.Time `json:"createdAt" gorm:"autoCreateTime"` UpdatedAt time.Time `json:"updatedAt" gorm:"autoUpdateTime"` CreatedBy string `json:"createdBy" gorm:"index"` // User ID who created the template DeletedAt gorm.DeletedAt `json:"-" gorm:"index"` // Soft delete support // Relationships Deployments []Deployment `json:"deployments" gorm:"foreignKey:AppID"` // Deployments using this app } type AppConfig struct { Components []ComponentConfig `json:"components"` // Components included in this app (renamed from apps) NetworkPolicies []NetworkPolicy `json:"networkPolicies"` // Network policies to apply EnvVariables map[string]string `json:"envVariables,omitempty"` // Environment variables Secrets []SecretConfig `json:"secrets,omitempty"` // Secret configurations } type ComponentConfig struct { ID int64 `json:"id"` // Reference to the component Name string `json:"name"` // Name of the component in this app ExposedPorts []int `json:"exposedPorts,omitempty"` // Ports to expose PublicAccess bool `json:"publicAccess"` // Whether the component is publicly accessible Resources ResourceConfig `json:"resources"` // Resource allocation Autoscaling AutoscalingConfig `json:"autoscaling,omitempty"` // Autoscaling configuration EnvOverrides map[string]string `json:"envOverrides,omitempty"` // Environment variable overrides ServiceMesh bool `json:"serviceMesh"` // Whether to include in service mesh } type ResourceConfig struct { CPU string `json:"cpu"` // e.g., "0.5" Memory string `json:"memory"` // e.g., "512Mi" Storage string `json:"storage"` // e.g., "1Gi" } type AutoscalingConfig struct { Enabled bool `json:"enabled"` // Whether autoscaling is enabled MinReplicas int `json:"minReplicas"` // Minimum number of replicas MaxReplicas int `json:"maxReplicas"` // Maximum number of replicas CPUThreshold int `json:"cpuThreshold"` // CPU threshold for scaling (percentage) Metric string `json:"metric"` // Metric to base scaling on (e.g., "cpu", "memory") } type NetworkPolicy struct { Name string `json:"name"` // Policy name FromComponents []string `json:"fromComponents"` // Source components (renamed from FromApps) ToComponents []string `json:"toComponents"` // Destination components (renamed from ToApps) Ports []int `json:"ports,omitempty"` // Allowed ports AllowEgress bool `json:"allowEgress"` // Whether to allow egress traffic } type SecretConfig struct { Name string `json:"name"` // Secret name Description string `json:"description"` // Secret description Required bool `json:"required"` // Whether the secret is required } // BeforeSave serializes the embedded JSON fields func (a *App) BeforeSave(tx *gorm.DB) error { // Marshal Config to JSON configJSON, err := json.Marshal(a.Config) if err != nil { return err } a.ConfigJSON = string(configJSON) return nil } // AfterFind deserializes the JSON fields func (a *App) AfterFind(tx *gorm.DB) error { // Unmarshal Config from JSON if a.ConfigJSON != "" { if err := json.Unmarshal([]byte(a.ConfigJSON), &a.Config); err != nil { return err } } return nil }