From 028b0eb0152e3af6846155b91e0400ac7b6d4605 Mon Sep 17 00:00:00 2001 From: weichen Date: Mon, 14 Sep 2026 10:51:25 +0000 Subject: [PATCH] feat(db): add FAV staging, outbox, and deletion ledger tables Use goose 00034 because 00033 already belongs to task-run governance. Co-authored-by: Cursor --- .../00034_2026-09-14-final-artifact-vault.sql | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 deploy/postgres/goose/00034_2026-09-14-final-artifact-vault.sql diff --git a/deploy/postgres/goose/00034_2026-09-14-final-artifact-vault.sql b/deploy/postgres/goose/00034_2026-09-14-final-artifact-vault.sql new file mode 100644 index 00000000..4064a813 --- /dev/null +++ b/deploy/postgres/goose/00034_2026-09-14-final-artifact-vault.sql @@ -0,0 +1,93 @@ +-- +goose Up +CREATE TABLE IF NOT EXISTS final_artifacts ( + artifact_uuid TEXT PRIMARY KEY, + idempotency_key TEXT NOT NULL UNIQUE, + artifact_type TEXT NOT NULL, + logical_resource_id TEXT NOT NULL, + environment TEXT NOT NULL, + project_id BIGINT, + project_external_key TEXT NOT NULL, + source_event_id TEXT NOT NULL, + source_event_kind TEXT NOT NULL DEFAULT '', + source_snapshot_id BIGINT, + source_message_id BIGINT, + source_run_id TEXT NOT NULL DEFAULT '', + payload_sha256 CHAR(64) NOT NULL, + manifest_sha256 CHAR(64), + vault_storage_identity TEXT, + terminal_state TEXT NOT NULL DEFAULT '', + policy_version TEXT NOT NULL DEFAULT '', + publication_status TEXT NOT NULL, + retention_class TEXT NOT NULL DEFAULT 'governance', + requested_at TIMESTAMPTZ NOT NULL DEFAULT now(), + verified_at TIMESTAMPTZ, + tombstoned_at TIMESTAMPTZ, + CONSTRAINT chk_fav_type CHECK (artifact_type IN ('agent_commit','sealed_version','approved_document','freeform_publish','assistant_reply')), + CONSTRAINT chk_fav_status CHECK (publication_status IN ('requested','publishing','verified','retryable_failed','tombstoned','purged','quarantine')) +); + +CREATE TABLE IF NOT EXISTS artifact_payload_staging ( + staging_uuid TEXT PRIMARY KEY, + project_id BIGINT, + source_event_id TEXT NOT NULL, + payload_sha256 CHAR(64) NOT NULL, + encrypted_payload BYTEA NOT NULL, + classification TEXT NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + releasable_at TIMESTAMPTZ, + UNIQUE (source_event_id, payload_sha256) +); + +CREATE TABLE IF NOT EXISTS artifact_blob_references ( + artifact_uuid TEXT NOT NULL REFERENCES final_artifacts(artifact_uuid), + project_scope TEXT NOT NULL, + payload_sha256 CHAR(64) NOT NULL, + envelope_key_ref TEXT NOT NULL DEFAULT '', + reference_status TEXT NOT NULL DEFAULT 'active', + retention_class TEXT NOT NULL DEFAULT 'governance', + legal_hold BOOLEAN NOT NULL DEFAULT FALSE, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + PRIMARY KEY (artifact_uuid, payload_sha256) +); + +CREATE TABLE IF NOT EXISTS artifact_publication_attempts ( + artifact_uuid TEXT NOT NULL, + idempotency_key TEXT NOT NULL, + attempt_no INT NOT NULL, + error_code TEXT NOT NULL DEFAULT '', + receipt TEXT NOT NULL DEFAULT '', + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + PRIMARY KEY (artifact_uuid, attempt_no) +); + +CREATE TABLE IF NOT EXISTS artifact_deletion_ledger ( + artifact_uuid TEXT NOT NULL, + reason TEXT NOT NULL, + authority TEXT NOT NULL DEFAULT '', + effective_at TIMESTAMPTZ NOT NULL, + applied_at TIMESTAMPTZ, + audit_ref TEXT NOT NULL DEFAULT '' +); + +CREATE TABLE IF NOT EXISTS artifact_quarantine ( + logical_resource_id TEXT NOT NULL, + reason TEXT NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE TABLE IF NOT EXISTS artifact_backfill_exclusions ( + logical_resource_id TEXT PRIMARY KEY, + reason TEXT NOT NULL, + approved_by TEXT NOT NULL, + expires_at TIMESTAMPTZ NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +-- +goose Down +DROP TABLE IF EXISTS artifact_backfill_exclusions; +DROP TABLE IF EXISTS artifact_quarantine; +DROP TABLE IF EXISTS artifact_deletion_ledger; +DROP TABLE IF EXISTS artifact_publication_attempts; +DROP TABLE IF EXISTS artifact_blob_references; +DROP TABLE IF EXISTS artifact_payload_staging; +DROP TABLE IF EXISTS final_artifacts;