Commit Graph

1411 Commits

Author SHA1 Message Date
mAi
49b61cfa73 Merge: paliadin meta-trailer defensive strip in renderer
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 19:53:35 +02:00
mAi
671e31557e fix(paliadin): defensively strip [paliadin-meta] trailer in renderer so it never reaches the user 2026-06-01 19:53:35 +02:00
mAi
0c9fe78f6b Merge: t-paliad-373 — editor grid 3-col fix (preview overlap + language-toggle-effect both resolved)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 19:45:52 +02:00
mAi
c8aa872802 fix(submissions): t-paliad-373 — restore 3-panel draft-editor layout (fixes preview overlap + 'dead' language toggle)
Two editor regressions from the t-paliad-370 S2/S5 relayout, both rooted in
ONE CSS bug.

BUG 1 — preview pane wrapped under the sidebar with no space.
.submission-draft-grid was a two-column track (minmax(280px,360px) 1fr) but
the grid has THREE children: sidebar, section panel, preview. Before S5 the
section panel hid itself (display:none) when a draft had no sections, so two
tracks happened to suffice. S5 (t-paliad-370) made the panel ALWAYS present
(it signposts its empty state instead of vanishing), so all three children
became permanently visible — and the third (preview) wrapped onto a new grid
row under the sidebar, squeezed to the sidebar's width and pushed far down
the page (repro: preview at y=1340, w=360 under the sidebar).

FIX: three named-area tracks — sidebar | sections | preview
(minmax(240px,300px) minmax(0,1fr) minmax(0,1.4fr), preview widest). Explicit
responsive collapse: <=1200px keeps the sidebar in its own column and stacks
section+preview in the second; <=900px single column. grid-template-areas on
the container + grid-area on each child keep placement deterministic (no
auto-placement wrap). Verified at 1400/1100/800px in a built-bundle harness;
all three panels lay out cleanly, preview fully visible, both the with-sections
and empty-state (merge-path) cases.

BUG 2 — language DE/EN toggle 'does nothing'. ROOT CAUSE: NOT a wiring bug.
Runtime repro against the built bundle proves the handlers attach
(de/en.onchange set), a click fires PATCH {language:"en"}, the radio flips,
and the preview + header re-render correctly. The toggle only LOOKED dead
because its primary visible output — the live preview — was the very pane
bug 1 displaced off-screen under the sidebar. Fixing the grid restores the
preview to a visible column, so toggling DE/EN now visibly swaps it
(repro: preview text DE->EN with the pane at x=849,w=399, top of viewport).
No client/markup change needed; the S2 toolbar move preserved every id and
the t-paliad-276 wiring was intact throughout.

CSS-only. bun build clean (i18n scan clean). No backend touched.
2026-06-01 19:43:51 +02:00
mAi
6b0f731c61 Merge: t-paliad-370 S5 — section-panel discoverability + [KEIN WERT] softening (docforge UX train COMPLETE)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 19:01:00 +02:00
mAi
298e1b22c8 feat(submissions): t-paliad-370 S5 — section-panel discoverability + [KEIN WERT] softening
docforge UX slice S5 (PRD §3 S5) — the final slice; completes the train.

- Section panel: instead of silently hiding when a draft has no sections
  (the §1.4 2-vs-3-panel inconsistency), the panel now always signposts its
  state. A Composer draft (base_id set) shows 'Dieser Entwurf hat noch keine
  Abschnitte' + a '+ Abschnitt hinzufügen' affordance; a fixed-template draft
  (merge path / uploaded template, base_id NULL) is told it uses a fixed
  template with no editable sections. The section editor is now discoverable
  and the panel's presence/absence is explicit.
- Live preview: unresolved placeholders render as a muted '‹noch leer: key›'
  prompt instead of the harsh [KEIN WERT: key] marker — a preview-display
  nicety done client-side in paintPreview. The EXPORTED .docx is unchanged and
  keeps the real marker (an honest blank the lawyer fills in Word).
- global.css: .submission-draft-sections-empty / -note + .preview-empty.

Frontend only (submission-draft.ts + global.css), no backend.
bun build (i18n scan clean) + go vet ./... + go test ./... (15 ok, 0 fail).
2026-06-01 19:00:23 +02:00
mAi
fbd6bf9bd0 Merge: S4 infra — gotenberg sidecar + poppler-utils (truthful base-preview render)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 18:59:19 +02:00
mAi
e751056d57 infra(preview): gotenberg sidecar + poppler for truthful base-preview render (t-paliad-370 S4) 2026-06-01 18:59:18 +02:00
mAi
0eb6cd2ce6 Merge: t-paliad-370 S4 — truthful base-preview render (code; gotenberg+poppler infra pending, graceful structural fallback)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 18:56:39 +02:00
mAi
8ccf64cf83 feat(submissions): t-paliad-370 S4 — truthful base-preview render (code)
docforge UX slice S4 (PRD §2.3). Extends the S3 /api/submission-preview
endpoint with a truthful page-image render behind the SAME modal+endpoint
shape (the swappable body region). Resolves the S3 caveat: anchors-only
Composer/Gitea bases now render their REAL letterhead/Rubrum styling instead
of falling back to a base-agnostic structural view.

Pipeline (PRD §2.3): build the .docx via the EXISTING export pipeline
(byte-faithful) → Gotenberg sidecar (.docx→PDF over HTTP, keeps the Go image
lean) → poppler pdftoppm (PDF→PNG-per-page) → cache + single-flight.

Code only — NO Dokploy/compose change (head provisions the sidecar + fonts).
When GOTENBERG_URL is unset or poppler is absent, Available()=false and the
endpoint gracefully falls back to S3 structural HTML, so merging this is safe
before the infra lands.

Backend:
- internal/services/preview_render.go: PreviewImageRenderer interface +
  GotenbergRenderer (.docx→PDF→PNG) + PreviewImageCache (bounded FIFO,
  single-flight per key, serialised conversions) + NewPreviewImageCacheFromEnv
  (GOTENBERG_URL / PREVIEW_DPI). The PNG cache is regenerable, not a retained
  document (no disk/DB persistence; rebuildable from inputs).
- /api/submission-preview gains fidelity=truthful: builds the truthful .docx
  (editor = clone draft + base override → full export pipeline incl. Composer;
  catalog = context bag → render), caches by (draft id+updated_at | code+
  project) × base × lang × data-mode, returns page data-URIs. Structural
  responses now carry truthful:false.
- exportSubmissionDraft + Export gain a pluggable missing-marker (nil = default,
  so every existing export path is byte-identical); enables sample-data truthful
  render. New SubmissionDraftService.{ExportWithMarker,RenderContextPreviewDocx}.
- Unit tests: cache hit/miss, single-flight, eviction, availability, gotenberg
  multipart request shape (httptest, no poppler needed).

Frontend:
- base-preview-modal.ts requests fidelity=truthful; renders <img> page(s) with
  a ‹ n/N › prev/next pager (instant — pages held client-side); falls back to
  the S3 structural sheet when truthful:false. CSS for .base-preview-img +
  page-nav.

bun build (i18n scan clean) + go vet ./... + go test ./... (15 ok, 0 fail;
+6 new service tests).
2026-06-01 18:54:41 +02:00
mAi
3d68de2568 Merge: t-paliad-370 S3 — Vorschau base-preview modal scaffold (structural render, swappable for S4)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 18:42:52 +02:00
mAi
a70508a7d5 feat(submissions): t-paliad-370 S3 — Vorschau base-preview modal scaffold
docforge UX slice S3 (PRD §2.1 / §3 S3). A shared, body-attached modal lets
the lawyer browse template bases, flip output language + data-mode, and — in
the editor — commit a base with 'Diese Basis verwenden', replacing the blind
<select> as the chooser. Opened from the editor 👁 button AND both catalog row
kebabs (the S1/S2 stubs are now live).

Body renders the EXISTING structural preview on cheap rails; the body region is
swappable so S4 drops a truthful .docx→image render behind the same modal +
endpoint shape. Spinner + pager are the shell S4 expects.

Backend (minimal, no truthful render — that's S4):
- GET /api/submission-preview?base&code&lang&data&draft?&project? → {preview_html}.
  Draft+mine uses the draft's resolved bag (previews a base the draft has NOT
  committed to — no persistence); else a fresh context bag (project-less fill,
  t-paliad-364). data=sample swaps a sample missing-marker so unresolved keys
  render readable sample text, not [KEIN WERT].
- SubmissionDraftService.RenderPreviewWithMarker + RenderContextPreviewHTML
  (thin: reuse BuildRenderBag / vars.Build + RenderHTML).
- resolvePreviewTemplateBytes: tpl:→carrier, base_id→bytes IFF it carries merge
  placeholders, else fall back to the code's merge template (anchors-only
  Composer bases can't be shown as structural HTML — their letterhead/styling
  surfaces in S4's truthful render). sampleMissingMarker by key suffix.
- Unit tests: sampleMissingMarker + normalizePreviewLang.

Frontend:
- New shared client/base-preview-modal.ts (built once, body-attached; serves
  editor + project tab + global picker). Base-switcher, DE/EN + meine/Beispiel
  toggles, swappable body, spinner, pager stub, conditional 'Diese Basis
  verwenden' (editor commits via onBaseChange; catalog = look-only).
- Editor 👁 button un-stubbed + wired; both catalog kebab 'Vorschau' items
  un-stubbed + wired. global.css: .base-preview-* modal styles.

bun build (i18n scan clean) + go vet ./... + go test ./... (15 ok, 0 fail).
2026-06-01 18:42:08 +02:00
mAi
7ec1908383 Merge: t-paliad-370 S2 — editor draft-meta into header toolbar (de-densify sidebar)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 18:29:30 +02:00
mAi
064ba79ecb feat(submissions): t-paliad-370 S2 — editor draft-meta lifted into a header toolbar
docforge UX slice S2 (PRD docs/plans/prd-docforge-ux-2026-06-01.md §3).
De-densifies the draft editor (G1-d): draft management + template controls
move out of the variable sidebar into a horizontal, wrap-friendly header
strip above the working grid. The sidebar then holds only the fill-in work
— 'Aus Projekt importieren', parties, and the variable fields.

- submission-draft.tsx: new .submission-draft-toolbar strip carrying the
  switcher (+ '+ Neuer Entwurf'), name (+ Löschen), Stichwort (+ hint),
  Vorlagenbasis picker, language toggle, fallback notice + savestatus. The
  'Als .docx exportieren' button stays top-right in the header.
- New 👁 Vorschau button next to the base picker (id
  submission-draft-preview-base-btn), disabled 'Bald verfügbar' stub — S3
  wires it to the truthful base-preview modal (PRD §2).
- global.css: .submission-draft-toolbar* layout + .submission-draft-base-
  controls (select + 👁 on one row); single-column collapse < 900px.
- i18n: submissions.draft.base.preview(.soon) (DE/EN).

Pure relayout — NOT a behavior change. Every control keeps its id, so the
existing wiring is untouched (switcher, name save, keyword→composer_meta,
base picker PATCH base_id, language autosave, savestatus). Grounded in the
2-panel reality (§1.4): the conditional Abschnitte section panel is
unchanged (still display:none when a draft has no sections; S5 addresses
its discoverability). TS/CSS only, no backend.

bun build (i18n scan clean) + go vet ./... + go test ./... (15 ok, 0 fail).
2026-06-01 18:29:01 +02:00
mAi
3f20823e18 Merge: t-paliad-370 S1 — catalog rows = one primary CTA + ⋯ menu (consistent across both entry points)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 18:23:48 +02:00
mAi
017e535541 feat(submissions): t-paliad-370 S1 — catalog rows = one primary CTA + ⋯ menu
docforge UX slice S1 (PRD docs/plans/prd-docforge-ux-2026-06-01.md §3).
Kills the invisible two-equal-buttons confusion (G1-b) on both catalog
surfaces, consistently, while keeping each surface's distinct context.

- New shared kebab helper frontend/src/client/row-action-menu.ts: an
  accessible ⋯ trigger + body-attached, position:fixed popover (the
  .entity-table-wrap clips with overflow-x:auto, so the popover is
  body-attached like the event-card choices popover). Outside-click /
  Escape / scroll / resize close it; one open at a time.
- Project Schriftsätze tab (client/submissions.ts): primary 'Entwurf
  öffnen' (was 'Bearbeiten') + ⋯ menu { Direkt exportieren (.docx) [was
  the 'Generieren' button], Vorschau Vorlagenbasis [disabled stub, S3
  wires it] }. onGenerateClick→generateAndDownload (busy-cursor feedback,
  no button to relabel).
- Global picker (client/submissions-new.ts): primary 'Entwurf starten'
  (project-less free-start, kept first-class) + ⋯ menu { Mit Projekt
  verknüpfen… [the modal picker], Vorschau Vorlagenbasis [disabled stub] }.
- i18n: new projects.detail.submissions.action.open (DE/EN); kebab item
  labels inline isEN() (matches the picker's dynamic-row convention).
- CSS: .row-action-menu* in global.css.

The 'Vorschau Vorlagenbasis' entries are disabled stubs ('Bald verfügbar')
until S3 lands the truthful base-preview modal. TS/CSS only, no backend.
bun build + go vet ./... + go test ./... clean.
2026-06-01 18:23:15 +02:00
mAi
f46b1b18a3 chore(patentsstyle): publish HLC Patents Style v0.260601-1614
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
sha256 A5B3F4FA2DA97242D0BA8B63B29F4F637600E8EF7217CCF446942B7C6DB3C9A4
Source: HL/mWorkRepo#37 (Build.ps1 -> publish.sh pipeline).
2026-06-01 18:14:44 +02:00
mAi
f03b00ee89 Merge: t-paliad-369 docforge UX PRD — truthful base preview + coherent drafting flow
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 18:12:46 +02:00
mAi
310c993d19 docs(docforge): t-paliad-369 PRD — truthful base preview + coherent submission-drafting UX
Audit of the end-to-end docforge journey (project Schriftsätze tab, global
/submissions/new picker, draft editor, /admin/templates authoring) + a
prioritized UX plan. Captures m's grill answers + 4 option-picker decisions:
- base preview = truthful (LibreOffice .docx→image, on-demand+cached), via a
  'Vorschau' button → modal with a base-switcher
- catalog rows = one primary 'Entwurf öffnen' + ⋯ kebab (kills the invisible
  Bearbeiten-vs-Generieren split)
- editor meta → header toolbar (de-densifies the sidebar)
- free-start stays first-class; entry points kept distinct-but-consistent
- live editing preview stays structural (only the base preview is pixel-true)

Resolved the 2-vs-3-panel discrepancy: the Abschnitte panel is display:none
when a draft has no seeded sections, so m correctly sees 2 panels.

Design only — no engine redesign, no code. Tracer-bullet slice train S1..S5.
2026-06-01 18:11:16 +02:00
mAi
b09fc687bd Merge: patentsstyle path rename + /patentstyle/ backwards-compat alias (work/paliad)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 18:08:38 +02:00
mAi
cd4ec074ca feat(patentstyle): rename served path /patentstyle/ -> /patentsstyle/ (alias old path for installed-client auto-update) 2026-06-01 18:08:38 +02:00
mAi
31ebec769a Merge: t-paliad-367 rebuild firm-skeleton from HLC Patents Style .dotm (authored letterhead+recitals, HLCpat-)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 17:14:22 +02:00
mAi
9dba2b627c Merge remote-tracking branch 'origin/main' into mai/bohr/coder-rebuild-merge-safe 2026-06-01 17:14:21 +02:00
mAi
8a51fbb9e4 feat(generation): t-paliad-367 rebuild firm-skeleton FROM HLC Patents Style .dotm — use the firm's authored letterhead+recitals tables
m mandate (2026-06-01): 'I dont want that formatting in code! it should use
our word files and styles.' The t-paliad-364 generator synthesised a flat
Rubrum in Go, borrowing only the firm's style NAMES. The HLC Patents Style
.dotm already contains the real, firm-authored letterhead + Rubrum in Word —
header table (logo via header2 + address blocks), case-info table, recitals
table — all in HLCpat- styles.

This rewrites gen-hl-skeleton-template to LIFT that authored layout verbatim:
- ConvertDotmToDocx strips macros → clean .docx carrier (idempotent on .docx)
- footer1 firm-NAME SDT → {{firm.name}} (A-S3); footer2 legal block kept
- document.xml body kept verbatim through the recitals table; the TOC +
  checklist demo + 'Template Info And Manual' style-guide section truncated
- carrier <w:document> open tag + <w:sectPr> reused → header1/2 + footer1/2 +
  titlePg letterhead wiring preserved
- structure-aware, occurrence-ordered paragraph walk swaps the firm's example
  text for paliad merge tokens (parties/caption/project/user/today/proc-event);
  transformed paragraphs keep their <w:pPr> verbatim — the named style supplies
  formatting, none authored in code

Reconciles t-paliad-366 item 1 (HLpat→HLCpat drift): carrier + Rubrum both HLCpat-.

DATA GAP flagged to m: no structured HL office postal addresses + no court_id FK
(project.court is free text), so the sender address block + recipient court
address lines are kept as the .dotm's authored editable text; only the court
NAME is wired to {{project.court}}. Rules flip to placeholders when that data lands.

Verified: HasMergePlaceholders=true (de+en); header2/footer2/media/styles.xml/
theme/numbering byte-identical to the .dotm; package integrity clean (macros
stripped, no dangling rels, main type demoted); merge dry-run fills with zero
leftover {{}} / zero [KEIN WERT]. go vet + go test ./... + bun build green.
2026-06-01 17:04:50 +02:00
mAi
327dc1169a chore(patentstyle): publish HLC Patents Style v0.260601-1442
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
sha256 074ED1339FFBC5514E9C347E28C3477F531306ABEA30EC3083B23E6095BD7E05
Source: HL/mWorkRepo#37 (Build.ps1 -> publish.sh pipeline).
2026-06-01 16:43:07 +02:00
mAi
08fb6ed501 chore(patentstyle): publish HLC Patents Style v0.260601
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
sha256 07AE5DC2BED8905964CC1FBB0B89300F5B444BC1729FCACFFCDE5E83A2F99EF0
Source: HL/mWorkRepo#37 (Build.ps1 -> publish.sh pipeline).
2026-06-01 16:30:43 +02:00
mAi
b582e62b2b Merge: t-paliad-364 styled+filled submissions — project-less caption fill (P3b) + merge-safe styled firm-skeleton generator (P3a Option B)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 16:17:19 +02:00
mAi
f152109bd3 Merge remote-tracking branch 'origin/main' into mai/bohr/coder-generation-core 2026-06-01 16:17:08 +02:00
mAi
c1781c9a89 feat(generation): t-paliad-364 styled+filled submissions — project-less caption fill (P3b) + merge-safe styled firm-skeleton generator (P3a Option B)
P3(b) fill-what-we-can (submission_vars.go):
The project-less branch of SubmissionVarsService.Build ran only firm/today/
user/proceduralEvent resolvers, so caption.*/project.proceeding.* never
populated and every Rubrum value rendered [KEIN WERT]. The rule is already
loaded on this path and carries ProceedingTypeID. Now the branch loads the
proceeding type via loadProceedingType(rule.ProceedingTypeID) (tolerates a nil
id) and appends a proceeding-only projectResolver{project:nil} + a
captionResolver{project:nil} — both nil-project safe. Result: caption heading /
designations / versus / subject + the proceeding line fill from the
submission_code's proceeding; only party names / case number / court stay blank
for the lawyer. Preserves the "Ohne Projekt" affordance (t-paliad-243).

addProjectVars is now nil-project safe (guards the project.* direct fields,
keeps the pt-driven project.proceeding.* block) so projectResolver can serve as
the proceeding-only resolver. Pinned by TestProjectlessFill_* +
TestAddProjectVars_NilProjectFillsProceedingOnly (no DB).

P3(a) styling — merge-safe styled firm-skeleton (scripts/gen-hl-skeleton-template):
Generation landed on docx.BuildFallbackSkeleton (generic Heading1/2/Normal)
because the firm-skeleton's body had been repurposed into an anchors-only
Composer base, which HasMergePlaceholders rejects. Rewrote the generator to take
the deployed clean .docx carrier and replace ONLY word/document.xml with a clean
caption-driven Rubrum that uses the firm Rubrum styles (Table-Recitals-Party/
PartyDetails/PartyRoles/Sequencers, Heading-H2, Signature, Body-B0) and the same
{{key}}/{{caption.*}} placeholders the in-process fallback uses — preserving the
carrier's styles/theme/numbering/letterhead/logo and its sectPr verbatim. Adds a
-lang flag (DE _firm-skeleton.docx, EN _skeleton.en.docx) and auto-detects the
firm style prefix (HLpat-/HLCpat-) so it stays correct across the .dotm rebrand
drift. The resolver's tier-4/tier-3 merge-safe guard auto-prefers the restored
templates — no handler change.

Dry-run (TEST_DATABASE_URL, de.inf.lg.erwidg): project-less render fills caption
heading="In dem Rechtsstreit"/Klägerin/gegen/Beklagte/Patentverletzung + the
proceeding line, only party/case/court blank; full-project render additionally
fills parties + case number + court. Both carry the HLpat-Table-Recitals-* /
HLpat-Heading-H2 / HLpat-Signature styles, HasMergePlaceholders=true, no
{{#section}} junk.
2026-06-01 16:14:28 +02:00
mAi
72ba8fb2b9 Merge: t-paliad-365 picker quality — re-kind 8 court-act rules (mig 164) + group-header contrast
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 15:59:19 +02:00
mAi
13166cd784 fix(submissions): t-paliad-365 picker quality — re-kind 8 court-act rules (mig 164) + group-header contrast
P1: 8 anchor/trigger rows (Zustellung des Urteils / Veröffentlichung der
Erteilung) were mislabeled event_type='filing'+primary_party='both' and leaked
into the /submissions/new draftable-submission picker. Migration 164 re-kinds
them to event_type='decision'+primary_party='court', aligning them with the 16
sibling court-act rows the model already has; the picker's event_type='filing'
filter then excludes them. Defensive guard added to loadSubmissionCatalog
(primary_party IS DISTINCT FROM 'court') as belt-and-braces against future drift.
Safety: the only event_type coupling for these rows is ruleAnchorKind
(projection_service.go) — they now anchor as appointments (correct, sibling-
consistent); deadline computation keys off is_court_set not event_type, and the
child sequence guard parentHasAnchoredActual UNIONs both anchor tables, so no
chain breaks. Verified: catalog 113->105, 8 court acts gone, 48 'both' party
submissions (incl. UPC appeal briefs) retained.

P2: the grouped picker table already renders a correct colspan group-header row
(a911a2d); the defect was contrast — the band used --color-bg-subtle, the SAME
token as the thead, so groups read as undelimited floating text. New
--color-bg-group-header token (cool/deeper in light, raised-cream in dark) +
heavier top divider + neutral left accent + darker label make each proceeding a
distinct section. Live deployed bundle confirmed current (not stale).
2026-06-01 15:58:32 +02:00
mAi
9e515551b2 Merge: t-paliad-363 generation-quality diagnosis (picker filter, layout, Rubrum styling+fill)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 15:50:56 +02:00
mAi
63e973df88 docs(generation-quality): t-paliad-363 diagnosis — picker court-act mislabel, group-header contrast, unstyled+unfilled Rubrum (2-layer P3 + 3 forks) 2026-06-01 15:48:11 +02:00
mAi
8eba20f46a Merge: t-paliad-361 caption-wording — Respondent + restored Streitpatent line + DE appeal/nullity role-label backfill (mig 163, lexy-confirmed)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 15:23:09 +02:00
mAi
d30556397a Merge remote-tracking branch 'origin/main' into mai/bohr/coder-apply-m-s-caption 2026-06-01 15:22:56 +02:00
mAi
1882468780 feat(caption): apply m's caption-wording decisions — Respondent + Streitpatent line + DE appeal/nullity role labels
Some checks are pending
Paliad CI gate / build (push) Waiting to run
Paliad CI gate / test-go (push) Waiting to run
Paliad CI gate / deploy (push) Blocked by required conditions
t-paliad-361, follow-up to t-paliad-358 A-S2. m ruled on the 7 lexy-wording
flags (AskUserQuestion 2026-06-01 14:30). Most flags CONFIRMED the live
wording; three changes land here, all caption (Rubrum) wording, all in one
reversible migration 163.

Change 1 — UPC appeal responding party (EN): 'Appellee' → 'Respondent'.
  Fixed at the data source: the mig-137 role-label override on
  upc.apl.unified (the only place 'Appellee' was stored). The caption
  resolver's instance-derived EN fallback already said 'Respondent', so no
  code change. DE side (Berufungsbeklagter) untouched per m.

Change 2 — restore the standalone 'Streitpatent: {{project.patent_number_upc}}'
  (DE) / 'Patent in suit:' (EN) line in the upc-formal Composer caption seed,
  dropped in A-S2 (mig 161). Keeps the parametric 'In der Sache' heading (m did
  not revert that). Only the upc-formal base is touched; grouped with the case
  number ahead of {{project.court}}.

Change 3 — backfill lexy-confirmed role-label overrides for the four DE
  appeal/nullity proceedings that carried none, so designations are correct
  even when project.instance_level is unset (statute-grounded: §§ 511/542/544
  ZPO, §§ 81/110 PatG; bracketed-inclusive gender style):
    de.inf.olg    Berufungskläger(in) / Berufungsbeklagte(r)              // Appellant / Respondent
    de.inf.bgh    Revisionskläger(in) / Revisionsbeklagte(r)              // Appellant / Respondent
    de.null.bpatg Nichtigkeitskläger(in) / Beklagte(r) (Patentinhaber(in)) // Nullity claimant / Defendant (patent proprietor)
    de.null.bgh   Berufungskläger(in) / Berufungsbeklagte(r)              // Appellant / Respondent

Updates submission_vars_caption_test.go: adds EN assertions + cases pinning the
Respondent change and the four backfilled designations (each with instance_level
unset, proving the override path). go vet + go test ./... + bun build clean.
2026-06-01 15:21:37 +02:00
mAi
3042bea3c2 Merge: patentstyle Content-Disposition derives filename from requested file (HLC install fix)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 15:18:32 +02:00
mAi
ea9dd261ae fix(patentstyle): derive Content-Disposition filename from requested file (HLC download saved under wrong name, install macro rejected) 2026-06-01 15:18:32 +02:00
mAi
78f9aa4f46 Merge: patentstyle download href flip → HLC-Patents-Style.dotm
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 15:04:43 +02:00
mAi
19f9604827 fix(patentstyle): flip download href to HLC-Patents-Style.dotm (m blocked on HL file) 2026-06-01 15:04:43 +02:00
mAi
c303c01652 chore(patentstyle): publish HLC Patents Style v0.260601
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
sha256 DE6B6A17AC603FF4A9B3893CD2A7EF8263C9E2D4224A0A5E28E2FABF5E27A798
Source: HL/mWorkRepo#37 (Build.ps1 -> publish.sh pipeline).
2026-06-01 14:52:35 +02:00
mAi
97a2742f10 Merge: patentstyle landing page — English + HLC rebrand (work/paliad coordination)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 13:28:04 +02:00
mAi
b26360111a docs(patentstyle): English + HLC rebrand of landing page (work/paliad coordination) 2026-06-01 13:27:57 +02:00
mAi
e914bac79a chore(patentstyle): publish HL Patents Style v0.260601
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
sha256 D4D0BDD31CC2C4F9A2362363FEC2A7D86B8BE8A4EA7B0F2CEF5F1944A15B3A4A
Source: HL/mWorkRepo#37 (Build.ps1 -> publish.sh pipeline).
2026-06-01 13:17:15 +02:00
mAi
713a4d4206 Merge: t-paliad-358 A-S3 — firm-agnostic merge-fallback + firm-skeleton letterhead (firm.name placeholderised) — COMPLETES Rubrum Option A
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 13:11:16 +02:00
mAi
cd3cd0230c Merge remote-tracking branch 'origin/main' into mai/bohr/coder-rubrum-letterhead 2026-06-01 13:11:05 +02:00
mAi
cd793b1d98 feat(submissions): firm-agnostic merge-fallback letterhead (t-paliad-358 A-S3)
A-S3 part 1 (merge-fallback letterhead, in-repo): the fallback skeleton
(docx.BuildFallbackSkeleton) gains a minimal Word page-header letterhead
(word/header1.xml) carrying only {{firm.name}}, filled from branding by the
variable bag. A generated fallback-path document now repeats a correct,
firm-agnostic firm identity on every page (the firm name moved out of the body
into the header; no hard-coded firm name anywhere). Wired the header part:
Content_Types override + document.xml.rels relationship (rId2) + sectPr
headerReference; document gains xmlns:r. Deliberately minimal — the fallback is
a starter, not full firm chrome.

A-S3 part 2 (firm-skeleton .docx, mWorkRepo — separate commit): _firm-skeleton.docx
footer1's "Firm name" SDT content control hard-coded "Hogan Lovells" → now
{{firm.name}}, filled by the Composer's final renderer pass / merge.go (both run
SubmissionRenderer over header/footer parts). Surgical <w:t> edit + repack (all
38 parts preserved, verified renders + fills cleanly, integrity OK). Pushed to
HL/mWorkRepo as mAi (commit 5a3a1722).

Path taken: option (a) for the firm NAME (cleanly placeholderised). NOT option
(a) for footer2's HL legal-entity boilerplate (registered no. OC323639, LLP
structure, 40+ office cities) — token-swapping the name into it would assert
false legal facts for a non-HLC firm; left intact and flagged (needs per-firm
legal-footer config, not templating). No corrupt .docx shipped.

Completes the Rubrum + letterhead auto-fill Option A train (A-S1 signature_block
+ generate-fallback fix; A-S2 parametric caption.*; A-S3 firm-agnostic letterhead).

Tests: fallback header asserts {{firm.name}} present + renders firm-agnostically
(de+en); patched firm-skeleton verified to render + fill (transient check).
go vet ./... + bun build clean; touched packages green.
2026-06-01 13:10:04 +02:00
mAi
a50ddc3927 Merge: t-paliad-356 Slice 5 — firm-wide default name compositions (mig 162) — COMPLETES nomen train
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-06-01 13:05:50 +02:00
mAi
c639c5695c Merge remote-tracking branch 'origin/main' into mai/fermi/coder-implement-nomen 2026-06-01 13:05:30 +02:00
mAi
a05ae1f2ae feat(settings): firm-wide default name compositions (t-paliad-356 Slice 5)
Completes the nomen train (S1–S5). Adds the FIRM tier of the name-composition
precedence chain — per-document → user → FIRM → system (PRD §3.1/§3.2) —
mirroring firm_dashboard_default exactly.

Storage + service:
- Migration 162: paliad.firm_name_compositions singleton (id=1, CHECK id=1,
  RLS read-all + service-role writes) — same shape as firm_dashboard_default
  (mig 117), holding a validated { artifact_id: Composition } jsonb map.
- FirmNameCompositionService (Get/Set/Clear) + getFirmNameCompositions /
  setFirmNameCompositions / clearFirmNameCompositions singleton helpers in
  name_composition_spec.go.

Resolution:
- resolveComposition is now variadic over ordered specs (user, firm); first
  valid wins, else system default. Existing single-spec callers unchanged.
- Render path threads the firm tier: renderSubmissionDraftTitle /
  RenderSubmissionFilenameFor gain a firm param; newDraftName +
  submissionDownloadFilename load it (nil-safe). A firm default thus changes
  the effective name for every user without a personal override.

Admin surface (mirrors firm_dashboard_default):
- GET/PUT/DELETE /api/admin/name-compositions{/artifact_id} (adminGate) read
  back / set / clear the firm default per artifact.
- /settings Namensschemata cards gain an admin-only "Firmenstandard" block
  (set from the current template field / clear) revealed via is_admin, plus a
  "Firmenstandard" badge for non-admin users whose effective name comes from
  the firm tier. SettingsNameArtifact now resolves user→firm→system and
  exposes firm_is_set/firm_template.

Tests: pure precedence (user>firm>system) + firm-tier view + live firm
round-trip/Validate-rejection (via db.ApplyMigrations). go vet, go test ./...,
bun build all clean; gated live tests green against TEST_DATABASE_URL.

NOTE (merge ordering): golang-migrate is forward-only. Migration 162 must not
reach a DB before bohr's 161 (Rubrum Composer seed) exists, or 161 will be
skipped (current>161 → never applied). Merge 161 before/with 162.

Browser Playwright of the admin firm controls deferred to post-deploy
mai-tester — shared Supabase login wall blocks pre-merge browser login (same
ceiling as t-paliad-354).
2026-06-01 13:04:11 +02:00