-- 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;
