Compare commits

...

4 Commits

Author SHA1 Message Date
mAi
a2e1d023e4 docs(t-paliad-207): close-out assessment — verdict (A) DONE
Read-only audit of the t-paliad-207 surface per paliadin's 2026-05-20
re-engage instruction. Six commits shipped under this task are now
merged. Two larger follow-ups (m/paliad#39 youpc-laws ingest + #41 DE
combined timeline) are filed with concrete scope. Remaining tail is
optional polish, best handled as discrete issues rather than a parked
inventor.
2026-05-20 10:46:07 +02:00
mAi
faaa98cbce feat(t-paliad-207): notes toggle — compact ⓘ hover by default, expand inline when "Hinweise anzeigen" is checked
m's ask 2026-05-18 18:21: per-rule descriptive notes ("Innerhalb von 1
Monat ab Zustellung der Klage. Drei mögliche Gründe…") are noisy in the
default timeline view. Make them optional — small ⓘ icon next to the
meta line by default with full text on hover; switch in the toggle bar
expands them inline when the user wants the wall of text.

**Renderer (verfahrensablauf-core.ts)** — `CardOpts.showNotes?: boolean`
gates two render paths:
- on  → `<div class="timeline-notes">…</div>` (today's behaviour)
- off → `<span class="timeline-note-hint" tabindex=0 role=note
        aria-label=… title=…>ⓘ</span>` inside the meta line (browser
        title for hover, aria-label for screen readers, tabindex for
        keyboard accessibility)

Pass-through wired in renderColumnsBody too so the columns view picks
up the toggle equally.

**Toggle UI** — added a checkbox row to the existing `fristen-view-toggle`
bar on both /tools/verfahrensablauf and /tools/fristenrechner:
"Hinweise anzeigen" / "Show details". CSS modifier
`.fristen-notes-option` separates it from the radio view-picker with
a leading border-left.

**State** — `paliad.fristen.notes-show` localStorage key (shared
between both pages so the preference carries across), default off,
re-render on flip.

i18n: 1 new key DE + EN (deadlines.notes.show). Build clean.
2026-05-18 18:18:19 +02:00
mAi
1e7f2ee5c3 feat(t-paliad-207): mig 102 — track-aware sequence reshuffle for upc.inf.cfi (infringement → revocation → amendment)
m's ask 2026-05-18 18:08: 'the infringement parts (like Replik) should
show above the part for the revocation (Erwiderung Nichtigkeitswider-
klage)'. Three tracks (infringement / revocation / amendment) coexist
on upc.inf.cfi once with_ccr / with_amend are set. They share tied
calendar dates because R.29/R.30/R.32 all key off the SoD or its
descendants. Current sequence_orders (post-mig 100) interleave them
arbitrarily; user sees Erwiderung-zur-CCR before Replik even though
Replik is the infringement-side response to the same triggering event.

**Re-sequencing** keeps the existing soc=0, prelim=5, sod=10 head and
the interim=40 / oral=50 / decision=60 / cost_app=70 / appeal_spawn=80
tail untouched. The 10 reshuffled rules move into a track-aware
arrangement:

  10-19 infringement: sod=10, reply=12, rejoin=14
  20-29 revocation:   ccr=20, def_to_ccr=22, reply_def_ccr=24, rejoin_reply_ccr=26
  30-39 amendment:    app_to_amend=30, def_to_amend=32, reply_def_amd=34, rejoin_amd=36

Tied-date ordering after the reshuffle:
  D+3mo: sod(10), ccr(20)                            — SoD then its CCR
  D+5mo: reply(12), def_to_ccr(22), app_to_amend(30) — inf → rev → amd
  D+7mo: reply_def_ccr(24), def_to_amend(32)         — rev → amd
  D+8mo: rejoin_reply_ccr(26), reply_def_amd(34)     — rev → amd

**Two-phase swap** — every reshuffled rule first parks at sequence
1000+number, then jumps to its final value. Prevents transient
sequence-collisions if Postgres evaluates UPDATEs in parallel within
the same statement. Each UPDATE is keyed by submission_code AND the
SOURCE sequence_order, so re-apply is a no-op.

audit_reason set_config at top per mig 099 hotfix pattern. Counter
re-checked.
2026-05-18 18:13:40 +02:00
mAi
cbf4fe6d93 fix(t-paliad-207): mig 101 — strip rule cite from Einspruch names + flip CCR priority informational→optional
Two corrections to mig 100's merged-state:

1. **CCR priority informational → optional**. m's correction
   2026-05-18 18:01. The fermi amend (e8d658a) flipping this didn't
   land — paliadin merged the pre-amend c10f8cf. The Nichtigkeits-
   widerklage is a substantive defensive choice, rendered unchecked
   in the save modal so user opts in if they want to track it.

2. **Strip rule-cite brackets from Einspruch names**. m's
   correction 2026-05-18 18:08. Every other rule name in the corpus
   carries the act-name without a parenthetical rule cite — the two
   Einspruch rules were outliers:
     upc.inf.cfi.prelim  'Einspruch (R. 19 VerfO)'             → 'Einspruch'
     upc.rev.cfi.prelim  'Einspruch (R. 19 i.V.m. R. 46 VerfO)' → 'Einspruch'
   plus EN equivalents. The legal_source / rule_code columns already
   carry the citation in the meta line, so the name stays clean.

Idempotent: priority UPDATE guarded on 'informational'; name UPDATEs
guarded on the current parenthetical-bearing values. audit_reason
set_config at top per mig 099 hotfix pattern. Counter re-checked
(mig 100 just merged; next is 101).
2026-05-18 18:12:16 +02:00
13 changed files with 559 additions and 8 deletions

View File

@@ -0,0 +1,52 @@
# t-paliad-207 follow-up scope — close-out assessment
**Author:** fermi (inventor)
**Date:** 2026-05-20
**Verdict:** **(A) DONE** — interactive session scope is shipped; remaining tail is filed-or-fileable as discrete issues, not a fresh fermi slice.
---
## 0. What shipped under t-paliad-207
Six substantive deliveries on `mai/fermi/interactive-session`, all merged to main as of 2026-05-20 morning:
1. **Verfahrensablauf + Fristenrechner polish** — jurisdiction prefix on the picked proceeding, trigger-event label derived from the root rule, flag rows lifted to `/tools/verfahrensablauf`, rule references rendered as `youpc.org/laws#…` links via new `BuildLegalSourceURL`, `Vorab-Einrede → Einspruch` rename (DE i18n).
2. **DE proceeding picker — sub-group headers** (`Verletzungsverfahren` / `Nichtigkeitsverfahren`) + parallel labels (`LG (1. Instanz)` / `OLG (Berufung)` / …).
3. **mig 099** — drop the `with_po` flag from the two RoP 19 rules (Einspruch is always-available, not flag-gated).
4. **mig 100**`upc.inf.cfi.ccr` visible rule (`Nichtigkeitswiderklage`) so the CCR filing event surfaces when `with_ccr` is set; later corrected to `priority='optional'` via mig 101.
5. **mig 101** — strip rule-cite brackets from the two Einspruch names + flip the CCR priority `informational → optional`.
6. **mig 102** — track-aware sequence reshuffle on `upc.inf.cfi` so at any tied date the order is infringement (Replik) → revocation (Erwiderung Nichtigkeitswiderklage) → amendment.
7. **Notes toggle**`Hinweise anzeigen` checkbox in the view-toggle bar; compact ⓘ hover hint when off (default), inline `timeline-notes` block when on. `localStorage` shared across both tool pages.
Filed two follow-up issues during the session:
- **m/paliad#39** — link DE + EPA + EU rule references to `youpc.org/laws` (depends on youpc.org ingesting the corpus).
- **m/paliad#41** — DE proceedings as one combined timeline per type (LG→OLG→BGH, BPatG→BGH) — corpus + spawn + de-duplication + multi-instance UI.
## 1. Why (A) DONE
Every concrete thing m surfaced in the session was addressed and merged. The two larger unaddressed asks — combined-timeline behaviour for DE proceedings, and DE/EPA rule-link coverage — are already captured in #39 and #41 with concrete scope notes. Neither belongs as a fermi "next slice" because:
- **#41** is a corpus + UI design pass of its own (3 new spawn rules, de-duplication of the existing `de.inf.lg.berufung ↔ de.inf.olg.berufung` pair, multi-court picker shape, instance markers in the timeline body). That's its own design ticket, not a fermi follow-up.
- **#39** is primarily a youpc.org-side ingest task; the paliad-side change is a 5-line `switch` extension once youpc serves the URLs. Wait for the dependency, then small.
Everything else I surfaced in the read-only audit is either pre-existing (not introduced by this session) or speculative (no user complaint behind it).
## 2. Optional tail — would file as discrete issues, not a fermi slice
Surfacing these for completeness; none are blocking, and most would be small enough to either roll into the existing tickets or land as one-off polish:
| # | Candidate | Size | Already covered? |
|---|---|---|---|
| 1 | **`legal_source` backfill on 47 unsourced active rules** — query: 4 of `upc.inf.cfi`, 4 of `upc.pi.cfi` (100% gap), 6 of `upc.rev.cfi`, others. Pre-condition for #39's links to bite. | Medium — corpus research per rule | Partially: huygens did the broader citation backfill in t-paliad-208 / mig 097. This is the remaining tail. |
| 2 | **`upc.pi.cfi` corpus completeness audit** — all 4 of its rules lack `legal_source`; likely also missing the analogous track-of-decision spawn rules to `upc.apl.merits`. | Small audit, medium fix | No — would be a fresh task. |
| 3 | **Touch-device fallback for the ⓘ hover hint**`title=` attribute degrades poorly on phones (no hover, no tap-to-show). Either a click-to-popover variant, or accept the gap. | Tiny | No, but no user complaint yet. |
| 4 | **R.46 mutatis-mutandis distinction in `upc.rev.cfi.prelim` description** — when mig 101 stripped the `(R. 19 i.V.m. R. 46)` cite, the legal nuance dropped from the user-visible name. Could be surfaced in the description text where it doesn't crowd the timeline cell. | Tiny (one row update) | No. |
| 5 | **Save-modal warning on SoD + CCR double-check** — with mig 100's new `upc.inf.cfi.ccr` rule, a user can save both `sod` and `ccr` from the same modal and get two `paliad.deadlines` rows on the same date. Today's pre-uncheck behaviour for optional priority mitigates accidental double-write but doesn't surface the duplication actively. | Small | No. |
| 6 | **Deferred slices from earlier design docs that touch this surface**: t-paliad-179 Slice 2-4 (variant chips, lane view, side-by-side compare on `/tools/verfahrensablauf`); t-paliad-169 "+ Eintrag" CTA on the SmartTimeline (project-bound) path. | Each a separate slice. | Yes — parked from their original tasks; would be revisited when m prioritises. |
None of these warrant a "next fermi slice" right now. They're polish + corpus tail, and best handled as individual issues that m can pick from.
## 3. Recommendation
Close t-paliad-207. Fire fermi. The remaining tail (items 16 above) is appropriate as a small "polish backlog" m can dip into when relevant, but not a coherent unit of work that needs a parked inventor.

View File

@@ -57,6 +57,19 @@ type ProcedureView = "timeline" | "columns";
// HLC team than the single vertical line.
let procedureView: ProcedureView = "columns";
// Notes toggle — off by default; per-rule notes render as a compact
// ⓘ hover icon. Flipped on, they expand under each card. Choice is
// localStorage-persisted (paliad.fristen.notes-show key shared with
// /tools/verfahrensablauf so the preference carries across both).
const NOTES_PREF_KEY = "paliad.fristen.notes-show";
function readNotesPref(): boolean {
try { return localStorage.getItem(NOTES_PREF_KEY) === "1"; } catch { return false; }
}
function writeNotesPref(on: boolean): void {
try { localStorage.setItem(NOTES_PREF_KEY, on ? "1" : "0"); } catch { /* no-op */ }
}
let showNotes = readNotesPref();
onLangChange(() => {
if (lastResponse) renderProcedureResults(lastResponse);
// Update trigger event name if a proceeding is selected
@@ -391,8 +404,8 @@ function renderProcedureResults(data: DeadlineResponse) {
</div>`;
const bodyHtml = procedureView === "columns"
? renderColumnsBody(data, { editable: true })
: renderTimelineBody(data, { showParty: true, editable: true });
? renderColumnsBody(data, { editable: true, showNotes })
: renderTimelineBody(data, { showParty: true, editable: true, showNotes });
container.innerHTML = headerHtml + bodyHtml;
printBtn.style.display = "block";
@@ -661,6 +674,18 @@ document.addEventListener("DOMContentLoaded", () => {
const saveBtn = document.getElementById("fristen-save-cta");
if (saveBtn) saveBtn.addEventListener("click", openSaveModal);
// Notes toggle — restores last preference on load + re-renders when
// the user flips it. Lives in the same toggle bar as the view picker.
const notesShowCb = document.getElementById("fristen-notes-show") as HTMLInputElement | null;
if (notesShowCb) {
notesShowCb.checked = showNotes;
notesShowCb.addEventListener("change", () => {
showNotes = notesShowCb.checked;
writeNotesPref(showNotes);
if (lastResponse) renderProcedureResults(lastResponse);
});
}
// View toggle (timeline vs. columns layout) for procedure mode.
initViewToggle();

View File

@@ -300,6 +300,7 @@ const translations: Record<Lang, Record<string, string>> = {
"deadlines.view.label": "Ansicht:",
"deadlines.view.timeline": "Zeitstrahl",
"deadlines.view.columns": "Spalten",
"deadlines.notes.show": "Hinweise anzeigen",
"deadlines.col.proactive": "Proaktiv",
"deadlines.col.court": "Gericht",
"deadlines.col.reactive": "Reaktiv",
@@ -2887,6 +2888,7 @@ const translations: Record<Lang, Record<string, string>> = {
"deadlines.view.label": "View:",
"deadlines.view.timeline": "Timeline",
"deadlines.view.columns": "Columns",
"deadlines.notes.show": "Show details",
"deadlines.col.proactive": "Proactive",
"deadlines.col.court": "Court",
"deadlines.col.reactive": "Reactive",

View File

@@ -25,6 +25,19 @@ let lastResponse: DeadlineResponse | null = null;
type ProcedureView = "timeline" | "columns";
let procedureView: ProcedureView = "columns";
// Notes toggle — when off (default), per-rule descriptive notes render
// as a compact ⓘ icon next to the meta line (hover for full text). When
// on, the full notes block expands under each card. Choice persists in
// localStorage so a reload or recalc keeps the user's preference.
const NOTES_PREF_KEY = "paliad.fristen.notes-show";
function readNotesPref(): boolean {
try { return localStorage.getItem(NOTES_PREF_KEY) === "1"; } catch { return false; }
}
function writeNotesPref(on: boolean): void {
try { localStorage.setItem(NOTES_PREF_KEY, on ? "1" : "0"); } catch { /* no-op */ }
}
let showNotes = readNotesPref();
// Jurisdiction display prefix for the proceeding-summary chip + the
// trigger-event placeholder. Same forum slugs the .proceeding-group
// `data-forum` attribute carries in verfahrensablauf.tsx /
@@ -167,8 +180,8 @@ function renderResults(data: DeadlineResponse) {
</div>`;
const bodyHtml = procedureView === "columns"
? renderColumnsBody(data)
: renderTimelineBody(data);
? renderColumnsBody(data, { showNotes })
: renderTimelineBody(data, { showParty: true, showNotes });
container.innerHTML = headerHtml + bodyHtml;
if (printBtn) printBtn.style.display = "block";
@@ -299,6 +312,18 @@ document.addEventListener("DOMContentLoaded", () => {
document.getElementById("fristen-print-btn")?.addEventListener("click", () => window.print());
// Notes toggle — restores last preference on load + re-renders when
// the user flips it. Lives in the same toggle bar as the view picker.
const notesShowCb = document.getElementById("fristen-notes-show") as HTMLInputElement | null;
if (notesShowCb) {
notesShowCb.checked = showNotes;
notesShowCb.addEventListener("change", () => {
showNotes = notesShowCb.checked;
writeNotesPref(showNotes);
if (lastResponse) renderResults(lastResponse);
});
}
initViewToggle();
onLangChange(() => {

View File

@@ -219,6 +219,13 @@ export interface CardOpts {
// verfahrensablauf abstract-browse surface keeps editable=false because
// there's no anchor-override state on that page in Slice 1.
editable?: boolean;
// showNotes controls how the per-rule descriptive notes render:
// true → expanded `<div class="timeline-notes">…</div>` below the card
// false → compact ⓘ icon next to the meta line, full text on hover
// (browser-native `title` attribute) and screen-reader-readable
// Page shells expose a toggle ("Hinweise anzeigen") that flips this and
// re-renders. Default false — notes are noisy on long timelines.
showNotes?: boolean;
}
export function deadlineCardHtml(dl: CalculatedDeadline, opts: CardOpts): string {
@@ -264,14 +271,19 @@ export function deadlineCardHtml(dl: CalculatedDeadline, opts: CardOpts): string
}
const noteText = getLang() === "en" ? (dl.notesEN || dl.notes) : dl.notes;
const notes = noteText
const showNotes = opts.showNotes === true;
const notesBlock = noteText && showNotes
? `<div class="timeline-notes">${noteText}</div>`
: "";
const noteHint = noteText && !showNotes
? `<span class="timeline-note-hint" tabindex="0" role="note" aria-label="${escAttr(noteText)}" title="${escAttr(noteText)}">ⓘ</span>`
: "";
const meta = (opts.showParty || ruleRef)
const meta = (opts.showParty || ruleRef || noteHint)
? `<div class="timeline-meta">
${opts.showParty ? partyBadge(dl.party) : ""}
${ruleRef}
${noteHint}
</div>`
: "";
@@ -284,7 +296,7 @@ export function deadlineCardHtml(dl: CalculatedDeadline, opts: CardOpts): string
</div>
${meta}
${adjustedNote}
${notes}`;
${notesBlock}`;
}
export function renderTimelineBody(data: DeadlineResponse, opts: CardOpts = { showParty: true }): string {
@@ -358,7 +370,7 @@ export function renderColumnsBody(data: DeadlineResponse, opts: Omit<CardOpts, "
unscheduledKeys.sort();
const keys = [...datedKeys, ...unscheduledKeys];
const cardOpts: CardOpts = { showParty: false, editable: opts.editable };
const cardOpts: CardOpts = { showParty: false, editable: opts.editable, showNotes: opts.showNotes };
const renderCell = (items: CalculatedDeadline[]): string => {
if (items.length === 0) {

View File

@@ -546,6 +546,10 @@ export function renderFristenrechner(): string {
<input type="radio" name="fristen-view" value="timeline" />
<span data-i18n="deadlines.view.timeline">Zeitstrahl</span>
</label>
<label className="fristen-notes-option">
<input type="checkbox" id="fristen-notes-show" />
<span data-i18n="deadlines.notes.show">Hinweise anzeigen</span>
</label>
</div>
<div id="timeline-container">

View File

@@ -1069,6 +1069,7 @@ export type I18nKey =
| "deadlines.neu.submit"
| "deadlines.neu.subtitle"
| "deadlines.neu.title"
| "deadlines.notes.show"
| "deadlines.optional.badge"
| "deadlines.party.both"
| "deadlines.party.both.label"

View File

@@ -3441,6 +3441,49 @@ input[type="range"]::-moz-range-thumb {
cursor: pointer;
}
/* Notes toggle — checkbox affordance in the view-toggle bar that flips
per-card descriptive notes between compact (ⓘ tooltip icon) and
expanded (timeline-notes block). Sits with a leading separator so it
reads as a distinct control from the radio view picker. */
.fristen-notes-option {
display: inline-flex;
align-items: center;
gap: 0.35rem;
cursor: pointer;
color: var(--color-text);
margin-left: auto;
padding-left: 0.75rem;
border-left: 1px solid var(--color-border);
}
.fristen-notes-option input[type=checkbox] {
margin: 0;
cursor: pointer;
}
/* Compact note hint — sits in the timeline-meta line when the notes
toggle is off. Native browser tooltip via title= attribute carries
the full text on hover; tabindex=0 + aria-label make it
keyboard / screen-reader accessible. */
.timeline-note-hint {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 1.1rem;
height: 1.1rem;
border-radius: 50%;
font-size: 0.85rem;
color: var(--color-text-muted);
cursor: help;
user-select: none;
}
.timeline-note-hint:hover,
.timeline-note-hint:focus-visible {
color: var(--color-text);
outline: none;
}
/* Fristenrechner — three-column lane view (Proactive | Court | Reactive).
Each lane is independently date-ordered; party=both rows render below
as full-width spans because they apply to all sides. */

View File

@@ -225,6 +225,10 @@ export function renderVerfahrensablauf(): string {
<input type="radio" name="fristen-view" value="timeline" />
<span data-i18n="deadlines.view.timeline">Zeitstrahl</span>
</label>
<label className="fristen-notes-option">
<input type="checkbox" id="fristen-notes-show" />
<span data-i18n="deadlines.notes.show">Hinweise anzeigen</span>
</label>
</div>
<div id="timeline-container">

View File

@@ -0,0 +1,52 @@
-- Revert mig 101 — restore the bracket-bearing Einspruch names and
-- flip the CCR priority back to 'informational'.
SELECT set_config(
'paliad.audit_reason',
'mig 101 down: restore "Einspruch (R. 19 VerfO)" and "Einspruch (R. 19 i.V.m. R. 46 VerfO)" names + flip upc.inf.cfi.ccr priority back to informational',
true);
UPDATE paliad.deadline_rules dr
SET name_en = 'Preliminary Objection (RoP 19 in conjunction with RoP 46)'
FROM paliad.proceeding_types pt
WHERE dr.proceeding_type_id = pt.id
AND pt.code = 'upc.rev.cfi'
AND dr.submission_code = 'upc.rev.cfi.prelim'
AND dr.lifecycle_state = 'published'
AND dr.name_en = 'Preliminary Objection';
UPDATE paliad.deadline_rules dr
SET name = 'Einspruch (R. 19 i.V.m. R. 46 VerfO)'
FROM paliad.proceeding_types pt
WHERE dr.proceeding_type_id = pt.id
AND pt.code = 'upc.rev.cfi'
AND dr.submission_code = 'upc.rev.cfi.prelim'
AND dr.lifecycle_state = 'published'
AND dr.name = 'Einspruch';
UPDATE paliad.deadline_rules dr
SET name_en = 'Preliminary Objection (RoP 19)'
FROM paliad.proceeding_types pt
WHERE dr.proceeding_type_id = pt.id
AND pt.code = 'upc.inf.cfi'
AND dr.submission_code = 'upc.inf.cfi.prelim'
AND dr.lifecycle_state = 'published'
AND dr.name_en = 'Preliminary Objection';
UPDATE paliad.deadline_rules dr
SET name = 'Einspruch (R. 19 VerfO)'
FROM paliad.proceeding_types pt
WHERE dr.proceeding_type_id = pt.id
AND pt.code = 'upc.inf.cfi'
AND dr.submission_code = 'upc.inf.cfi.prelim'
AND dr.lifecycle_state = 'published'
AND dr.name = 'Einspruch';
UPDATE paliad.deadline_rules dr
SET priority = 'informational'
FROM paliad.proceeding_types pt
WHERE dr.proceeding_type_id = pt.id
AND pt.code = 'upc.inf.cfi'
AND dr.submission_code = 'upc.inf.cfi.ccr'
AND dr.lifecycle_state = 'published'
AND dr.priority = 'optional';

View File

@@ -0,0 +1,89 @@
-- t-paliad-207 (m's interactive session) — two label/priority polish
-- fixes on upc.inf.cfi / upc.rev.cfi:
--
-- 1. **CCR priority informational → optional.** m's correction
-- 2026-05-18 18:01: the Nichtigkeitswiderklage is a substantive
-- defensive choice the defendant makes — not just an informational
-- notice. priority='optional' renders it as an unchecked save row
-- the user can opt into. The fermi amend (commit e8d658a) flipping
-- this didn't land in main — paliadin's merge of mig 100 (commit
-- c10f8cf, merge 4ddcd28) picked up the pre-amend 'informational'
-- version. This is the recovery.
--
-- 2. **Strip rule citation from Einspruch names.** m's correction
-- 2026-05-18 18:08: every other rule name in the corpus carries
-- the act-name without a parenthetical rule cite (Klageerwiderung,
-- Antrag auf Patentänderung, Replik, etc.). The Einspruch rule
-- names are the outliers:
-- upc.inf.cfi.prelim "Einspruch (R. 19 VerfO)" → "Einspruch"
-- upc.rev.cfi.prelim "Einspruch (R. 19 i.V.m. R. 46 VerfO)" → "Einspruch"
-- and EN equivalents:
-- "Preliminary Objection (RoP 19)" → "Preliminary Objection"
-- "Preliminary Objection (RoP 19 in conjunction with RoP 46)"
-- → "Preliminary Objection"
-- The legal_source / rule_code columns already carry the citation
-- and render in the deadline card's meta line, so the name stays
-- clean. The R.46-i.V.m. distinction is preserved in the legal
-- source field (RoP.019.1 for both — m may want to further
-- differentiate; flagged in description text instead).
--
-- audit_reason set_config required at the top — the deadline_rules
-- audit trigger raises EXCEPTION 'audit reason required' on any
-- mutation without it (cf. mig 099 hotfix history).
--
-- Idempotency:
-- * Priority UPDATE guarded on the current 'informational' value.
-- * Name UPDATEs guarded on the current parenthetical-bearing names.
SELECT set_config(
'paliad.audit_reason',
'mig 101: flip upc.inf.cfi.ccr priority informational→optional + strip rule-cite brackets from R.19 Einspruch names on both upc.inf.cfi.prelim and upc.rev.cfi.prelim (m''s corrections 2026-05-18, t-paliad-207 interactive session)',
true);
-- 1) Flip CCR priority
UPDATE paliad.deadline_rules dr
SET priority = 'optional'
FROM paliad.proceeding_types pt
WHERE dr.proceeding_type_id = pt.id
AND pt.code = 'upc.inf.cfi'
AND dr.submission_code = 'upc.inf.cfi.ccr'
AND dr.lifecycle_state = 'published'
AND dr.priority = 'informational';
-- 2a) Strip "(R. 19 VerfO)" from upc.inf.cfi.prelim DE/EN names
UPDATE paliad.deadline_rules dr
SET name = 'Einspruch'
FROM paliad.proceeding_types pt
WHERE dr.proceeding_type_id = pt.id
AND pt.code = 'upc.inf.cfi'
AND dr.submission_code = 'upc.inf.cfi.prelim'
AND dr.lifecycle_state = 'published'
AND dr.name = 'Einspruch (R. 19 VerfO)';
UPDATE paliad.deadline_rules dr
SET name_en = 'Preliminary Objection'
FROM paliad.proceeding_types pt
WHERE dr.proceeding_type_id = pt.id
AND pt.code = 'upc.inf.cfi'
AND dr.submission_code = 'upc.inf.cfi.prelim'
AND dr.lifecycle_state = 'published'
AND dr.name_en = 'Preliminary Objection (RoP 19)';
-- 2b) Strip "(R. 19 i.V.m. R. 46 VerfO)" from upc.rev.cfi.prelim DE/EN names
UPDATE paliad.deadline_rules dr
SET name = 'Einspruch'
FROM paliad.proceeding_types pt
WHERE dr.proceeding_type_id = pt.id
AND pt.code = 'upc.rev.cfi'
AND dr.submission_code = 'upc.rev.cfi.prelim'
AND dr.lifecycle_state = 'published'
AND dr.name = 'Einspruch (R. 19 i.V.m. R. 46 VerfO)';
UPDATE paliad.deadline_rules dr
SET name_en = 'Preliminary Objection'
FROM paliad.proceeding_types pt
WHERE dr.proceeding_type_id = pt.id
AND pt.code = 'upc.rev.cfi'
AND dr.submission_code = 'upc.rev.cfi.prelim'
AND dr.lifecycle_state = 'published'
AND dr.name_en = 'Preliminary Objection (RoP 19 in conjunction with RoP 46)';

View File

@@ -0,0 +1,31 @@
-- Revert mig 102 — restore the pre-mig-102 sequence_order values
-- (post-mig-100 state). Same two-phase swap pattern.
SELECT set_config(
'paliad.audit_reason',
'mig 102 down: restore pre-track-aware sequence_order on upc.inf.cfi rules',
true);
-- Phase 1: park
UPDATE paliad.deadline_rules SET sequence_order = 1011 WHERE submission_code = 'upc.inf.cfi.ccr' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 20;
UPDATE paliad.deadline_rules SET sequence_order = 1012 WHERE submission_code = 'upc.inf.cfi.def_to_ccr' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 22;
UPDATE paliad.deadline_rules SET sequence_order = 1013 WHERE submission_code = 'upc.inf.cfi.app_to_amend' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 30;
UPDATE paliad.deadline_rules SET sequence_order = 1020 WHERE submission_code = 'upc.inf.cfi.reply' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 12;
UPDATE paliad.deadline_rules SET sequence_order = 1021 WHERE submission_code = 'upc.inf.cfi.def_to_amend' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 32;
UPDATE paliad.deadline_rules SET sequence_order = 1022 WHERE submission_code = 'upc.inf.cfi.reply_def_ccr' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 24;
UPDATE paliad.deadline_rules SET sequence_order = 1030 WHERE submission_code = 'upc.inf.cfi.rejoin' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 14;
UPDATE paliad.deadline_rules SET sequence_order = 1031 WHERE submission_code = 'upc.inf.cfi.reply_def_amd' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 34;
UPDATE paliad.deadline_rules SET sequence_order = 1032 WHERE submission_code = 'upc.inf.cfi.rejoin_reply_ccr' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 26;
UPDATE paliad.deadline_rules SET sequence_order = 1033 WHERE submission_code = 'upc.inf.cfi.rejoin_amd' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 36;
-- Phase 2: assign originals
UPDATE paliad.deadline_rules SET sequence_order = 11 WHERE submission_code = 'upc.inf.cfi.ccr' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 1011;
UPDATE paliad.deadline_rules SET sequence_order = 12 WHERE submission_code = 'upc.inf.cfi.def_to_ccr' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 1012;
UPDATE paliad.deadline_rules SET sequence_order = 13 WHERE submission_code = 'upc.inf.cfi.app_to_amend' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 1013;
UPDATE paliad.deadline_rules SET sequence_order = 20 WHERE submission_code = 'upc.inf.cfi.reply' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 1020;
UPDATE paliad.deadline_rules SET sequence_order = 21 WHERE submission_code = 'upc.inf.cfi.def_to_amend' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 1021;
UPDATE paliad.deadline_rules SET sequence_order = 22 WHERE submission_code = 'upc.inf.cfi.reply_def_ccr' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 1022;
UPDATE paliad.deadline_rules SET sequence_order = 30 WHERE submission_code = 'upc.inf.cfi.rejoin' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 1030;
UPDATE paliad.deadline_rules SET sequence_order = 31 WHERE submission_code = 'upc.inf.cfi.reply_def_amd' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 1031;
UPDATE paliad.deadline_rules SET sequence_order = 32 WHERE submission_code = 'upc.inf.cfi.rejoin_reply_ccr' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 1032;
UPDATE paliad.deadline_rules SET sequence_order = 33 WHERE submission_code = 'upc.inf.cfi.rejoin_amd' AND proceeding_type_id = 8 AND lifecycle_state = 'published' AND sequence_order = 1033;

View File

@@ -0,0 +1,211 @@
-- t-paliad-207 — re-sequence upc.inf.cfi rules so within any tied-date
-- group the infringement-track responses sit ABOVE the revocation-
-- track responses ABOVE the amendment-track responses. m's ask
-- 2026-05-18 18:08: "the infringement parts (like Replik) should show
-- above the part for the revocation (Erwiderung Nichtigkeitswider-
-- klage)".
--
-- Three tracks coexist on upc.inf.cfi once the with_ccr / with_amend
-- flags are set. They share calendar dates because R.29 / R.30 / R.32
-- all key off the SoD or its descendants. The current sequence_orders
-- (post-mig 100) interleave them; the user sees Erwiderung-zur-CCR
-- before Replik even though Replik is the infringement-side response
-- to the same triggering event.
--
-- New sequence_order assignment (preserves the soc=0, prelim=5,
-- sod=10, ccr=11 anchors at the head; phase markers interim/oral/
-- decision/cost_app/appeal_spawn keep their existing 40/50/60/70/80
-- slots at the tail):
--
-- Old → New submission_code track date
-- --- --- --------------- ----- ----
-- 0 0 upc.inf.cfi.soc — D+0
-- 5 5 upc.inf.cfi.prelim — D+1mo
-- 10 10 upc.inf.cfi.sod infringement D+3mo
-- 11 20 upc.inf.cfi.ccr revocation D+3mo
-- 20 12 upc.inf.cfi.reply infringement D+5mo ← MOVED UP
-- 12 22 upc.inf.cfi.def_to_ccr revocation D+5mo
-- 13 30 upc.inf.cfi.app_to_amend amendment D+5mo
-- 30 14 upc.inf.cfi.rejoin infringement D+6mo ← MOVED UP
-- 22 24 upc.inf.cfi.reply_def_ccr revocation D+7mo
-- 21 32 upc.inf.cfi.def_to_amend amendment D+7mo
-- 32 26 upc.inf.cfi.rejoin_reply_ccr revocation D+8mo
-- 31 34 upc.inf.cfi.reply_def_amd amendment D+8mo
-- 33 36 upc.inf.cfi.rejoin_amd amendment D+9mo
-- 40 40 upc.inf.cfi.interim phase later
-- 50 50 upc.inf.cfi.oral phase later
-- 60 60 upc.inf.cfi.decision phase later
-- 70 70 upc.inf.cfi.cost_app phase later
-- 80 80 upc.inf.cfi.appeal_spawn phase later
--
-- Order within each tied-date group after the reshuffle:
-- D+3mo: sod(10), ccr(20) — SoD then its CCR
-- D+5mo: reply(12), def_to_ccr(22), app_to_amend(30) — inf → rev → amd
-- D+7mo: reply_def_ccr(24), def_to_amend(32) — rev → amd
-- D+8mo: rejoin_reply_ccr(26), reply_def_amd(34) — rev → amd
--
-- (no infringement-track rule at +7mo or +8mo so revocation leads
-- those dates; rejoin sits alone at +6mo so it has no peers to order
-- against.)
--
-- audit_reason set_config required at the top — the deadline_rules
-- audit trigger raises EXCEPTION 'audit reason required' on any
-- mutation without it (cf. mig 099 hotfix history).
--
-- Idempotency: every UPDATE is guarded by both the submission_code
-- AND the SOURCE sequence_order, so re-apply is a no-op once the new
-- numbers are in place.
SELECT set_config(
'paliad.audit_reason',
'mig 102: re-sequence upc.inf.cfi rules track-aware (infringement → revocation → amendment within tied-date groups; m''s 2026-05-18 ask, t-paliad-207 interactive session)',
true);
-- Two-phase swap to avoid sequence collisions during the UPDATE
-- (otherwise two rules can briefly share a sequence_order if Postgres
-- evaluates them in parallel). Phase 1: move every reshuffled rule to
-- a high temporary number (1000+). Phase 2: assign final numbers.
-- ─── Phase 1: park reshuffled rules at 1000+ ────────────────────────
UPDATE paliad.deadline_rules
SET sequence_order = 1011
WHERE submission_code = 'upc.inf.cfi.ccr'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 11;
UPDATE paliad.deadline_rules
SET sequence_order = 1012
WHERE submission_code = 'upc.inf.cfi.def_to_ccr'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 12;
UPDATE paliad.deadline_rules
SET sequence_order = 1013
WHERE submission_code = 'upc.inf.cfi.app_to_amend'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 13;
UPDATE paliad.deadline_rules
SET sequence_order = 1020
WHERE submission_code = 'upc.inf.cfi.reply'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 20;
UPDATE paliad.deadline_rules
SET sequence_order = 1021
WHERE submission_code = 'upc.inf.cfi.def_to_amend'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 21;
UPDATE paliad.deadline_rules
SET sequence_order = 1022
WHERE submission_code = 'upc.inf.cfi.reply_def_ccr'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 22;
UPDATE paliad.deadline_rules
SET sequence_order = 1030
WHERE submission_code = 'upc.inf.cfi.rejoin'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 30;
UPDATE paliad.deadline_rules
SET sequence_order = 1031
WHERE submission_code = 'upc.inf.cfi.reply_def_amd'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 31;
UPDATE paliad.deadline_rules
SET sequence_order = 1032
WHERE submission_code = 'upc.inf.cfi.rejoin_reply_ccr'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 32;
UPDATE paliad.deadline_rules
SET sequence_order = 1033
WHERE submission_code = 'upc.inf.cfi.rejoin_amd'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 33;
-- ─── Phase 2: assign final track-aware numbers ──────────────────────
UPDATE paliad.deadline_rules
SET sequence_order = 12
WHERE submission_code = 'upc.inf.cfi.reply'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 1020;
UPDATE paliad.deadline_rules
SET sequence_order = 14
WHERE submission_code = 'upc.inf.cfi.rejoin'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 1030;
UPDATE paliad.deadline_rules
SET sequence_order = 20
WHERE submission_code = 'upc.inf.cfi.ccr'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 1011;
UPDATE paliad.deadline_rules
SET sequence_order = 22
WHERE submission_code = 'upc.inf.cfi.def_to_ccr'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 1012;
UPDATE paliad.deadline_rules
SET sequence_order = 24
WHERE submission_code = 'upc.inf.cfi.reply_def_ccr'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 1022;
UPDATE paliad.deadline_rules
SET sequence_order = 26
WHERE submission_code = 'upc.inf.cfi.rejoin_reply_ccr'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 1032;
UPDATE paliad.deadline_rules
SET sequence_order = 30
WHERE submission_code = 'upc.inf.cfi.app_to_amend'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 1013;
UPDATE paliad.deadline_rules
SET sequence_order = 32
WHERE submission_code = 'upc.inf.cfi.def_to_amend'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 1021;
UPDATE paliad.deadline_rules
SET sequence_order = 34
WHERE submission_code = 'upc.inf.cfi.reply_def_amd'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 1031;
UPDATE paliad.deadline_rules
SET sequence_order = 36
WHERE submission_code = 'upc.inf.cfi.rejoin_amd'
AND proceeding_type_id = 8
AND lifecycle_state = 'published'
AND sequence_order = 1033;