Phase 2 P1 / m's Q5 divergence (2026-05-27, verbatim):
"Reverse the unification as suggested in 3. They are different
proceedings, I only wanted the approach to be unified in the
'determinator' — but they are actually different proceedings!"
Mig 155 reverts the mig-096 unification:
Before: id=160 upc.apl.unified active (16 rules), id=11/19/20 inactive
After: id=11 upc.apl.merits (7 rules), id=19 upc.apl.cost (2 rules),
id=20 upc.apl.order (7 rules) all active; id=160 inactive
The 16 rules under id=160 split cleanly by event_code prefix; all 10
parent_id edges among them are bucket-local (pre-flight audit), so
the tree shape survives the rebind unchanged.
Spawn FK retarget: pi.cfi.appeal_spawn flips from 11 (merits) → 20
(orders track) per design §3.1 — PI appeals land on orders, not
merits. The inf/rev/dmgs spawns keep target=11 (merits), now active.
Determinator routing layer (proceeding_mapping.go) keeps its single
"Berufung" front door per m's intent — only the data shape changes.
Pre-flight verified: 0 projects bound to id=160, 0 scenarios reference
upc.apl. Zero data migration on the project side.
Tests: lookup_events_test.go assertions on the three appeal_target
buckets updated to the new codes (endentscheidung → upc.apl.merits,
schadensbemessung → upc.apl.merits, bucheinsicht → upc.apl.order).
Same rule set, post-split coordinates.
Snapshot regen (pkg/litigationplanner/embedded/upc/) deferred: the
current snapshot only contains inf+rev so the apl re-split doesn't
shift its contents; regenerating would surface unrelated active PTs
and pollute this slice. Tracked as a follow-up.
Verified: go vet clean, go test ./internal/services/... -run
LookupEvents|proceeding_codes clean.
Design: docs/design-deadline-system-revision-2026-05-27.md §3.1
(re-split mig), §1.3 (spawn graph post-Q5). t-paliad-331.
192 lines
7.5 KiB
PL/PgSQL
192 lines
7.5 KiB
PL/PgSQL
-- 155_upc_apl_resplit — t-paliad-331 / m/paliad#149 Phase 2 P1
|
|
--
|
|
-- Reverts the upc.apl unification that mig 096 introduced. m's Q5
|
|
-- (2026-05-27, verbatim):
|
|
--
|
|
-- "Reverse the unification as suggested in 3. They are different
|
|
-- proceedings, I only wanted the approach to be unified in the
|
|
-- 'determinator' — but they are actually different proceedings!"
|
|
--
|
|
-- The current state (audited 2026-05-27, mig 155 pre-flight):
|
|
--
|
|
-- id=160 upc.apl.unified is_active=true (carries all 16 rules)
|
|
-- id=11 upc.apl.merits is_active=false
|
|
-- id=19 upc.apl.cost is_active=false
|
|
-- id=20 upc.apl.order is_active=false
|
|
--
|
|
-- The 16 rules under id=160 split cleanly by event_code prefix:
|
|
-- 7 rows match 'upc.apl.merits.%' → target id=11
|
|
-- 2 rows match 'upc.apl.cost.%' → target id=19
|
|
-- 7 rows match 'upc.apl.order.%' → target id=20
|
|
--
|
|
-- Every parent_id chain among those 16 rows stays inside its bucket
|
|
-- (audited: 10/10 parent edges are bucket-local), so retargeting by
|
|
-- event_code prefix preserves the tree shape — no extra parent_id
|
|
-- surgery needed.
|
|
--
|
|
-- Spawn FKs: 4 rules currently target id=11 (was inactive — this is
|
|
-- the R3 finding athena flagged, re-interpreted by m's Q5 as correct
|
|
-- intent rather than broken state):
|
|
--
|
|
-- upc.inf.cfi.appeal_spawn → 11 (merits) — keep
|
|
-- upc.rev.cfi.appeal_spawn → 11 (merits) — keep
|
|
-- upc.dmgs.cfi.appeal_spawn → 11 (merits) — keep
|
|
-- upc.pi.cfi.appeal_spawn → 11 (merits) — RETARGET to 20 (order),
|
|
-- since PI appeals
|
|
-- land on the orders
|
|
-- track per design §3.1.
|
|
--
|
|
-- Active scenarios / projects pointing at id=160: zero (verified
|
|
-- pre-flight: 0 projects, 0 scenarios reference 'upc.apl'). No data
|
|
-- migration on the project side; no production traffic is mid-flight
|
|
-- on id=160.
|
|
--
|
|
-- Mig 153's `projects_proceeding_type_kind_check` trigger gates
|
|
-- inserts/updates against kind='proceeding'. id=11/19/20 already
|
|
-- carry kind='proceeding' (verified pre-flight), so the trigger
|
|
-- won't fire on the re-activations.
|
|
|
|
BEGIN;
|
|
|
|
SELECT set_config(
|
|
'paliad.audit_reason',
|
|
'mig 155: upc.apl re-split — reactivate merits/cost/order, retire unified (t-paliad-331 / m/paliad#149 P1)',
|
|
true
|
|
);
|
|
|
|
-- ----------------------------------------------------------------
|
|
-- 1. Snapshot for audit + rollback.
|
|
-- ----------------------------------------------------------------
|
|
|
|
CREATE TABLE paliad.proceeding_types_pre_155 AS
|
|
SELECT * FROM paliad.proceeding_types WHERE id IN (11, 19, 20, 160);
|
|
|
|
CREATE TABLE paliad.sequencing_rules_pre_155 AS
|
|
SELECT * FROM paliad.sequencing_rules
|
|
WHERE proceeding_type_id = 160
|
|
OR (is_spawn AND spawn_proceeding_type_id IN (11, 19, 20, 160));
|
|
|
|
COMMENT ON TABLE paliad.proceeding_types_pre_155 IS
|
|
'Snapshot of the 4 appeal-related proceeding_types rows taken in '
|
|
'the same TX as mig 155 (upc.apl re-split). Audit + rollback safety.';
|
|
|
|
COMMENT ON TABLE paliad.sequencing_rules_pre_155 IS
|
|
'Snapshot of the 16 rules under id=160 + the 4 spawn rules targeting '
|
|
'the appeal cluster, taken in the same TX as mig 155. Audit + rollback.';
|
|
|
|
-- ----------------------------------------------------------------
|
|
-- 2. Re-activate the three discrete appeal PTs; retire the unified row.
|
|
-- ----------------------------------------------------------------
|
|
|
|
UPDATE paliad.proceeding_types SET is_active = true WHERE id IN (11, 19, 20);
|
|
UPDATE paliad.proceeding_types SET is_active = false WHERE id = 160;
|
|
|
|
DO $$
|
|
DECLARE
|
|
n_active int;
|
|
n_inactive int;
|
|
BEGIN
|
|
SELECT COUNT(*) INTO n_active FROM paliad.proceeding_types
|
|
WHERE id IN (11, 19, 20) AND is_active = true;
|
|
SELECT COUNT(*) INTO n_inactive FROM paliad.proceeding_types
|
|
WHERE id = 160 AND is_active = false;
|
|
IF n_active <> 3 OR n_inactive <> 1 THEN
|
|
RAISE EXCEPTION '[mig 155] activation check failed — active(11,19,20)=% / inactive(160)=%', n_active, n_inactive;
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ----------------------------------------------------------------
|
|
-- 3. Retarget the 16 rules on id=160 to merits/cost/order by event_code
|
|
-- prefix. parent_id stays intact (all parent edges are bucket-local
|
|
-- per pre-flight audit).
|
|
-- ----------------------------------------------------------------
|
|
|
|
UPDATE paliad.sequencing_rules sr
|
|
SET proceeding_type_id = 11
|
|
FROM paliad.procedural_events pe
|
|
WHERE pe.id = sr.procedural_event_id
|
|
AND sr.proceeding_type_id = 160
|
|
AND pe.code LIKE 'upc.apl.merits.%';
|
|
|
|
UPDATE paliad.sequencing_rules sr
|
|
SET proceeding_type_id = 19
|
|
FROM paliad.procedural_events pe
|
|
WHERE pe.id = sr.procedural_event_id
|
|
AND sr.proceeding_type_id = 160
|
|
AND pe.code LIKE 'upc.apl.cost.%';
|
|
|
|
UPDATE paliad.sequencing_rules sr
|
|
SET proceeding_type_id = 20
|
|
FROM paliad.procedural_events pe
|
|
WHERE pe.id = sr.procedural_event_id
|
|
AND sr.proceeding_type_id = 160
|
|
AND pe.code LIKE 'upc.apl.order.%';
|
|
|
|
DO $$
|
|
DECLARE
|
|
remaining int;
|
|
merits int; cost int; ord int;
|
|
BEGIN
|
|
SELECT COUNT(*) INTO remaining
|
|
FROM paliad.sequencing_rules WHERE proceeding_type_id = 160;
|
|
IF remaining <> 0 THEN
|
|
RAISE EXCEPTION '[mig 155] rebind failed — % rules still on id=160 (expected 0)', remaining;
|
|
END IF;
|
|
SELECT COUNT(*) INTO merits
|
|
FROM paliad.sequencing_rules WHERE proceeding_type_id = 11;
|
|
SELECT COUNT(*) INTO cost
|
|
FROM paliad.sequencing_rules WHERE proceeding_type_id = 19;
|
|
SELECT COUNT(*) INTO ord
|
|
FROM paliad.sequencing_rules WHERE proceeding_type_id = 20;
|
|
IF merits <> 7 OR cost <> 2 OR ord <> 7 THEN
|
|
RAISE EXCEPTION
|
|
'[mig 155] post-rebind counts wrong — merits=% (want 7) / cost=% (want 2) / order=% (want 7)',
|
|
merits, cost, ord;
|
|
END IF;
|
|
RAISE NOTICE '[mig 155] rebind OK — merits=% cost=% order=%', merits, cost, ord;
|
|
END $$;
|
|
|
|
-- ----------------------------------------------------------------
|
|
-- 4. Retarget the upc.pi.cfi.appeal_spawn rule to id=20 (orders track).
|
|
-- PI appeals don't go to the merits track — they're orders.
|
|
-- The inf/rev/dmgs spawns keep target=11 (now active, was inactive
|
|
-- by accident of the unification).
|
|
-- ----------------------------------------------------------------
|
|
|
|
UPDATE paliad.sequencing_rules
|
|
SET spawn_proceeding_type_id = 20
|
|
WHERE is_spawn = true
|
|
AND procedural_event_id = (
|
|
SELECT id FROM paliad.procedural_events WHERE code = 'upc.pi.cfi.appeal_spawn'
|
|
)
|
|
AND spawn_proceeding_type_id = 11;
|
|
|
|
DO $$
|
|
DECLARE
|
|
pi_target int;
|
|
others int;
|
|
BEGIN
|
|
SELECT spawn_proceeding_type_id INTO pi_target
|
|
FROM paliad.sequencing_rules sr
|
|
JOIN paliad.procedural_events pe ON pe.id = sr.procedural_event_id
|
|
WHERE pe.code = 'upc.pi.cfi.appeal_spawn' AND sr.is_spawn = true
|
|
LIMIT 1;
|
|
IF pi_target IS DISTINCT FROM 20 THEN
|
|
RAISE EXCEPTION '[mig 155] pi.cfi spawn retarget failed — got %, want 20', pi_target;
|
|
END IF;
|
|
SELECT COUNT(*) INTO others
|
|
FROM paliad.sequencing_rules sr
|
|
JOIN paliad.procedural_events pe ON pe.id = sr.procedural_event_id
|
|
WHERE sr.is_spawn = true
|
|
AND sr.spawn_proceeding_type_id = 11
|
|
AND pe.code IN ('upc.inf.cfi.appeal_spawn',
|
|
'upc.rev.cfi.appeal_spawn',
|
|
'upc.dmgs.cfi.appeal_spawn');
|
|
IF others <> 3 THEN
|
|
RAISE EXCEPTION '[mig 155] inf/rev/dmgs spawn target check failed — % rows point at 11 (want 3)', others;
|
|
END IF;
|
|
RAISE NOTICE '[mig 155] spawn graph OK — pi → 20 (order); inf/rev/dmgs → 11 (merits)';
|
|
END $$;
|
|
|
|
COMMIT;
|