Files
Agent-System/deploy/postgres/goose/00038_2026-09-15-dataset-lifecycle.sql
T
weichenandCursor 5ac14d649b feat(db): add goose 00038 dataset lifecycle tables
Registry、checkpoint queue 与 destroy 请求表属主 dataset;必须可 Down,不改历史 Goose。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 02:31:34 +00:00

92 lines
3.4 KiB
SQL

-- +goose Up
-- U9 dataset registry, checkpointed backfill queue, and destroy gates.
-- Do not modify historical Goose files.
CREATE TABLE IF NOT EXISTS dataset_registry (
dataset_id TEXT PRIMARY KEY,
class TEXT NOT NULL,
display_name TEXT NOT NULL,
storage_identity TEXT NOT NULL,
source_schema INT NOT NULL DEFAULT 0,
source_commit TEXT NOT NULL DEFAULT '',
status TEXT NOT NULL DEFAULT 'approved',
project_count INT NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
CONSTRAINT chk_dataset_class CHECK (class IN (
'pinned', 'demo', 'regression', 'migration_baseline', 'ephemeral', 'quarantine'
)),
CONSTRAINT chk_dataset_status CHECK (status IN (
'approved', 'imported', 'quarantine', 'retired'
))
);
CREATE TABLE IF NOT EXISTS dataset_backfill_jobs (
job_id TEXT PRIMARY KEY,
status TEXT NOT NULL,
source_schema INT NOT NULL DEFAULT 0,
source_commit TEXT NOT NULL DEFAULT '',
storage_identity TEXT NOT NULL DEFAULT '',
paused_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
CONSTRAINT chk_backfill_job_status CHECK (status IN (
'running', 'paused', 'completed', 'failed'
))
);
CREATE TABLE IF NOT EXISTS dataset_backfill_checkpoints (
job_id TEXT NOT NULL REFERENCES dataset_backfill_jobs(job_id) ON DELETE CASCADE,
shard INT NOT NULL,
source_kind TEXT NOT NULL,
last_pk BIGINT NOT NULL DEFAULT 0,
scanned INT NOT NULL DEFAULT 0,
succeeded INT NOT NULL DEFAULT 0,
quarantined INT NOT NULL DEFAULT 0,
retry_watermark INT NOT NULL DEFAULT 0,
PRIMARY KEY (job_id, shard, source_kind),
CONSTRAINT chk_backfill_source_kind CHECK (source_kind IN (
'snapshot', 'agent_commit', 'approved', 'chat_turn'
))
);
CREATE TABLE IF NOT EXISTS dataset_backfill_queue (
job_id TEXT NOT NULL REFERENCES dataset_backfill_jobs(job_id) ON DELETE CASCADE,
source_kind TEXT NOT NULL,
source_pk BIGINT NOT NULL,
shard INT NOT NULL DEFAULT 0,
status TEXT NOT NULL DEFAULT 'pending',
payload_sha256 CHAR(64) NOT NULL DEFAULT '',
logical_id TEXT NOT NULL DEFAULT '',
claimed_at TIMESTAMPTZ,
PRIMARY KEY (job_id, source_kind, source_pk),
CONSTRAINT chk_backfill_queue_status CHECK (status IN (
'pending', 'claimed', 'done', 'quarantine'
))
);
CREATE INDEX IF NOT EXISTS idx_dataset_backfill_queue_claim
ON dataset_backfill_queue (job_id, status, source_pk);
CREATE TABLE IF NOT EXISTS dataset_destroy_requests (
request_id TEXT PRIMARY KEY,
target_identity TEXT NOT NULL,
delete_manifest_sha CHAR(64) NOT NULL,
recoverable_location TEXT NOT NULL,
quarantine_until TIMESTAMPTZ NOT NULL,
approval_1_by TEXT NOT NULL DEFAULT '',
approval_2_by TEXT NOT NULL DEFAULT '',
coverage_ok BOOLEAN NOT NULL DEFAULT FALSE,
backup_ok BOOLEAN NOT NULL DEFAULT FALSE,
corpus_ok BOOLEAN NOT NULL DEFAULT FALSE,
status TEXT NOT NULL DEFAULT 'blocked',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
CONSTRAINT chk_destroy_status CHECK (status IN ('blocked', 'approved', 'applied'))
);
-- +goose Down
DROP TABLE IF EXISTS dataset_destroy_requests;
DROP TABLE IF EXISTS dataset_backfill_queue;
DROP TABLE IF EXISTS dataset_backfill_checkpoints;
DROP TABLE IF EXISTS dataset_backfill_jobs;
DROP TABLE IF EXISTS dataset_registry;