rdev/internal/domain/deployment.go
jordan a8c8a0a14d
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
feat: add GCS-based persistent media storage, AI generation pipeline, and composable skeleton packages
Adds complete media storage pipeline with GCS presigned uploads, AI image/video/text generation
via queue-based workers, realtime SSE event streaming, and comprehensive skeleton packages
(storage, mediagen, textgen, generation, realtime, persona, routing, ai-client). Includes
security fixes for media delete authorization, nil pointer guards in handlers, video persistence
via download-then-upload, consistent signed URLs, and Image→ImageIcon rename to avoid DOM collision.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:29:09 -07:00

110 lines
4.2 KiB
Go

// Package domain contains pure domain models with no external dependencies.
package domain
import "time"
// DeploySpec defines a deployment request.
type DeploySpec struct {
ProjectName string // Project identifier
ComponentPath string // Component path within monorepo (e.g., "services/auth-api"), empty for single-app projects
Image string // Container image (e.g., zot.threesix.svc:5000/myapp:latest)
Domain string // Domain for ingress (e.g., myapp.threesix.ai)
Port int // Container port to expose
Replicas int // Number of replicas
EnvVars map[string]string // Plain environment variables
Secrets map[string]string // Secret environment variables (stored in K8s Secret)
BasePath string // URL path prefix for Ingress (e.g., "/api/auth", "/"); empty defaults to "/"
// SiblingServices maps environment variable names to internal service URLs.
// Used for service discovery - each component gets env vars for all sibling services.
// Example: {"AUTH_SVC_URL": "http://myproject-auth-svc:8001", "CHAT_SVC_URL": "http://myproject-chat-svc:8002"}
SiblingServices map[string]string
// ExtraLabels are additional k8s labels applied to the Deployment and Pod template.
// Used for Citadel agent routing (citadel.io/environment, citadel.io/service).
ExtraLabels map[string]string
}
// DeploymentName returns the K8s resource name for this deployment.
// For monorepo components, it's "{project}-{component}", for single apps it's just "{project}".
func (s DeploySpec) DeploymentName() string {
if s.ComponentPath == "" {
return s.ProjectName
}
// Extract component name from path (e.g., "services/auth-api" -> "auth-api")
parts := splitPath(s.ComponentPath)
if len(parts) > 0 {
return s.ProjectName + "-" + parts[len(parts)-1]
}
return s.ProjectName
}
// splitPath splits a path like "services/auth-api" into ["services", "auth-api"].
func splitPath(path string) []string {
var parts []string
current := ""
for _, c := range path {
if c == '/' {
if current != "" {
parts = append(parts, current)
current = ""
}
} else {
current += string(c)
}
}
if current != "" {
parts = append(parts, current)
}
return parts
}
// DeployStatus represents the current state of a deployment.
type DeployStatus struct {
ProjectName string
ComponentPath string // Component path if this is a component deployment
Image string
Replicas int
ReadyReplicas int
URL string
Status DeploymentStatus
CreatedAt time.Time
UpdatedAt time.Time
}
// ComponentDeployStatus holds deployment status for a component.
type ComponentDeployStatus struct {
ComponentPath string // e.g., "services/auth-api"
ComponentName string // e.g., "auth-api"
ComponentType string // e.g., "service", "worker", "app"
Image string // Container image
Replicas int // Desired replicas
ReadyReplicas int // Ready replicas
URL string // URL if component has ingress
Status DeploymentStatus // Current status
}
// ProjectDeployStatus holds overall deployment status for a project.
type ProjectDeployStatus struct {
ProjectName string // Project identifier
Components []ComponentDeployStatus // Status of each deployed component
OverallURL string // Primary URL (usually app or main service)
}
// DeploymentStatus represents the state of a deployment.
type DeploymentStatus string
const (
DeploymentStatusNone DeploymentStatus = "none" // No deployment exists
DeploymentStatusPending DeploymentStatus = "pending" // Deployment created, waiting for pods
DeploymentStatusRunning DeploymentStatus = "running" // All pods are ready
DeploymentStatusFailed DeploymentStatus = "failed" // Pods failed to start
DeploymentStatusUpdating DeploymentStatus = "updating" // Rolling update in progress
DeploymentStatusUnknown DeploymentStatus = "unknown" // Status could not be determined
)
// IsReady returns true if the deployment is fully available.
func (s DeploymentStatus) IsReady() bool {
return s == DeploymentStatusRunning
}