Phase 3 Slice 9 Step E (design §3.E, §9.1). m approved the
downtime window 2026-05-15 ("paliad ist nicht in use heute,
downtime ist egal") so the destructive drops can land.
Drops four superseded columns on paliad.deadline_rules:
is_mandatory → priority='mandatory' | other (Slice 2 mig 083)
is_optional → priority='optional' (Slice 2 mig 083)
condition_flag → condition_expr (Slice 2 mig 084)
condition_rule_id → DEAD (no live rows, Q13 m's approved drop)
Pre-drop snapshot: paliad.deadline_rules_pre_091 (id +
the four columns + snapshotted_at). Lets the down-migration
restore values to existing rows; a follow-up cleanup slice drops
the snapshot table once the rule editor's migration-export flow
has been used to roll any post-drop edits back into version
control.
Hard assertions at end:
- count(priority IS NULL) == 0 (Slice 2 mig 083 must have run).
- count(rule with pre-drop condition_flag but no condition_expr)
== 0 (Slice 2 mig 084 must have populated every row).
Both raise EXCEPTION on violation — fails the migration loudly
before legacy code paths get pulled out from under the unified
calculator.
Audit-reason wrapper set; ALTER TABLE DROP COLUMN doesn't fire
the mig 079 row-level trigger, but the wrapper is the standard
Phase 3 pattern.
Sibling drops deferred — see live-data audit in head ping:
- mig 092 (event_deadlines + trigger_events tables): SKIPPED.
trigger_events has 33 event_types FKs + 77 deadline_rules
FKs; event_deadlines + event_deadline_rule_codes still
consumed by EventDeadlineService.Calculate for the frontend's
"Was kommt nach…" tab (/api/tools/event-deadlines is still
in use post-Slice-3 delegate).
- mig 093 (retire litigation category): SKIPPED. 40 active
deadline_rules still reference litigation-category
proceeding_types (the Pipeline-A INF/REV/CCR/APM/APP/AMD/
ZPO_CIVIL rules; Slice 5 retired them from project-binding,
not from the rule corpus).
Both deferrals are tracked in the head ping; the litigation drop
can land after a focused slice that splits the Pipeline-A rules
off the litigation category onto a fristenrechner-side parent.
The event_deadlines drop needs EventDeadlineService.Calculate
to stop reading the source rows first.
117 lines
5.1 KiB
SQL
117 lines
5.1 KiB
SQL
-- t-paliad-195 / Fristen Phase 3 Slice 9 Step E (design §3.E, §9.1).
|
|
-- m approved the downtime window 2026-05-15 ("paliad ist nicht in use
|
|
-- heute, downtime ist egal") so the destructive drops can land.
|
|
--
|
|
-- This migration drops the four legacy columns on
|
|
-- paliad.deadline_rules that the unified Phase 3 calculator no longer
|
|
-- reads. The replacements have been backfilled (Slice 2 mig 082/083/
|
|
-- 084), wired into the calculator (Slice 4), and on the wire (Slice 8):
|
|
--
|
|
-- is_mandatory → priority='mandatory' | (recommended | optional | informational)
|
|
-- is_optional → priority='optional' (the RoP.151 T/T case)
|
|
-- condition_flag → condition_expr (jsonb long form)
|
|
-- condition_rule_id → DEAD (no live rows, Q13 m's approved drop)
|
|
--
|
|
-- Sibling drops (event_deadlines/trigger_events tables, retire of
|
|
-- litigation category) are deferred from this slice per the live-data
|
|
-- audit (see head ping). This file is the legacy-column-drop only.
|
|
--
|
|
-- Backup: paliad.deadline_rules_pre_091 snapshot of the four columns +
|
|
-- id BEFORE the drop, so the down-migration can restore individual
|
|
-- values if a deploy needs to roll back. The backup uses CREATE TABLE
|
|
-- IF NOT EXISTS so a re-applied migration is a no-op.
|
|
--
|
|
-- Audit-reason set at the top: the mig 079 trigger fires on every
|
|
-- UPDATE/DELETE on paliad.deadline_rules; ALTER TABLE DROP COLUMN
|
|
-- doesn't fire the row-level trigger but the wrapper is the standard
|
|
-- Phase 3 pattern. The reason persists in the audit log only for
|
|
-- write paths.
|
|
|
|
SELECT set_config(
|
|
'paliad.audit_reason',
|
|
'mig 091: drop legacy rule columns per design §3.E + m''s 2026-05-15 approval',
|
|
true);
|
|
|
|
-- =============================================================================
|
|
-- 1. Snapshot of the four columns + id, so the down-migration can
|
|
-- restore values to existing rows. Skipping the snapshot table
|
|
-- would mean a rollback adds the columns back but with NULL data;
|
|
-- the snapshot preserves the legacy values for any downstream
|
|
-- consumer the audit might surface.
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS paliad.deadline_rules_pre_091 AS
|
|
SELECT id,
|
|
is_mandatory,
|
|
is_optional,
|
|
condition_flag,
|
|
condition_rule_id,
|
|
now() AS snapshotted_at
|
|
FROM paliad.deadline_rules;
|
|
|
|
COMMENT ON TABLE paliad.deadline_rules_pre_091 IS
|
|
'Snapshot of paliad.deadline_rules.(is_mandatory, is_optional, '
|
|
'condition_flag, condition_rule_id) before mig 091''s drop. Lets '
|
|
'a rollback restore the legacy values for the 172 rules that '
|
|
'existed at drop time. Drop this table after Slice 9 is verified '
|
|
'in prod (a focused follow-up slice or part of Slice 12 cleanup).';
|
|
|
|
-- =============================================================================
|
|
-- 2. Drop the columns. Order doesn't matter — none of them reference
|
|
-- each other or other tables (condition_rule_id was a dead self-FK
|
|
-- that no live row uses, Q13).
|
|
-- =============================================================================
|
|
|
|
ALTER TABLE paliad.deadline_rules
|
|
DROP COLUMN IF EXISTS is_mandatory,
|
|
DROP COLUMN IF EXISTS is_optional,
|
|
DROP COLUMN IF EXISTS condition_flag,
|
|
DROP COLUMN IF EXISTS condition_rule_id;
|
|
|
|
-- =============================================================================
|
|
-- 3. Hard assertion: every remaining row carries a valid priority +
|
|
-- has condition_expr populated when its legacy condition_flag was
|
|
-- non-empty pre-mig. Belt-and-braces — Slice 2 backfilled both
|
|
-- paths and Slice 4 unified the calculator, but a stale row would
|
|
-- light up here BEFORE we hand the schema to the unified code.
|
|
-- =============================================================================
|
|
|
|
DO $$
|
|
DECLARE
|
|
n_total int;
|
|
n_null_prio int;
|
|
n_lost int;
|
|
BEGIN
|
|
SELECT count(*), count(*) FILTER (WHERE priority IS NULL)
|
|
INTO n_total, n_null_prio
|
|
FROM paliad.deadline_rules;
|
|
|
|
-- Cross-check against the snapshot: every pre-mig row with a
|
|
-- non-empty condition_flag must have a non-NULL condition_expr
|
|
-- post-mig. If any row lost its gate, the calculator's gate
|
|
-- behaviour would silently change — surface it loudly.
|
|
SELECT count(*)
|
|
INTO n_lost
|
|
FROM paliad.deadline_rules_pre_091 b
|
|
JOIN paliad.deadline_rules dr ON dr.id = b.id
|
|
WHERE b.condition_flag IS NOT NULL
|
|
AND array_length(b.condition_flag, 1) > 0
|
|
AND dr.condition_expr IS NULL;
|
|
|
|
RAISE NOTICE 'mig 091: % rules, % with NULL priority, % lost condition_expr',
|
|
n_total, n_null_prio, n_lost;
|
|
|
|
IF n_null_prio > 0 THEN
|
|
RAISE EXCEPTION 'mig 091: % rules have priority IS NULL post-drop — '
|
|
'the priority column must be backfilled (Slice 2 mig 083) '
|
|
'before legacy columns are dropped',
|
|
n_null_prio;
|
|
END IF;
|
|
|
|
IF n_lost > 0 THEN
|
|
RAISE EXCEPTION 'mig 091: % rules had a condition_flag pre-drop but no '
|
|
'condition_expr post-drop — Slice 2 mig 084 missed them',
|
|
n_lost;
|
|
END IF;
|
|
END $$;
|