Add goose v19 task_runs/task_run_events tables with PG store for restart replay, orphan interruption on startup, strict /ready checks, and strip client work_dir from chat/SSE paths per P0 path sandbox requirements. Co-authored-by: Cursor <cursoragent@cursor.com>
42 lines
1.8 KiB
SQL
42 lines
1.8 KiB
SQL
-- +goose Up
|
|
-- Phase 4: 长任务持久化与 SSE 事件重放
|
|
|
|
CREATE TABLE IF NOT EXISTS task_runs (
|
|
run_id TEXT PRIMARY KEY,
|
|
session_id TEXT NOT NULL DEFAULT '',
|
|
project_id BIGINT REFERENCES projects(id) ON DELETE SET NULL,
|
|
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
client_turn_id TEXT NOT NULL DEFAULT '',
|
|
task_key TEXT NOT NULL DEFAULT '',
|
|
stage TEXT NOT NULL DEFAULT '',
|
|
status TEXT NOT NULL DEFAULT 'running',
|
|
workspace_id TEXT NOT NULL DEFAULT '',
|
|
assistant_message_id BIGINT,
|
|
error_message TEXT NOT NULL DEFAULT '',
|
|
idempotency_key TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CONSTRAINT chk_task_run_status CHECK (
|
|
status IN ('pending', 'running', 'completed', 'failed', 'cancelled', 'finalizing_failed', 'quality_failed', 'interrupted')
|
|
)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_user ON task_runs(user_id, updated_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_project ON task_runs(project_id, updated_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_running ON task_runs(status) WHERE status = 'running';
|
|
|
|
CREATE TABLE IF NOT EXISTS task_run_events (
|
|
run_id TEXT NOT NULL REFERENCES task_runs(run_id) ON DELETE CASCADE,
|
|
seq BIGINT NOT NULL,
|
|
event_type TEXT NOT NULL,
|
|
payload JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (run_id, seq)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_task_run_events_run ON task_run_events(run_id, seq);
|
|
|
|
-- +goose Down
|
|
DROP TABLE IF EXISTS task_run_events;
|
|
DROP TABLE IF EXISTS task_runs;
|