T 090
uid: T-090 title: Vendor-invoice display name β add vendor_invoice branch to the enricher status: done area: accounting-display created: 2026-06-21 updated: 2026-06-23 related: I-003
Why (owner, 2026-06-21, verbatim via I-003)¶
"a) Why is it that the display name for Vendor invoice didn't work on 8DX0qDUm5UuePIMVaPoK"
I-003 is the symptom record (tx 8DX0qDUm5UuePIMVaPoK, Birdie Mobile, invoice 1447641076). This
task is the structural fix on top.
Root cause (from I-003)¶
enrichTransactionDisplayName's linkedRecordType resolution chain in
lib/accounting/transactions.ts has no vendor_invoice branch. A vendor-matched tx (gl.{code}.
matchedFingerprint set, vendor invoice linked via receiptIds + gl.{code}) resolves to
linkedRecordType = null because it's not WOPC/workspace/gcp, matchedReceipts is empty (the V1
adapter derives it from gl.receipts, not receiptIds), and it's not GL 6400. With null, the
vendor_invoice doc-type template is never fetched and the name falls back to GL 6010's own template
(which references the GCP-only {{gcpInvoiceNumber}} token, leaving the invoice number blank and the
| separator dangling β [6010 - Telecommunications] Birdie |).
Fix¶
Add a vendor_invoice branch to the linkedRecordType chain, keyed on
transaction.expenseMetadata?.matchedFingerprint (the vendor matcher's signature, written by
applyVendorLink in lib/accounting/matching/vendorMatch.server.ts), placed before the generic
receipt check so a vendor invoice isn't mis-classified as a plain receipt. vendor_invoice is
already in the DocType union + token whitelist (payee, merchant, merchantCategory, invoiceNumber,
accountName, accountCode), so the existing template renders correctly with the tokens already on the
tx β no template / type / data change needed beyond the enricher branch.
Decision log¶
2026-06-21 β opened + fixed in commit 19e83136¶
- β
Attestation (Accounting (Diagnostics)): read
AGENTS.md(tip2d64e9fc); scope-scanned the board β new scope. T-029 / T-031 are vendor-invoice matching / editing, not display-name rendering. - Source: Accounting (Diagnostics) Β· https://claude.ai/code/session_01G58Y71noihrYCDEDMexmea
- What changed: opened T-090 + ticket I-003; recorded the root cause (verified against live tx
8DX0qDUm5UuePIMVaPoK+ the liveaccounting/settings/docTypestemplates). - Proposed by: the owner (reported the symptom). Approved by: the owner β "proceed with your plan please" (2026-06-21).
- Evidence β owner, 2026-06-21 (verbatim):
"a) Why is it that the display name for Vendor invoice didn't work on 8DX0qDUm5UuePIMVaPoK"
2026-06-21 β scope narrowed (split out the receipt-modal regression)¶
- β
Attestation (Accounting (Diagnostics)): read
AGENTS.md; scope-edit, not adding scope. - Source: Accounting (Diagnostics) Β· https://claude.ai/code/session_01G58Y71noihrYCDEDMexmea
- What changed: the originally-bundled fix (b) (Records receipt-modal double-click regression)
moved to a new task T-087 with its own ticket I-004 on branch
claude/records-modal-regression-bN3pZ(PR #779). T-090 now scopes to fix (a) β the vendor-invoice display-name enricher branch β only. Cross-link: I-003 β T-090 (this task); I-004 β T-087 (sibling). - Why split: owner directive β "split the symptoms differently" + chose "Two new tickets, two tasks" (2026-06-21). Tickets-are-symptoms, tasks-are-deliberate-work (the AGENTS.md "Tickets" rule) is cleaner with one ticket per distinct symptom + one task per fix.
- Branch effect: force-pushed
claude/records-display-fixes-yxMLMto drop the fix-b commit (8b0f8f33); that commit is cherry-picked + re-attributed to T-087 on PR #779. Force-push is safe β the branch is mine, the PR is draft, no upstream consumers. - Tickets-rule miss + correction: I-003 / I-004 should have been opened before the structural task per AGENTS.md β "Tickets" (escalation rule). I missed it on first pass; the owner caught it ("Should you have created and log any I-xxx issue as a ticket per the AGENTS.MD's rules"); both tickets opened retroactively as part of this split.
- UID note: this task was originally opened as T-084 (nightly's
READMEnext-free at the time). PR #775 (WOPC restructure) holds T-085 + T-086; PR #779 holds T-087.
2026-06-22 β renumbered T-084 β T-090 (collision; renumber-on-merge rule)¶
- β
Attestation (Accounting (Diagnostics)): read
AGENTS.md; renumber, not a scope change. - Source: Accounting (Diagnostics) Β· https://claude.ai/code/session_01G58Y71noihrYCDEDMexmea
- Why: while this PR (#777) was in draft, another agent's T-084 (cronβDSM migration) merged to
nightly. Two different T-084s β a guaranteed merge conflict on
tasks/T-084.md. Renamed this task's file + frontmatter + the I-003 cross-link + the in-code[T-084]marker inlib/accounting/transactions.tsto T-090 (free past every in-flight PR). README next-free bumped to T-091. Commit messages on this branch keep the original "t-084a/t-084" text (immutable history). - Rule (owner-approved, 2026-06-22): "Renumber on merge, per PR" β whoever merges second rebases and renumbers their task/ticket to the real next-free. This is the first application.
2026-06-23 β DONE (audit close-out)¶
- β
Attestation (Accounting (Diagnostics)): read
AGENTS.md; status-audit close-out, not new scope. - Source: Accounting (Diagnostics) Β· https://claude.ai/code/session_01G58Y71noihrYCDEDMexmea
- Verdict: the enricher fix shipped β commit
19e83136(vendor_invoice branch inenrichTransactionDisplayName), merged via PR #777. Confirmed live onmain:lib/accounting/transactions.tsresolveslinkedRecordType = 'vendor_invoice'ontransaction.expenseMetadata?.matchedFingerprint(lines ~976-977). Status was left ondoingafter merge; flipped todonehere. - Blast radius: display-name enrichment only; a vendor-matched tx now renders its
vendor_invoicedoc-type template instead of falling back to GL 6010's GCP-token template. No matching/data change. Symptom record I-003 (tx8DX0qDUm5UuePIMVaPoK) is the verification case.