feat(orders): log the client price figures the server discards (MON-08)
Step 2 of the owner's MON-08 ruling. An app order is priced by the server (steps 1, 3, 4 landed with the wage-formula work), but the client's own wagePercent, discountPercent and flatRialCharge were being thrown away in silence — so a stale app build, a promotion that expired between the product page and checkout, and a deliberately tampered request were indistinguishable and left no trace anywhere. They are now logged with both numbers, the same pattern already used for the body's customerId. The pricing itself is untouched: the server's figures are what the order is charged, and an operator ordering from the panel still keeps the numbers they typed. Also adds the comparison test the ruling asked for, which step 3 never actually had — the suite only proved a tampered request gets overridden. The new test places one honest order as a customer and the same order as an operator and asserts the totals are identical, which is the real claim: an ordinary customer's total does not move. Two more cover the logging, including that an honest order logs nothing — so the quiet case cannot pass merely because the method never ran. Closes STUB-05 in the docs as well: the reference's six hardcoded staff numbers have been behind PROFILE_ADMIN_MOBILES / ORDER_ADMIN_MOBILES for a while, but its status still read "pending". api: 286/286 tests, 26 suites, typecheck clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
83e5d2868b
commit
fd9191eca8
@@ -829,3 +829,50 @@ sales-expert 33/33 · name trigger 9/9 · typecheck clean on all four apps.
|
||||
table was written.
|
||||
|
||||
_No data was deleted in this entry._
|
||||
|
||||
---
|
||||
|
||||
## 2026-10-12 — Phase 2 — item #1: MON-08 step 2 (the discarded client price is now logged)
|
||||
|
||||
- **What:** `OrdersService.warnOnPriceMismatch` — when an app order is priced by
|
||||
the server and the client had sent different figures, the difference is logged
|
||||
(`wagePercent sent=… used=…`, same for `discountPercent`, plus any non-zero
|
||||
`flatRialCharge`). The order is still charged the server's figures; nothing
|
||||
about the pricing changed.
|
||||
- **Why:** step 2 of the owner's MON-08 ruling. Steps 1, 3 and 4 had landed with
|
||||
the wage-formula work, but the client's values were being discarded **in
|
||||
silence** — so a stale app version, a promotion that expired between the
|
||||
product page and checkout, and a tampered request were indistinguishable and
|
||||
left no trace at all.
|
||||
- **Reference:** `henza_server/app/Http/Controllers/Api/ApiMobileController.php:536-541`
|
||||
(debt computed from the request, nothing re-read from the DB);
|
||||
`henza_pwa/src/views/cart.vue:170-179` (the app computes all three).
|
||||
- **Target:** `apps/api/src/modules/orders/orders.service.ts` (the call site in
|
||||
the per-item map; the method beside `adminMobiles`).
|
||||
- **Matrix row:** MON-08 in `ISSUES.md` §"Phase 2 — item #1".
|
||||
- **Commit:** see below.
|
||||
|
||||
**Also added — the comparison test the ruling asked for.** Step 3 required «تست
|
||||
مقایسهای که نشان دهد نتیجه برای کاربر عادی یکسان است», and the suite did not
|
||||
have one: it only proved that a *tampered* request gets overridden. The new
|
||||
`"gives an honest app exactly the total it sent"` places the same honest order
|
||||
once as a customer (server-priced) and once as an operator (client-priced) and
|
||||
asserts the two totals are identical — which is the actual claim, that an
|
||||
ordinary customer sees no change. Two more cover the logging itself: the
|
||||
tampered order logs all three fields, and an honest one logs nothing (so a green
|
||||
"quiet" test cannot be green merely because the method never ran).
|
||||
|
||||
`orders.service.spec.ts`: 13 → 16 tests. Full api suite **286/286, 26 suites**,
|
||||
`tsc --noEmit` clean, and the run log inspected for swallowed errors.
|
||||
|
||||
**STUB-05 closed** in the same pass: the status still read "Pending the SMS
|
||||
approval" though `PROFILE_ADMIN_MOBILES` and `ORDER_ADMIN_MOBILES` had replaced
|
||||
the reference's six hardcoded staff numbers. No literal number is in the
|
||||
target's git history.
|
||||
|
||||
**Deliberately unchanged:** the target reads `rashWeightGrams` from the variant
|
||||
row rather than trusting the client, unlike the reference. Per the owner's
|
||||
earlier ruling this deviation stays, and it is re-recorded in `ISSUES.md` so it
|
||||
is not "fixed" later by someone restoring parity for its own sake.
|
||||
|
||||
_No data was deleted in this entry._
|
||||
|
||||
Reference in New Issue
Block a user