rdev/internal/domain/session.go
jordan 9226454b85
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
feat: label-based undeploy, GC reconciliation, checkout/sessions, pool status
- Add UndeployAll() using label selectors to clean up monorepo components
  on project deletion (replaces name-based Undeploy in DeleteProject and
  the direct undeploy handler)
- Add ResourceGC background worker that periodically finds K8s resources
  whose project label has no matching DB record, deletes after 1h safety
  window
- Widen deployer client type from *kubernetes.Clientset to
  kubernetes.Interface for testability
- UndeployAll accumulates errors via errors.Join instead of failing fast
- Add checkout/checkin sidecar dev flow: temporary git tokens, branch
  checkout, review on checkin with cleanup workers
- Add interactive sessions: pod binding, command execution, SSE streaming,
  ephemeral preview URLs with session cleanup workers
- Add GET /workers/pool endpoint for aggregate capacity and queue depth
- Add sessions:read and sessions:execute auth scopes

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

71 lines
2.0 KiB
Go

// Package domain contains pure domain models with no external dependencies.
package domain
import "time"
// SessionID is a strongly-typed identifier for sessions.
type SessionID string
// SessionStatus represents the state of a session.
type SessionStatus string
const (
// SessionStatusActive indicates the session is currently in use.
SessionStatusActive SessionStatus = "active"
// SessionStatusEnded indicates the session was completed via checkin.
SessionStatusEnded SessionStatus = "ended"
// SessionStatusExpired indicates the session expired without checkin.
SessionStatusExpired SessionStatus = "expired"
)
// Session represents an interactive remote development session.
// A session composes a checkout (git token + branch), pod binding, and ephemeral preview URL.
type Session struct {
// ID is the unique session identifier.
ID SessionID
// ProjectID is the project this session belongs to.
ProjectID ProjectID
// CheckoutID links to the checkout that provides git access.
CheckoutID CheckoutID
// PodName is the bound project pod for command execution.
PodName string
// PreviewURL is the full HTTPS URL for the ephemeral preview.
// Format: https://{session-slug}.preview.threesix.ai
PreviewURL string
// PreviewHost is the hostname for the K8s Ingress.
// Format: {session-slug}.preview.threesix.ai
PreviewHost string
// CreatedBy is the user or API key that created the session.
CreatedBy string
// CreatedAt is when the session was created.
CreatedAt time.Time
// ExpiresAt is when the session will automatically expire.
ExpiresAt time.Time
// Status is the current state of the session.
Status SessionStatus
// EndedAt is when the session was ended (if ended or expired).
EndedAt *time.Time
}
// IsActive returns true if the session can still be used.
func (s *Session) IsActive() bool {
return s.Status == SessionStatusActive && time.Now().Before(s.ExpiresAt)
}
// IsExpired returns true if the session has expired.
func (s *Session) IsExpired() bool {
return s.Status == SessionStatusActive && time.Now().After(s.ExpiresAt)
}