-- Operations: Tracks all project operations for debugging -- Operations capture what happened step-by-step with enough detail to pinpoint failures. -- 30-day retention - operations are for debugging, not compliance. CREATE TABLE IF NOT EXISTS operations ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), project_id TEXT NOT NULL, type TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'pending', -- Correlation request_id TEXT, -- HTTP request that initiated triggered_by UUID REFERENCES operations(id) ON DELETE SET NULL, commit_sha TEXT, -- Git commit this operation created/triggered external_ref TEXT, -- Woodpecker build#, K8s deployment, etc. -- Timing started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), completed_at TIMESTAMPTZ, duration_ms INT, -- Content (JSONB for flexibility) input JSONB, -- What was requested output JSONB, -- What was produced -- Error handling: essence + detail error TEXT, -- One-line summary error_detail TEXT, -- Full stack/output (truncated to 10KB) -- Steps steps JSONB NOT NULL DEFAULT '[]', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Index for listing operations by project (most common query) CREATE INDEX IF NOT EXISTS idx_ops_project_time ON operations(project_id, started_at DESC); -- Partial index for active/failed operations (status queries) CREATE INDEX IF NOT EXISTS idx_ops_project_status ON operations(project_id, status) WHERE status IN ('pending', 'running', 'failed'); -- Index for finding operations by commit SHA (build correlation) CREATE INDEX IF NOT EXISTS idx_ops_commit ON operations(commit_sha) WHERE commit_sha IS NOT NULL; -- Index for cleanup worker (delete operations older than 30 days) CREATE INDEX IF NOT EXISTS idx_ops_cleanup ON operations(started_at); -- Comments COMMENT ON TABLE operations IS 'Tracks project operations for debugging (30-day retention)'; COMMENT ON COLUMN operations.id IS 'Unique operation ID'; COMMENT ON COLUMN operations.project_id IS 'Project this operation belongs to'; COMMENT ON COLUMN operations.type IS 'Operation type: project.create, component.add, build, resource.provision'; COMMENT ON COLUMN operations.status IS 'Operation status: pending, running, completed, failed'; COMMENT ON COLUMN operations.request_id IS 'HTTP request ID that initiated this operation'; COMMENT ON COLUMN operations.triggered_by IS 'Parent operation that triggered this one'; COMMENT ON COLUMN operations.commit_sha IS 'Git commit this operation created or was triggered by'; COMMENT ON COLUMN operations.external_ref IS 'External reference (e.g., Woodpecker build#42)'; COMMENT ON COLUMN operations.started_at IS 'When the operation started'; COMMENT ON COLUMN operations.completed_at IS 'When the operation finished'; COMMENT ON COLUMN operations.duration_ms IS 'Total operation duration in milliseconds'; COMMENT ON COLUMN operations.input IS 'Operation input parameters as JSONB'; COMMENT ON COLUMN operations.output IS 'Operation output/result as JSONB'; COMMENT ON COLUMN operations.error IS 'One-line error summary'; COMMENT ON COLUMN operations.error_detail IS 'Full error detail (truncated to 10KB)'; COMMENT ON COLUMN operations.steps IS 'Operation steps as JSONB array'; COMMENT ON COLUMN operations.created_at IS 'When the record was created';