Skip to content

History / ADR 034 Client Side Report PDF Generation

Revisions

  • docs(adr-034): document docDefinition.ts as the shared document definition (#2161) Add docDefinition.ts (buildReportDocDefinition) to the module table and the multi-PDF dependency table, with why it is not in pageGeometry.ts (shared.ts imports pageGeometry.ts). Add a merge.ts dependency row, fix the parts.ts row, restate the one-definition rule, and align the lazy-load wording with the code comments (page tests partially mock reportPdf/index.js and paperlessApi.js). Deviation Log row added. Co-Authored-By: Claude product-architect <noreply@anthropic.com>

    @steilerDev steilerDev committed Oct 1, 2026
  • docs(adr-034): correct #2161 addendum per PR #2167 review Lazy-load rationale: parts.js stays out of the page tests' partial mocks of reportPdf/index.js, and the pipeline loads only when a size limit is set (not paperlessApi avoidance). Record PDF_DEFAULT_STYLE moving to pageGeometry.ts, single-part-first planning with the N=99 estimate as a fallback only, and the always-bulleted continuation invoice list. Co-Authored-By: Claude product-architect <noreply@anthropic.com>

    @steilerDev steilerDev committed Oct 1, 2026
  • docs(adr-034): multi-PDF split addendum (#2161) Add the addendum for splitting a report into parts by a maximum file size: new modules and dependency shape, the parts.js dynamic-import contract, ReportContent.partTexts closures as the channel for parameterised report-language strings (invariant 5 holds), client-side sizing via the existing preview proxy with a documentId-keyed session cache, the ordered greedy planner plus bounded verification pass, and the 1 MB = 1,000,000 B decision with formatFileSizeDecimal. Also update the module table, extend the builder-signature rule, make the lazy-loading and invariant-1 grep guards return nothing (test-file and unionKeys.js exclusions), extend the merge-memory consequence, and log three Deviation Log rows. Co-Authored-By: Claude product-architect <noreply@anthropic.com>

    @steilerDev steilerDev committed Oct 1, 2026
  • docs(adr-034): tier-3 summary block follows the table width; sum check for columns groups (#2011, PR #2133) Co-Authored-By: Claude product-architect <noreply@anthropic.com>

    Frank Steiler committed Sep 30, 2026
  • docs(adr): ADR-034 column geometry is a computed engine, not two pinned shapes (#1973) The "Geometry constraint that blocks a feature" section stated the PDF's column count is fixed at 6 or 7 and that wiring the wizard's column-visibility toggles through to the PDF "is a re-measurement story, not a UI change". PR #2010 falsified every clause: overviewPdf.ts now renders any of 96 legal column subsets via a single-absorber geometry engine. Replaced the section, recording the load-bearing fact that previously existed only in a function doc comment: USAGE_WIDTH_7COL (138.28pt) is provably the narrowest Usage width across all 96 subsets, so the measured 650-character ceiling is a floor and hiding columns only ever makes it more conservative -- which is why no re-measurement was needed. Also records the one-sided usageChunkCharsForWidth clamp, the residual "adding a column IS a re-measurement story" constraint, and which links force a new ReportColumnKey at compile time versus which fail soft. Two adjacent staleness fixes in the same section: the bound's call site was quoted as packUsageCellRows(segments, MAX_SAFE_USAGE_CHUNK_CHARS) (now the per-subset usageChunkChars), and the "Related sharp edge" paragraph claimed packUsageCellRows hangs on maxChars <= 0 when a prior fix had already made it throw -- its own prediction ("it matters the moment it becomes computed") went live with this change. Added reportContent/columns.ts to the module structure as the sole derivation of which columns exist, with the reason it lives outside reportPdf/. Architecture.md: added a "Multi-step wizard state: tier factories" subsection. The freshXTier()-spread convention introduced in #1947 (after #1943/#1946) had never been documented, so a reviewer had to reconstruct it from the reducer to judge whether DISCARD_EDITS's hiddenColumns write was drift or a deliberate exception. States the convention, the single opt-out, and the limit: a second opt-out must trigger a tier split rather than another exception. Deviation Log rows added to both pages. Co-Authored-By: Claude product-architect <noreply@anthropic.com>

    Frank Steiler committed Aug 5, 2026
  • docs(adr): align ADR-034 rule #1 implementing-test pointer with exact describe block name

    @steilerDev steilerDev committed Aug 5, 2026
  • docs(adr): correct ADR-034 rule #1 implementing test — per-cell _minWidth replaces vacuous horizontalRatio assertion (3rd correction, PR #2008)

    @steilerDev steilerDev committed Aug 5, 2026
  • docs(ADR-034): add pointer to implementing test for horizontal-overflow rule (#2003)

    @steilerDev steilerDev committed Aug 5, 2026
  • docs(adr-034): compiler-enforced locale contract after TFunction removal (#2001) Add invariant 5 (no TFunction under reportPdf/) with its own grep guard and a note that the invariant-1 guard structurally cannot match a `t: TFunction` parameter. Correct line 82's builder signature, re-scope the "nothing in the type system distinguishes reportT" sentence, generalise the #1993 footer paragraph into the closed-class statement, replace the now-empty "still re-translated independently" list, record the value-keyed label set rule from the PR #2007 review, and fix the Reference:/Subject: worked case. Co-Authored-By: Claude product-architect <noreply@anthropic.com>

    @steilerDev steilerDev committed Aug 5, 2026
  • docs(adr-034): remove stale merge.ts header ref from line-219, reword line-190 to not imply Seite state

    @steilerDev steilerDev committed Aug 4, 2026
  • docs(adr-034): reframe footer deviation as fragility fix, correct line-219 cross-ref, fix test count

    @steilerDev steilerDev committed Aug 4, 2026
  • docs(adr-034): mark pageFooter locale violation fixed in PR #2000 (#1993)

    @steilerDev steilerDev committed Aug 4, 2026
  • docs(api-contract): fix LLM_NOT_CONFIGURED gate flag name + ADR-034 deviation log API-Contract.md: two LLM_NOT_CONFIGURED error rows still said 'autoItemizeEnabled is false' after the #1917 gate switch to llmEnabled. ADR-034 Deviation Log: the gateway-path-references row incorrectly stated Security-Audit.md was NOT updated; security-engineer reviewed and approved those path updates in the same PR. Co-Authored-By: Claude product-architect <noreply@anthropic.com>

    @steilerDev steilerDev committed Aug 4, 2026
  • docs(wiki): follow the budgetExtraction -> llmGateway rename (#1917) The #1917 rename of `server/src/services/budgetExtraction/` to `server/src/services/llmGateway/` left live path references on the pages owned by product-architect. Updated: - ADR-034 content-layers addendum (LLM gateway reuse note) - API-Contract.md `REPORT_CONTENT_LIMITS` and `REPORT_CONTENT_SYSTEM_PROMPT` source-of-truth pointers Historical Deviation Log rows keep their then-current paths deliberately. Security-Audit.md L1567-1568 still reference the old path; that page is owned by security-engineer and is left for them. Refs #1917 Co-Authored-By: Claude product-architect <noreply@anthropic.com>

    @steilerDev steilerDev committed Aug 4, 2026
  • docs(wiki): fix budgetLines scope, ADR-034 width rule and module table (#1914) API-Contract.md: - Correct `invoices[].budgetLines[]` from "all ibl lines per invoice" to source-scoped, and drop the unconditional "even portion 0" claim (claim reports skip zero-contribution lines). - Add a "Budget Line Scope" note: the array is a subtraction basis, not an inventory, and `isSplit` is the only answer to multi-source funding. - Deviation Log row. ADR-034: - Replace minimum-bar rule #1: `_minWidth <= 515.28` was a mis-transcription of B2's diagnostic into a correctness check. Correct checks are `max(positions[].horizontalRatio) <= 1` and the `_calcWidth` sum. - Rewrite the module table: add `pageGeometry.ts` and `index.ts`, drop the formatters and geometry constants from `shared.ts`. - Correct the override-key list against `overrideKeys.ts`. - New section "Unbreakable rows are silently dropped" with the bound-the-rendered-cell rule and two detection recipes. - New "injection is the only channel" subsection: four locale invariants, a grep guard, and the known open `merge.ts` footer violation. - Strengthen the labels rule in the content-layers addendum. - Six Deviation Log rows. Refs #1914 Co-Authored-By: Claude product-architect <noreply@anthropic.com>

    @steilerDev steilerDev committed Aug 4, 2026
  • docs(adr-034): correct per-row footnote claim — legend entries are document-level and deduplicated (#1965)

    @steilerDev steilerDev committed Aug 3, 2026
  • docs(adr): align ADR-034 monetary-unit invariant with the shipped rounding Records the final round-the-sum step and the parts-must-add-up-to-the-whole rule for per-invoice amounts handed to the generator (PR #1916 round 2). Co-Authored-By: Claude product-architect (Opus 4.6) <noreply@anthropic.com>

    Frank Steiler committed Aug 1, 2026
  • docs(api): document POST /api/source-reports/generate-content and llmEnabled - API Contract: full request/response/error spec for the AI report-content endpoint (story #1901), two-tier length caps, llmEnabled vs autoItemizeEnabled guidance, and the LLM-configured gating note. - ADR-034: add two addenda — report-language decoupling from the UI locale (#1899) and the baseline -> AI -> user-overrides content layering (#1900, #1901), including the major-currency-unit invariant across the AI seam. Co-Authored-By: Claude product-architect (Opus 4.6) <noreply@anthropic.com>

    Frank Steiler committed Jul 31, 2026
  • docs(adr): add ADR-034 client-side report PDF generation Documents the decision to generate bank report PDFs in the browser (pdfmake for authoring + pdf-lib for merging fetched Paperless invoice PDFs) rather than server-side (puppeteer/pdfkit), the ~2MB lazy-chunk and Roboto-only trade-offs, the pdfmake 0.3.x constraints pinned by loader.test.ts, and the real-render testing requirement derived from the PR #1887 review findings B1-B5/M4. Owed from PR #1887 review finding B6. Co-Authored-By: Claude product-architect (Opus 4.6) <noreply@anthropic.com>

    Frank Steiler committed Jul 30, 2026