fix/cfdi-columns
needs attentionf88ee88 · incrementalpre-PRreviewed 2026-08-10 16:25 UTC0H · 1M · 1L- Purpose
- Fix CFDI fiscal concept display — surface stamp state and stop numeric coercion corrupting all-digit identifiers like SAT certificate numbers and meter IDs
- Goal
- CFDI XML concepts (uuid, satCertificateNumber, RFC, meter numbers) must display their raw string value, not a numeric parse that drops leading zeros or produces NaN
- Sub-goals
- SG-1: Parse and surface CFDI stamp fields from XML (sello, noCertificadoCfdi, etc.)
- SG-2: Stop decideColumnType from defaulting all line-item concepts to 'number' by deriving render type from catalog units
- SG-3: Stop transformBillToPresentation from preferring numericValue for text/date-units concepts
- SG-4: Backfill CFDI fiscal concept catalog rows by organization
- SG-5: ops-guards for safe DB migrations
- What
- This commit adds isTextualUnits() — a thin public wrapper around the private decideTypeFromUnits() — and threads it into transformBillToPresentation so that line items with units 'text', 'json', or 'date' use lineItem.value (the raw string) rather than lineItem.numericValue ?? value.
- Why
- satCertificateNumber stores '00001000000700926429' alongside numericValue:1000000700926429; preferring the number silently drops the leading zeros of a 20-digit SAT identifier. Same shape for any all-digit id (meter, barcode, folio).
- Areas
- domains/utility+189−6packages/database+78−0scripts+448−0services/utility/bills/cfe+327−1
- Blast
- 11 files, +1042/-7 across utility domain, database package, backfill scripts, and CFE XML parser. Latest commit is 3 files, +39/-2 (narrowly scoped to decisions + tests).
Findings · 2
tests2
No regression test for the actual bug in transformBillToPresentation
domains/utility/src/bill/__tests__/bill.shells.test.ts
The fix changes how transformBillToPresentation picks between numericValue and value for textual-units line items, but no test exercises this path end-to-end. Every existing fixture uses units:'MXN'. The motivating bug — satCertificateNumber with value:'00001000000700926429' and numericValue:1000000700926429 — is never asserted at the transformBillToPresentation level. Reverting the isTextualUnits call in bill.decisions.ts would not be caught by any test. Add a fixture with a text-units line item carrying both fields and assert the raw string is returned.
payment_status units omitted from the decideColumnType agreement test
domains/utility/src/bill-concepts-catalog/__tests__/bill-concepts-catalog.decisions.test.ts
The cross-check loop in 'agrees with decideColumnType' iterates ['text','date','json','MXN','kWh','count',null] but omits 'payment_status'. decideTypeFromUnits returns 'payment_status' for that value — a third outcome. The assertion still passes (false === false), so no bug is masked, but adding 'payment_status' to the iteration makes the contract explicit.