m's 2026-05-18 call (workstream B): the paliad.deadline_rules.code field
is a SUBMISSION identifier (the filing/event within a proceeding), not
the legal-citation rule code (which lives in rule_code / legal_source).
Two cleanups land in this migration:
1. DATA — prefix every existing submission code with its proceeding
code so submission codes carry the full hierarchical shape:
inf.soc (on upc.inf.cfi) → upc.inf.cfi.soc
de_inf.klage (on de.inf.lg) → de.inf.lg.klage
de_inf_bgh.revision (on de.inf.bgh) → de.inf.bgh.revision
Idempotent: WHERE NOT LIKE pt.code || '.%' skips already-prefixed
rows so re-running is a no-op.
2. SCHEMA — rename paliad.deadline_rules.code → submission_code so
future devs don't conflate it with rule_code (legal citation) or
proceeding_types.code. The rename is guarded by a column-existence
check, idempotent on a second run.
Drops + recreates the deadline_search materialized view because its
SELECT bakes `dr.code AS rule_local_code` (mig 051 §4); the rebuild
sources from `dr.submission_code` and reproduces every index from mig
051 verbatim.
Backup snapshot table paliad.deadline_rules_pre_098 captures the rows
before the prefix step; serves as the audit anchor and the down's
source.
Hard assertions (§6) gate the migration on:
- every active+published row matches the 4+-segment proceeding-prefixed
shape regex
- no NULL submission_code on active+published rows
- the column was actually renamed
163 lines
6.6 KiB
SQL
163 lines
6.6 KiB
SQL
-- Reverses mig 098. Restores the pre-098 submission codes on
|
|
-- paliad.deadline_rules, renames the column back to `code`, recreates
|
|
-- the deadline_search matview against the restored column, then drops
|
|
-- the snapshot table.
|
|
--
|
|
-- audit_reason wrapper required by the mig 079 audit trigger.
|
|
|
|
SELECT set_config(
|
|
'paliad.audit_reason',
|
|
'mig 098 (down): revert t-paliad-209 workstream B — restore paliad.deadline_rules.code values from deadline_rules_pre_098 snapshot and rename submission_code → code; matview deadline_search rebuilt against the restored column.',
|
|
true);
|
|
|
|
-- =============================================================================
|
|
-- 1. Drop the matview so the column rename can succeed.
|
|
-- =============================================================================
|
|
|
|
DROP MATERIALIZED VIEW IF EXISTS paliad.deadline_search;
|
|
|
|
-- =============================================================================
|
|
-- 2. Rename the column back. Guarded so a down run on a DB where the
|
|
-- up never ran (or where the column is already named `code`) is a
|
|
-- no-op rather than an error.
|
|
-- =============================================================================
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF EXISTS (
|
|
SELECT 1
|
|
FROM information_schema.columns
|
|
WHERE table_schema = 'paliad'
|
|
AND table_name = 'deadline_rules'
|
|
AND column_name = 'submission_code'
|
|
) THEN
|
|
ALTER TABLE paliad.deadline_rules
|
|
RENAME COLUMN submission_code TO code;
|
|
END IF;
|
|
END $$;
|
|
|
|
-- =============================================================================
|
|
-- 3. Restore code values from the pre_098 snapshot. The snapshot was
|
|
-- captured at the 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 = 'deadline_rules_pre_098'
|
|
) INTO v_snap_exists;
|
|
|
|
IF NOT v_snap_exists THEN
|
|
RAISE NOTICE
|
|
'mig 098 (down): snapshot table paliad.deadline_rules_pre_098 missing — nothing to restore';
|
|
RETURN;
|
|
END IF;
|
|
|
|
UPDATE paliad.deadline_rules dr
|
|
SET code = snap.code
|
|
FROM paliad.deadline_rules_pre_098 snap
|
|
WHERE dr.id = snap.id
|
|
AND dr.code <> snap.code;
|
|
END $$;
|
|
|
|
-- =============================================================================
|
|
-- 4. Recreate the deadline_search matview against the restored column.
|
|
-- Identical body to mig 051 §4, reproduced here so the down leaves
|
|
-- the schema in the same shape mig 051 created.
|
|
-- =============================================================================
|
|
|
|
CREATE MATERIALIZED VIEW paliad.deadline_search AS
|
|
SELECT
|
|
'rule'::text AS kind,
|
|
'r:' || dr.id::text AS row_key,
|
|
dc.id AS concept_id,
|
|
dc.slug AS concept_slug,
|
|
dc.name_de AS concept_name_de,
|
|
dc.name_en AS concept_name_en,
|
|
dc.description AS concept_description,
|
|
dc.aliases AS concept_aliases,
|
|
dc.party AS concept_party,
|
|
dc.category AS concept_category,
|
|
dc.sort_order AS concept_sort_order,
|
|
dr.id AS rule_id,
|
|
NULL::bigint AS trigger_event_id,
|
|
pt.code AS proceeding_code,
|
|
pt.name AS proceeding_name_de,
|
|
pt.name_en AS proceeding_name_en,
|
|
pt.jurisdiction AS jurisdiction,
|
|
pt.display_order AS proceeding_display_order,
|
|
dr.code AS rule_local_code,
|
|
dr.name AS rule_name_de,
|
|
dr.name_en AS rule_name_en,
|
|
dr.legal_source AS legal_source,
|
|
dr.rule_code AS rule_code,
|
|
dr.duration_value,
|
|
dr.duration_unit,
|
|
dr.timing,
|
|
COALESCE(dr.primary_party, dc.party) AS effective_party
|
|
FROM paliad.deadline_rules dr
|
|
JOIN paliad.proceeding_types pt ON pt.id = dr.proceeding_type_id
|
|
JOIN paliad.deadline_concepts dc ON dc.id = dr.concept_id
|
|
WHERE dr.is_active
|
|
AND pt.is_active
|
|
AND pt.category = 'fristenrechner'
|
|
|
|
UNION ALL
|
|
|
|
SELECT
|
|
'trigger'::text,
|
|
't:' || te.id::text,
|
|
dc.id,
|
|
dc.slug,
|
|
dc.name_de,
|
|
dc.name_en,
|
|
dc.description,
|
|
dc.aliases,
|
|
dc.party,
|
|
dc.category,
|
|
dc.sort_order,
|
|
NULL::uuid,
|
|
te.id,
|
|
NULL::text,
|
|
NULL::text,
|
|
NULL::text,
|
|
'cross-cutting'::text,
|
|
9999::int AS proceeding_display_order,
|
|
te.code,
|
|
te.name_de,
|
|
te.name,
|
|
NULL::text,
|
|
NULL::text,
|
|
NULL::int,
|
|
NULL::text,
|
|
NULL::text,
|
|
dc.party
|
|
FROM paliad.trigger_events te
|
|
JOIN paliad.deadline_concepts dc ON dc.slug = te.concept_id
|
|
WHERE te.is_active;
|
|
|
|
CREATE UNIQUE INDEX deadline_search_row_key ON paliad.deadline_search (row_key);
|
|
CREATE INDEX deadline_search_concept_id ON paliad.deadline_search (concept_id);
|
|
CREATE INDEX deadline_search_proc_code ON paliad.deadline_search (proceeding_code);
|
|
CREATE INDEX deadline_search_legal_source ON paliad.deadline_search (legal_source);
|
|
CREATE INDEX deadline_search_effective_party ON paliad.deadline_search (effective_party);
|
|
CREATE INDEX deadline_search_legal_source_trgm ON paliad.deadline_search USING gin (legal_source gin_trgm_ops);
|
|
CREATE INDEX deadline_search_concept_de_trgm ON paliad.deadline_search USING gin (concept_name_de gin_trgm_ops);
|
|
CREATE INDEX deadline_search_concept_en_trgm ON paliad.deadline_search USING gin (concept_name_en gin_trgm_ops);
|
|
CREATE INDEX deadline_search_rule_de_trgm ON paliad.deadline_search USING gin (rule_name_de gin_trgm_ops);
|
|
CREATE INDEX deadline_search_rule_en_trgm ON paliad.deadline_search USING gin (rule_name_en gin_trgm_ops);
|
|
CREATE INDEX deadline_search_rule_code_trgm ON paliad.deadline_search USING gin (rule_code gin_trgm_ops);
|
|
|
|
-- =============================================================================
|
|
-- 5. Drop the snapshot table so a re-applied up captures a fresh
|
|
-- snapshot of the current state.
|
|
-- =============================================================================
|
|
|
|
DROP TABLE IF EXISTS paliad.deadline_rules_pre_098;
|