Revert "Merge: t-paliad-133 — Fristenrechner v3 (Pathway A/B fork + B1 decision tree + B2 forum filter + retire legacy tabs)"

This reverts commit f7d72ff1d3, reversing
changes made to 1ea983f0c7.
This commit is contained in:
m
2026-05-05 11:17:58 +02:00
parent f7d72ff1d3
commit 5bd17de732
19 changed files with 64 additions and 3683 deletions

View File

@@ -1,11 +0,0 @@
-- t-paliad-133 Phase A schema rollback.
-- 3. Drop is_bilateral column.
DROP INDEX IF EXISTS paliad.deadline_rules_is_bilateral;
ALTER TABLE paliad.deadline_rules DROP COLUMN IF EXISTS is_bilateral;
-- 2. Drop the junction table.
DROP TABLE IF EXISTS paliad.event_category_concepts;
-- 1. Drop the taxonomy tree (CASCADE handles children).
DROP TABLE IF EXISTS paliad.event_categories;

View File

@@ -1,137 +0,0 @@
-- t-paliad-133 Phase A: event taxonomy schema for the Fristenrechner v3
-- decision tree (Pathway B / B1) AND a bilateral-rule flag for the
-- party-perspective selector.
--
-- Three artefacts in one migration (additive, no breaking changes):
--
-- 1. paliad.event_categories — the decision-tree taxonomy. Recursive
-- tree (parent_id self-FK) of "what happened" nodes. Internal
-- nodes carry a step_question_de/en (the question to ask under
-- this node). Leaves are user-actionable events that map to one
-- or more concepts via the junction below.
--
-- 2. paliad.event_category_concepts — many-to-many junction from
-- taxonomy leaves to deadline_concepts. Optional
-- proceeding_type_code narrows the card pills at this leaf to a
-- specific context (e.g. "Hinweisbeschluss" → response-to-
-- preliminary-opinion narrowed to DE_NULL only).
--
-- 3. paliad.deadline_rules.is_bilateral — new bool flag for genuinely-
-- bilateral rules (Schriftsatzfristen with Anwaltszwang, joint
-- Mängelbeseitigung). When true AND primary_party='both', the rule
-- mirrors into both party columns of the columns view. Otherwise
-- 'both' → the rule applies to whichever party took the action.
--
-- Seed data + bilateral backfill ship in migrations 049 / 050.
--
-- Design ref: docs/plans/unified-fristenrechner-v3.md §4.1 + §10 Q12.
-- ============================================================================
-- 1. paliad.event_categories — recursive taxonomy tree
-- ============================================================================
CREATE TABLE paliad.event_categories (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
parent_id uuid REFERENCES paliad.event_categories(id) ON DELETE CASCADE,
slug text NOT NULL UNIQUE,
label_de text NOT NULL,
label_en text NOT NULL,
description_de text,
description_en text,
step_question_de text,
step_question_en text,
icon text,
sort_order int NOT NULL DEFAULT 100,
is_leaf bool NOT NULL DEFAULT false,
is_active bool NOT NULL DEFAULT true,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
COMMENT ON TABLE paliad.event_categories IS
'Decision-tree taxonomy for Fristenrechner v3 Pathway B / B1. Each '
'row is a node in a recursive tree of "what happened" categories. '
'The tree shape is data-driven — depth is unlimited per m''s '
'2026-05-05 spec lock.';
COMMENT ON COLUMN paliad.event_categories.slug IS
'Materialised path-with-dots (e.g. cms-eingang.gericht.hinweisbeschluss). '
'Unique across the table. Drives URL bookmarks ?b1=<slug>.';
COMMENT ON COLUMN paliad.event_categories.step_question_de IS
'The question this node''s CHILDREN answer. Rendered above the button '
'row for the next step. NULL on leaves (terminal events that map to '
'concepts via paliad.event_category_concepts).';
COMMENT ON COLUMN paliad.event_categories.is_leaf IS
'True when this node has no children and produces concept outcomes '
'via the junction. False on internal navigation nodes.';
COMMENT ON COLUMN paliad.event_categories.icon IS
'Single emoji or icon slug rendered on the button face. Optional.';
CREATE INDEX event_categories_parent_id ON paliad.event_categories (parent_id);
CREATE INDEX event_categories_slug ON paliad.event_categories (slug);
CREATE INDEX event_categories_active ON paliad.event_categories (is_active);
-- updated_at is managed app-side (consistent with paliad.deadline_concepts
-- and other tables in this schema). No DB-level trigger.
-- ============================================================================
-- 2. paliad.event_category_concepts — leaf → concept junction
-- ============================================================================
CREATE TABLE paliad.event_category_concepts (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
event_category_id uuid NOT NULL
REFERENCES paliad.event_categories(id) ON DELETE CASCADE,
concept_id uuid NOT NULL
REFERENCES paliad.deadline_concepts(id) ON DELETE CASCADE,
proceeding_type_code text,
sort_order int NOT NULL DEFAULT 100,
-- NULLS NOT DISTINCT: treat (leaf, concept, NULL) as a single tuple
-- so we can't accidentally seed the same concept twice with no
-- proceeding-narrowing. Requires PostgreSQL 15+ (Supabase ships ≥15).
UNIQUE NULLS NOT DISTINCT (event_category_id, concept_id, proceeding_type_code)
);
COMMENT ON TABLE paliad.event_category_concepts IS
'Many-to-many junction: an event_category leaf produces one or more '
'deadline_concepts as its candidate Frist outcomes. Optional '
'proceeding_type_code narrows the resulting card pills to that '
'context only.';
COMMENT ON COLUMN paliad.event_category_concepts.proceeding_type_code IS
'NULL = all contexts of the concept apply (the result card shows '
'every pill). Set = limit the card''s pill set to this proceeding '
'(e.g. leaf cms-eingang.gericht.hinweisbeschluss → response-to-'
'preliminary-opinion narrowed to DE_NULL only).';
CREATE INDEX event_category_concepts_category
ON paliad.event_category_concepts (event_category_id);
CREATE INDEX event_category_concepts_concept
ON paliad.event_category_concepts (concept_id);
CREATE INDEX event_category_concepts_proceeding
ON paliad.event_category_concepts (proceeding_type_code)
WHERE proceeding_type_code IS NOT NULL;
-- ============================================================================
-- 3. paliad.deadline_rules.is_bilateral — genuinely-bilateral flag
-- ============================================================================
ALTER TABLE paliad.deadline_rules
ADD COLUMN is_bilateral bool NOT NULL DEFAULT false;
COMMENT ON COLUMN paliad.deadline_rules.is_bilateral IS
'When true AND primary_party=''both'', the rule mirrors into both '
'party columns of the columns view (genuinely-bilateral rules: '
'Schriftsatzfristen with Anwaltszwang, joint Mängelbeseitigung, '
'mündliche Verhandlung). When false (default) AND primary_party='
'''both'', the rule applies only to the side that took the action '
'(determined from the parent rule''s party or, if root, from the '
'perspective selector). Backfilled in migration 050 for the small '
'set of genuinely-bilateral rules in the existing corpus.';
CREATE INDEX deadline_rules_is_bilateral
ON paliad.deadline_rules (is_bilateral)
WHERE is_bilateral = true;

View File

@@ -1,12 +0,0 @@
-- t-paliad-133 Phase A seed rollback. CASCADE on the parent_id FK
-- handles descendant rows automatically; we delete by root slug.
DELETE FROM paliad.event_categories
WHERE parent_id IS NULL
AND slug IN (
'cms-eingang',
'muendl-verhandlung',
'beschluss-entscheidung',
'frist-verpasst',
'ich-moechte-einreichen',
'sonstiges'
);

View File

@@ -1,790 +0,0 @@
-- t-paliad-133 Phase A seed: event taxonomy for the v3 decision tree.
--
-- Six root buckets (m's design 2026-05-05):
-- 📥 cms-eingang — CMS-Eingang (Schriftstück erhalten)
-- 🎤 muendl-verhandlung — Mündliche Verhandlung
-- 📊 beschluss-entscheidung — Beschluss / Entscheidung erhalten
-- 🚫 frist-verpasst — Frist verpasst
-- 📤 ich-moechte-einreichen — Ich möchte etwas einreichen (proactive)
-- ❓ sonstiges — Anderes / Sonstiges (B2 fallback)
--
-- Tree depth is unlimited per design lock §10 Q2; current seed reaches
-- depth 4 at deepest (cms-eingang gericht endentscheidung <leaf>).
--
-- Coverage gate at the end of this migration: every concept with
-- category='submission' must be reachable from at least one leaf, except
-- the pure-administrative slugs in the exempt list (filing,
-- request-for-examination, approval-and-translation).
-- ============================================================================
-- 0. Locals: stable parent-slug references for INSERT-time lookups.
-- ============================================================================
-- We INSERT in tree order (roots first, then children) so each parent_id
-- subquery resolves at execution time. Slugs are unique → safe lookup.
-- ============================================================================
-- 1. Roots
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, description_de, description_en,
step_question_de, step_question_en, icon, sort_order, is_leaf)
VALUES
('cms-eingang', NULL, 'CMS-Eingang', 'CMS receipt',
'Ein Schriftstück ist im CMS eingegangen.',
'A document arrived in the CMS.',
'Von wem ist das Schriftstück?',
'Who sent the document?',
'📥', 100, false),
('muendl-verhandlung', NULL, 'Mündliche Verhandlung', 'Oral hearing',
'Etwas rund um eine mündliche Verhandlung.',
'Something about an oral hearing.',
'Was ist mit der Verhandlung passiert?',
'What happened with the hearing?',
'🎤', 200, false),
('beschluss-entscheidung', NULL, 'Beschluss / Entscheidung', 'Decision / Order',
'Eine Entscheidung oder ein Beschluss wurde erlassen.',
'A decision or order has been issued.',
'Welche Art von Entscheidung?',
'What kind of decision?',
'📊', 300, false),
('frist-verpasst', NULL, 'Frist verpasst', 'Missed deadline',
'Eine gesetzliche Frist wurde versäumt — Wiedereinsetzung prüfen.',
'A statutory deadline was missed — check for re-establishment of rights.',
'In welchem System?',
'Which legal system?',
'🚫', 400, false),
('ich-moechte-einreichen', NULL, 'Ich möchte etwas einreichen', 'I want to file something',
'Proaktiv: ein Schriftsatz / Klage / Antrag soll eingereicht werden.',
'Proactive: a submission / claim / application is to be filed.',
'Was möchten Sie einreichen?',
'What would you like to file?',
'📤', 500, false),
('sonstiges', NULL, 'Anderes / Sonstiges', 'Other',
'Etwas Anderes — wechseln Sie zum Filter / zur Suche.',
'Something else — switch to filter / search.',
NULL, NULL,
'', 600, true);
-- ============================================================================
-- 2. Level 2 — children of cms-eingang
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, step_question_de, step_question_en,
icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, s.step_question_de, s.step_question_en,
s.icon, s.sort_order, s.is_leaf
FROM paliad.event_categories p
CROSS JOIN (VALUES
('cms-eingang.gericht', 'Vom Gericht', 'From the Court',
'Welcher Charakter hat das Schriftstück?',
'What is the nature of the document?',
'', 100, false),
('cms-eingang.gegenseite', 'Von der Gegenseite', 'From the opposing party',
'In welchem Verfahrenstyp?',
'In which proceeding type?',
'👥', 200, false)
) AS s(slug, label_de, label_en, step_question_de, step_question_en,
icon, sort_order, is_leaf)
WHERE p.slug = 'cms-eingang';
-- ============================================================================
-- 3. Level 3 — children of cms-eingang.gericht
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, step_question_de, step_question_en,
icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, s.step_question_de, s.step_question_en,
s.icon, s.sort_order, s.is_leaf
FROM paliad.event_categories p
CROSS JOIN (VALUES
('cms-eingang.gericht.hinweisbeschluss',
'Hinweisbeschluss / vorläufige Würdigung',
'Preliminary opinion / court hint',
NULL, NULL, '📋', 100, true),
('cms-eingang.gericht.ladung',
'Ladung zur mündlichen Verhandlung',
'Summons to oral hearing',
NULL, NULL, '📅', 200, true),
('cms-eingang.gericht.bescheid-mit-frist',
'Bescheid mit explizit gesetzter Frist',
'Order with court-set deadline',
NULL, NULL, '📨', 300, true),
('cms-eingang.gericht.endentscheidung',
'Endentscheidung / Urteil',
'Final decision / Judgment',
'Welche Instanz / welches Verfahren?',
'Which instance / proceeding?',
'🏛', 400, false),
('cms-eingang.gericht.kostenfestsetzung',
'Kostenfestsetzungsbeschluss',
'Cost-fixing order',
NULL, NULL, '💰', 500, true),
('cms-eingang.gericht.rechtsverlust-epa',
'Mitteilung über Rechtsverlust (EPA)',
'Loss-of-rights notice (EPO)',
NULL, NULL, '🚫', 600, true),
('cms-eingang.gericht.anordnung',
'Anordnung / Order (PI, Beweissicherung)',
'Order (PI, evidence preservation)',
NULL, NULL, '📌', 700, true)
) AS s(slug, label_de, label_en, step_question_de, step_question_en,
icon, sort_order, is_leaf)
WHERE p.slug = 'cms-eingang.gericht';
-- ============================================================================
-- 4. Level 4 — children of cms-eingang.gericht.endentscheidung
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, step_question_de, step_question_en,
icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, NULL, NULL,
s.icon, s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('cms-eingang.gericht.endentscheidung.urteil-de-inf-lg',
'Urteil LG (Verletzung)', 'LG judgment (infringement)', '', 100),
('cms-eingang.gericht.endentscheidung.urteil-de-inf-olg',
'Urteil OLG (Verletzung)', 'OLG judgment (infringement)', '', 200),
('cms-eingang.gericht.endentscheidung.urteil-de-null-bpatg',
'Urteil BPatG (Nichtigkeit)', 'BPatG judgment (nullity)', '', 300),
('cms-eingang.gericht.endentscheidung.urteil-upc-cfi',
'Sachentscheidung UPC (CFI)', 'UPC CFI decision', '', 400),
('cms-eingang.gericht.endentscheidung.urteil-upc-coa',
'Sachentscheidung UPC (CoA)', 'UPC CoA decision', '', 500),
('cms-eingang.gericht.endentscheidung.entscheidung-epa-opp',
'Einspruchsentscheidung EPA', 'EPO opposition decision', '', 600),
('cms-eingang.gericht.endentscheidung.entscheidung-epa-boa',
'Beschwerdeentscheidung EPA', 'EPO Board of Appeal decision', '', 700),
('cms-eingang.gericht.endentscheidung.entscheidung-dpma',
'DPMA-Einspruchsentscheidung', 'DPMA opposition decision', '', 800),
('cms-eingang.gericht.endentscheidung.beschluss-bpatg-beschwerde',
'Beschluss BPatG (DPMA-Beschwerde)', 'BPatG order (DPMA appeal)', '', 900),
('cms-eingang.gericht.endentscheidung.versaeumnisurteil',
'Versäumnisurteil (DE)', 'Default judgment (DE)', '📊', 1000)
) AS s(slug, label_de, label_en, icon, sort_order)
WHERE p.slug = 'cms-eingang.gericht.endentscheidung';
-- ============================================================================
-- 5. Level 3 — children of cms-eingang.gegenseite
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, step_question_de, step_question_en,
icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, s.step_question_de, s.step_question_en,
s.icon, s.sort_order, s.is_leaf
FROM paliad.event_categories p
CROSS JOIN (VALUES
('cms-eingang.gegenseite.upc-inf',
'UPC Verletzungsverfahren', 'UPC infringement',
'Welcher Schriftsatz wurde eingereicht?',
'Which submission was filed?', '', 100, false),
('cms-eingang.gegenseite.upc-rev',
'UPC Nichtigkeitsverfahren', 'UPC revocation',
'Welcher Schriftsatz?',
'Which submission?', '', 200, false),
('cms-eingang.gegenseite.de-inf',
'DE Verletzungsklage (LG/OLG)', 'DE infringement (LG/OLG)',
'Welcher Schriftsatz?',
'Which submission?', '🏛', 300, false),
('cms-eingang.gegenseite.de-null',
'DE Nichtigkeitsklage (BPatG)', 'DE nullity (BPatG)',
'Welcher Schriftsatz?',
'Which submission?', '🏛', 400, false),
('cms-eingang.gegenseite.epa-opp',
'EPA Einspruch', 'EPO opposition',
'Welcher Schriftsatz?',
'Which submission?', '🏛', 500, false),
('cms-eingang.gegenseite.epa-app',
'EPA Beschwerde', 'EPO appeal',
NULL, NULL, '🏛', 600, true),
('cms-eingang.gegenseite.dpma-opp',
'DPMA Einspruchsschrift', 'DPMA opposition',
NULL, NULL, '🏛', 700, true)
) AS s(slug, label_de, label_en, step_question_de, step_question_en,
icon, sort_order, is_leaf)
WHERE p.slug = 'cms-eingang.gegenseite';
-- ============================================================================
-- 6. Level 4 — children of cms-eingang.gegenseite.upc-inf
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, s.icon, s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('cms-eingang.gegenseite.upc-inf.klageschrift',
'Klageschrift', 'Statement of claim', '📜', 100),
('cms-eingang.gegenseite.upc-inf.klageerwiderung-mit-ccr',
'Klageerwiderung MIT Nichtigkeitswiderklage',
'Statement of defence WITH CCR', '🔄', 200),
('cms-eingang.gegenseite.upc-inf.klageerwiderung-ohne-ccr',
'Klageerwiderung OHNE Nichtigkeitswiderklage',
'Statement of defence WITHOUT CCR', '🔄', 300),
('cms-eingang.gegenseite.upc-inf.replik',
'Replik (Reply to Defence)', 'Reply to Defence', '', 400),
('cms-eingang.gegenseite.upc-inf.antrag-patentaenderung',
'Antrag auf Patentänderung (R.30)',
'Application to amend (R.30)', '🔁', 500),
('cms-eingang.gegenseite.upc-inf.berufungsschrift',
'Berufungsschrift Gegner', 'Opposing party''s notice of appeal', '📈', 600)
) AS s(slug, label_de, label_en, icon, sort_order)
WHERE p.slug = 'cms-eingang.gegenseite.upc-inf';
-- ============================================================================
-- 7. Level 4 — children of cms-eingang.gegenseite.upc-rev
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, s.icon, s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('cms-eingang.gegenseite.upc-rev.nichtigkeitsklage',
'Nichtigkeitsklage (Statement for Revocation)',
'Application for revocation', '📜', 100),
('cms-eingang.gegenseite.upc-rev.defence-to-revocation',
'Defence to Revocation (mit/ohne Amend, mit/ohne CCI)',
'Defence to revocation', '🔄', 200),
('cms-eingang.gegenseite.upc-rev.berufungsschrift',
'Berufungsschrift Gegner (UPC_REV)',
'Opposing party''s notice of appeal (UPC_REV)', '📈', 300)
) AS s(slug, label_de, label_en, icon, sort_order)
WHERE p.slug = 'cms-eingang.gegenseite.upc-rev';
-- ============================================================================
-- 8. Level 4 — children of cms-eingang.gegenseite.de-inf
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, s.icon, s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('cms-eingang.gegenseite.de-inf.klageschrift',
'Klageschrift LG', 'LG statement of claim', '📜', 100),
('cms-eingang.gegenseite.de-inf.klageerwiderung',
'Klageerwiderung LG', 'LG statement of defence', '🔄', 200),
('cms-eingang.gegenseite.de-inf.berufungsschrift-olg',
'Berufungsschrift OLG', 'OLG notice of appeal', '📈', 300)
) AS s(slug, label_de, label_en, icon, sort_order)
WHERE p.slug = 'cms-eingang.gegenseite.de-inf';
-- ============================================================================
-- 9. Level 4 — children of cms-eingang.gegenseite.de-null
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, s.icon, s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('cms-eingang.gegenseite.de-null.nichtigkeitsklage',
'Nichtigkeitsklage BPatG', 'BPatG application for revocation', '📜', 100),
('cms-eingang.gegenseite.de-null.klageerwiderung',
'Klageerwiderung BPatG', 'BPatG statement of defence', '🔄', 200),
('cms-eingang.gegenseite.de-null.berufungsschrift-bgh',
'Berufungsschrift BGH (Nichtigkeit)',
'BGH notice of appeal (nullity)', '📈', 300)
) AS s(slug, label_de, label_en, icon, sort_order)
WHERE p.slug = 'cms-eingang.gegenseite.de-null';
-- ============================================================================
-- 10. Level 4 — children of cms-eingang.gegenseite.epa-opp
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, '📜', s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('cms-eingang.gegenseite.epa-opp.einspruchsschrift',
'Einspruchsschrift', 'Notice of opposition', 100)
) AS s(slug, label_de, label_en, sort_order)
WHERE p.slug = 'cms-eingang.gegenseite.epa-opp';
-- ============================================================================
-- 11. Level 2 — children of muendl-verhandlung
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, s.icon, s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('muendl-verhandlung.geladen',
'Geladen — wann findet sie statt?', 'Summoned — when?', '📅', 100),
('muendl-verhandlung.gehalten',
'Soeben gehalten / heute', 'Just held / today', '', 200),
('muendl-verhandlung.verlegt',
'Verlegt', 'Postponed', '🔁', 300),
('muendl-verhandlung.zwischenverfahren',
'Zwischenverfahren / interim conference', 'Interim conference', '🤝', 400)
) AS s(slug, label_de, label_en, icon, sort_order)
WHERE p.slug = 'muendl-verhandlung';
-- ============================================================================
-- 12. Level 2 — children of beschluss-entscheidung
-- (parallel set to cms-eingang.gericht.endentscheidung — different
-- mental classification, same outcomes)
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, s.icon, s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('beschluss-entscheidung.urteil-de-inf-lg',
'Urteil LG (Verletzung)', 'LG judgment (infringement)', '', 100),
('beschluss-entscheidung.urteil-de-inf-olg',
'Urteil OLG (Verletzung)', 'OLG judgment (infringement)', '', 200),
('beschluss-entscheidung.urteil-de-null-bpatg',
'Urteil BPatG (Nichtigkeit)', 'BPatG judgment (nullity)', '', 300),
('beschluss-entscheidung.urteil-upc-cfi',
'Sachentscheidung UPC (CFI)', 'UPC CFI decision', '', 400),
('beschluss-entscheidung.urteil-upc-coa',
'Sachentscheidung UPC (CoA)', 'UPC CoA decision', '', 500),
('beschluss-entscheidung.entscheidung-epa-opp',
'Einspruchsentscheidung EPA', 'EPO opposition decision', '', 600),
('beschluss-entscheidung.entscheidung-epa-boa',
'Beschwerdeentscheidung EPA', 'EPO Board of Appeal decision', '', 700),
('beschluss-entscheidung.entscheidung-dpma',
'DPMA-Einspruchsentscheidung', 'DPMA opposition decision', '', 800),
('beschluss-entscheidung.beschluss-bpatg-beschwerde',
'Beschluss BPatG (DPMA-Beschwerde)', 'BPatG order (DPMA appeal)', '', 900),
('beschluss-entscheidung.versaeumnisurteil',
'Versäumnisurteil (DE)', 'Default judgment (DE)', '📊', 1000),
('beschluss-entscheidung.kostenfestsetzung',
'Kostenfestsetzungsbeschluss', 'Cost-fixing order', '💰', 1100)
) AS s(slug, label_de, label_en, icon, sort_order)
WHERE p.slug = 'beschluss-entscheidung';
-- ============================================================================
-- 13. Level 2 — children of frist-verpasst
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, '🏛', s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('frist-verpasst.de-patg',
'DE Patentverfahren (PatG §123 — 2 Monate)',
'DE patent proceedings (PatG §123)', 100),
('frist-verpasst.de-zpo',
'DE Zivilverfahren (ZPO §233 — 2 Wochen!)',
'DE civil proceedings (ZPO §233 — 2 weeks!)', 200),
('frist-verpasst.epa',
'EPA (Art. 122 EPÜ — 2 Monate)',
'EPO (Art. 122 EPC)', 300),
('frist-verpasst.dpma',
'DPMA (PatG §123)',
'DPMA (PatG §123)', 400)
) AS s(slug, label_de, label_en, sort_order)
WHERE p.slug = 'frist-verpasst';
-- ============================================================================
-- 14. Level 2 — children of ich-moechte-einreichen
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, step_question_de, step_question_en,
icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, s.step_question_de, s.step_question_en,
s.icon, s.sort_order, s.is_leaf
FROM paliad.event_categories p
CROSS JOIN (VALUES
('ich-moechte-einreichen.klage',
'Klage / Antrag (1. Instanz)', 'Claim / application (1st instance)',
'In welchem Verfahren?', 'Which proceeding?',
'📜', 100, false),
('ich-moechte-einreichen.berufung',
'Berufung / Beschwerde (höhere Instanz)',
'Appeal (higher instance)',
'Welche Konstellation?', 'Which constellation?',
'📈', 200, false),
('ich-moechte-einreichen.widerklage',
'Widerklage / Counterclaim',
'Counterclaim',
'Welche Art von Widerklage?', 'Which kind of counterclaim?',
'🔁', 300, false),
('ich-moechte-einreichen.spaetere-schriftsaetze',
'Späterer Schriftsatz im laufenden Verfahren',
'Later submission in pending proceedings',
'Welcher späterer Schriftsatz?', 'Which later submission?',
'', 400, false),
('ich-moechte-einreichen.einspruch-erteilung',
'Einspruchsfrist nach Erteilung',
'Opposition deadline after grant',
NULL, NULL,
'', 500, true)
) AS s(slug, label_de, label_en, step_question_de, step_question_en,
icon, sort_order, is_leaf)
WHERE p.slug = 'ich-moechte-einreichen';
-- ============================================================================
-- 15. Level 3 — children of ich-moechte-einreichen.klage
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, '📜', s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('ich-moechte-einreichen.klage.upc-inf',
'UPC Verletzungsklage', 'UPC infringement claim', 100),
('ich-moechte-einreichen.klage.upc-rev',
'UPC Nichtigkeitsklage', 'UPC revocation claim', 200),
('ich-moechte-einreichen.klage.upc-pi',
'UPC einstw. Maßnahmen', 'UPC provisional measures', 300),
('ich-moechte-einreichen.klage.upc-damages',
'UPC Schadensbemessung', 'UPC damages determination', 400),
('ich-moechte-einreichen.klage.upc-discovery',
'UPC Bucheinsicht', 'UPC lay open books', 500),
('ich-moechte-einreichen.klage.de-inf',
'DE Verletzungsklage LG', 'DE infringement claim (LG)', 600),
('ich-moechte-einreichen.klage.de-null',
'DE Nichtigkeitsklage BPatG', 'DE revocation (BPatG)', 700),
('ich-moechte-einreichen.klage.epa-opp',
'EPA Einspruch', 'EPO opposition', 800),
('ich-moechte-einreichen.klage.dpma-opp',
'DPMA Einspruch', 'DPMA opposition', 900)
) AS s(slug, label_de, label_en, sort_order)
WHERE p.slug = 'ich-moechte-einreichen.klage';
-- ============================================================================
-- 16. Level 3 — children of ich-moechte-einreichen.berufung
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, '📈', s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('ich-moechte-einreichen.berufung.de-olg',
'Berufung OLG (Verletzung)', 'OLG appeal (infringement)', 100),
('ich-moechte-einreichen.berufung.de-bgh-nzb',
'Nichtzulassungsbeschwerde BGH', 'BGH leave-appeal complaint', 200),
('ich-moechte-einreichen.berufung.de-bgh-revision',
'Revision BGH', 'BGH revision', 300),
('ich-moechte-einreichen.berufung.de-bgh-null',
'Berufung BGH (Patentnichtigkeit)', 'BGH appeal (nullity)', 400),
('ich-moechte-einreichen.berufung.upc-coa',
'Berufung UPC CoA', 'UPC CoA appeal', 500),
('ich-moechte-einreichen.berufung.upc-coa-orders',
'Berufung UPC mit Zulassung (Anordnungen)',
'UPC appeal with leave (orders)', 600),
('ich-moechte-einreichen.berufung.upc-cost',
'Berufung UPC Kostenentscheidung', 'UPC cost-decision appeal', 700),
('ich-moechte-einreichen.berufung.epa',
'Beschwerde EPA', 'EPO appeal', 800),
('ich-moechte-einreichen.berufung.bpatg-beschwerde',
'Beschwerde BPatG (gegen DPMA)',
'BPatG appeal (vs DPMA)', 900),
('ich-moechte-einreichen.berufung.bgh-rb',
'Rechtsbeschwerde BGH (DPMA)',
'BGH legal-complaint (DPMA)', 1000)
) AS s(slug, label_de, label_en, sort_order)
WHERE p.slug = 'ich-moechte-einreichen.berufung';
-- ============================================================================
-- 17. Level 3 — children of ich-moechte-einreichen.widerklage
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, '🔁', s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('ich-moechte-einreichen.widerklage.nichtigkeit-upc',
'Nichtigkeitswiderklage (UPC R.25)',
'Counterclaim for revocation (UPC R.25)', 100),
('ich-moechte-einreichen.widerklage.verletzung-upc',
'Verletzungswiderklage (UPC R.50/49.2.b)',
'Counterclaim for infringement (UPC R.50/49.2.b)', 200)
) AS s(slug, label_de, label_en, sort_order)
WHERE p.slug = 'ich-moechte-einreichen.widerklage';
-- ============================================================================
-- 18. Level 3 — children of ich-moechte-einreichen.spaetere-schriftsaetze
-- ============================================================================
INSERT INTO paliad.event_categories
(slug, parent_id, label_de, label_en, icon, sort_order, is_leaf)
SELECT
s.slug, p.id, s.label_de, s.label_en, '', s.sort_order, true
FROM paliad.event_categories p
CROSS JOIN (VALUES
('ich-moechte-einreichen.spaetere-schriftsaetze.replik-ccr-upc',
'Replik auf Erwiderung zur Nichtigkeitsw. (UPC R.29.d)',
'Reply to Defence to CCR (UPC R.29.d)', 100),
('ich-moechte-einreichen.spaetere-schriftsaetze.duplik-ccr-upc',
'Duplik auf Replik zur Nichtigkeitsw. (UPC R.29.e)',
'Rejoinder on Reply to CCR (UPC R.29.e)', 200),
('ich-moechte-einreichen.spaetere-schriftsaetze.duplik-amend-upc',
'Duplik auf Replik zum Patentänderungsantrag (UPC R.32.3)',
'Rejoinder on Reply to Application to amend (UPC R.32.3)', 300),
('ich-moechte-einreichen.spaetere-schriftsaetze.replik-cci-upc',
'Replik auf Erwiderung zur Verletzungsw. (UPC R.56.3)',
'Reply to Defence to CCI (UPC R.56.3)', 400),
('ich-moechte-einreichen.spaetere-schriftsaetze.duplik-cci-upc',
'Duplik auf Replik zur Verletzungsw. (UPC R.56.4)',
'Rejoinder on Reply to CCI (UPC R.56.4)', 500),
('ich-moechte-einreichen.spaetere-schriftsaetze.kostenantrag',
'Antrag auf Kostenentscheidung',
'Application for cost decision', 600)
) AS s(slug, label_de, label_en, sort_order)
WHERE p.slug = 'ich-moechte-einreichen.spaetere-schriftsaetze';
-- ============================================================================
-- 19. Junction: leaf → concept (with optional proceeding_type_code)
-- Each row is one (leaf, concept, proceeding_code) tuple.
-- ============================================================================
WITH leaf AS (
SELECT id, slug FROM paliad.event_categories WHERE is_leaf = true
), concept AS (
SELECT id, slug FROM paliad.deadline_concepts
)
INSERT INTO paliad.event_category_concepts
(event_category_id, concept_id, proceeding_type_code, sort_order)
SELECT l.id, c.id, m.proceeding_type_code, m.sort_order
FROM (VALUES
-- ── 1. CMS-Eingang vom Gericht ──
('cms-eingang.gericht.hinweisbeschluss', 'response-to-preliminary-opinion', 'DE_NULL', 100),
('cms-eingang.gericht.hinweisbeschluss', 'response-to-preliminary-opinion', 'DE_INF', 200),
('cms-eingang.gericht.ladung', 'r116-final-submissions', 'EPA_OPP', 100),
('cms-eingang.gericht.ladung', 'r116-final-submissions', 'EPA_APP', 200),
('cms-eingang.gericht.ladung', 'schriftsatznachreichung', NULL, 300),
('cms-eingang.gericht.kostenfestsetzung', 'notice-of-appeal', 'UPC_COST_APPEAL', 100),
('cms-eingang.gericht.rechtsverlust-epa', 'weiterbehandlung', NULL, 100),
('cms-eingang.gericht.rechtsverlust-epa', 'wiedereinsetzung', NULL, 200),
('cms-eingang.gericht.anordnung', 'request-for-discretionary-review', NULL, 100),
-- ── 1.x Endentscheidung (CMS-Eingang variant) ──
('cms-eingang.gericht.endentscheidung.urteil-de-inf-lg', 'notice-of-appeal', 'DE_INF_OLG', 100),
('cms-eingang.gericht.endentscheidung.urteil-de-inf-lg', 'statement-of-grounds-of-appeal', 'DE_INF_OLG', 200),
('cms-eingang.gericht.endentscheidung.urteil-de-inf-olg', 'nichtzulassungsbeschwerde', 'DE_INF_BGH', 100),
('cms-eingang.gericht.endentscheidung.urteil-de-inf-olg', 'nichtzulassungsbeschwerde-begruendung', 'DE_INF_BGH', 200),
('cms-eingang.gericht.endentscheidung.urteil-de-inf-olg', 'revisionsfrist', 'DE_INF_BGH', 300),
('cms-eingang.gericht.endentscheidung.urteil-de-inf-olg', 'revisionsbegruendung', 'DE_INF_BGH', 400),
('cms-eingang.gericht.endentscheidung.urteil-de-null-bpatg', 'notice-of-appeal', 'DE_NULL_BGH', 100),
('cms-eingang.gericht.endentscheidung.urteil-de-null-bpatg', 'statement-of-grounds-of-appeal', 'DE_NULL_BGH', 200),
('cms-eingang.gericht.endentscheidung.urteil-upc-cfi', 'notice-of-appeal', 'UPC_APP', 100),
('cms-eingang.gericht.endentscheidung.urteil-upc-cfi', 'statement-of-grounds-of-appeal', 'UPC_APP', 200),
('cms-eingang.gericht.endentscheidung.urteil-upc-coa', 'petition-for-review', NULL, 100),
('cms-eingang.gericht.endentscheidung.entscheidung-epa-opp', 'notice-of-appeal', 'EPA_APP', 100),
('cms-eingang.gericht.endentscheidung.entscheidung-epa-opp', 'statement-of-grounds-of-appeal', 'EPA_APP', 200),
('cms-eingang.gericht.endentscheidung.entscheidung-epa-boa', 'petition-for-review', 'EPA_APP', 100),
('cms-eingang.gericht.endentscheidung.entscheidung-dpma', 'notice-of-appeal', 'DPMA_BPATG_BESCHWERDE', 100),
('cms-eingang.gericht.endentscheidung.entscheidung-dpma', 'statement-of-grounds-of-appeal', 'DPMA_BPATG_BESCHWERDE', 200),
('cms-eingang.gericht.endentscheidung.beschluss-bpatg-beschwerde', 'rechtsbeschwerde', 'DPMA_BGH_RB', 100),
('cms-eingang.gericht.endentscheidung.beschluss-bpatg-beschwerde', 'rechtsbeschwerde-begruendung', 'DPMA_BGH_RB', 200),
('cms-eingang.gericht.endentscheidung.versaeumnisurteil', 'versaeumnisurteil-einspruch', NULL, 100),
-- ── 1.x Gegenseite UPC_INF ──
('cms-eingang.gegenseite.upc-inf.klageschrift', 'notice-of-defence-intention', 'UPC_INF', 100),
('cms-eingang.gegenseite.upc-inf.klageschrift', 'statement-of-defence', 'UPC_INF', 200),
('cms-eingang.gegenseite.upc-inf.klageerwiderung-mit-ccr', 'defence-to-counterclaim-for-revocation', 'UPC_INF', 100),
('cms-eingang.gegenseite.upc-inf.klageerwiderung-mit-ccr', 'application-to-amend', 'UPC_INF', 200),
('cms-eingang.gegenseite.upc-inf.klageerwiderung-mit-ccr', 'reply-to-defence', 'UPC_INF', 300),
('cms-eingang.gegenseite.upc-inf.klageerwiderung-ohne-ccr', 'reply-to-defence', 'UPC_INF', 100),
('cms-eingang.gegenseite.upc-inf.replik', 'rejoinder', 'UPC_INF', 100),
('cms-eingang.gegenseite.upc-inf.antrag-patentaenderung', 'defence-to-application-to-amend', 'UPC_INF', 100),
('cms-eingang.gegenseite.upc-inf.antrag-patentaenderung', 'reply-to-defence-to-application-to-amend', 'UPC_INF', 200),
('cms-eingang.gegenseite.upc-inf.berufungsschrift', 'response-to-appeal', 'UPC_APP', 100),
('cms-eingang.gegenseite.upc-inf.berufungsschrift', 'cross-appeal', 'UPC_APP', 200),
-- ── 1.x Gegenseite UPC_REV ──
('cms-eingang.gegenseite.upc-rev.nichtigkeitsklage', 'statement-of-defence', 'UPC_REV', 100),
('cms-eingang.gegenseite.upc-rev.defence-to-revocation', 'reply-to-defence', 'UPC_REV', 100),
('cms-eingang.gegenseite.upc-rev.defence-to-revocation', 'defence-to-application-to-amend', 'UPC_REV', 200),
('cms-eingang.gegenseite.upc-rev.defence-to-revocation', 'defence-to-counterclaim-for-infringement', 'UPC_REV', 300),
('cms-eingang.gegenseite.upc-rev.berufungsschrift', 'response-to-appeal', 'UPC_APP', 100),
('cms-eingang.gegenseite.upc-rev.berufungsschrift', 'cross-appeal', 'UPC_APP', 200),
-- ── 1.x Gegenseite DE_INF ──
('cms-eingang.gegenseite.de-inf.klageschrift', 'notice-of-defence-intention', 'DE_INF', 100),
('cms-eingang.gegenseite.de-inf.klageschrift', 'statement-of-defence', 'DE_INF', 200),
('cms-eingang.gegenseite.de-inf.klageerwiderung', 'reply-to-defence', 'DE_INF', 100),
('cms-eingang.gegenseite.de-inf.berufungsschrift-olg', 'response-to-appeal', 'DE_INF_OLG', 100),
('cms-eingang.gegenseite.de-inf.berufungsschrift-olg', 'cross-appeal', 'DE_INF_OLG', 200),
-- ── 1.x Gegenseite DE_NULL ──
('cms-eingang.gegenseite.de-null.nichtigkeitsklage', 'statement-of-defence', 'DE_NULL', 100),
('cms-eingang.gegenseite.de-null.klageerwiderung', 'reply-to-defence', 'DE_NULL', 100),
('cms-eingang.gegenseite.de-null.berufungsschrift-bgh', 'response-to-appeal', 'DE_NULL_BGH', 100),
-- ── 1.x Gegenseite EPA OPP / APP / DPMA ──
('cms-eingang.gegenseite.epa-opp.einspruchsschrift', 'statement-of-defence', 'EPA_OPP', 100),
('cms-eingang.gegenseite.epa-opp.einspruchsschrift', 'r79-further-stellungnahme', 'EPA_OPP', 200),
('cms-eingang.gegenseite.epa-app', 'response-to-appeal', 'EPA_APP', 100),
('cms-eingang.gegenseite.dpma-opp', 'statement-of-defence', 'DPMA_OPP', 100),
-- ── 2. Mündliche Verhandlung ──
('muendl-verhandlung.geladen', 'r116-final-submissions', 'EPA_OPP', 100),
('muendl-verhandlung.geladen', 'r116-final-submissions', 'EPA_APP', 200),
('muendl-verhandlung.geladen', 'schriftsatznachreichung', NULL, 300),
('muendl-verhandlung.gehalten', 'schriftsatznachreichung', NULL, 100),
('muendl-verhandlung.zwischenverfahren', 'interim-conference', 'UPC_INF', 100),
('muendl-verhandlung.zwischenverfahren', 'interim-conference', 'UPC_REV', 200),
-- (verlegt has no concept outcome — informational card only)
-- ── 3. Beschluss / Entscheidung (parallel set, same outcomes) ──
('beschluss-entscheidung.urteil-de-inf-lg', 'notice-of-appeal', 'DE_INF_OLG', 100),
('beschluss-entscheidung.urteil-de-inf-lg', 'statement-of-grounds-of-appeal', 'DE_INF_OLG', 200),
('beschluss-entscheidung.urteil-de-inf-olg', 'nichtzulassungsbeschwerde', 'DE_INF_BGH', 100),
('beschluss-entscheidung.urteil-de-inf-olg', 'nichtzulassungsbeschwerde-begruendung', 'DE_INF_BGH', 200),
('beschluss-entscheidung.urteil-de-inf-olg', 'revisionsfrist', 'DE_INF_BGH', 300),
('beschluss-entscheidung.urteil-de-inf-olg', 'revisionsbegruendung', 'DE_INF_BGH', 400),
('beschluss-entscheidung.urteil-de-null-bpatg', 'notice-of-appeal', 'DE_NULL_BGH', 100),
('beschluss-entscheidung.urteil-de-null-bpatg', 'statement-of-grounds-of-appeal', 'DE_NULL_BGH', 200),
('beschluss-entscheidung.urteil-upc-cfi', 'notice-of-appeal', 'UPC_APP', 100),
('beschluss-entscheidung.urteil-upc-cfi', 'statement-of-grounds-of-appeal', 'UPC_APP', 200),
('beschluss-entscheidung.urteil-upc-coa', 'petition-for-review', NULL, 100),
('beschluss-entscheidung.entscheidung-epa-opp', 'notice-of-appeal', 'EPA_APP', 100),
('beschluss-entscheidung.entscheidung-epa-opp', 'statement-of-grounds-of-appeal', 'EPA_APP', 200),
('beschluss-entscheidung.entscheidung-epa-boa', 'petition-for-review', 'EPA_APP', 100),
('beschluss-entscheidung.entscheidung-dpma', 'notice-of-appeal', 'DPMA_BPATG_BESCHWERDE', 100),
('beschluss-entscheidung.entscheidung-dpma', 'statement-of-grounds-of-appeal', 'DPMA_BPATG_BESCHWERDE', 200),
('beschluss-entscheidung.beschluss-bpatg-beschwerde', 'rechtsbeschwerde', 'DPMA_BGH_RB', 100),
('beschluss-entscheidung.beschluss-bpatg-beschwerde', 'rechtsbeschwerde-begruendung', 'DPMA_BGH_RB', 200),
('beschluss-entscheidung.versaeumnisurteil', 'versaeumnisurteil-einspruch', NULL, 100),
('beschluss-entscheidung.kostenfestsetzung', 'notice-of-appeal', 'UPC_COST_APPEAL', 100),
-- ── 4. Frist verpasst ──
('frist-verpasst.de-patg', 'wiedereinsetzung', NULL, 100),
('frist-verpasst.de-zpo', 'wiedereinsetzung', NULL, 100),
('frist-verpasst.epa', 'wiedereinsetzung', NULL, 100),
('frist-verpasst.epa', 'weiterbehandlung', NULL, 200),
('frist-verpasst.dpma', 'wiedereinsetzung', NULL, 100),
-- ── 5. Ich möchte einreichen — Klage ──
('ich-moechte-einreichen.klage.upc-inf', 'statement-of-claim', 'UPC_INF', 100),
('ich-moechte-einreichen.klage.upc-rev', 'application-for-revocation', 'UPC_REV', 100),
('ich-moechte-einreichen.klage.upc-pi', 'application-for-provisional-measures', 'UPC_PI', 100),
('ich-moechte-einreichen.klage.upc-damages', 'application-for-determination-of-damages', 'UPC_DAMAGES', 100),
('ich-moechte-einreichen.klage.upc-discovery', 'request-to-lay-open-books', 'UPC_DISCOVERY', 100),
('ich-moechte-einreichen.klage.de-inf', 'statement-of-claim', 'DE_INF', 100),
('ich-moechte-einreichen.klage.de-null', 'application-for-revocation', 'DE_NULL', 100),
('ich-moechte-einreichen.klage.epa-opp', 'opposition', 'EPA_OPP', 100),
('ich-moechte-einreichen.klage.dpma-opp', 'opposition', 'DPMA_OPP', 100),
-- ── 6. Ich möchte einreichen — Berufung ──
('ich-moechte-einreichen.berufung.de-olg', 'notice-of-appeal', 'DE_INF_OLG', 100),
('ich-moechte-einreichen.berufung.de-olg', 'statement-of-grounds-of-appeal', 'DE_INF_OLG', 200),
('ich-moechte-einreichen.berufung.de-bgh-nzb', 'nichtzulassungsbeschwerde', 'DE_INF_BGH', 100),
('ich-moechte-einreichen.berufung.de-bgh-nzb', 'nichtzulassungsbeschwerde-begruendung', 'DE_INF_BGH', 200),
('ich-moechte-einreichen.berufung.de-bgh-revision', 'revisionsfrist', 'DE_INF_BGH', 100),
('ich-moechte-einreichen.berufung.de-bgh-revision', 'revisionsbegruendung', 'DE_INF_BGH', 200),
('ich-moechte-einreichen.berufung.de-bgh-null', 'notice-of-appeal', 'DE_NULL_BGH', 100),
('ich-moechte-einreichen.berufung.de-bgh-null', 'statement-of-grounds-of-appeal', 'DE_NULL_BGH', 200),
('ich-moechte-einreichen.berufung.upc-coa', 'notice-of-appeal', 'UPC_APP', 100),
('ich-moechte-einreichen.berufung.upc-coa', 'statement-of-grounds-of-appeal', 'UPC_APP', 200),
('ich-moechte-einreichen.berufung.upc-coa-orders', 'appeal-with-leave', 'UPC_APP_ORDERS', 100),
('ich-moechte-einreichen.berufung.upc-coa-orders', 'application-for-leave-to-appeal', 'UPC_APP_ORDERS', 200),
('ich-moechte-einreichen.berufung.upc-cost', 'notice-of-appeal', 'UPC_COST_APPEAL', 100),
('ich-moechte-einreichen.berufung.epa', 'notice-of-appeal', 'EPA_APP', 100),
('ich-moechte-einreichen.berufung.epa', 'statement-of-grounds-of-appeal', 'EPA_APP', 200),
('ich-moechte-einreichen.berufung.bpatg-beschwerde', 'notice-of-appeal', 'DPMA_BPATG_BESCHWERDE', 100),
('ich-moechte-einreichen.berufung.bpatg-beschwerde', 'statement-of-grounds-of-appeal', 'DPMA_BPATG_BESCHWERDE', 200),
('ich-moechte-einreichen.berufung.bgh-rb', 'rechtsbeschwerde', 'DPMA_BGH_RB', 100),
('ich-moechte-einreichen.berufung.bgh-rb', 'rechtsbeschwerde-begruendung', 'DPMA_BGH_RB', 200),
-- ── 7. Ich möchte einreichen — Widerklage ──
('ich-moechte-einreichen.widerklage.nichtigkeit-upc', 'counterclaim-for-revocation', 'UPC_INF', 100),
('ich-moechte-einreichen.widerklage.nichtigkeit-upc', 'application-to-amend', 'UPC_INF', 200),
('ich-moechte-einreichen.widerklage.verletzung-upc', 'counterclaim-for-infringement', 'UPC_REV', 100),
-- ── 8. Ich möchte einreichen — Spätere Schriftsätze ──
('ich-moechte-einreichen.spaetere-schriftsaetze.replik-ccr-upc', 'reply-to-defence-to-counterclaim-for-revocation', 'UPC_INF', 100),
('ich-moechte-einreichen.spaetere-schriftsaetze.duplik-ccr-upc', 'rejoinder-on-reply-to-defence-to-ccr', 'UPC_INF', 100),
('ich-moechte-einreichen.spaetere-schriftsaetze.duplik-amend-upc','rejoinder-on-reply-to-amend', 'UPC_INF', 100),
('ich-moechte-einreichen.spaetere-schriftsaetze.duplik-amend-upc','rejoinder-on-reply-to-amend', 'UPC_REV', 200),
('ich-moechte-einreichen.spaetere-schriftsaetze.replik-cci-upc', 'reply-to-defence-to-counterclaim-for-infringement', 'UPC_REV', 100),
('ich-moechte-einreichen.spaetere-schriftsaetze.duplik-cci-upc', 'rejoinder-on-counterclaim-for-infringement', 'UPC_REV', 100),
('ich-moechte-einreichen.spaetere-schriftsaetze.kostenantrag', 'application-for-cost-decision', 'UPC_INF', 100),
-- ── 9. Einspruch nach Erteilung ──
('ich-moechte-einreichen.einspruch-erteilung', 'opposition', 'EPA_OPP', 100),
('ich-moechte-einreichen.einspruch-erteilung', 'opposition', 'DPMA_OPP', 200)
) AS m(leaf_slug, concept_slug, proceeding_type_code, sort_order)
JOIN leaf l ON l.slug = m.leaf_slug
JOIN concept c ON c.slug = m.concept_slug;
-- ============================================================================
-- 20. Coverage gate: every category='submission' concept must be reachable
-- from at least one leaf, except a small exempt list of pure-administrative
-- concepts that live on Pathway A (browse-by-proceeding) only.
-- ============================================================================
DO $coverage$
DECLARE
unreachable_count int;
unreachable_slugs text;
BEGIN
SELECT count(*),
string_agg(dc.slug, ', ' ORDER BY dc.slug)
INTO unreachable_count, unreachable_slugs
FROM paliad.deadline_concepts dc
WHERE dc.is_active
AND dc.category = 'submission'
AND dc.slug NOT IN (
-- Pure-administrative concepts: filed during prosecution, not
-- typically discovered via "what happened" decision tree.
'filing',
'request-for-examination',
'approval-and-translation'
)
AND NOT EXISTS (
SELECT 1
FROM paliad.event_category_concepts ecc
WHERE ecc.concept_id = dc.id
);
IF unreachable_count > 0 THEN
RAISE EXCEPTION
'Phase A seed: % submission concept(s) unreachable from any leaf: %',
unreachable_count, unreachable_slugs;
END IF;
END $coverage$;

View File

@@ -1,9 +0,0 @@
-- t-paliad-133 Phase A bilateral-tag rollback.
UPDATE paliad.deadline_rules
SET is_bilateral = false
WHERE code IN (
'de_null.stellungnahme',
'epa_opp.r79_further',
'epa_opp.r116',
'epa_app.r116'
);

View File

@@ -1,51 +0,0 @@
-- t-paliad-133 Phase A backfill: tag genuinely-bilateral deadline rules.
--
-- Most rules with primary_party='both' are role-swap appeals — either
-- party can file depending on who lost / acted at the lower instance.
-- Those resolve at render time via the new perspective selector
-- (?my_side= + ?appeal_filed_by=). The renderer assigns them to ONE
-- column based on perspective.
--
-- The exceptions are GENUINELY BILATERAL rules — both parties can or
-- must file independently of who acted before. These mirror into BOTH
-- party columns of the v3 column-timeline view.
--
-- Set is_bilateral=true ONLY for:
-- • Stellungnahme zum Hinweisbeschluss (DE_NULL §83(2)) — both parties
-- comment on the court's preliminary opinion.
-- • R.79 Stellungnahme weiterer Beteiligter (EPA_OPP) — multi-party
-- opposition; all parties may submit.
-- • R.116 Eingaben vor mündl. Verhandlung (EPA_OPP, EPA_APP) — every
-- party prepares submissions before the oral hearing.
--
-- The cross-cutting schriftsatznachreichung lives in event_deadlines
-- (not deadline_rules), so its bilateral nature is handled by the
-- frontend renderer separately — no DB change needed.
--
-- Spot-checkable list of 4 rules; m or HLC colleague reviews on this
-- commit.
UPDATE paliad.deadline_rules
SET is_bilateral = true
WHERE code IN (
'de_null.stellungnahme',
'epa_opp.r79_further',
'epa_opp.r116',
'epa_app.r116'
)
AND is_active = true;
-- Sanity check: exactly 4 rules tagged.
DO $check$
DECLARE
tagged int;
BEGIN
SELECT count(*) INTO tagged
FROM paliad.deadline_rules
WHERE is_bilateral = true;
IF tagged <> 4 THEN
RAISE EXCEPTION
'Phase A bilateral backfill: expected 4 rules tagged, got %',
tagged;
END IF;
END $check$;