- Add ListPipelines/GetPipeline to CIProvider port with Woodpecker adapter
- Add DNS alias endpoints: GET/POST/DELETE /projects/{id}/domains
- Implement worker executor daemon, build executor, and git operations
- Add build service, worker service, and build audit tracking
- Add worker registry with PostgreSQL adapter and migration
- Add multi-provider code agent interface (Claude Code + OpenCode)
- Add create-and-build combo endpoint
- Update landing-page cookbook to reflect all gaps closed
- Fix tech debt: unified validation, auth scopes, error wrapping, slog patterns
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
// Package domain contains pure domain models with no external dependencies.
|
|
package domain
|
|
|
|
import "time"
|
|
|
|
// Worker represents a registered worker in the pool.
|
|
type Worker struct {
|
|
// ID is the unique worker identifier (typically pod name).
|
|
ID string `json:"id"`
|
|
|
|
// Hostname is the worker's hostname.
|
|
Hostname string `json:"hostname"`
|
|
|
|
// Status is the current worker state.
|
|
Status WorkerStatus `json:"status"`
|
|
|
|
// CurrentTask is the ID of the task currently being executed.
|
|
CurrentTask string `json:"current_task,omitempty"`
|
|
|
|
// Capabilities lists what this worker can do (e.g., "build", "deploy").
|
|
Capabilities []string `json:"capabilities,omitempty"`
|
|
|
|
// RegisteredAt is when the worker first joined the pool.
|
|
RegisteredAt time.Time `json:"registered_at"`
|
|
|
|
// LastHeartbeat is the most recent heartbeat timestamp.
|
|
LastHeartbeat time.Time `json:"last_heartbeat"`
|
|
|
|
// Version is the worker binary version.
|
|
Version string `json:"version,omitempty"`
|
|
}
|
|
|
|
// IsAvailable returns true if the worker can accept new tasks.
|
|
func (w *Worker) IsAvailable() bool {
|
|
return w.Status == WorkerStatusIdle
|
|
}
|
|
|
|
// IsHealthy returns true if the worker has a recent heartbeat.
|
|
func (w *Worker) IsHealthy(threshold time.Duration) bool {
|
|
return time.Since(w.LastHeartbeat) < threshold
|
|
}
|
|
|
|
// WorkerStatus represents the current state of a worker.
|
|
type WorkerStatus string
|
|
|
|
const (
|
|
WorkerStatusIdle WorkerStatus = "idle"
|
|
WorkerStatusBusy WorkerStatus = "busy"
|
|
WorkerStatusDraining WorkerStatus = "draining"
|
|
WorkerStatusOffline WorkerStatus = "offline"
|
|
)
|
|
|
|
// IsValid returns true if the status is a known valid status.
|
|
func (s WorkerStatus) IsValid() bool {
|
|
switch s {
|
|
case WorkerStatusIdle, WorkerStatusBusy, WorkerStatusDraining, WorkerStatusOffline:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ValidWorkerStatuses returns all valid worker status values.
|
|
func ValidWorkerStatuses() []WorkerStatus {
|
|
return []WorkerStatus{WorkerStatusIdle, WorkerStatusBusy, WorkerStatusDraining, WorkerStatusOffline}
|
|
}
|
|
|
|
// Validate checks that the Worker has required fields for registration.
|
|
func (w *Worker) Validate() error {
|
|
if w.ID == "" {
|
|
return ErrWorkerIDRequired
|
|
}
|
|
if w.Hostname == "" {
|
|
return ErrWorkerHostnameRequired
|
|
}
|
|
return nil
|
|
}
|