-- ============ jobs(DB-backed 事件型任务) ============ CREATE TABLE jobs ( id UUID PRIMARY KEY, type TEXT NOT NULL, payload JSONB NOT NULL DEFAULT '{}'::jsonb, status TEXT NOT NULL DEFAULT 'pending', scheduled_at TIMESTAMPTZ NOT NULL DEFAULT now(), attempts INT NOT NULL DEFAULT 0, max_attempts INT NOT NULL DEFAULT 5, leased_at TIMESTAMPTZ, leased_by TEXT, last_error TEXT, completed_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), CONSTRAINT jobs_status_check CHECK (status IN ('pending','running','completed','dead')) ); CREATE INDEX idx_jobs_pickup ON jobs(scheduled_at, status) WHERE status = 'pending'; CREATE INDEX idx_jobs_lease ON jobs(leased_at) WHERE status = 'running'; CREATE INDEX idx_jobs_purge ON jobs(completed_at) WHERE status IN ('completed', 'dead'); -- ============ ALTER workspace_worktrees: add prune_warning_at ============ ALTER TABLE workspace_worktrees ADD COLUMN prune_warning_at TIMESTAMPTZ;