rdev/internal/db/migrations/012_worker_registry.sql
jordan bc47e426b0 feat: Add CI pipeline proxy, DNS alias management, and worker executor system
- 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>
2026-01-27 21:05:28 -07:00

72 lines
3.4 KiB
SQL

-- Workers table for worker pool registration and health tracking.
-- Workers register on startup, send heartbeats, and are marked offline
-- if they miss heartbeats beyond the configured threshold.
CREATE TABLE IF NOT EXISTS workers (
id VARCHAR(255) PRIMARY KEY,
hostname VARCHAR(255) NOT NULL,
status VARCHAR(50) NOT NULL DEFAULT 'idle',
current_task VARCHAR(255),
capabilities JSONB DEFAULT '[]',
version VARCHAR(50),
registered_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
last_heartbeat TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT workers_valid_status CHECK (status IN ('idle', 'busy', 'draining', 'offline'))
);
-- Index for finding idle workers (used during task assignment)
CREATE INDEX IF NOT EXISTS idx_workers_status
ON workers(status)
WHERE status = 'idle';
-- Index for health checker (finding stale heartbeats)
CREATE INDEX IF NOT EXISTS idx_workers_heartbeat
ON workers(last_heartbeat);
COMMENT ON TABLE workers IS 'Worker pool registry for tracking worker lifecycle and health';
COMMENT ON COLUMN workers.id IS 'Unique worker identifier (typically Kubernetes pod name)';
COMMENT ON COLUMN workers.hostname IS 'Worker hostname for identification';
COMMENT ON COLUMN workers.status IS 'Worker status: idle, busy, draining, offline';
COMMENT ON COLUMN workers.current_task IS 'ID of the work queue task currently being executed';
COMMENT ON COLUMN workers.capabilities IS 'JSON array of worker capabilities (e.g., build, deploy)';
COMMENT ON COLUMN workers.version IS 'Worker binary version string';
COMMENT ON COLUMN workers.last_heartbeat IS 'Most recent heartbeat timestamp for health monitoring';
-- Build audit table for tracking build execution history.
-- Every build request creates an audit entry that is updated
-- when the build completes or fails.
CREATE TABLE IF NOT EXISTS build_audit (
task_id VARCHAR(255) PRIMARY KEY,
project_id VARCHAR(255) NOT NULL,
worker_id VARCHAR(255),
spec JSONB NOT NULL,
result JSONB,
status VARCHAR(50) NOT NULL DEFAULT 'pending',
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
completed_at TIMESTAMPTZ,
CONSTRAINT build_audit_valid_status CHECK (status IN ('pending', 'running', 'completed', 'failed', 'cancelled'))
);
-- Index for project build history queries
CREATE INDEX IF NOT EXISTS idx_build_audit_project
ON build_audit(project_id);
-- Index for status-based queries (e.g., "show all running builds")
CREATE INDEX IF NOT EXISTS idx_build_audit_status
ON build_audit(status);
-- Index for time-ordered queries (most recent first)
CREATE INDEX IF NOT EXISTS idx_build_audit_started
ON build_audit(started_at DESC);
COMMENT ON TABLE build_audit IS 'Audit trail for build executions with full spec and result history';
COMMENT ON COLUMN build_audit.task_id IS 'Work queue task ID (links to work_queue.id)';
COMMENT ON COLUMN build_audit.project_id IS 'Project this build belongs to';
COMMENT ON COLUMN build_audit.worker_id IS 'Worker that executed the build';
COMMENT ON COLUMN build_audit.spec IS 'JSON build specification (prompt, template, variables, etc.)';
COMMENT ON COLUMN build_audit.result IS 'JSON build result (output, commit_sha, files_changed, etc.)';
COMMENT ON COLUMN build_audit.status IS 'Build status: pending, running, completed, failed, cancelled';