feat(t-paliad-131): Phase B5 — EPA gap-fill (R.79.2/3, R.116, R.106) + EPA_OPP/APP anchor fix
PR-6 of the Unified Fristenrechner. Fills the EPA-side coverage gaps
named in the design + repairs three pre-existing EPA bugs surfaced
during this work.
Migration 045:
PRE-EXISTING BUG FIXES
1. EPA anchor convention bug. epa_opp.grant and epa_app.entsch were
seeded with party='court' + event_type='decision' → calculator's
isCourtDeterminedRule(r) returned true → those anchor rows
rendered as IsCourtSet (no date), propagating IsCourtSet to every
downstream rule that chained off them. Result on prod: EPA_OPP
showed "court-set" for Einspruchsfrist / Erwiderung / Entscheidung
instead of computed dates; ONLY the trailing beschwerde + begr
rendered dates (and only by accident, because they had parent_id=
NULL and computed off triggerDate directly).
Fix: changed both anchors to party='both' + event_type='filing' so
they render as IsRootEvent. Matches the convention I established
for DE_INF_OLG / DE_INF_BGH / DE_NULL_BGH / DPMA_BPATG_BESCHWERDE /
DPMA_BGH_RB anchors in PR-3/4/5.
2. EPA_OPP appeal-phase parent bug. epa_opp.beschwerde +
beschwerde_begr had parent_id=NULL → were computing 2mo and 4mo
from the GRANT date instead of from the OPPOSITION DECISION date.
Re-parented both on epa_opp.entsch. They now correctly render as
IsCourtSet placeholders (because entsch is court-set) until the
user enters the real decision date via the Phase A click-to-edit
affordance.
3. EPA_APP.erwidg modelling bug. Was parent_id=NULL + duration=0 +
party=both + event=filing → IsRootEvent → emitted the trigger date
as "Erwiderung". Now properly modelled per Art. 12(1)(c) RPBA 2020:
parent=epa_app.begr, duration=4 months, name="Beschwerdeerwiderung",
legal_source=EU.RPBA.12.1.c, response-to-appeal concept.
NEW COVERAGE (per design §5.3)
EPA_OPP gains 2 rules:
- epa_opp.r79_further: Stellungnahme weiterer Beteiligter
(R.79(2)/(3) EPC) — court-set, parent=erwidg
- epa_opp.r116: Eingaben vor mündl. Verhandlung
(R.116(1) EPC) — court-set, parent=entsch (so it surfaces in the
opposition phase but stays IsCourtSet until oral hearing date is
entered via override)
EPA_APP gains 2 rules:
- epa_app.r116: Eingaben vor mündl. Verhandlung
(R.116(1) EPC + Art. 13 RPBA) — court-set, parent=oral
- epa_app.r106: Antrag auf Überprüfung
(Art. 112a EPÜ) — 2 months from service of decision, parent=
entsch2 (the BoA decision)
Three new EN-slug concepts (UPC/EPC-native): r79-further-stellungnahme,
r116-final-submissions, petition-for-review.
Live-verified on paliad.de:
EPA_OPP trigger 2026-05-04 → grant IsRootEvent / Einspruchsfrist
2027-02-04 (9mo) / Erwiderung 2027-06-04 (4mo from frist) /
r79_further 2027-06-04 (filed-with-erwidg) / Entscheidung +
Beschwerde + Begründung + r116 IsCourtSet (waiting for entsch).
EPA_APP trigger 2026-05-04 → entsch IsRootEvent / Beschwerde
2026-07-06 (2mo, weekend-shift) / Begründung 2026-09-04 (4mo from
entsch) / Beschwerdeerwiderung 2027-01-04 (4mo from Begründung
per RPBA 12.1.c) / r116 IsCourtSet (parent=oral) / r106 IsCourtSet
(parent=entsch2, will compute 2mo from BoA decision once entered).
Out of scope (deferred to PR-7 cross-cutting): Wiedereinsetzung
(Art. 122 EPÜ + R.136 EPC), Weiterbehandlung (Art. 121 EPÜ + R.135 EPC),
Validierungsfrist national (Art. 65 EPÜ).
This commit is contained in:
53
internal/db/migrations/045_epa_gap_fill.down.sql
Normal file
53
internal/db/migrations/045_epa_gap_fill.down.sql
Normal file
@@ -0,0 +1,53 @@
|
||||
-- Reverses 045_epa_gap_fill.
|
||||
|
||||
DELETE FROM paliad.deadline_rules
|
||||
WHERE proceeding_type_id IN (
|
||||
SELECT id FROM paliad.proceeding_types WHERE code IN ('EPA_OPP','EPA_APP')
|
||||
)
|
||||
AND code IN ('epa_opp.r79_further','epa_opp.r116','epa_app.r116','epa_app.r106');
|
||||
|
||||
-- Restore epa_app.erwidg to its pre-fix shape.
|
||||
UPDATE paliad.deadline_rules
|
||||
SET name = 'Erwiderung',
|
||||
name_en = 'Response',
|
||||
parent_id = NULL,
|
||||
duration_value = 0,
|
||||
duration_unit = 'months',
|
||||
primary_party = 'both',
|
||||
event_type = 'filing',
|
||||
rule_code = NULL,
|
||||
legal_source = NULL,
|
||||
deadline_notes = NULL,
|
||||
deadline_notes_en = NULL,
|
||||
concept_id = NULL
|
||||
WHERE proceeding_type_id = (SELECT id FROM paliad.proceeding_types WHERE code = 'EPA_APP')
|
||||
AND code = 'epa_app.erwidg';
|
||||
|
||||
-- Restore epa_opp.beschwerde + beschwerde_begr to parent_id=NULL.
|
||||
UPDATE paliad.deadline_rules
|
||||
SET parent_id = NULL
|
||||
WHERE proceeding_type_id = (SELECT id FROM paliad.proceeding_types WHERE code = 'EPA_OPP')
|
||||
AND code IN ('epa_opp.beschwerde', 'epa_opp.beschwerde_begr');
|
||||
|
||||
-- Restore anchor party/event_type.
|
||||
UPDATE paliad.deadline_rules
|
||||
SET primary_party = 'court',
|
||||
event_type = 'decision',
|
||||
deadline_notes = NULL,
|
||||
deadline_notes_en = NULL
|
||||
WHERE proceeding_type_id = (SELECT id FROM paliad.proceeding_types WHERE code = 'EPA_OPP')
|
||||
AND code = 'epa_opp.grant';
|
||||
|
||||
UPDATE paliad.deadline_rules
|
||||
SET primary_party = 'court',
|
||||
event_type = 'decision',
|
||||
name = 'Zustellung der Entscheidung',
|
||||
name_en = 'Notification of Decision',
|
||||
deadline_notes = NULL,
|
||||
deadline_notes_en = NULL
|
||||
WHERE proceeding_type_id = (SELECT id FROM paliad.proceeding_types WHERE code = 'EPA_APP')
|
||||
AND code = 'epa_app.entsch';
|
||||
|
||||
DELETE FROM paliad.deadline_concepts
|
||||
WHERE slug IN ('r79-further-stellungnahme','r116-final-submissions','petition-for-review')
|
||||
AND id NOT IN (SELECT concept_id FROM paliad.deadline_rules WHERE concept_id IS NOT NULL);
|
||||
192
internal/db/migrations/045_epa_gap_fill.up.sql
Normal file
192
internal/db/migrations/045_epa_gap_fill.up.sql
Normal file
@@ -0,0 +1,192 @@
|
||||
-- t-paliad-131 Phase B5: EPA gap-fill.
|
||||
--
|
||||
-- Three concerns:
|
||||
--
|
||||
-- 1. Existing EPA anchor bug. Both epa_opp.grant and epa_app.entsch
|
||||
-- are anchor rows ("the trigger date is the grant publication" /
|
||||
-- "the trigger is the service of the appealable decision") but were
|
||||
-- seeded with party='court' + event_type='decision'. The
|
||||
-- calculator's isCourtDeterminedRule(r) returns true for that
|
||||
-- combo → those rows render as IsCourtSet (no date), which then
|
||||
-- propagates IsCourtSet to every downstream rule that chains off
|
||||
-- them. As a result, EPA_OPP today shows "court-set" for
|
||||
-- Einspruchsfrist / Erwiderung etc. instead of computed dates.
|
||||
-- Fix: change anchor rows to party='both' + event_type='filing' so
|
||||
-- they render as IsRootEvent — matches the convention used for
|
||||
-- DE_INF_OLG / DE_INF_BGH / DE_NULL_BGH / DPMA_BPATG_BESCHWERDE /
|
||||
-- DPMA_BGH_RB anchors landed in PR-3/4/5.
|
||||
--
|
||||
-- 2. Existing EPA_OPP appeal-phase parent bug. epa_opp.beschwerde +
|
||||
-- beschwerde_begr currently have parent_id=NULL → they compute from
|
||||
-- triggerDate (= grant publication), which is wrong: the appeal
|
||||
-- period runs from service of the OPPOSITION decision, not from
|
||||
-- grant. Re-parent them on epa_opp.entsch.
|
||||
--
|
||||
-- 3. Coverage gap-fill per design §5.3:
|
||||
-- - R.79(2)/(3) EPC: Stellungnahmen weiterer Beteiligter im
|
||||
-- Einspruch — court-set
|
||||
-- - R.116(1) EPC: 1-Monats-Frist vor mündlicher Verhandlung für
|
||||
-- letzte Schriftsätze — court-set (EPA sets the absolute date when
|
||||
-- summoning, this rule guarantees ≥1 month of preparation)
|
||||
-- - Art.112a EPÜ + R.106 EPC: Antrag auf Überprüfung der
|
||||
-- Beschwerdekammerentscheidung beim Großen Beschwerdekammer —
|
||||
-- 2 Monate ab Zustellung der Entscheidung
|
||||
--
|
||||
-- Three new concepts (UPC/EPC-native → EN slugs):
|
||||
-- r79-stellungnahme, r116-eingaben, petition-for-review
|
||||
-- Plus reuse existing decision/oral-hearing/notice-of-appeal etc.
|
||||
|
||||
-- ============================================================================
|
||||
-- 1. Fix anchor convention on existing EPA_OPP / EPA_APP / EP_GRANT
|
||||
-- ============================================================================
|
||||
|
||||
UPDATE paliad.deadline_rules
|
||||
SET primary_party = 'both',
|
||||
event_type = 'filing',
|
||||
deadline_notes = 'Veröffentlichung der Patenterteilung im EPA-Patentblatt — Trigger für die 9-Monats-Einspruchsfrist (Art. 99(1) EPÜ).',
|
||||
deadline_notes_en = 'Publication of the patent grant in the EPO Bulletin — trigger for the 9-month opposition period (Art. 99(1) EPC).'
|
||||
WHERE proceeding_type_id = (SELECT id FROM paliad.proceeding_types WHERE code = 'EPA_OPP')
|
||||
AND code = 'epa_opp.grant';
|
||||
|
||||
UPDATE paliad.deadline_rules
|
||||
SET primary_party = 'both',
|
||||
event_type = 'filing',
|
||||
name = 'Zustellung der Beschwerdeentscheidung',
|
||||
name_en = 'Service of Decision under Appeal',
|
||||
deadline_notes = 'Zustellung der angegriffenen Entscheidung der Einspruchs- oder Prüfungsabteilung — Trigger für die 2-Monats-Beschwerdefrist (Art. 108 EPÜ).',
|
||||
deadline_notes_en = 'Service of the decision under appeal (from the Opposition or Examining Division) — trigger for the 2-month appeal period (Art. 108 EPC).'
|
||||
WHERE proceeding_type_id = (SELECT id FROM paliad.proceeding_types WHERE code = 'EPA_APP')
|
||||
AND code = 'epa_app.entsch';
|
||||
|
||||
-- ============================================================================
|
||||
-- 2. Fix EPA_OPP appeal-phase parent: should chain off entsch, not trigger
|
||||
-- ============================================================================
|
||||
|
||||
UPDATE paliad.deadline_rules
|
||||
SET parent_id = (
|
||||
SELECT dr.id FROM paliad.deadline_rules dr
|
||||
JOIN paliad.proceeding_types pt ON pt.id = dr.proceeding_type_id
|
||||
WHERE pt.code = 'EPA_OPP' AND dr.code = 'epa_opp.entsch'
|
||||
)
|
||||
WHERE proceeding_type_id = (SELECT id FROM paliad.proceeding_types WHERE code = 'EPA_OPP')
|
||||
AND code IN ('epa_opp.beschwerde', 'epa_opp.beschwerde_begr');
|
||||
|
||||
-- ============================================================================
|
||||
-- 3. Fix EPA_APP.erwidg modelling
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Today: parent_id=NULL, duration=0, party=both, event=filing →
|
||||
-- IsRootEvent → emits trigger date as "Erwiderung". Wrong: the
|
||||
-- Beschwerdeerwiderung is a real submission per Art. 12(1)(c) RPBA 2020,
|
||||
-- typical 4 months from service of the Statement of Grounds.
|
||||
|
||||
UPDATE paliad.deadline_rules
|
||||
SET name = 'Beschwerdeerwiderung',
|
||||
name_en = 'Response to Statement of Grounds',
|
||||
parent_id = (
|
||||
SELECT dr.id FROM paliad.deadline_rules dr
|
||||
JOIN paliad.proceeding_types pt ON pt.id = dr.proceeding_type_id
|
||||
WHERE pt.code = 'EPA_APP' AND dr.code = 'epa_app.begr'
|
||||
),
|
||||
duration_value = 4,
|
||||
duration_unit = 'months',
|
||||
primary_party = 'both',
|
||||
event_type = 'filing',
|
||||
rule_code = 'RPBA Art. 12',
|
||||
legal_source = 'EU.RPBA.12.1.c',
|
||||
deadline_notes = 'Erwiderung der anderen Verfahrensbeteiligten auf die Beschwerdebegründung — typischerweise 4 Monate ab Zustellung der Begründung (Art. 12(1)(c) RPBA 2020). Kammer kann andere Frist setzen.',
|
||||
deadline_notes_en = 'Response by other parties to the Statement of Grounds of Appeal — typically 4 months from service of the grounds (Art. 12(1)(c) RPBA 2020). The Board may set a different period.'
|
||||
WHERE proceeding_type_id = (SELECT id FROM paliad.proceeding_types WHERE code = 'EPA_APP')
|
||||
AND code = 'epa_app.erwidg';
|
||||
|
||||
-- ============================================================================
|
||||
-- 4. New concepts (UPC/EPC-native → EN slugs)
|
||||
-- ============================================================================
|
||||
|
||||
INSERT INTO paliad.deadline_concepts (slug, name_de, name_en, description, aliases, party, category, sort_order) VALUES
|
||||
('r79-further-stellungnahme', 'Stellungnahme weiterer Beteiligter', 'Further-Party Submission (R.79)',
|
||||
'Stellungnahmen anderer Verfahrensbeteiligter im EPA-Einspruchsverfahren (R. 79(2) und R. 79(3) EPÜ) — vom EPA gesetzte Frist.',
|
||||
ARRAY['Stellungnahme weiterer Beteiligter', 'further party submission', 'R79 submission'],
|
||||
'both', 'submission', 43),
|
||||
('r116-final-submissions', 'Eingaben vor mündl. Verhandlung', 'Final Written Submissions before Oral Proceedings (R.116)',
|
||||
'Letzte schriftliche Eingaben vor der mündlichen Verhandlung (R. 116(1) EPÜ) — vom EPA mindestens 1 Monat vor der mündl. Verhandlung gesetzt.',
|
||||
ARRAY['R116 submissions', 'R 116', 'final submissions oral hearing', 'Eingaben mündliche Verhandlung'],
|
||||
'both', 'submission', 44),
|
||||
('petition-for-review', 'Antrag auf Überprüfung', 'Petition for Review (Art. 112a EPC)',
|
||||
'Antrag auf Überprüfung der Entscheidung der Beschwerdekammer durch die Große Beschwerdekammer (Art. 112a EPÜ) — 2 Monate ab Zustellung der Entscheidung. Beschränkt auf Verfahrensmängel.',
|
||||
ARRAY['Antrag auf Überprüfung', 'petition for review', 'Art. 112a EPÜ', 'Große Beschwerdekammer'],
|
||||
'both', 'submission', 45)
|
||||
ON CONFLICT (slug) DO UPDATE SET
|
||||
name_de = EXCLUDED.name_de,
|
||||
name_en = EXCLUDED.name_en,
|
||||
description = EXCLUDED.description,
|
||||
aliases = EXCLUDED.aliases,
|
||||
party = EXCLUDED.party,
|
||||
sort_order = EXCLUDED.sort_order,
|
||||
updated_at = now();
|
||||
|
||||
-- Backfill concept_id on the existing fixed epa_app.erwidg
|
||||
UPDATE paliad.deadline_rules
|
||||
SET concept_id = (SELECT id FROM paliad.deadline_concepts WHERE slug = 'response-to-appeal')
|
||||
WHERE proceeding_type_id = (SELECT id FROM paliad.proceeding_types WHERE code = 'EPA_APP')
|
||||
AND code = 'epa_app.erwidg';
|
||||
|
||||
-- ============================================================================
|
||||
-- 5. New rules — EPA_OPP gets R.79(2/3) + R.116
|
||||
-- ============================================================================
|
||||
|
||||
INSERT INTO paliad.deadline_rules (
|
||||
proceeding_type_id, parent_id, code, name, name_en, primary_party, event_type,
|
||||
is_mandatory, duration_value, duration_unit, timing, rule_code, deadline_notes, deadline_notes_en,
|
||||
sequence_order, condition_flag, concept_id, legal_source, is_spawn, is_active
|
||||
)
|
||||
SELECT
|
||||
pt.id, parent_rule.id, new.code, new.name, new.name_en, new.primary_party, new.event_type,
|
||||
false, new.duration_value, new.duration_unit, 'after', new.rule_code, new.deadline_notes, new.deadline_notes_en,
|
||||
new.sequence_order, NULL,
|
||||
(SELECT id FROM paliad.deadline_concepts WHERE slug = new.concept_slug),
|
||||
new.legal_source, false, true
|
||||
FROM (VALUES
|
||||
('epa_opp.erwidg', 'epa_opp.r79_further', 'Stellungnahme weiterer Beteiligter', 'Further-Party Submission',
|
||||
'both', 'filing', 0, 'months', 'R. 79 EPÜ',
|
||||
'Stellungnahmen anderer Verfahrensbeteiligter (R. 79(2), R. 79(3) EPÜ) — vom EPA gesetzte Frist nach der Erwiderung des Patentinhabers.',
|
||||
'Submissions by other parties to opposition proceedings (R. 79(2)/(3) EPC) — EPO-set deadline following the proprietor''s response.',
|
||||
25, 'r79-further-stellungnahme', 'EU.EPC-R.79.2'),
|
||||
('epa_opp.entsch', 'epa_opp.r116', 'Eingaben vor mündl. Verhandlung', 'Final Written Submissions before Oral Proceedings',
|
||||
'both', 'filing', 0, 'months', 'R. 116 EPÜ',
|
||||
'Letzte schriftliche Eingaben mindestens 1 Monat vor der mündlichen Verhandlung (R. 116(1) EPÜ) — die EPA-Einspruchsabteilung setzt das genaue Datum mit der Ladung.',
|
||||
'Final written submissions at least 1 month before the oral proceedings (R. 116(1) EPC) — the EPO Opposition Division sets the exact date when issuing the summons.',
|
||||
28, 'r116-final-submissions', 'EU.EPC-R.116.1')
|
||||
) AS new(parent_code, code, name, name_en, primary_party, event_type, duration_value, duration_unit, rule_code, deadline_notes, deadline_notes_en, sequence_order, concept_slug, legal_source)
|
||||
JOIN paliad.proceeding_types pt ON pt.code = 'EPA_OPP'
|
||||
JOIN paliad.deadline_rules parent_rule ON parent_rule.proceeding_type_id = pt.id AND parent_rule.code = new.parent_code;
|
||||
|
||||
-- ============================================================================
|
||||
-- 6. New rules — EPA_APP gets R.116 + Art.112a Petition for Review
|
||||
-- ============================================================================
|
||||
|
||||
INSERT INTO paliad.deadline_rules (
|
||||
proceeding_type_id, parent_id, code, name, name_en, primary_party, event_type,
|
||||
is_mandatory, duration_value, duration_unit, timing, rule_code, deadline_notes, deadline_notes_en,
|
||||
sequence_order, condition_flag, concept_id, legal_source, is_spawn, is_active
|
||||
)
|
||||
SELECT
|
||||
pt.id, parent_rule.id, new.code, new.name, new.name_en, new.primary_party, new.event_type,
|
||||
false, new.duration_value, new.duration_unit, 'after', new.rule_code, new.deadline_notes, new.deadline_notes_en,
|
||||
new.sequence_order, NULL,
|
||||
(SELECT id FROM paliad.deadline_concepts WHERE slug = new.concept_slug),
|
||||
new.legal_source, false, true
|
||||
FROM (VALUES
|
||||
('epa_app.oral', 'epa_app.r116', 'Eingaben vor mündl. Verhandlung', 'Final Written Submissions before Oral Proceedings',
|
||||
'both', 'filing', 0, 'months', 'R. 116 EPÜ',
|
||||
'Letzte schriftliche Eingaben mindestens 1 Monat vor der mündlichen Verhandlung der Beschwerdekammer (R. 116(1) EPÜ i.V.m. Art. 13 RPBA). Kammer setzt genaues Datum mit Ladung.',
|
||||
'Final written submissions at least 1 month before the oral proceedings of the Board of Appeal (R. 116(1) EPC read with Art. 13 RPBA). The Board sets the exact date in the summons.',
|
||||
35, 'r116-final-submissions', 'EU.EPC-R.116.1'),
|
||||
('epa_app.entsch2', 'epa_app.r106', 'Antrag auf Überprüfung', 'Petition for Review',
|
||||
'both', 'filing', 2, 'months', 'Art. 112a EPÜ',
|
||||
'Antrag auf Überprüfung der Beschwerdekammerentscheidung durch die Große Beschwerdekammer (Art. 112a EPÜ, R. 106-109 EPÜ) — 2 Monate ab Zustellung der Entscheidung. Beschränkt auf Verfahrensmängel.',
|
||||
'Petition for review of the Board of Appeal''s decision by the Enlarged Board of Appeal (Art. 112a EPC, R. 106-109 EPC) — 2 months from service of the decision. Limited to procedural defects.',
|
||||
60, 'petition-for-review', 'EU.EPÜ.112a')
|
||||
) AS new(parent_code, code, name, name_en, primary_party, event_type, duration_value, duration_unit, rule_code, deadline_notes, deadline_notes_en, sequence_order, concept_slug, legal_source)
|
||||
JOIN paliad.proceeding_types pt ON pt.code = 'EPA_APP'
|
||||
JOIN paliad.deadline_rules parent_rule ON parent_rule.proceeding_type_id = pt.id AND parent_rule.code = new.parent_code;
|
||||
Reference in New Issue
Block a user