-- t-paliad-183 / Fristen Phase 3 Slice 2 Step B-2 — backfill -- paliad.deadline_rules.priority from the legacy (is_mandatory, -- is_optional) pair per DESIGN §2.3 (NOT the inverted mapping in -- head's msg 1746 — head's clarification msg 1750 rules in favour of -- the design doc). -- -- Final mapping (design §2.3 + RoP.151 / mig 068 t-paliad-157 semantic): -- -- is_mandatory=true, is_optional=false → 'mandatory' (statutory must, -- ☑ pre-checked in -- save modal) -- is_mandatory=true, is_optional=true → 'optional' (statutorily strict -- ONCE IT APPLIES, -- but applies only -- if a party files — -- RoP.151 is the -- canonical case; -- ☐ pre-unchecked) -- is_mandatory=false, is_optional=true → 'recommended' (no live data, but -- defensive default -- so the CHECK -- constraint stays -- satisfied if such -- a row ever lands) -- is_mandatory=false, is_optional=false → 'recommended' (situational filings -- — Berufungserwiderung, -- Replik, Duplik, -- R.19 Preliminary -- Objection, R.116 -- EPÜ, Anschluss- -- berufung, etc. -- Default-save with -- override, not -- 'informational' -- which would make -- them never-saveable) -- -- Live-data expected delta (172 rules total, mig 078 set every row to -- the default 'mandatory'): -- T/F (153 rows) → 'mandatory' — 153 no-op UPDATEs (already correct) -- T/T ( 1 row) → 'optional' — 1 row flips -- F/F ( 18 rows) → 'recommended' — 18 rows flip -- F/T ( 0 rows) → 'recommended' — 0 rows (no live data) -- -- The UPDATE is split into branches with explicit WHERE clauses so the -- audit log records each branch as a distinct backfill action (separate -- audit row chains by (is_mandatory, is_optional) shape). It also keeps -- the migration idempotent: re-running only touches rows whose priority -- doesn't already match the target. -- -- Audit-reason cites design §2.3 — that's the persistent rationale in -- the paliad.deadline_rule_audit log. SELECT set_config( 'paliad.audit_reason', 'backfill 083: priority from (is_mandatory, is_optional) per design §2.3 — ' || 'T/T→optional (RoP.151), F/F→recommended (situational filings)', true); -- Branch 1: T/T → 'optional' (RoP.151). UPDATE paliad.deadline_rules SET priority = 'optional' WHERE is_mandatory = true AND is_optional = true AND priority <> 'optional'; -- Branch 2: F/F → 'recommended'. UPDATE paliad.deadline_rules SET priority = 'recommended' WHERE is_mandatory = false AND is_optional = false AND priority <> 'recommended'; -- Branch 3: F/T → 'recommended' (defensive; no live rows today). UPDATE paliad.deadline_rules SET priority = 'recommended' WHERE is_mandatory = false AND is_optional = true AND priority <> 'recommended'; -- Branch 4: T/F → 'mandatory'. Skipped explicitly: the mig 078 column -- default is already 'mandatory', so every T/F row already has the -- correct value. A defensive UPDATE here would write 153 needless -- audit rows. Leave T/F untouched. DO $$ DECLARE n_mand int; n_opt int; n_reco int; n_info int; n_null int; BEGIN SELECT count(*) FILTER (WHERE priority = 'mandatory'), count(*) FILTER (WHERE priority = 'optional'), count(*) FILTER (WHERE priority = 'recommended'), count(*) FILTER (WHERE priority = 'informational'), count(*) FILTER (WHERE priority IS NULL) INTO n_mand, n_opt, n_reco, n_info, n_null FROM paliad.deadline_rules; RAISE NOTICE 'backfill 083: priority distribution — ' 'mandatory=%, optional=%, recommended=%, informational=%, NULL=%', n_mand, n_opt, n_reco, n_info, n_null; -- Hard assertion: priority is NOT NULL by schema (mig 078) and -- every value must lie in the CHECK enum. n_null must be 0. IF n_null > 0 THEN RAISE EXCEPTION 'backfill 083: % rows still have priority IS NULL — ' 'schema violation', n_null; END IF; END $$;