Verfahrensablauf side semantics: WE always on left (Client Side / Court / Opponent Side) — drop Proaktiv/Reaktiv framing #88

Open
opened 2026-05-25 12:24:07 +00:00 by mAi · 1 comment
Collaborator

m's report (2026-05-25 14:22)

Switching sides in the "Verfahrensablauf" doesn't do it right — "Klägerseite" can never be "Reaktiv". What are we trying to show there?

In a normal proceeding, it should just switch left and right so "WE" are always on the left. And any other triggers like appeal need to get a side selection — because there things depend on the position. But for us, We should have Client left, not "Proactive". And then just say "Client Side" / COURT / "Opponent Side" and switch whatever that means. If we are patentee or alleged user.

Context — what shipped

t-paliad-250 / m/paliad#81 (commit 02255c4 on main) added side+appellant selectors to Verfahrensablauf and kept the existing Proaktiv / Court / Reaktiv column labels. m's report says the Proaktiv/Reaktiv axis is the wrong frame entirely — Klägerseite is sometimes proactive (filing) and sometimes reactive (responding), so the static label-pair lies.

What m wants instead — user-perspective axis

  1. Three columns rename: Client Side / COURT / Opponent Side (DE primary: Unsere Seite / Gericht / Gegnerseite).
  2. "WE" always on the left. The side toggle picks who we are in this proceeding (Klägerseite vs Beklagtenseite, i.e. patentee vs alleged infringer / Einsprechender vs Patentinhaber, etc.). When the user flips the side toggle, the columns swap so the user's side stays in the Unsere Seite (left) column.
  3. Appeal-type proceedings keep a separate appellant selector — because the appellant axis is independent of who-we-are. Example: in an Appeal CoA, both parties can theoretically appeal; the appellant selector picks which party initiates, and the side toggle still picks which of those is "us".
  4. Default when a project has a proceeding chosen: derive side from the project's our_side field (already on paliad.projects, per t-paliad-217 ish). Read-only display with override toggle.

What to do

Part 1 — Column relabel + semantics flip

  • frontend/src/client/views/verfahrensablauf-core.ts (and the renderColumnsBody hermes touched in t-paliad-250) — rename column headers from Proaktiv / Reaktiv to Unsere Seite / Gegnerseite (EN: Client Side / Opponent Side).
  • The mapping logic that currently places each rule in Proaktiv vs Reaktiv was based on whether the rule's party_role equals the project's claimant/defendant role. Re-frame it: each rule has a party_role; if it matches our_side → Unsere Seite column; if it matches the opposing role → Gegnerseite column; if it's "both parties" AND no appellant chosen → could render in either or both — coder picks the cleanest UI (probably full-width across both columns OR a single "both" pill row spanning).
  • When the side toggle flips, the two columns visually swap — but functionally, the rule placement re-resolves against the new our_side value.

Part 2 — Appellant selector stays

Keep the appellant selector hermes added for appeal-type proceedings. Its role: when an Appeal is selected and the project doesn't pin which party appealed, the user picks. Without this pick, "both parties" appeal-rules still need to render somewhere — fall back to showing in BOTH columns until pinned.

Part 3 — Project default

paliad.projects.our_side (if it exists) drives the initial side selection. If the project has a proceeding chosen + our_side set, the selectors are auto-filled and shown read-only with a small "override" affordance.

If the our_side column does NOT exist yet (verify), this issue's scope expands to add it as a migration. Flag in completion report. Likely DB shape: paliad.projects.our_side text CHECK (our_side IN ('claimant','defendant','patentee','opponent', etc.)).

Part 4 — i18n

Rename existing keys (or add new keys + deprecate old):

  • proaktivour_side ("Unsere Seite" / "Client Side")
  • reaktivopponent_side ("Gegnerseite" / "Opponent Side")
  • Court column label unchanged

Files most likely touched

  • frontend/src/client/views/verfahrensablauf-core.ts (column placement logic + headers)
  • frontend/src/client/views/verfahrensablauf-core.test.ts (update test expectations)
  • frontend/src/client/verfahrensablauf.ts (selector wiring)
  • frontend/src/verfahrensablauf.tsx
  • frontend/src/client/i18n.ts + frontend/src/i18n-keys.ts
  • Possibly internal/models/models.go + a migration for paliad.projects.our_side if it doesn't exist
  • Possibly internal/services/projection_service.go if the column placement is computed server-side

Hard rules

  • No regression on t-paliad-250's URL-state plumbing — the side / appellant URL params keep working; this is a semantics + label change, not a remove.
  • Tests updated — verfahrensablauf-core.test.ts has the old Proaktiv/Reaktiv expectations; update them.
  • DE primary, EN secondary for the new labels.
  • go build ./... && go test ./internal/... && cd frontend && bun run build clean.
  • Branch: mai/<worker>/side-semantics-our-perspective.

Out of scope

  • Reworking deadline rule party_role semantics in the DB (those stay; we're re-projecting them).
  • Adding new proceeding types or modifying their rule sets.
  • A separate "perspective save" feature ("save this side+appellant combo as a named scenario").

Reporting

mai report completed with branch + SHAs + UX path: open any case project with our_side set → see Unsere Seite + Gegnerseite columns with all rules placed correctly → flip side toggle → columns swap, every rule re-resolves to the right column → confirm UPC Appeal still respects the separate appellant selector.

## m's report (2026-05-25 14:22) > Switching sides in the "Verfahrensablauf" doesn't do it right — "Klägerseite" can never be "Reaktiv". What are we trying to show there? > > In a normal proceeding, it should just switch left and right so "WE" are always on the left. And any other triggers like appeal need to get a side selection — because there things depend on the position. But for us, We should have Client left, not "Proactive". And then just say "Client Side" / COURT / "Opponent Side" and switch whatever that means. If we are patentee or alleged user. ## Context — what shipped t-paliad-250 / m/paliad#81 (commit 02255c4 on main) added side+appellant selectors to Verfahrensablauf and kept the existing **Proaktiv / Court / Reaktiv** column labels. m's report says the Proaktiv/Reaktiv axis is the wrong frame entirely — Klägerseite is sometimes proactive (filing) and sometimes reactive (responding), so the static label-pair lies. ## What m wants instead — user-perspective axis 1. **Three columns rename**: `Client Side` / `COURT` / `Opponent Side` (DE primary: `Unsere Seite` / `Gericht` / `Gegnerseite`). 2. **"WE" always on the left.** The side toggle picks **who we are in this proceeding** (Klägerseite vs Beklagtenseite, i.e. patentee vs alleged infringer / Einsprechender vs Patentinhaber, etc.). When the user flips the side toggle, the columns swap so the user's side stays in the **Unsere Seite** (left) column. 3. **Appeal-type proceedings** keep a separate appellant selector — because the appellant axis is independent of who-we-are. Example: in an Appeal CoA, both parties can theoretically appeal; the appellant selector picks which party initiates, and the side toggle still picks which of those is "us". 4. **Default** when a project has a proceeding chosen: derive `side` from the project's `our_side` field (already on `paliad.projects`, per t-paliad-217 ish). Read-only display with override toggle. ## What to do ### Part 1 — Column relabel + semantics flip - `frontend/src/client/views/verfahrensablauf-core.ts` (and the renderColumnsBody hermes touched in t-paliad-250) — rename column headers from `Proaktiv` / `Reaktiv` to `Unsere Seite` / `Gegnerseite` (EN: `Client Side` / `Opponent Side`). - The mapping logic that currently places each rule in Proaktiv vs Reaktiv was based on whether the rule's party_role equals the project's claimant/defendant role. Re-frame it: each rule has a party_role; if it matches our_side → Unsere Seite column; if it matches the opposing role → Gegnerseite column; if it's "both parties" AND no appellant chosen → could render in either or both — coder picks the cleanest UI (probably full-width across both columns OR a single "both" pill row spanning). - When the side toggle flips, the two columns visually swap — but functionally, the rule placement re-resolves against the new `our_side` value. ### Part 2 — Appellant selector stays Keep the appellant selector hermes added for appeal-type proceedings. Its role: when an Appeal is selected and the project doesn't pin which party appealed, the user picks. Without this pick, "both parties" appeal-rules still need to render somewhere — fall back to showing in BOTH columns until pinned. ### Part 3 — Project default `paliad.projects.our_side` (if it exists) drives the initial side selection. If the project has a proceeding chosen + `our_side` set, the selectors are auto-filled and shown read-only with a small "override" affordance. If the `our_side` column does NOT exist yet (verify), this issue's scope expands to add it as a migration. Flag in completion report. Likely DB shape: `paliad.projects.our_side text CHECK (our_side IN ('claimant','defendant','patentee','opponent', etc.))`. ### Part 4 — i18n Rename existing keys (or add new keys + deprecate old): - `proaktiv` → `our_side` ("Unsere Seite" / "Client Side") - `reaktiv` → `opponent_side` ("Gegnerseite" / "Opponent Side") - Court column label unchanged ## Files most likely touched - `frontend/src/client/views/verfahrensablauf-core.ts` (column placement logic + headers) - `frontend/src/client/views/verfahrensablauf-core.test.ts` (update test expectations) - `frontend/src/client/verfahrensablauf.ts` (selector wiring) - `frontend/src/verfahrensablauf.tsx` - `frontend/src/client/i18n.ts` + `frontend/src/i18n-keys.ts` - Possibly `internal/models/models.go` + a migration for `paliad.projects.our_side` if it doesn't exist - Possibly `internal/services/projection_service.go` if the column placement is computed server-side ## Hard rules - **No regression on t-paliad-250's URL-state plumbing** — the side / appellant URL params keep working; this is a semantics + label change, not a remove. - **Tests updated** — verfahrensablauf-core.test.ts has the old Proaktiv/Reaktiv expectations; update them. - **DE primary, EN secondary** for the new labels. - `go build ./... && go test ./internal/... && cd frontend && bun run build` clean. - Branch: `mai/<worker>/side-semantics-our-perspective`. ## Out of scope - Reworking deadline rule party_role semantics in the DB (those stay; we're re-projecting them). - Adding new proceeding types or modifying their rule sets. - A separate "perspective save" feature ("save this side+appellant combo as a named scenario"). ## Reporting `mai report completed` with branch + SHAs + UX path: open any case project with `our_side` set → see Unsere Seite + Gegnerseite columns with all rules placed correctly → flip side toggle → columns swap, every rule re-resolves to the right column → confirm UPC Appeal still respects the separate appellant selector.
mAi self-assigned this 2026-05-25 12:24:07 +00:00
Author
Collaborator

Verfahrensablauf side semantics — done

Branch: mai/hermes/gitster-verfahrensablaufa9a9adb

What changed

The Proaktiv | Gericht | Reaktiv triplet is gone. Columns are now Unsere Seite | Gericht | Gegnerseite (EN: Client Side | Court | Opponent Side). The side toggle drives row PLACEMENT into the ours/opponent buckets — labels stay truthful regardless of which physical party (claimant vs defendant) occupies them.

Old framing lied half the time: Klägerseite is sometimes proactive (filing a claim), sometimes reactive (responding to a CCR). The new framing is purely positional with semantic labels.

Files touched

  • frontend/src/client/views/verfahrensablauf-core.ts
    • ColumnsRow.proactive/reactiveours/opponent
    • renderColumnsBody picks static deadlines.col.ours / deadlines.col.opponent labels — no more variant-by-side keys
    • bucketDeadlinesIntoColumns: routes user's party into ours when opts.side === "defendant". Default (side === null) keeps the legacy "we are claimant" fallback so the claimant-on-left default survives
  • frontend/src/client/views/verfahrensablauf-core.test.ts — rewritten expectations on new fields. Added two new tests pinning the WE-on-left semantics and the side+appellant interaction (side=defendant + appellant=claimant"both" collapses into opponent column)
  • frontend/src/client/fristenrechner.ts — wires currentPerspective into renderColumnsBody as side. Without this, a defendant-perspective user would see claimant filings under the Unsere Seite header. The old code didn't need the wire-up because the labels weren't perspective-aware
  • frontend/src/client/i18n.ts — DE: Unsere Seite / Gegnerseite. EN: Client Side / Opponent Side. Drops the now-redundant *.proactive.defendant / *.reactive.claimant variant keys
  • frontend/src/i18n-keys.ts — regenerated union
  • frontend/src/styles/global.css.fr-col-proactive / .fr-col-reactive.fr-col-ours / .fr-col-opponent

Hard-rule checks

  • URL-state plumbing intact?side= + ?appellant= continue to drive perspective + appellant axis. Only the labels and field names changed; the URL contract is identical to t-paliad-250
  • Tests updated — old Proaktiv/Reaktiv expectations replaced. bun test passes 112/112 (was 110, +2 new tests for WE-on-left + side×appellant interaction)
  • DE primary, EN secondaryUnsere Seite / Gegnerseite in DE, Client Side / Opponent Side in EN
  • Build cleanbun run build (2794 i18n keys, no scan warnings) + go build ./... + go test ./internal/... all green
  • our_side column already exists on paliad.projects (verified via information_schema.columns) — no migration needed for Part 3

Part 3 (project default) — out of scope as written, no work needed

The issue's "derive side from project's our_side field" applies to surfaces with project context. /tools/verfahrensablauf is the abstract-browse tool — it has no project picker, so there's nothing to predefine. The fristenrechner side (/tools/fristenrechner) already does this via applyOurSidePredefine()ourSideToPerspective() (t-paliad-164/180), and that wire is now coherent with the new column labels via the side: currentPerspective pass-through I added.

If m wants /tools/verfahrensablauf to accept a project context in the URL (e.g. ?project=<uuid> and predefine side from there), that's a separate feature — flag it and I'll file a follow-up.

Appellant axis

Kept as-is. The appellant selector still pins which party initiated an Appeal/Counterclaim, and it's still independent of the side toggle:

  • side=defendant, appellant=defendant → "both" rows collapse into ours (we appealed)
  • side=defendant, appellant=claimant → "both" rows collapse into opponent (they appealed)
  • appellant=null → "both" rows mirror into both columns (legacy behaviour)

The new test side=defendant + appellant=claimant routes 'both' into opponent pins exactly this scenario.

UX path to verify

  1. Open /tools/verfahrensablauf → pick UPC Verletzungsverfahren
  2. Headers read Unsere Seite | Gericht | Gegnerseite. Default side is unset (Beide) → claimant filings on the left, defendant on the right
  3. Flip side toggle to Beklagtenseite → columns swap: defendant filings now on the left under Unsere Seite, claimant filings on the right under Gegnerseite. Court column unchanged
  4. Switch proceeding to UPC Berufung (appellant-axis proceeding). Appellant row appears. Set Berufung durch: Klägerseite while side=Beklagtenseite → all both rows collapse into the right column (opponent appealed)
  5. Flip Berufung durch to Beklagtenseite (we appealed) → both rows collapse into the left column (Unsere Seite)

Out of scope (untouched)

  • Deadline party_role semantics in the DB — re-projected, not re-tagged
  • Side selector's third "Beide" radio option — left as-is. Under the new framing it means "no explicit perspective, default to we-are-claimant". If m wants this renamed to for consistency with the appellant row, that's a one-line tweak — flag it and I'll do a follow-up
## Verfahrensablauf side semantics — done Branch: `mai/hermes/gitster-verfahrensablauf` → [a9a9adb](https://mgit.msbls.de/m/paliad/commit/a9a9adbd2a61ada9fc9a3b519ec555f5abf848e7) ### What changed The `Proaktiv | Gericht | Reaktiv` triplet is gone. Columns are now `Unsere Seite | Gericht | Gegnerseite` (EN: `Client Side | Court | Opponent Side`). The side toggle drives row PLACEMENT into the `ours`/`opponent` buckets — labels stay truthful regardless of which physical party (claimant vs defendant) occupies them. Old framing lied half the time: Klägerseite is sometimes proactive (filing a claim), sometimes reactive (responding to a CCR). The new framing is purely positional with semantic labels. ### Files touched - `frontend/src/client/views/verfahrensablauf-core.ts` - `ColumnsRow.proactive/reactive` → `ours/opponent` - `renderColumnsBody` picks static `deadlines.col.ours` / `deadlines.col.opponent` labels — no more variant-by-side keys - `bucketDeadlinesIntoColumns`: routes user's party into `ours` when `opts.side === "defendant"`. Default (`side === null`) keeps the legacy "we are claimant" fallback so the claimant-on-left default survives - `frontend/src/client/views/verfahrensablauf-core.test.ts` — rewritten expectations on new fields. Added two new tests pinning the WE-on-left semantics and the side+appellant interaction (`side=defendant + appellant=claimant` → `"both"` collapses into opponent column) - `frontend/src/client/fristenrechner.ts` — wires `currentPerspective` into `renderColumnsBody` as `side`. Without this, a defendant-perspective user would see claimant filings under the `Unsere Seite` header. The old code didn't need the wire-up because the labels weren't perspective-aware - `frontend/src/client/i18n.ts` — DE: `Unsere Seite` / `Gegnerseite`. EN: `Client Side` / `Opponent Side`. Drops the now-redundant `*.proactive.defendant` / `*.reactive.claimant` variant keys - `frontend/src/i18n-keys.ts` — regenerated union - `frontend/src/styles/global.css` — `.fr-col-proactive` / `.fr-col-reactive` → `.fr-col-ours` / `.fr-col-opponent` ### Hard-rule checks - ✅ **URL-state plumbing intact** — `?side=` + `?appellant=` continue to drive perspective + appellant axis. Only the labels and field names changed; the URL contract is identical to t-paliad-250 - ✅ **Tests updated** — old Proaktiv/Reaktiv expectations replaced. `bun test` passes 112/112 (was 110, +2 new tests for WE-on-left + side×appellant interaction) - ✅ **DE primary, EN secondary** — `Unsere Seite` / `Gegnerseite` in DE, `Client Side` / `Opponent Side` in EN - ✅ **Build clean** — `bun run build` (2794 i18n keys, no scan warnings) + `go build ./...` + `go test ./internal/...` all green - ✅ **`our_side` column already exists** on `paliad.projects` (verified via `information_schema.columns`) — no migration needed for Part 3 ### Part 3 (project default) — out of scope as written, no work needed The issue's "derive `side` from project's `our_side` field" applies to surfaces with project context. `/tools/verfahrensablauf` is the abstract-browse tool — it has no project picker, so there's nothing to predefine. The fristenrechner side (`/tools/fristenrechner`) already does this via `applyOurSidePredefine()` → `ourSideToPerspective()` (t-paliad-164/180), and that wire is now coherent with the new column labels via the `side: currentPerspective` pass-through I added. If m wants `/tools/verfahrensablauf` to accept a project context in the URL (e.g. `?project=<uuid>` and predefine side from there), that's a separate feature — flag it and I'll file a follow-up. ### Appellant axis Kept as-is. The appellant selector still pins which party initiated an Appeal/Counterclaim, and it's still independent of the side toggle: - `side=defendant, appellant=defendant` → "both" rows collapse into `ours` (we appealed) - `side=defendant, appellant=claimant` → "both" rows collapse into `opponent` (they appealed) - `appellant=null` → "both" rows mirror into both columns (legacy behaviour) The new test `side=defendant + appellant=claimant routes 'both' into opponent` pins exactly this scenario. ### UX path to verify 1. Open `/tools/verfahrensablauf` → pick `UPC Verletzungsverfahren` 2. Headers read `Unsere Seite | Gericht | Gegnerseite`. Default side is unset (`Beide`) → claimant filings on the left, defendant on the right 3. Flip side toggle to `Beklagtenseite` → columns swap: defendant filings now on the left under `Unsere Seite`, claimant filings on the right under `Gegnerseite`. Court column unchanged 4. Switch proceeding to `UPC Berufung` (appellant-axis proceeding). Appellant row appears. Set `Berufung durch: Klägerseite` while `side=Beklagtenseite` → all `both` rows collapse into the right column (opponent appealed) 5. Flip `Berufung durch` to `Beklagtenseite` (we appealed) → `both` rows collapse into the left column (`Unsere Seite`) ### Out of scope (untouched) - Deadline `party_role` semantics in the DB — re-projected, not re-tagged - Side selector's third "Beide" radio option — left as-is. Under the new framing it means "no explicit perspective, default to we-are-claimant". If m wants this renamed to `—` for consistency with the appellant row, that's a one-line tweak — flag it and I'll do a follow-up
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#88
No description provided.