feat(reports): wire report column visibility toggles through to the generated PDF (#1973) - #2010
Conversation
…enerated PDF Generalizes overviewPdf.ts from 2 hardcoded table shapes to the full 96-legal-subset geometry engine driven by a single column-visibility derivation (client/src/lib/reportContent/columns.ts) consumed by both the editor UI and the PDF builder. Adds per-run hiddenColumns wizard state that resets on use-case change and is never persisted server-side. Locks the Allocated Amount checkbox and introduces the shared .bannerWarning class. Removes the superseded columnVisibilityHint string. Fixes #1973 Co-Authored-By: Claude dev-team-lead <noreply@anthropic.com> Co-Authored-By: Claude frontend-developer <noreply@anthropic.com> Co-Authored-By: Claude translator <noreply@anthropic.com> Co-Authored-By: Claude qa-integration-tester <noreply@anthropic.com> Co-Authored-By: Claude e2e-test-engineer <noreply@anthropic.com> Co-Authored-By: Claude ux-designer <noreply@anthropic.com>
|
[ux-designer] Verdict: APPROVED Design-system review of PR #2010 against the visual spec I posted on issue #1973 (comment 5196838267). (Note: posted as a regular comment, not a formal PR review — 1. Locked Allocated Amount checkbox (AC 2.2) — matches spec
2.
|
|
[product-owner] Verdict: APPROVE (requirements coverage / acceptance criteria)Reviewed against #1973 rev 3 (re-read in full, including my own amendment log — the R- and AC-numbering was reassigned in the rev 1 → rev 2 rewrite, so this walk is against the current body, not memory). 8 groups, 33 criteria walked individually at 28 satisfied, 5 partially satisfied (all Medium, non-blocking), 0 functional gaps. Two of the "partial" items are errors in my own AC text, not in the implementation — corrections are on me and are listed at the bottom. The four criteria I flagged up front as most likely to be quietly unmetAC 1.3 — grep verified myself. AC 2.1 — the round-1 fix is real and complete. AC 4.5 / 4.6 — tiers asserted per tier; 4.5's all-96 half is short. AC 4.6 is fully met and is the best-tested part of the PR: Tier 1 asserts the exact summary row array; Tier 2 asserts the label lands in the AC 4.5 is the short one: the 96-subset loop in the AC 6.1 — verified the test's form, not just its existence. The legend is unconditional in the production path: AC 6.2 — the 4-combination matrix is asserted in both the unit test and E2E (all three viewports). The banner is a sibling of the toggle group with AC 8.1 — both new keys ( AC 2.4 / 3.x / 4.x — real enumeration, not sampling
AC 2.7 gets the strongest available treatment: beyond the doc-definition check, R6 — Status was not smuggled inConfirmed clean, three ways: AC 7.4 — full E2E result (this is now knowable)The PR body sets the triage framework up correctly — it states the hazard, names the prior-beta baseline (#2007's shard 10/16 The run has since completed. On Non-blocking findings (Medium — fix before merge or in refinement)M1 — AC 4.1's second half is unasserted. The 96-subset loop checks the header row's cell count but never "each header cell's text equals the expected label for that column in order." A M2 — AC 4.2 excludes continuation rows by construction. The all-96 loop's own comment says "no continuation rows possible with this short fixture text," and the existing continuation-row tests (scenarios 9–11) run with no M3 — AC 4.5's all-96 label assertion. As above. M4 — AC 3.3's "otherwise Vendor" half is unasserted. The 72-subset test only asserts M5 — AC 7.4's reporting half is still open on the PR body. The body says results "will be appended here once the full E2E run completes." They have. Append the green-across-all-16 result (and note that the #2007 shard-10 baseline did not recur) so the criterion is closed on the artifact the AC names, rather than only in this review comment. Low / informationalL1 — AC 6.3 asserts a proxy. The test compares skip-footnote output with and without Usage hidden, not the set of embedded documents. Combined with L2 — German quotation marks in Corrections I owe on #1973 (my errors, not this PR's)AC 4.6's "92 subsets" figure is wrong. The correct partition is Tier 1 = 88, Tier 2 = 4, Tier 3 = 4. The 92 came from AC 5.3's "leaving and re-entering the step" clause over-reaches R5. The implementation resets Merge gate vs Done gateEvery acceptance criterion here is machine-checked, including the degenerate single-column case through real pdfmake — so nothing blocks the merge on a human check. But two outcomes are stated by my rulings and pinned numerically by tests without anyone having confirmed they look right in a real bank document:
The geometry is provably within bounds and the placement is provably present, which is what the ACs asked for. Whether either reads as a valid funding document to a recipient is a visual judgment no assertion can make. So: merge on the code gate; #1973 goes to UAT for a visual check of those two states before it moves to Done. If UAT rejects either, reopen #1973 rather than filing a follow-up — the ruling would be the thing that was wrong, not the implementation. Board: #1973 stays In Progress through UAT, not Done-on-merge. |
|
[product-architect] Architecture review — PR #2010 (#1973) Read: issue #1973 rev 3 (R1–R8, AC 1.1–8.1), the full diff (27 files), Verdict: CHANGES REQUESTED — one HIGH finding, and it is documentation, not codeThe engineering here is genuinely good, and I have no correctness objection to the geometry engine, the clamp, the module boundary, or the state placement. The blocker is that this PR deletes an architectural constraint that ADR-034 currently states as a prohibition, and touches no wiki file. HIGH — ADR-034 still says this feature is impossible, and this PR does not update it
Every clause of that paragraph is now false: the column count is 1–7, the toggles are not preview-only, and — the interesting part — no re-measurement was needed, because hiding a column only ever widens Usage and This is squarely CLAUDE.md's Wiki Update Discipline ("decision → ADR-NNN + ADR-Index, in the same PR"). Please add to this branch:
No Answers to the five questions you asked1. Is the absorber the right mechanism, and is it robust to a future column? Yes, and it is the only one of the three plausible mechanisms that satisfies R7 as written. On robustness, the forcing functions are asymmetric and worth knowing:
2. The one-sided clamp. Correct as implemented and correctly asymmetric. 3. Module home. Right home, right direction. 4. State placement. Endorsed, and the reasoning in R5 holds up under review: no network dependency in a step that currently has none, no inheritance of #1955's race or #1972's silent-save failure, and 5. ADR / wiki. ADR-034 amendment required (the HIGH above). No new ADR, no Schema/API-Contract change. MEDIUM — non-blocking, but worth fixing in this roundM1 — AC 4.2's continuation rows are named by the AC and never exercised under a hidden-column subset. Both enumeration fixtures use short Usage text; the tests say so ("no continuation rows possible with this short fixture text"). Continuation rows are a different code path from content rows ( M2 — AC 4.5 asks for the label at all 96 subsets; only 6 are covered. The all-96 loop ( M3 — the tier-3 summary block is not width-constrained, so on M4 — const COLUMN_ORDER: Record<ReportColumnKey, number> = { vendor: 0, invoiceNumber: 1, date: 2, status: 3, invoiceAmount: 4, allocatedAmount: 5, usage: 6 };
const ALL_COLUMNS = (Object.keys(COLUMN_ORDER) as ReportColumnKey[]).sort((a, b) => COLUMN_ORDER[a] - COLUMN_ORDER[b]);
const CLAIM_COLUMNS = ALL_COLUMNS.filter((c) => c !== 'status'); // R6Same class, softer, in LOW / informationalL1 — AC 4.6's "92 subsets" for tier 1 is arithmetically wrong, and the test title copies it. Tier 3 is 4 subsets; tier 2 ( L2 — record why the clamp returns exactly 650 at the reference width. L3 — L4 — AC 5.3's "leaving and re-entering the step" is implemented as per-run persistence, and I think that is correct. L5 — the AC 1.3 test name overstates its guard. L6 — What I verified as correct and am not asking you to change
Re-request me once ADR-034 is updated on this branch (with the submodule pushed and the parent ref bumped). The M/L items are yours to take or defer; none of them blocks. |
|
[product-owner] Follow-ups filed — none expands this PRPer the coordinator's ruling that a green PR is not to be reopened to absorb non-blocking findings, the review findings are now issues. All four are on the board in
M5 is closed — the PR body now carries the E2E determination. On why M3 slipped, since it is worth not repeatingR7 (table geometry when no free-form column is visible) and R2 (summary-label placement when no leading cell exists) were written separately, in different revisions of #1973, against different problems. Neither anticipated that the same degenerate subsets fire both: R7 makes the table narrow, R2 moves the total out of it, and the interaction — a narrow table under a full-width block — was stated by neither. The generalisable rule, recorded on #2011: when a ruling introduces a new element outside an existing element's geometry, state its width relationship to that element explicitly. Two rulings that each constrain a different element can produce an unstated third outcome wherever their triggers coincide. #1973's dispositionRecorded on the issue (#1973): it stays In Progress pending UAT on merge, not Done, for R7's narrow table and R2's tier-3 block. #2011 is a live candidate for that UAT rejection, so the two are separated there — a width rejection is #2011, a design rejection ("the total should not have left the table at all") reopens #1973, because then the ruling was what was wrong. |
…i pointer Review-round follow-up on #1973. ADR-034's "geometry constraint that blocks a feature" prohibition is removed and replaced with a computed-engine section, including the fact that no re-measurement was needed because USAGE_WIDTH_7COL is provably the narrowest Usage width across all 96 column subsets. Architecture.md gains a new section on the wizard tier-factory convention. The overviewPdf.ts clamp doc comment is corrected: an earlier draft claimed a fractional pinned width would make Math.floor start returning 649, but exhaustively testing all 720 orderings of the six pinned widths against 8 fractional candidates in each of 6 positions shows the sum is order-independent at these magnitudes. The comment now documents the real fragility instead: USAGE_FIXED_SUM_7COL / USAGE_FIXED_SUM_6COL are hand-written literal sums with no type-level tether to PINNED_WIDTHS or the column lists, so a future column change could update one without the other. Also corrects the packUsageCellRows throws-not-hangs note. Bumps the wiki submodule pointer (da1324b -> eb24774) to match content already pushed to origin/master, preventing beta from silently diverging from the remote wiki state. Refs #1973 Co-Authored-By: Claude frontend-developer <noreply@anthropic.com> Co-Authored-By: Claude product-architect <noreply@anthropic.com> Co-Authored-By: Claude product-owner <noreply@anthropic.com>
|
🎉 This PR is included in version 2.14.0-beta.14 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 2.14.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Summary
overviewPdf.tsfrom 2 hardcoded table shapes to the full 96-legal-subset column-geometry engine, so the PDF renders whatever combination of columns the preview allows.client/src/lib/reportContent/columns.ts(AC 2.1), consumed by both theReportContentEditorpreview toggles and theoverviewPdfbuilder — eliminating drift between what the user sees and what gets generated.hiddenColumnsstate to the report wizard reducer, reset whenever the use case changes (AC 5.1); never persisted server-side (AC 5.2) — every wizard run starts from the full column set..bannerWarningclass inshared.module.cssfor the wizard's warning banner.columnVisibilityHinti18n string, replaced by the locked-checkbox affordance.Fixes #1973
Test plan
columns.ts/columns.test.ts,overviewPdf.ts/overviewPdf.test.ts,wizardReducer.ts/wizardReducer.test.ts,ReportContentEditor.tsx/.test.tsx,merge.ts/merge.test.ts,realRender.test.tsAC 7.4 — E2E shard hygiene
This story adds 19 new E2E tests (
e2e/tests/budget/reportWizardEditableContent.spec.ts) across three viewports. New tests rehash Playwright's worker-hash assignment and can redistribute the whole suite across shards, so an unrelated shard going red is a live possibility on this PR — it must be triaged, not re-run past.Prior beta state (baseline, not this PR): PR #2007 (merged 2026-08-05) had shard 10/16 fail on
invoices/invoice-vendor-change.spec.ts:129[tablet], on both the initial attempt and the retry, withTimeoutError: locator.waitFor: Timeout 10000ms exceeded. Triaged as not caused by #2007 — that PR's diff is scoped entirely toreportContent/reportPdf/ReportWizardPage.tsx, nothing underinvoices/orvendors/. Unrelated to #1973 as well (different domain, different files). Logged in.claude/agent-memory/e2e-test-engineer/known-flakes-and-regressions.md.This PR's own shard results (final, head
b5b03bec): the full matrix completed green — 33/33 check-runs successful. All 16 E2E shards passed, plusE2E Gates,E2E Smoke Tests,E2E Cache Warmup,Merge E2E Reports, all 6 Jest shards,Static Analysis,Docker,Docker PR Release,Coverage ReportandTrailer Check.Determination: zero red shards. AC 7.4's triage obligation therefore resolves to "no shard to triage" — no re-runs were performed, and no shard was retried to reach this state. The redistribution hazard flagged above did not materialise despite the 19 added tests. AC 7.5 does not fire, since no latent cross-file hazard was surfaced.
The prior-beta finding recorded above (PR #2007, shard 10/16,
invoices/invoice-vendor-change.spec.ts) did not recur on this run — shard 10/16 passed here. It remains logged as an open single-occurrence flake for whoever next touches that spec; it is not evidence about this PR either way.Co-Authored-By: Claude dev-team-lead noreply@anthropic.com
Co-Authored-By: Claude frontend-developer noreply@anthropic.com
Co-Authored-By: Claude translator noreply@anthropic.com
Co-Authored-By: Claude qa-integration-tester noreply@anthropic.com
Co-Authored-By: Claude e2e-test-engineer noreply@anthropic.com
Co-Authored-By: Claude ux-designer noreply@anthropic.com