From 472b0cfd2b908b520ef1446ab70ed9bca92b5e70 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Tue, 16 Jun 2026 17:29:39 +0200 Subject: [PATCH] fix(db): canonical_controls PK + FKs wiederherstellen (prod DB-Swap-Verlust) Migration 157: ADD PRIMARY KEY canonical_controls(id) + FK atom_classification + FK control_suppressions, jeweils nur falls fehlend (No-Op auf macmini, fixt prod). Verifiziert: 314.811 distinct ids, 0 NULL, 0 Orphans. DB-Owner-Freigabe. [migration-approved] Co-Authored-By: Claude Opus 4.8 --- .../157_restore_canonical_pk_fks.sql | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 backend-compliance/migrations/157_restore_canonical_pk_fks.sql diff --git a/backend-compliance/migrations/157_restore_canonical_pk_fks.sql b/backend-compliance/migrations/157_restore_canonical_pk_fks.sql new file mode 100644 index 00000000..b0299467 --- /dev/null +++ b/backend-compliance/migrations/157_restore_canonical_pk_fks.sql @@ -0,0 +1,45 @@ +-- Migration 157: restore the canonical_controls PRIMARY KEY + the foreign keys +-- that the prod DB-swap dropped (data copied without constraints). macmini hat +-- beides bereits → die Guards machen es dort zum No-Op; auf prod wird es gesetzt. +-- Verifiziert vor Anwendung: canonical_controls.id 314.811/314.811 distinct, 0 +-- NULL; atom_classification 0 Orphans. DB-Owner-Freigabe 2026-06-16. Idempotent. +-- [migration-approved] + +SET search_path TO compliance, public; + +DO $$ +BEGIN + -- 1) Primary key on canonical_controls(id) + IF NOT EXISTS ( + SELECT 1 FROM pg_constraint + WHERE conrelid = 'compliance.canonical_controls'::regclass AND contype = 'p' + ) THEN + ALTER TABLE compliance.canonical_controls ADD PRIMARY KEY (id); + END IF; + + -- 2) atom_classification.control_uuid → canonical_controls(id) + IF NOT EXISTS ( + SELECT 1 FROM pg_constraint + WHERE conrelid = 'compliance.atom_classification'::regclass AND contype = 'f' + AND conname = 'atom_classification_control_uuid_fkey' + ) THEN + ALTER TABLE compliance.atom_classification + ADD CONSTRAINT atom_classification_control_uuid_fkey + FOREIGN KEY (control_uuid) + REFERENCES compliance.canonical_controls(id) ON DELETE CASCADE; + END IF; + + -- 3) control_suppressions.control_uuid → canonical_controls(id) + IF EXISTS (SELECT 1 FROM information_schema.tables + WHERE table_schema = 'compliance' + AND table_name = 'control_suppressions') + AND NOT EXISTS ( + SELECT 1 FROM pg_constraint + WHERE conrelid = 'compliance.control_suppressions'::regclass AND contype = 'f' + ) THEN + ALTER TABLE compliance.control_suppressions + ADD CONSTRAINT control_suppressions_control_uuid_fkey + FOREIGN KEY (control_uuid) + REFERENCES compliance.canonical_controls(id) ON DELETE CASCADE; + END IF; +END $$;