"This is like Transactions level not Settings. So like, if an Order has 1 Free Iced Latte in it (and what order it belongs to), then the Iced Latte should show there and reason would be like BOGO or Staff Manual Discount or Reward Coupon Used. This is a table we can use to track down what has been discounted, the money that was deducted from the Original Sales."
One row per discounted order line — what was given away, why, and the money it took off the sale. Getting there needed more than a screen: the database could not say why a line was discounted, so this slice adds the attribution, fixes two real bugs found on the way, and moves the promotion setup page back to Configurations.
A discounted line stored an amount and a free-text copy of the promotion's name. That name is mutable and non-unique, it was always empty for manual discounts (the till nulled it on purpose), and the percentage was thrown away once resolved to dollars. "Free Item vs Discount" was not stored at all — and it cannot be inferred, because a BOGO that frees 1 of 3 units is arithmetically identical to a 33% discount.
So each line now records the promotion it came from, a stable reason code, how many units were actually free, and the rate applied. The code is a plain string rather than a fixed database enum specifically so that Happy Hour or Membership can be added later without another migration.
Two real bugs surfaced while doing this — both fixed here.
Lumière had no discounted lines at all, so the ledger could only ever have shown its empty state. The test rings a
real order through POST /cafe/api/cafe/orders — the same endpoint the till posts to — and then asserts
the ledger lists it. A hand-inserted row would only have proved the read query.


The manual row is the one that was impossible before this slice — its reason was stored as null, so it could only ever have rendered as a blank cell.
Every row carries Completed, Voided or Refunded, and the four metric tiles deliberately count Completed only — voided and refunded rows stay listed as the audit trail. The tiles say so on screen, because otherwise the numbers simply look like they disagree with the rows underneath.
Status is derived per line, not per order: a partially-refunded order contains both refunded and still-completed lines, and only the refunded one should drop out of the totals. (Voided has no equivalent state in the product yet; it is mapped so it works the day one exists.)
One thing worth a decision. A whole-order manual discount has no line, no item and no quantity, so it cannot be an item row. Rather than drop it silently — which would under-report the very thing this screen exists to show — the total is disclosed beneath the tiles. It is not a rounding detail: on the local dataset it is $414.61 of order-level discount against $890.34 itemized.
The Point of Sale slot is transactions, not settings, so the promotion setup returned to Configurations → Discount & Loyalty → Discounts where it started. Its nav gate also changed: the ledger is a multi-day financial history, so it now uses the same permission as Sessions and Refunds rather than the settings permission — which would have both exposed it to anyone who can edit settings and hidden it from a manager who reads every other report.


| Suite | Result |
|---|---|
| Local — attribution, Free-vs-Discount, per-reason rendering, the status rule, every filter, the nav move in both directions, and that deleting a promotion keeps sales history | 15/15 |
| Staging — a real order rung through the production route on the deployed Worker, then read back | 8/8 |
| Staging smoke | 5/5 |
tsc --noEmit (nix-cafe) | clean |
Expected values come from independent SQL run against the database at test time, never from re-implementing the page's own logic. The load-bearing rule was checked by breaking it on purpose: making the totals count every status failed exactly three assertions with precise numbers, and restoring it returned the suite to green. Free-vs-Discount is asserted on the 1-of-3-units BOGO case — the one that is arithmetically identical to a percentage — and the refunded row is proven to be listed but not counted, which a ledger that simply hid refunded rows would not satisfy.
nix-cafe staging cd3c637 (Worker 19f29e90) · nix-OS-backend dev
c76a78c · localization main cfbd603.
Migration 20260726120000 — additive, no backfill; rows predating it read "—".
Applied to staging; joins the scheduled prod promote.