feat(t-paliad-206): mig 096 — rename proceeding_types.code to lowercase dot-form
19 active fristenrechner codes renamed from UPPER_SNAKE to the lowercase three-position dot-separated taxonomy ratified by m on 2026-05-18 (see docs/design-proceeding-code-taxonomy-2026-05-18.md). IDs are stable; only the `code` STRING changes. Adds upc.ccr.cfi as an illustrative peer of upc.inf.cfi (is_active=true, no rules — Go code routes cascade hits back to inf.cfi with with_ccr=true). Also updates the soft `proceeding_type_code` references on paliad.event_category_concepts so the soft-join through proceeding_types.code keeps resolving, refreshes the deadline_search materialized view, and installs the paliad_proceeding_code_shape CHECK constraint enforcing `^[a-z]+\\.[a-z]+\\.[a-z]+$` on every active row. Idempotent: every UPDATE is guarded on the OLD code; INSERT uses WHERE NOT EXISTS; CHECK is dropped-then-recreated by name. Backup snapshot lives in paliad.proceeding_types_pre_096. Dry-run on the live youpc DB (BEGIN; … ROLLBACK) confirmed 20 active rows on the new shape, 0 old codes left, 1 active upc.ccr.cfi.
This commit is contained in:
99
internal/db/migrations/096_proceeding_code_rename.down.sql
Normal file
99
internal/db/migrations/096_proceeding_code_rename.down.sql
Normal file
@@ -0,0 +1,99 @@
|
||||
-- Reverses mig 096. Restores the original UPPER_SNAKE codes on
|
||||
-- paliad.proceeding_types + paliad.event_category_concepts, drops the
|
||||
-- new upc.ccr.cfi row, removes the shape CHECK, refreshes the
|
||||
-- deadline_search materialized view, then drops the snapshot table.
|
||||
--
|
||||
-- audit_reason wrapper required by the mig 079 audit trigger.
|
||||
|
||||
SELECT set_config(
|
||||
'paliad.audit_reason',
|
||||
'mig 096 (down): revert t-paliad-206 proceeding-code rename — restore UPPER_SNAKE codes from proceeding_types_pre_096, delete upc.ccr.cfi peer, drop shape CHECK',
|
||||
true);
|
||||
|
||||
-- =============================================================================
|
||||
-- 1. Drop the shape CHECK first so the UPPER_SNAKE restores don't trip it.
|
||||
-- =============================================================================
|
||||
|
||||
ALTER TABLE paliad.proceeding_types
|
||||
DROP CONSTRAINT IF EXISTS paliad_proceeding_code_shape;
|
||||
|
||||
-- =============================================================================
|
||||
-- 2. Delete the upc.ccr.cfi peer. The down restores the pre-096 state, which
|
||||
-- didn't have this row. If the row is already missing, the DELETE
|
||||
-- matches zero — idempotent.
|
||||
-- =============================================================================
|
||||
|
||||
DELETE FROM paliad.proceeding_types
|
||||
WHERE code = 'upc.ccr.cfi';
|
||||
|
||||
-- =============================================================================
|
||||
-- 3. Restore proceeding_types.code from the pre_096 snapshot. The snapshot
|
||||
-- captured the rows at first up-migration run; if the table is missing
|
||||
-- (down run before up), the restore is a no-op.
|
||||
-- =============================================================================
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
v_snap_exists boolean;
|
||||
BEGIN
|
||||
SELECT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = 'paliad'
|
||||
AND table_name = 'proceeding_types_pre_096'
|
||||
) INTO v_snap_exists;
|
||||
|
||||
IF NOT v_snap_exists THEN
|
||||
RAISE NOTICE
|
||||
'mig 096 (down): snapshot table paliad.proceeding_types_pre_096 missing — nothing to restore';
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
UPDATE paliad.proceeding_types pt
|
||||
SET code = snap.code
|
||||
FROM paliad.proceeding_types_pre_096 snap
|
||||
WHERE pt.id = snap.id
|
||||
AND pt.code <> snap.code;
|
||||
END $$;
|
||||
|
||||
-- =============================================================================
|
||||
-- 4. Revert soft references on event_category_concepts.proceeding_type_code
|
||||
-- by running the inverse mapping. Symmetric with §4 of the up migration.
|
||||
-- =============================================================================
|
||||
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'UPC_INF' WHERE proceeding_type_code = 'upc.inf.cfi';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'UPC_REV' WHERE proceeding_type_code = 'upc.rev.cfi';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'UPC_PI' WHERE proceeding_type_code = 'upc.pi.cfi';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'UPC_APP' WHERE proceeding_type_code = 'upc.apl.merits';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'UPC_DAMAGES' WHERE proceeding_type_code = 'upc.dmgs.cfi';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'UPC_DISCOVERY' WHERE proceeding_type_code = 'upc.disc.cfi';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'UPC_COST_APPEAL' WHERE proceeding_type_code = 'upc.apl.cost';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'UPC_APP_ORDERS' WHERE proceeding_type_code = 'upc.apl.order';
|
||||
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'DE_INF' WHERE proceeding_type_code = 'de.inf.lg';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'DE_INF_OLG' WHERE proceeding_type_code = 'de.inf.olg';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'DE_INF_BGH' WHERE proceeding_type_code = 'de.inf.bgh';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'DE_NULL' WHERE proceeding_type_code = 'de.null.bpatg';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'DE_NULL_BGH' WHERE proceeding_type_code = 'de.null.bgh';
|
||||
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'EP_GRANT' WHERE proceeding_type_code = 'epa.grant.exa';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'EPA_OPP' WHERE proceeding_type_code = 'epa.opp.opd';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'EPA_APP' WHERE proceeding_type_code = 'epa.opp.boa';
|
||||
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'DPMA_OPP' WHERE proceeding_type_code = 'dpma.opp.dpma';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'DPMA_BPATG_BESCHWERDE' WHERE proceeding_type_code = 'dpma.appeal.bpatg';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'DPMA_BGH_RB' WHERE proceeding_type_code = 'dpma.appeal.bgh';
|
||||
|
||||
-- =============================================================================
|
||||
-- 5. Refresh deadline_search so the reverted proceeding_code strings
|
||||
-- repopulate the materialized view.
|
||||
-- =============================================================================
|
||||
|
||||
REFRESH MATERIALIZED VIEW paliad.deadline_search;
|
||||
|
||||
-- =============================================================================
|
||||
-- 6. Drop the snapshot table so a re-applied up migration captures a
|
||||
-- fresh snapshot of the current state.
|
||||
-- =============================================================================
|
||||
|
||||
DROP TABLE IF EXISTS paliad.proceeding_types_pre_096;
|
||||
226
internal/db/migrations/096_proceeding_code_rename.up.sql
Normal file
226
internal/db/migrations/096_proceeding_code_rename.up.sql
Normal file
@@ -0,0 +1,226 @@
|
||||
-- t-paliad-206 / proceeding-code rename — replace the historical
|
||||
-- UPPER_SNAKE proceeding codes with the lowercase dot-separated
|
||||
-- taxonomy ratified by m on 2026-05-18 (see
|
||||
-- docs/design-proceeding-code-taxonomy-2026-05-18.md).
|
||||
--
|
||||
-- IDs are stable. Only the `code` STRING changes. FKs
|
||||
-- (deadline_rules.proceeding_type_id, projects.proceeding_type_id,
|
||||
-- deadline_rules.spawn_proceeding_type_id) reference IDs, so the
|
||||
-- existing rule corpus and spawn wiring continue to work unchanged
|
||||
-- (incl. mig 095's spawn_proceeding_type_id=11 which becomes
|
||||
-- 'upc.apl.merits' after this migration).
|
||||
--
|
||||
-- Soft references on `code` (text column on event_category_concepts) are
|
||||
-- updated row-for-row to keep the soft join through proceeding_types.code
|
||||
-- resolving.
|
||||
--
|
||||
-- The materialized view paliad.deadline_search projects pt.code as
|
||||
-- proceeding_code; mig 096 REFRESHes it at the bottom so the new codes
|
||||
-- show up in search results immediately.
|
||||
--
|
||||
-- Idempotent:
|
||||
-- * UPDATEs are guarded by `WHERE code = '<OLD>'`. Re-running after a
|
||||
-- successful first apply is a no-op.
|
||||
-- * INSERT of upc.ccr.cfi uses `WHERE NOT EXISTS` keyed on the new
|
||||
-- code (bohr noted in t-paliad-205 that a UNIQUE constraint on the
|
||||
-- code column is not present, hence WHERE NOT EXISTS rather than
|
||||
-- ON CONFLICT).
|
||||
-- * CHECK constraint is dropped-then-recreated under the same name
|
||||
-- (paliad_proceeding_code_shape) so reapplication doesn't error.
|
||||
-- * Snapshot table uses CREATE TABLE IF NOT EXISTS.
|
||||
--
|
||||
-- audit_reason wrapper required by the mig 079 audit trigger.
|
||||
|
||||
SELECT set_config(
|
||||
'paliad.audit_reason',
|
||||
'mig 096: t-paliad-206 proceeding-code rename — lowercase dot-separated taxonomy + new upc.ccr.cfi illustrative peer; see docs/design-proceeding-code-taxonomy-2026-05-18.md',
|
||||
true);
|
||||
|
||||
-- =============================================================================
|
||||
-- 1. Backup snapshot of paliad.proceeding_types BEFORE the rename. The
|
||||
-- rename is forward-only in code (the Go + frontend sweeps reference
|
||||
-- the new strings) but the DB snapshot is the audit anchor and the
|
||||
-- source for the down migration.
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS paliad.proceeding_types_pre_096 AS
|
||||
SELECT *, now() AS snapshotted_at
|
||||
FROM paliad.proceeding_types;
|
||||
|
||||
COMMENT ON TABLE paliad.proceeding_types_pre_096 IS
|
||||
'Snapshot of paliad.proceeding_types taken before mig 096 renamed '
|
||||
'the `code` strings to the lowercase dot-separated taxonomy '
|
||||
'(t-paliad-206, 2026-05-18). Source-of-truth for the down '
|
||||
'migration; persists post-rename as the permanent audit record.';
|
||||
|
||||
-- =============================================================================
|
||||
-- 2. Drop any prior shape CHECK so we can recreate it post-rename. The
|
||||
-- constraint name is stable so reapplication idempotently drops it.
|
||||
-- =============================================================================
|
||||
|
||||
ALTER TABLE paliad.proceeding_types
|
||||
DROP CONSTRAINT IF EXISTS paliad_proceeding_code_shape;
|
||||
|
||||
-- =============================================================================
|
||||
-- 3. The 19 renames. Order-independent — every UPDATE is guarded by
|
||||
-- `WHERE code = '<OLD>'` so re-application is a no-op. id values in
|
||||
-- the trailing comment for cross-reference with the design doc.
|
||||
-- =============================================================================
|
||||
|
||||
-- UPC
|
||||
UPDATE paliad.proceeding_types SET code = 'upc.inf.cfi' WHERE code = 'UPC_INF'; -- id=8
|
||||
UPDATE paliad.proceeding_types SET code = 'upc.rev.cfi' WHERE code = 'UPC_REV'; -- id=9
|
||||
UPDATE paliad.proceeding_types SET code = 'upc.pi.cfi' WHERE code = 'UPC_PI'; -- id=10
|
||||
UPDATE paliad.proceeding_types SET code = 'upc.apl.merits' WHERE code = 'UPC_APP'; -- id=11
|
||||
UPDATE paliad.proceeding_types SET code = 'upc.dmgs.cfi' WHERE code = 'UPC_DAMAGES'; -- id=17
|
||||
UPDATE paliad.proceeding_types SET code = 'upc.disc.cfi' WHERE code = 'UPC_DISCOVERY'; -- id=18
|
||||
UPDATE paliad.proceeding_types SET code = 'upc.apl.cost' WHERE code = 'UPC_COST_APPEAL';-- id=19
|
||||
UPDATE paliad.proceeding_types SET code = 'upc.apl.order' WHERE code = 'UPC_APP_ORDERS'; -- id=20
|
||||
|
||||
-- DE
|
||||
UPDATE paliad.proceeding_types SET code = 'de.inf.lg' WHERE code = 'DE_INF'; -- id=12
|
||||
UPDATE paliad.proceeding_types SET code = 'de.inf.olg' WHERE code = 'DE_INF_OLG'; -- id=25
|
||||
UPDATE paliad.proceeding_types SET code = 'de.inf.bgh' WHERE code = 'DE_INF_BGH'; -- id=26
|
||||
UPDATE paliad.proceeding_types SET code = 'de.null.bpatg' WHERE code = 'DE_NULL'; -- id=13
|
||||
UPDATE paliad.proceeding_types SET code = 'de.null.bgh' WHERE code = 'DE_NULL_BGH'; -- id=27
|
||||
|
||||
-- EPA
|
||||
UPDATE paliad.proceeding_types SET code = 'epa.grant.exa' WHERE code = 'EP_GRANT'; -- id=16
|
||||
UPDATE paliad.proceeding_types SET code = 'epa.opp.opd' WHERE code = 'EPA_OPP'; -- id=14
|
||||
UPDATE paliad.proceeding_types SET code = 'epa.opp.boa' WHERE code = 'EPA_APP'; -- id=15
|
||||
|
||||
-- DPMA
|
||||
UPDATE paliad.proceeding_types SET code = 'dpma.opp.dpma' WHERE code = 'DPMA_OPP'; -- id=28
|
||||
UPDATE paliad.proceeding_types SET code = 'dpma.appeal.bpatg' WHERE code = 'DPMA_BPATG_BESCHWERDE';-- id=29
|
||||
UPDATE paliad.proceeding_types SET code = 'dpma.appeal.bgh' WHERE code = 'DPMA_BGH_RB'; -- id=30
|
||||
|
||||
-- =============================================================================
|
||||
-- 4. Update soft references on event_category_concepts.proceeding_type_code.
|
||||
-- Same OLD→NEW table as above; the column has a UNIQUE NULLS NOT
|
||||
-- DISTINCT constraint on (event_category_id, concept_id, proceeding_type_code)
|
||||
-- but no row has the NEW string yet so the UPDATEs cannot collide.
|
||||
-- =============================================================================
|
||||
|
||||
-- UPC
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'upc.inf.cfi' WHERE proceeding_type_code = 'UPC_INF';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'upc.rev.cfi' WHERE proceeding_type_code = 'UPC_REV';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'upc.pi.cfi' WHERE proceeding_type_code = 'UPC_PI';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'upc.apl.merits' WHERE proceeding_type_code = 'UPC_APP';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'upc.dmgs.cfi' WHERE proceeding_type_code = 'UPC_DAMAGES';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'upc.disc.cfi' WHERE proceeding_type_code = 'UPC_DISCOVERY';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'upc.apl.cost' WHERE proceeding_type_code = 'UPC_COST_APPEAL';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'upc.apl.order' WHERE proceeding_type_code = 'UPC_APP_ORDERS';
|
||||
|
||||
-- DE
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'de.inf.lg' WHERE proceeding_type_code = 'DE_INF';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'de.inf.olg' WHERE proceeding_type_code = 'DE_INF_OLG';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'de.inf.bgh' WHERE proceeding_type_code = 'DE_INF_BGH';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'de.null.bpatg' WHERE proceeding_type_code = 'DE_NULL';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'de.null.bgh' WHERE proceeding_type_code = 'DE_NULL_BGH';
|
||||
|
||||
-- EPA
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'epa.grant.exa' WHERE proceeding_type_code = 'EP_GRANT';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'epa.opp.opd' WHERE proceeding_type_code = 'EPA_OPP';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'epa.opp.boa' WHERE proceeding_type_code = 'EPA_APP';
|
||||
|
||||
-- DPMA
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'dpma.opp.dpma' WHERE proceeding_type_code = 'DPMA_OPP';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'dpma.appeal.bpatg' WHERE proceeding_type_code = 'DPMA_BPATG_BESCHWERDE';
|
||||
UPDATE paliad.event_category_concepts SET proceeding_type_code = 'dpma.appeal.bgh' WHERE proceeding_type_code = 'DPMA_BGH_RB';
|
||||
|
||||
-- =============================================================================
|
||||
-- 5. Insert the new illustrative peer `upc.ccr.cfi`. is_active=true so it
|
||||
-- surfaces in the determinator + dropdowns; no rules attached.
|
||||
-- proceeding_mapping.go routes cascade hits on this code back to
|
||||
-- upc.inf.cfi (id=8) with the with_ccr default flag — see design doc S1.
|
||||
--
|
||||
-- WHERE NOT EXISTS gates the insert on the new code so re-application
|
||||
-- is a no-op even though there's no UNIQUE constraint on (code).
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO paliad.proceeding_types
|
||||
(code, category, jurisdiction, is_active, name, name_en, description)
|
||||
SELECT
|
||||
'upc.ccr.cfi',
|
||||
'fristenrechner',
|
||||
'UPC',
|
||||
true,
|
||||
'Widerklage auf Nichtigkeit',
|
||||
'Counterclaim for Revocation',
|
||||
'Illustrativer Peer von upc.inf.cfi für Widerklagen auf Nichtigkeit. Regeln liegen auf upc.inf.cfi (with_ccr=true); der Fristenrechner leitet bei Auswahl dorthin weiter. Keine eigenen Fristregeln.'
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM paliad.proceeding_types
|
||||
WHERE code = 'upc.ccr.cfi');
|
||||
|
||||
-- =============================================================================
|
||||
-- 6. CHECK constraint on the code shape. Active rows must conform to the
|
||||
-- new lowercase dot-separated form; the carve-out for
|
||||
-- `_archived_litigation` keeps the Pipeline-A bucket addressable.
|
||||
-- =============================================================================
|
||||
|
||||
ALTER TABLE paliad.proceeding_types
|
||||
ADD CONSTRAINT paliad_proceeding_code_shape
|
||||
CHECK (
|
||||
code ~ '^[a-z]+\.[a-z]+\.[a-z]+$'
|
||||
OR code ~ '^_archived_'
|
||||
);
|
||||
|
||||
-- =============================================================================
|
||||
-- 7. Refresh the deadline_search materialized view so search hits return
|
||||
-- the new proceeding_code strings immediately.
|
||||
-- =============================================================================
|
||||
|
||||
REFRESH MATERIALIZED VIEW paliad.deadline_search;
|
||||
|
||||
-- =============================================================================
|
||||
-- 8. Hard assertions. Half-applied migrations would leave the rule corpus
|
||||
-- inconsistent with the new shape; assert every active fristenrechner
|
||||
-- code conforms and that no old codes leak.
|
||||
-- =============================================================================
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
v_new_shape integer;
|
||||
v_old_codes integer;
|
||||
v_ccr_row integer;
|
||||
BEGIN
|
||||
-- 8.1 Every active fristenrechner row matches the new shape regex.
|
||||
-- 20 = 19 renamed rows + 1 newly inserted upc.ccr.cfi. The check
|
||||
-- uses >= so an additional row added in a follow-up migration
|
||||
-- doesn't trip the assertion.
|
||||
SELECT count(*) INTO v_new_shape
|
||||
FROM paliad.proceeding_types
|
||||
WHERE category = 'fristenrechner'
|
||||
AND is_active = true
|
||||
AND code ~ '^[a-z]+\.[a-z]+\.[a-z]+$';
|
||||
IF v_new_shape < 20 THEN
|
||||
RAISE EXCEPTION
|
||||
'mig 096: expected >= 20 active fristenrechner rows on the new shape, got %',
|
||||
v_new_shape;
|
||||
END IF;
|
||||
|
||||
-- 8.2 No old UPPER_SNAKE codes remain on any row.
|
||||
SELECT count(*) INTO v_old_codes
|
||||
FROM paliad.proceeding_types
|
||||
WHERE code LIKE 'UPC\_%' ESCAPE '\'
|
||||
OR code LIKE 'DE\_%' ESCAPE '\'
|
||||
OR code LIKE 'EPA\_%' ESCAPE '\'
|
||||
OR code LIKE 'EP\_%' ESCAPE '\'
|
||||
OR code LIKE 'DPMA\_%' ESCAPE '\';
|
||||
IF v_old_codes <> 0 THEN
|
||||
RAISE EXCEPTION
|
||||
'mig 096: expected 0 old UPPER_SNAKE codes after rename, got %',
|
||||
v_old_codes;
|
||||
END IF;
|
||||
|
||||
-- 8.3 The new ccr peer exists and is active.
|
||||
SELECT count(*) INTO v_ccr_row
|
||||
FROM paliad.proceeding_types
|
||||
WHERE code = 'upc.ccr.cfi'
|
||||
AND is_active = true;
|
||||
IF v_ccr_row <> 1 THEN
|
||||
RAISE EXCEPTION
|
||||
'mig 096: expected 1 active upc.ccr.cfi row, got %',
|
||||
v_ccr_row;
|
||||
END IF;
|
||||
END $$;
|
||||
Reference in New Issue
Block a user