Skip to content

T 197


uid: T-197 title: Records WOPC tab polish (Type/Nature columns, drawer thumbnail) + reimbursement WOPC lifecycle fixes status: done area: accounting created: 2026-07-31 updated: 2026-07-31 owner: girafeev1 assignee: Records (Infrastructure) related: T-178, T-196, T-194


βœ… Read AGENTS.md Β· Records (Infrastructure) Β· https://claude.ai/code/session_018RDB37kCqfouHdygVXTAtD Β· checked the board (next free was T-197; no dup β€” this is Records-WOPC-tab display + reimbursement-WOPC lifecycle, distinct from T-178's pipeline and T-196's signer widening).

Five owner items (2026-07-31), grouped.

Group A β€” Records page β†’ WOPC tab display

  1. Drawer previewer β†’ thumbnail, side-by-side. The drawer (WopcDetailDrawer, RecordsApp) shows the WOPC in a full PDF <iframe> (/api/records/wopcs/pdf?ref= β†’ application/pdf), i.e. the browser's native PDF viewer with its function bar, stacked ABOVE the info table. Owner wants a thumbnail with the payee / total / issue-date / payment-date table side-by-side. (No PNG WOPC thumbnail endpoint exists β€” reuse the scaled HTML render, no puppeteer, no function bar.) DONE β€” new ref-keyed /api/records/wopcs/thumbnail (works for reimbursement WOPCs, which have no tx); drawer is now thumbnail + info table side-by-side.
  2. Columns. Rename 'Project' β†’ 'Nature'; add a 'Type' column (Sub-Contractor Fees / Reimbursement) immediately right of the reference-number column. DONE (type derived in the list serializer; new column + row fields).
  3. Nature for reimbursements. Today reimbursement WOPCs show β€” (they carry no projectSnapshot). Show, from the WOPC's line items: one receipt β†’ merchant + category Β· date; more β†’ "N receipts β€” mixed purposes". DONE.

Group B β€” reimbursement WOPC lifecycle (bugs)

  1. Can't remove a pending reimbursement WOPC. Records only voids Sealed WOPCs; Pending removal is punted to "unmatch the linked transaction" β€” but a reimbursement WOPC is built from receipts, not a matched transaction, so there's nothing to unmatch and it's stranded. Fix: a direct Remove for a pending WOPC with no linked transaction, and extend /delete to reopen its receipts (clear metadata.wopc.ref) β€” mirroring how it already clears the tx back-ref. DONE.
  2. Already-WOPC'd receipts stay selectable. The Reimbursements tab only disabled receipts awaitingSignature; an unsigned-reimbursement receipt (WOPC with no signer) kept a wopcRef but stayed pickable β€” so it could land on a second WOPC. Fix: disable + tag any receipt with a wopcRef. DONE (widened getCheckboxProps to !!r.wopcRef).

Key findings (map)

  • No WOPC type/purpose field β€” reimbursement is derived: notes === 'Reimbursement of out-of-pocket expenses' OR a line-item id starting reimbursement-. Derive in pages/api/records/wopcs.ts (list serializer) + thread onto WOPCRow.
  • Reimbursement receipt info lives in lineItems[] (one per receipt): description = merchant, itemSnapshot.feeType = "<category label> Β· <date>", amount. Present on the detail endpoint; must be added to the list row for the Nature column.
  • Reopen mechanism: patchParsedReceipt({ metadataFields: { wopcRef: null } }) reverses the issue-time backlink (wopcRef is a nullable metadata field).

Decisions (owner-confirmable)

  • Type labels: Sub-Contractor Fees / Reimbursement.
  • Nature multi-receipt text: "Multiple receipts β€” mixed purposes".
  • Committed receipts: disabled + labelled, not hidden (so they don't silently vanish).
  • Drawer thumbnail: reuse the existing scaled HTML render (no PDF toolbar), no new puppeteer endpoint.

Progress / SHAs (append-only, newest last)

  • fix(T-197): reimbursement receipts already on a WOPC are no longer re-selectable β€” item 5.
  • feat(T-197): remove a pending reimbursement WOPC + reopen its receipts β€” item 4. /delete clears each backlinked receipt's wopc.ref; the Records batch-remove offers a direct Remove for a pending WOPC with no linked transaction (was a dead-end). tsc + tests green.
  • feat(T-197): WOPC tab β€” Type column + Projectβ†’Nature + reimbursement receipt info β€” items 2 + 3. Type derived in the list serializer; new Type column + reimbursement Nature render (single receipt info / "N receipts β€” mixed purposes"). tsc + tests green.
  • feat(T-197): WOPC drawer β€” thumbnail + info table side-by-side β€” item 1. New ref-keyed /api/records/wopcs/thumbnail (scaled HTML render, no PDF toolbar; serves reimbursement WOPCs); drawer restructured to thumbnail | info-table. tsc + tests green. All 5 items done.

Source: Records (Infrastructure) Β· https://claude.ai/code/session_018RDB37kCqfouHdygVXTAtD