Import the committed KnowledgeFS snapshot dc4072ee302317145612087ce7440851dc329fd0 under knowledge-fs/ without its Git history, local IDE settings, or build artifacts.
270 lines
9.4 KiB
SQL
270 lines
9.4 KiB
SQL
-- Knowledge Platform schema migration
|
|
-- Migration id: 0009_legacy_space_bootstrap
|
|
-- Dialect: postgres
|
|
|
|
-- Legacy NULL-generation artifacts cannot be adopted safely: historical Graph entities may span
|
|
-- documents and therefore do not have a recoverable single-document owner. A bootstrap instead
|
|
-- rebuilds the frozen document snapshot through the durable generation writer. The job row is
|
|
-- also the query-readiness latch: strict readers remain unavailable until run_state=succeeded.
|
|
CREATE TABLE IF NOT EXISTS "legacy_space_publication_bootstraps" (
|
|
"id" UUID PRIMARY KEY NOT NULL,
|
|
"tenant_id" VARCHAR(255) NOT NULL,
|
|
"knowledge_space_id" UUID NOT NULL,
|
|
"idempotency_key" VARCHAR(255) NOT NULL,
|
|
"checkpoint" VARCHAR(32) NOT NULL,
|
|
"run_state" VARCHAR(16) NOT NULL,
|
|
"total_documents" INTEGER NOT NULL,
|
|
"completed_documents" INTEGER NOT NULL,
|
|
"worker_id" VARCHAR(255),
|
|
"lease_token" UUID,
|
|
"lease_expires_at" TIMESTAMPTZ,
|
|
"heartbeat_at" TIMESTAMPTZ,
|
|
"last_error_code" VARCHAR(64),
|
|
"last_error_message" TEXT,
|
|
"row_version" INTEGER NOT NULL,
|
|
"published_publication_id" UUID,
|
|
"published_fingerprint" VARCHAR(86),
|
|
"published_head_revision" INTEGER,
|
|
"snapshot_metadata" JSONB NOT NULL,
|
|
"created_at" TIMESTAMPTZ NOT NULL,
|
|
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
"completed_at" TIMESTAMPTZ,
|
|
CONSTRAINT "legacy_space_bootstraps_checkpoint_ck"
|
|
CHECK (
|
|
"checkpoint" IN (
|
|
'pending_snapshot',
|
|
'snapshot_captured',
|
|
'rebuilding',
|
|
'verifying',
|
|
'published'
|
|
)
|
|
),
|
|
CONSTRAINT "legacy_space_bootstraps_run_state_ck"
|
|
CHECK ("run_state" IN ('queued', 'running', 'succeeded', 'failed', 'canceled')),
|
|
CONSTRAINT "legacy_space_bootstraps_counts_ck"
|
|
CHECK (
|
|
"total_documents" >= 0
|
|
AND "completed_documents" >= 0
|
|
AND "completed_documents" <= "total_documents"
|
|
),
|
|
CONSTRAINT "legacy_space_bootstraps_row_version_ck" CHECK ("row_version" >= 0),
|
|
CONSTRAINT "legacy_space_bootstraps_lease_state_ck"
|
|
CHECK (
|
|
(
|
|
"run_state" = 'running'
|
|
AND "worker_id" IS NOT NULL
|
|
AND "lease_token" IS NOT NULL
|
|
AND "lease_expires_at" IS NOT NULL
|
|
AND "heartbeat_at" IS NOT NULL
|
|
AND "completed_at" IS NULL
|
|
)
|
|
OR (
|
|
"run_state" <> 'running'
|
|
AND "worker_id" IS NULL
|
|
AND "lease_token" IS NULL
|
|
AND "lease_expires_at" IS NULL
|
|
AND "heartbeat_at" IS NULL
|
|
)
|
|
),
|
|
CONSTRAINT "legacy_space_bootstraps_terminal_ck"
|
|
CHECK (
|
|
("run_state" IN ('succeeded', 'failed', 'canceled') AND "completed_at" IS NOT NULL)
|
|
OR ("run_state" IN ('queued', 'running') AND "completed_at" IS NULL)
|
|
),
|
|
CONSTRAINT "legacy_space_bootstraps_publication_ck"
|
|
CHECK (
|
|
(
|
|
"run_state" = 'succeeded'
|
|
AND "checkpoint" = 'published'
|
|
AND "completed_documents" = "total_documents"
|
|
AND (
|
|
"total_documents" = 0
|
|
OR (
|
|
"published_publication_id" IS NOT NULL
|
|
AND "published_fingerprint" IS NOT NULL
|
|
AND "published_head_revision" IS NOT NULL
|
|
AND "published_head_revision" > 0
|
|
)
|
|
)
|
|
)
|
|
OR "run_state" <> 'succeeded'
|
|
),
|
|
CONSTRAINT "legacy_space_bootstraps_lease_token_ck"
|
|
CHECK (
|
|
"lease_token" IS NULL
|
|
OR "lease_token" <> '00000000-0000-0000-0000-000000000000'::uuid
|
|
),
|
|
FOREIGN KEY ("tenant_id", "knowledge_space_id")
|
|
REFERENCES "knowledge_spaces" ("tenant_id", "id")
|
|
ON DELETE CASCADE,
|
|
FOREIGN KEY (
|
|
"tenant_id",
|
|
"knowledge_space_id",
|
|
"published_publication_id",
|
|
"published_fingerprint"
|
|
)
|
|
REFERENCES "projection_set_publications" (
|
|
"tenant_id",
|
|
"knowledge_space_id",
|
|
"id",
|
|
"fingerprint"
|
|
)
|
|
ON DELETE RESTRICT
|
|
);
|
|
|
|
-- One immutable migration ledger exists per tenant-scoped space. A failed job is retried in place,
|
|
-- so operators cannot accidentally create a second snapshot with different membership.
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "legacy_space_bootstraps_space_uq"
|
|
ON "legacy_space_publication_bootstraps" ("tenant_id", "knowledge_space_id");
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "legacy_space_bootstraps_idempotency_uq"
|
|
ON "legacy_space_publication_bootstraps" (
|
|
"tenant_id",
|
|
"knowledge_space_id",
|
|
"idempotency_key"
|
|
);
|
|
CREATE INDEX IF NOT EXISTS "legacy_space_bootstraps_claim_idx"
|
|
ON "legacy_space_publication_bootstraps" (
|
|
"run_state",
|
|
"lease_expires_at",
|
|
"updated_at",
|
|
"id"
|
|
);
|
|
|
|
-- Items freeze the complete document/version/hash set before any generation build is admitted.
|
|
-- compilation_attempt_id is intentionally an audit reference rather than an FK: normal retention
|
|
-- may delete terminal compilation attempts without weakening the bootstrap ledger.
|
|
CREATE TABLE IF NOT EXISTS "legacy_space_publication_bootstrap_items" (
|
|
"bootstrap_id" UUID NOT NULL,
|
|
"document_asset_id" UUID NOT NULL,
|
|
"document_version" INTEGER NOT NULL,
|
|
"document_sha256" VARCHAR(64) NOT NULL,
|
|
"ordinal" INTEGER NOT NULL,
|
|
"compilation_attempt_id" UUID,
|
|
"status" VARCHAR(16) NOT NULL,
|
|
"last_error" TEXT,
|
|
"created_at" TIMESTAMPTZ NOT NULL,
|
|
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
PRIMARY KEY ("bootstrap_id", "document_asset_id"),
|
|
CONSTRAINT "legacy_space_bootstrap_items_version_ck" CHECK ("document_version" > 0),
|
|
CONSTRAINT "legacy_space_bootstrap_items_ordinal_ck" CHECK ("ordinal" >= 0),
|
|
CONSTRAINT "legacy_space_bootstrap_items_status_ck"
|
|
CHECK ("status" IN ('pending', 'running', 'succeeded', 'failed')),
|
|
FOREIGN KEY ("bootstrap_id")
|
|
REFERENCES "legacy_space_publication_bootstraps" ("id")
|
|
ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "legacy_space_bootstrap_items_ordinal_uq"
|
|
ON "legacy_space_publication_bootstrap_items" ("bootstrap_id", "ordinal");
|
|
CREATE INDEX IF NOT EXISTS "legacy_space_bootstrap_items_next_idx"
|
|
ON "legacy_space_publication_bootstrap_items" (
|
|
"bootstrap_id",
|
|
"status",
|
|
"ordinal",
|
|
"document_asset_id"
|
|
);
|
|
CREATE INDEX IF NOT EXISTS "legacy_space_bootstrap_items_attempt_idx"
|
|
ON "legacy_space_publication_bootstrap_items" (
|
|
"compilation_attempt_id",
|
|
"bootstrap_id",
|
|
"document_asset_id"
|
|
);
|
|
|
|
-- A document mutation holds this durable, space-exclusive lease from admission through its final
|
|
-- metadata write. Bootstrap snapshot capture takes the same knowledge_spaces row lock and refuses
|
|
-- to run while a lease exists, closing the check-then-write race. Leases never expire implicitly:
|
|
-- a crashed writer fails closed until an operator proves it stopped and removes the orphan.
|
|
CREATE TABLE IF NOT EXISTS "knowledge_space_mutation_leases" (
|
|
"id" UUID PRIMARY KEY NOT NULL,
|
|
"tenant_id" VARCHAR(255) NOT NULL,
|
|
"knowledge_space_id" UUID NOT NULL,
|
|
"operation" VARCHAR(64) NOT NULL,
|
|
"acquired_at" TIMESTAMPTZ NOT NULL,
|
|
FOREIGN KEY ("tenant_id", "knowledge_space_id")
|
|
REFERENCES "knowledge_spaces" ("tenant_id", "id")
|
|
ON DELETE CASCADE
|
|
);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "knowledge_space_mutation_leases_space_uq"
|
|
ON "knowledge_space_mutation_leases" ("tenant_id", "knowledge_space_id");
|
|
|
|
-- Install the fail-closed latch in the same migration that introduces strict published reads.
|
|
-- The marker deliberately does not copy the document set inside this DDL transaction. The bounded
|
|
-- bootstrap runtime freezes that set under the stable space-row lock before admitting any build.
|
|
-- knowledge_space_id is already a tenant-owned UUID and is safe as the one-time ledger id.
|
|
INSERT INTO "legacy_space_publication_bootstraps" (
|
|
"id",
|
|
"tenant_id",
|
|
"knowledge_space_id",
|
|
"idempotency_key",
|
|
"checkpoint",
|
|
"run_state",
|
|
"total_documents",
|
|
"completed_documents",
|
|
"row_version",
|
|
"snapshot_metadata",
|
|
"created_at",
|
|
"updated_at"
|
|
)
|
|
SELECT
|
|
ks."id",
|
|
ks."tenant_id",
|
|
ks."id",
|
|
'legacy-space-publication-bootstrap-v1',
|
|
'pending_snapshot',
|
|
'queued',
|
|
0,
|
|
0,
|
|
0,
|
|
'{"schemaVersion":1,"strategy":"full-generation-rebuild","source":"migration-marker"}'::jsonb,
|
|
CURRENT_TIMESTAMP,
|
|
CURRENT_TIMESTAMP
|
|
FROM "knowledge_spaces" ks
|
|
WHERE NOT EXISTS (
|
|
SELECT 1
|
|
FROM "projection_set_publication_heads" head
|
|
WHERE head."tenant_id" = ks."tenant_id"
|
|
AND head."knowledge_space_id" = ks."id"
|
|
)
|
|
AND (
|
|
EXISTS (
|
|
SELECT 1 FROM "document_assets" asset
|
|
WHERE asset."knowledge_space_id" = ks."id"
|
|
)
|
|
OR EXISTS (
|
|
SELECT 1 FROM "knowledge_nodes" node
|
|
WHERE node."knowledge_space_id" = ks."id"
|
|
AND node."publication_generation_id" IS NULL
|
|
)
|
|
OR EXISTS (
|
|
SELECT 1 FROM "index_projections" projection
|
|
WHERE projection."knowledge_space_id" = ks."id"
|
|
AND projection."publication_generation_id" IS NULL
|
|
)
|
|
OR EXISTS (
|
|
SELECT 1 FROM "document_outlines" outline
|
|
WHERE outline."knowledge_space_id" = ks."id"
|
|
AND outline."publication_generation_id" IS NULL
|
|
)
|
|
OR EXISTS (
|
|
SELECT 1 FROM "document_multimodal_manifests" manifest
|
|
WHERE manifest."knowledge_space_id" = ks."id"
|
|
AND manifest."publication_generation_id" IS NULL
|
|
)
|
|
OR EXISTS (
|
|
SELECT 1 FROM "knowledge_paths" path
|
|
WHERE path."knowledge_space_id" = ks."id"
|
|
AND path."publication_generation_id" IS NULL
|
|
)
|
|
OR EXISTS (
|
|
SELECT 1 FROM "graph_entities" entity
|
|
WHERE entity."knowledge_space_id" = ks."id"
|
|
AND entity."publication_generation_id" IS NULL
|
|
)
|
|
OR EXISTS (
|
|
SELECT 1 FROM "graph_relations" relation
|
|
WHERE relation."knowledge_space_id" = ks."id"
|
|
AND relation."publication_generation_id" IS NULL
|
|
)
|
|
)
|
|
ON CONFLICT ("tenant_id", "knowledge_space_id") DO NOTHING;
|