management: Berat (gram) input silently misreads 1.500 as 1.5 (same type=number defect as price) #59
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found by
Author43bwhile fixing the price-field blocker on PR #56, and correctly declined there as out of scope. Filing so it is not lost.The defect
Berat (gram)inapps/management/app/(dashboard)/stok/inventory-edit-form.tsxis still an<input type="number">, which carries the same misread that made the price field dangerous:1.500— ordinary Indonesian thousands formatting for 1500 g — is parsed by the browser as the decimal1.5, not1500.abc,1,500or a pasted value with a unit blanks the field, and aNumber(raw) || 0style coercion turns that into0.Why it is lower severity than the price case (and why it still matters)
Lower, because
weightGramsis not a published price: a wrong weight does not advertise a 1000×-wrong number to buyers, and PR #56 already bounded the field server-side with.int().positive(), so the trust boundary holds and the column cannot take a fractional or negative value.Still matters, because weight is what
docs/store-overhaul-spec.mdidentifies as the input to the ongkir question — "Ongkir. Buyer's first question. Needs item weight + destination." A weight silently stored as1.5instead of1500(or rejected to0) feeds a wrong shipping quote, which is settled over WhatsApp and therefore lands on the operator rather than being caught by the site.Fix
Reuse what PR #56 built rather than inventing a second parser. That PR replaced the price field with
inputMode="numeric"text plus aparseRupiahInputthat refuses anything which is not a digit run, marksaria-invalid, swaps the hint, and disables submit. Apply the same shape here:type="number"so the raw string survives and an emptied field stays distinguishable from unparseable input1.500is 1500 to a typist and1.5to the browser, so any rule that rescues one input silently misreads another.int().positive()as the guarantee; the widget is convenience onlyCheck whether the parser generalises cleanly — if it does, share it; if the unit differs enough to need its own bounds, say so.
Also worth checking in the same pass
Any other
type="number"field in the two inventory forms (add-inventory-modal.tsx,inventory-edit-form.tsx). This is the third instance of this misread found in this codebase, so audit rather than patch one field.Verification
1.500,1,500,abc, an empty string and a pasted"1500 g"in the real form against a real database; readweight_gramsback from Postgres each time and confirm no value was silently reinterpreted or zeroed.Acceptance
No weight input is ever silently reinterpreted or coerced to
0; invalid input is refused visibly; the server-side bound remains the guarantee; everytype="number"field in both inventory forms is audited and listed here.