-- t-paliad-285 (m/paliad#117) + t-paliad-286 (m/paliad#118) —
-- post-submission court followup for UPC Damages and appeal route
-- for UPC Provisional Measures.
--
-- m's 2026-05-25 report: the upc.dmgs.cfi proceeding stops at the
-- last party submission (rejoin) — no interim conference, no oral
-- hearing, no decision row, no appeal-spawn. The upc.pi.cfi
-- proceeding has its decision row (`pi.order`) but no spawn into
-- the appeal tree. Both gaps prevent the Verfahrensablauf timeline
-- from rendering the court phase plus any downstream appeal sub-
-- tree that atlas's #96 spawn-rendering mechanism is otherwise
-- ready to surface.
--
-- Two sections in one migration (slot 133 — knuth on 132, paliadin
-- coordinated):
--
--   A. UPC Damages tree-end rows (#117)
--      A1  upc.dmgs.cfi.interim       UPC RoP R.105   court-set hearing
--      A2  upc.dmgs.cfi.oral          UPC RoP R.118 / R.250  court-set hearing
--      A3  upc.dmgs.cfi.decision      UPC RoP R.118 / R.144  court-set decision
--      A4  upc.dmgs.cfi.appeal_spawn  UPC RoP R.220.1(a) / R.224.1(a)  2mo, spawn → upc.apl.merits (id=11)
--
--   B. UPC Provisional Measures appeal route (#118)
--      B1  upc.pi.cfi.appeal_spawn    UPC RoP R.220.1(a) / R.224.1(a)  2mo, spawn → upc.apl.merits (id=11)
--
-- Source citations:
--   * docs/research-deadlines-completeness-2026-05-25.md
--       — §2.1 (upc.dmgs.cfi has only 4 rules: R.131.2 / R.137.2 / R.139)
--       — §D Damages table (R.144 tree-end row missing — listed
--         in Tier 4 as "cosmetic", upgraded to Tier-0 by m's
--         report once the wider follow-up gap was understood)
--   * docs/audit-upc-rop-deadlines-2026-05-08.md §D row R.144,
--     §F R.220.1(a) / R.224.1(a) (verified verbatim in youpc DB
--     under law_type=UPCRoP).
--   * UPC Rules of Procedure (consolidated):
--       R.105 — Interim conference (court fixes after written
--         procedure closes; same structural shape as the inf
--         interim conference, already modelled as `upc.inf.cfi.interim`).
--       R.118 — Decision after oral hearing; general rule for
--         deciding panels.
--       R.250 — Determination of damages decision; damages-
--         specific decision rule (chains R.144 indication →
--         damages award).
--       R.144 — Final decision on damages quantum (tree-end
--         anchor for §A3).
--       R.220.1(a) — Appeal lies from any final decision /
--         decision disposing of the case at first instance.
--         A PI order under R.211 disposes of the urgent question
--         and is therefore appealable on the main 2-month track
--         (not the 15-day order track of R.220.1(c), which covers
--         case-management and procedural orders requiring leave).
--         Curie's §F table confirms the main-track wiring for
--         decisions on merits / disposing orders.
--       R.224.1(a) — Statement of Appeal within 2 months of
--         service of the final decision; the deadline-notes text
--         mirrors mig 095's inf.appeal_spawn / rev.appeal_spawn.
--       R.224.2(a) — Statement of grounds within 4 months
--         (separate deadline in the spawned upc.apl.merits
--         proceeding; already present as upc.apl.merits.grounds).
--
-- Shape decisions (mirroring mig 012 / mig 095 conventions):
--   * Court-set rows (interim / oral / decision) carry
--     primary_party='court', event_type='hearing'|'decision',
--     duration_value=0, is_court_set=true, parent_id=NULL,
--     concept_id reuses the shared concepts already wired for
--     upc.inf.cfi (interim-conference / oral-hearing / decision).
--   * Spawn rows carry primary_party='both', is_spawn=true,
--     spawn_proceeding_type_id=11 (upc.apl.merits), spawn_label
--     identical to the merits spawn already in production. The
--     spawn row's parent_id is the spawning decision/order row
--     (so the audit log carries the trigger link).
--   * No condition_expr — m's F2.3 decision recorded in mig 095
--     §3: "the appeal deadline should always be triggered by a
--     decision … appeal is always a possibility." Visibility
--     filtering on the frontend hides appeals on projects where
--     no appeal is contemplated.
--   * sequence_order numbering follows the inf convention
--     (40=interim, 50=oral, 60=decision, 80=appeal_spawn) so the
--     Verfahrensablauf timeline orders consistently across
--     proceedings. For PI the existing pi.order sits at
--     sequence_order=3; the appeal_spawn lands at 10 (clear of
--     the writ phase, room for future court-phase rows).
--
-- Idempotency: every INSERT is gated by `WHERE NOT EXISTS (… same
-- submission_code, proceeding_type_id, lifecycle_state)`. Re-apply
-- against an already-migrated DB inserts zero rows and the audit
-- log carries no duplicate entries.
--
-- audit_reason set_config required at the top — the mig 079 trigger
-- on paliad.deadline_rules raises EXCEPTION 'audit reason required'
-- on INSERT/UPDATE/DELETE without it.

SELECT set_config(
    'paliad.audit_reason',
    'mig 133: t-paliad-285 / m/paliad#117 + t-paliad-286 / m/paliad#118 — UPC Damages tree-end rows (interim conference R.105, oral hearing R.118/R.250, decision R.118/R.144, appeal-spawn R.220.1(a)) and UPC Provisional Measures appeal-spawn R.220.1(a); see docs/research-deadlines-completeness-2026-05-25.md §D and docs/audit-upc-rop-deadlines-2026-05-08.md §D/§F',
    true);

-- =============================================================================
-- A. UPC Damages — court-phase tree end (m/paliad#117)
-- =============================================================================

-- A1. upc.dmgs.cfi.interim — Interim conference (UPC RoP R.105).
--     Court-set hearing fixed by the judge-rapporteur once the
--     written procedure closes. Identical shape to
--     upc.inf.cfi.interim; reuses the shared interim-conference
--     concept node.
INSERT INTO paliad.deadline_rules
    (proceeding_type_id, parent_id, submission_code, name, name_en,
     description, primary_party, event_type,
     duration_value, duration_unit, timing,
     rule_code, deadline_notes, deadline_notes_en, sequence_order,
     is_spawn, spawn_proceeding_type_id, spawn_label,
     is_active, legal_source, is_bilateral,
     condition_expr, priority, is_court_set, lifecycle_state,
     concept_id)
SELECT
    17,
    NULL,
    'upc.dmgs.cfi.interim',
    'Zwischenverfahren',
    'Interim Conference',
    NULL,
    'court',
    'hearing',
    0,
    'months',
    'after',
    NULL,
    'Termin vom Gericht bestimmt',
    'Date set by the court',
    40,
    false,
    NULL,
    NULL,
    true,
    NULL,
    false,
    NULL,
    'optional',
    true,
    'published',
    'e5071152-d408-4455-b644-9e79d86fd538'
WHERE NOT EXISTS (
    SELECT 1 FROM paliad.deadline_rules
     WHERE submission_code = 'upc.dmgs.cfi.interim'
       AND proceeding_type_id = 17
       AND lifecycle_state = 'published');

-- A2. upc.dmgs.cfi.oral — Oral hearing (UPC RoP R.118 / R.250).
--     Court-set hearing after the interim conference / close of
--     written procedure. Same shape as upc.inf.cfi.oral; reuses
--     the shared oral-hearing concept node.
INSERT INTO paliad.deadline_rules
    (proceeding_type_id, parent_id, submission_code, name, name_en,
     description, primary_party, event_type,
     duration_value, duration_unit, timing,
     rule_code, deadline_notes, deadline_notes_en, sequence_order,
     is_spawn, spawn_proceeding_type_id, spawn_label,
     is_active, legal_source, is_bilateral,
     condition_expr, priority, is_court_set, lifecycle_state,
     concept_id)
SELECT
    17,
    NULL,
    'upc.dmgs.cfi.oral',
    'Mündliche Verhandlung',
    'Oral Hearing',
    NULL,
    'court',
    'hearing',
    0,
    'months',
    'after',
    NULL,
    NULL,
    NULL,
    50,
    false,
    NULL,
    NULL,
    true,
    NULL,
    false,
    NULL,
    'optional',
    true,
    'published',
    'd6e5b793-dcf1-4d83-81ff-34f42dbb3693'
WHERE NOT EXISTS (
    SELECT 1 FROM paliad.deadline_rules
     WHERE submission_code = 'upc.dmgs.cfi.oral'
       AND proceeding_type_id = 17
       AND lifecycle_state = 'published');

-- A3. upc.dmgs.cfi.decision — Damages decision (UPC RoP R.118 /
--     R.144 / R.250). Court-set decision delivered after oral
--     hearing; closes the §3.1 audit gap (R.144 tree-end). Same
--     shape as upc.inf.cfi.decision; reuses the shared decision
--     concept node.
INSERT INTO paliad.deadline_rules
    (proceeding_type_id, parent_id, submission_code, name, name_en,
     description, primary_party, event_type,
     duration_value, duration_unit, timing,
     rule_code, deadline_notes, deadline_notes_en, sequence_order,
     is_spawn, spawn_proceeding_type_id, spawn_label,
     is_active, legal_source, is_bilateral,
     condition_expr, priority, is_court_set, lifecycle_state,
     concept_id)
SELECT
    17,
    NULL,
    'upc.dmgs.cfi.decision',
    'Entscheidung',
    'Decision',
    NULL,
    'court',
    'decision',
    0,
    'months',
    'after',
    NULL,
    NULL,
    NULL,
    60,
    false,
    NULL,
    NULL,
    true,
    NULL,
    false,
    NULL,
    'optional',
    true,
    'published',
    '472fc32d-cc4f-4aa4-8ace-e422031812de'
WHERE NOT EXISTS (
    SELECT 1 FROM paliad.deadline_rules
     WHERE submission_code = 'upc.dmgs.cfi.decision'
       AND proceeding_type_id = 17
       AND lifecycle_state = 'published');

-- A4. upc.dmgs.cfi.appeal_spawn — Appeal against damages decision
--     (UPC RoP R.220.1(a), 2-month main track; grounds R.224.2(a)
--     run as a separate deadline in the spawned upc.apl.merits
--     proceeding). Parent points at the freshly-inserted
--     upc.dmgs.cfi.decision; the SELECT subquery resolves it
--     after A3 lands. Same shape as the mig 095 inf.appeal_spawn.
INSERT INTO paliad.deadline_rules
    (proceeding_type_id, parent_id, submission_code, name, name_en,
     description, primary_party, event_type,
     duration_value, duration_unit, timing,
     rule_code, deadline_notes, deadline_notes_en, sequence_order,
     is_spawn, spawn_proceeding_type_id, spawn_label,
     is_active, legal_source, is_bilateral,
     condition_expr, priority, is_court_set, lifecycle_state)
SELECT
    17,
    (SELECT id FROM paliad.deadline_rules
      WHERE submission_code = 'upc.dmgs.cfi.decision'
        AND proceeding_type_id = 17
        AND lifecycle_state = 'published'
        AND is_active = true),
    'upc.dmgs.cfi.appeal_spawn',
    'Berufung gegen Schadensentscheidung',
    'Appeal against damages decision',
    'Berufung gegen die Entscheidung über die Schadensbemessung (R.118 / R.144). Statutarische Frist von 2 Monaten ab Zustellung der Entscheidung (R.224.1(a)); die Berufungsbegründung folgt mit 4 Monaten ab Zustellung (R.224.2(a), eigenständige Frist im Berufungsverfahren).',
    'both',
    'filing',
    2,
    'months',
    'after',
    'RoP.220.1.a',
    'Innerhalb von 2 Monaten ab Zustellung der Schadensentscheidung Berufungsschrift einreichen (R.224.1(a)). Die Berufungsbegründung (R.224.2(a), 4 Monate) läuft als separate Frist im Berufungsverfahren.',
    'Within 2 months of service of the damages decision lodge the Statement of appeal (R.224.1(a)). The Statement of grounds (R.224.2(a), 4 months) runs as an independent deadline in the appeal proceeding.',
    80,
    true,
    11,
    'Berufungsverfahren öffnen',
    true,
    'UPC.RoP.220.1',
    false,
    NULL,
    'optional',
    false,
    'published'
WHERE NOT EXISTS (
    SELECT 1 FROM paliad.deadline_rules
     WHERE submission_code = 'upc.dmgs.cfi.appeal_spawn'
       AND proceeding_type_id = 17
       AND lifecycle_state = 'published');

-- =============================================================================
-- B. UPC Provisional Measures — appeal route (m/paliad#118)
-- =============================================================================

-- B1. upc.pi.cfi.appeal_spawn — Appeal against PI order (UPC RoP
--     R.220.1(a), 2-month main track). PI orders under R.211
--     dispose of the urgent question and are appealable on the
--     main 2-month track (R.220.1(a)/R.224.1(a)); the 15-day
--     order track of R.220.1(c) is for case-management /
--     procedural orders requiring leave and does not apply to
--     PI dispositions. Parent points at the existing
--     upc.pi.cfi.order (sequence_order=3) so the spawn fires
--     once the order is anchored on a project's timeline.
INSERT INTO paliad.deadline_rules
    (proceeding_type_id, parent_id, submission_code, name, name_en,
     description, primary_party, event_type,
     duration_value, duration_unit, timing,
     rule_code, deadline_notes, deadline_notes_en, sequence_order,
     is_spawn, spawn_proceeding_type_id, spawn_label,
     is_active, legal_source, is_bilateral,
     condition_expr, priority, is_court_set, lifecycle_state)
SELECT
    10,
    (SELECT id FROM paliad.deadline_rules
      WHERE submission_code = 'upc.pi.cfi.order'
        AND proceeding_type_id = 10
        AND lifecycle_state = 'published'
        AND is_active = true),
    'upc.pi.cfi.appeal_spawn',
    'Berufung gegen Anordnung',
    'Appeal against PI order',
    'Berufung gegen die einstweilige Anordnung nach R.211. Eine PI-Anordnung erledigt die einstweilige Streitfrage und wird wie eine Endentscheidung im Hauptverfahren behandelt: statutarische Frist von 2 Monaten ab Zustellung (R.224.1(a)); die Berufungsbegründung folgt mit 4 Monaten ab Zustellung (R.224.2(a), eigenständige Frist im Berufungsverfahren). Die 15-Tage-Spur nach R.220.1(c) / R.220.2 gilt für Verfahrensanordnungen mit Zulassung und ist hier nicht einschlägig.',
    'both',
    'filing',
    2,
    'months',
    'after',
    'RoP.220.1.a',
    'Innerhalb von 2 Monaten ab Zustellung der PI-Anordnung Berufungsschrift einreichen (R.224.1(a)). Die Berufungsbegründung (R.224.2(a), 4 Monate) läuft als separate Frist im Berufungsverfahren.',
    'Within 2 months of service of the PI order lodge the Statement of appeal (R.224.1(a)). The Statement of grounds (R.224.2(a), 4 months) runs as an independent deadline in the appeal proceeding.',
    10,
    true,
    11,
    'Berufungsverfahren öffnen',
    true,
    'UPC.RoP.220.1',
    false,
    NULL,
    'optional',
    false,
    'published'
WHERE NOT EXISTS (
    SELECT 1 FROM paliad.deadline_rules
     WHERE submission_code = 'upc.pi.cfi.appeal_spawn'
       AND proceeding_type_id = 10
       AND lifecycle_state = 'published');

-- =============================================================================
-- C. Post-insert verification — raise if any expected row is missing
--    (matches the mig 095 / 127 convention; protects against a future
--    re-shape of the table that silently drops one of the WHERE NOT
--    EXISTS predicates).
-- =============================================================================

DO $$
DECLARE
    v_missing text;
BEGIN
    SELECT string_agg(expected, ', ' ORDER BY expected)
      INTO v_missing
      FROM (VALUES
            ('upc.dmgs.cfi.interim'),
            ('upc.dmgs.cfi.oral'),
            ('upc.dmgs.cfi.decision'),
            ('upc.dmgs.cfi.appeal_spawn'),
            ('upc.pi.cfi.appeal_spawn')
        ) AS t(expected)
     WHERE NOT EXISTS (
        SELECT 1 FROM paliad.deadline_rules dr
         WHERE dr.submission_code = t.expected
           AND dr.lifecycle_state = 'published'
           AND dr.is_active = true);

    IF v_missing IS NOT NULL THEN
        RAISE EXCEPTION
            'mig 133: expected published rules missing after insert: %', v_missing;
    END IF;

    IF NOT EXISTS (
        SELECT 1 FROM paliad.deadline_rules dr
         WHERE dr.submission_code = 'upc.dmgs.cfi.appeal_spawn'
           AND dr.proceeding_type_id = 17
           AND dr.spawn_proceeding_type_id = 11
           AND dr.is_spawn = true
           AND dr.parent_id IS NOT NULL
           AND dr.lifecycle_state = 'published'
    ) THEN
        RAISE EXCEPTION
            'mig 133: upc.dmgs.cfi.appeal_spawn shape check failed (expected is_spawn=true, spawn_proceeding_type_id=11, parent_id set)';
    END IF;

    IF NOT EXISTS (
        SELECT 1 FROM paliad.deadline_rules dr
         WHERE dr.submission_code = 'upc.pi.cfi.appeal_spawn'
           AND dr.proceeding_type_id = 10
           AND dr.spawn_proceeding_type_id = 11
           AND dr.is_spawn = true
           AND dr.parent_id IS NOT NULL
           AND dr.lifecycle_state = 'published'
    ) THEN
        RAISE EXCEPTION
            'mig 133: upc.pi.cfi.appeal_spawn shape check failed (expected is_spawn=true, spawn_proceeding_type_id=11, parent_id set)';
    END IF;
END $$;
