T-134 β Records page + Employer's Returns (IR56M) tab overhaul¶
Why this exists¶
Owner-requested batch of UX/structure changes to the Records page and the IR56M ("Employer's Returns") tab, dumped across several messages on 2026-06-29 while reviewing the freshly-deployed app. Captured here so the interdependent pieces build in a sensible order instead of piecemeal.
Workstreams¶
A β Distribution settings modal (components/ir56m/IR56MDistributionEditModal.tsx + kebab)¶
- Remove the redundant "Distribution" text (the modal/section already says it).
- Stop showing the read-only notice ("The completed email has already been sent β these settings can no longer be changed."). Instead hide the settings AND the "Distribution settings" kebab item entirely once the IR56M is awaiting-signature / sealed / archived. β This rolls back the "editable after signing on both tabs" behavior from T-047 #5d: distribution becomes set-only-at-sign-time. (Owner's explicit wording; flagged as a deliberate reversal.)
B β Tab title row (components/records/RecordsApp.tsx)¶
- Rename the Receipts parent tab β "Receipts & Service Invoices" (inactive label).
- When selected, hide the grouped name and show "Receipts (x) | Service Invoices (x)" (the active-expand-to-subcounts pattern already exists for this tab β extend the label).
- Add an expand/collapse animation to that label transition.
- Merge Project Invoices + Coaching Invoices into one parent "Project & Coaching Invoices" with sub-tabs, applying #2 + #3 (inactive = grouped name; active = "Project Invoices (x) | Coaching Invoices (x)" + animation). RBAC: Project = ERL, Coaching = MEL β parent visible if the user can see either; each sub-tab gates to its own subsidiary.
- Reorder top-level tabs β Project & Coaching Invoices | Receipts & Service Invoices | WOPCs | Bank Statements | Employer's Returns.
- Rename the IR56M tab β "Employer's Returns" (owner wrote "Employment's Returns" β interpreting as the standard term; IR56M is an employer's return).
C β IR56M 7-state lifecycle (extends T-047 / I-018)¶
Replace the vestigial draft|confirmed|signed|filed enum + mirror the full lifecycle
onto the filing doc (the I-018 mirror already shipped for draftβsigned). Locked labels:
| key | display | colour | set when |
|---|---|---|---|
draft |
Drafted | grey | filing exists, configured FY not fully closed |
awaiting_director |
Assign Signing Director | red | configured FY fully closed, no director |
ready_to_send |
Signature Required | gold | director assigned, not sent |
awaiting_signature |
Awaiting signature | blue | sent to director |
rejected |
Rejected | volcano | director declined |
sealed |
Sealed | green | signed & sealed |
archived |
Archived | purple | completed copy distributed / fully settled & turned in |
- Window = the user-configured fiscal year (not the fixed 1 Aprβ31 Mar YA). Re-key the
draft β awaiting_directorgate to "configured FY fully closed." - Re-open + figure changed β jump back to
ready_to_send(keep director, void old copy). - Manual "fully close FY" gate + any further confirmation status β deferred to T-133.
- Collapse the Records tab's two status columns ("Status" + "Signing") into this one.
D β Employer's Returns tab: row selection + batch download¶
Mirror the Project Invoices tab selection behaviour (select + download + right-click menu) on the IR56M tab: - The collapsed FY (group) row is clickable + selectable; selecting an FY row = "all IR56Ms under that FY." - Support mixed selection: a whole FY row + individual recipient IR56M(s) inside expanded FYs, selected together. - Download = all signed IR56M PDFs across the selected FYs + individual rows (batch ZIP, reusing the records batch-download popup).
Build order (by dependency + risk)¶
- C (lifecycle) β foundational: A's hide-condition + the tab status column key off it.
- A (distribution modal) β uses C's statuses.
- D (selection + batch download) β self-contained to the IR56M tab.
- B (tab row) β self-contained top-level restructure (riskiest merge; do last so the IR56M-internal work isn't churned by it).
Decision log¶
2026-06-29 β β Read AGENTS.md before opening this task. Source: Records (Infrastructure) Β· https://claude.ai/code/session_018RDB37kCqfouHdygVXTAtD
Owner dumped the spec across several 2026-06-29 messages (distribution modal β tab row β
IR56M selection/download), plus the earlier locked 7-state lifecycle. Two interpretations
pending owner confirm: (1) "Employment's Returns" β "Employer's Returns"; (2) A#2 is a
deliberate rollback of T-047 #5d's after-signing editing. Awaiting a single "go" before
the multi-part build (touches shared RecordsApp.tsx + audit-critical IR56M code).
2026-06-29 β owner refinements (round 2)¶
Source: Records (Infrastructure) Β· https://claude.ai/code/session_018RDB37kCqfouHdygVXTAtD
- "Employer's Returns" CONFIRMED (B#6).
- WOPC batch-download filename β DONE this round (commit
2ef5733b): a sealed refERL-WOPC/2024-001produced a ZIP entry with a/, nesting the file under anERL-WOPC/folder and dropping the<sub>-WOPCprefix. Flattened/β_centrally inrecordsBatchPopup(+ the WOPC filename builder). Not a workstream item β standalone bug. - D additions: (a) double-click a YA (FY) group row β expand it; (b) IR56M download
filename =
<subsidiaryId>_IRD_IR56M_<FY>_<lastName>_<firstName>_<YYYYMMDD>(e.g.ERL_IRD_IR56M_FY24-25_Chan_Jeffero_20260629; date = download day). - C lifecycle revisions:
- Blink every status tag EXCEPT
SignedandArchived(CSS pulse). - Archived = the FY is manually closed β render the tag and the entire YA row greyed out. β οΈ Trigger = the manual FY-close gate, which is T-133 (currently deferred) β so Archived isn't reachable until T-133 ships (see open question below).
- New state "Cooling Off" for a sealed IR56M inside the regret/cooling-off (grace)
period. OPEN QUESTION (blocking C): the owner's confirm-list of 7 states does NOT
include "Cooling Off", so its placement + colour are unresolved. Working hypothesis:
Awaiting signature β Cooling Off (signed, regret window open; distribution editable; blinks) β Signed (regret elapsed/sent; no blink; distribution locked) β Archived. Needs owner confirmation before building C. - A#2 hide-rule REVISED: hide the "Distribution settings" kebab item ONLY when the status is Signed or Archived (not the earlier "awaiting-signature/sealed/archived"). So distribution settings stay editable through Cooling Off β consistent with the regret window β and lock once Signed/Archived.
- Cooling Off placement CONFIRMED (owner, 2026-06-29): conditional on the signing
director's choice β regret window chosen β
Awaiting signature β Cooling Off β Signed; send-immediately βAwaiting signature β Signed(Cooling Off skipped). Maps to the distributiongraceMode(gracevsimmediate).
2026-06-29 β first batch SHIPPED + deployed (merge/C-finish remain)¶
Source: Records (Infrastructure) Β· https://claude.ai/code/session_018RDB37kCqfouHdygVXTAtD
Merged to main (merge commit 2f895c9b, PR #820). β οΈ The 2f895c9b production
build FAILED (next build TS7006 β implicit any on the IR56M tab's AntD Table
callbacks; the sandbox's npx tsc missed it without the pinned TS + antd types). Prod
stayed on the prior good build (no breakage). Fixed by annotating the callback params
(ba730cbb, after npm ci + a faithful pinned-tsc check) β the redeploy of
ba730cbb is READY/live. Landed:
- WOPC batch-download filename /-flatten (2ef5733b).
- C inc 1 β derived 8-state IR56M status column (blink + Cooling Off split via the
distribution grace window) (1243d747).
- A β distribution modal: dropped the redundant "Distribution" text; the kebab
"Distribution settings" item shows only during Cooling Off (59b413b8).
- D β double-click a YA row to expand (4db54a8a); whole-FY + individual-recipient
selection + batch ZIP of signed IR56Ms, filename
<SUB>_IRD_IR56M_FY<yy-yy>_<Last>_<First>_<YYYYMMDD>.pdf (401c8533).
- B part 1 β IR56M tab β "Employer's Returns"; Receipts tab β "Receipts & Service
Invoices" with active sub-counts + expand animation (bd854760).
REMAINING (follow-up PR):
- B#4 β merge Project + Coaching into one "Project & Coaching Invoices" parent (the
high-risk multi-touch refactor: the tab IDs project-invoices/coaching-invoices are
referenced in ~6 places β deep-link remap, active-tab toolbar logic, csvExportableTabs,
keyboard shortcuts, the two selection stores, the activeTab effects β all must change in
lockstep) + reorder to Project & Coaching | Receipts & Service Invoices | WOPCs | Bank
Statements | Employer's Returns.
- C-finish β re-key the DraftedβAssign-Director gate to the configured FY; Archived
row-greying (needs T-133 manual FY-close); readjustβSignature-Required jump.
- Small: right-click menu on the Employer's Returns tab (Project-Invoices parity); the
AccountingβFilings distribution-gear cooling-off gate.
Blast radius (shipped): Records β Employer's Returns tab (status column, selection,
double-click), Receipts tab label, the IR56M distribution modal, and recordsBatchPopup
(new ir56m BatchKind + the central /-flatten β affects every batch download).
2026-06-29 β batch 2 (merge + WOPC sorting + C item) on PR #821¶
Source: Records (Infrastructure) Β· https://claude.ai/code/session_018RDB37kCqfouHdygVXTAtD
Built on a fresh branch off the live main; on draft PR #821, pinned-tsc clean AND
a local next build β Compiled successfully (the build phase that broke batch 1; the
non-zero exit was a sandbox-only Firebase-env false negative on the unrelated /v/[id]).
- B#4/B#5 β merged Project + Coaching β "Project & Coaching Invoices" (animated
sub-counts, in-place panes, RBAC-aware) + tab reorder; done via boundary edits (no
150-line block relocation) + a TAB_ORDER sort; all 8 tab-ID reference sites updated.
- WOPC tab (owner follow-up) β sortable Reference column (numeric-aware) + the WOPC
XLSX export ordered by ref number instead of issue date.
- C item 3 β readjust (figure changed on YA re-close) β a signed IR56M shows
Signature Required (signature stale, needs void + re-file).
Deferred to T-133 (need the manual FY-close infra): C item 1 (re-key the DraftedβAssign-Director gate to the configured FY β the current fixed-YA gate is the legally-correct salaries-tax window, so this is a refinement, not a bug) and C item 2 (Archived row-greying β Archived is unreachable until the manual FY-close sets it).
2026-07-01 β reconciliation β DONE (EOP Local Assistance board sweep)¶
Source: Records (Infrastructure) Β· https://claude.ai/code/session_018RDB37kCqfouHdygVXTAtD
Answering the fork's status question + adding the missing updated::
- PR #821 is MERGED and live in production. Its commits are in origin/main
(8e108cf7 merge Project + Coaching + reorder; f8f988b5 readjust β Signature Required;
c8d362e6 the batch-2 docs entry) and it deployed 2026-06-30 alongside I-020.
- Workstreams A / B / C / D β all shipped + deployed (PR #820 batch 1, live build
ba730cbb, + PR #821 batch 2). The owner reviewed the deployed result across the
2026-06-29β30 iterations.
- Only substantive remainder is carved into T-133 (todo): C item 1 (configured-FY
gate re-key) + C item 2 (Archived row-greying). Both need the manual FY-close infra, so
they are correctly NOT part of T-134.
- Two minor batch-1 "Small" follow-ups were NOT built β descoped (owner never
re-requested; reopen or spin a ticket if wanted):
1. A row right-click context menu on the Employer's Returns tab for Project/WOPC-tab
parity. The tab has selection + batch download + a click-kebab, but not the
trigger:['contextMenu'] row menu the Project/WOPC tabs use (RecordsApp.tsx
2571/2757 vs zero onContextMenu in IR56MFilingsTab.tsx).
2. The Accounting β Filings distribution-gear cooling-off gate. The gear exists
(IR56MFilingTab.tsx) and the Records-side distribution modal is already
Cooling-Off-gated; matching that visibility gate on the Accounting Filings gear was
never separately done.
Closing T-134 done β the owner-requested overhaul is delivered + live; the deferred
work is tracked in T-133 and the two residuals are minor, un-requested polish.