Problem
Same class of bug as #179 (injbAmount) and #171 (cpayAmount), on the
PurchaseOrderLine schema. Both polQty and polPrice are typed as
bare z.coerce.number(). zod's .number() rejects NaN by default
but lets Infinity / -Infinity slip through. The coerce path turns
the string "Infinity" into the float, so even via JSON (which has
no Infinity literal) a client can land non-finite values in either
column.
Both columns are Sequelize DOUBLE and will store inf happily.
An inf on a PO line silently corrupts every downstream
calculation: PO totals, inventory valuation, GL reconciliation.
Fix
Add .finite() via shared polQtyField + polPriceField validators.
Zero and negative values still pass — a $0 freebie line and a
negative inline-credit line are both real PO use cases.
Acceptance
Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/
Problem
Same class of bug as #179 (injbAmount) and #171 (cpayAmount), on the
PurchaseOrderLine schema. Both
polQtyandpolPriceare typed asbare
z.coerce.number(). zod's.number()rejectsNaNby defaultbut lets
Infinity/-Infinityslip through. The coerce path turnsthe string
"Infinity"into the float, so even via JSON (which hasno Infinity literal) a client can land non-finite values in either
column.
Both columns are Sequelize
DOUBLEand will storeinfhappily.An
infon a PO line silently corrupts every downstreamcalculation: PO totals, inventory valuation, GL reconciliation.
Fix
Add
.finite()via sharedpolQtyField+polPriceFieldvalidators.Zero and negative values still pass — a $0 freebie line and a
negative inline-credit line are both real PO use cases.
Acceptance
polQty: 'Infinity'/polQty: '-Infinity'polPrice: 'Infinity'/polPrice: '-Infinity'tests/api/purchaseorderline.test.jscover all of the aboveProudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/