Narong, on the Discounts & Promotions page: "let's show the Discounted Items." Each promotion card summarised its scope as a shop plus either its categories or All products — the rule, but not the effect. A merchant couldn't see which products a promotion actually discounts. No migration.
Every card now carries an "N items" chip that expands to the concrete products the promotion discounts. Karou chose count-plus-expandable over listing names inline — it stays compact when a promotion covers the whole catalogue and expands on demand.
A promotion is scoped by category (or applies to everything) — there is no per-item selection in the model. So the discounted items are the sellable products that scope resolves to: every product when it applies to all, otherwise the products whose category membership intersects the promotion's categories — the same test the POS apply-side uses. The list is drawn at the template level (the product names a merchant recognises) and limited to what's actually orderable at the till: a hidden or inactive product can't be sold, so it can't be discounted.


The screenshots are Lumière's real Buy 1 Get 1 Free promotion on the deployed staging Worker. It applies to all products, so its chip reads the whole sellable catalogue and its list is exactly those three products — matched name-for-name against the database at run time, never hardcoded.
The proof that it genuinely filters (rather than always showing every product) lives in the local suite, where a category-scoped promotion is checked to list exactly its category's products and nothing from the other categories, an all-products promotion to count the entire catalogue, and an empty category to read "No items" with its chip disabled. All three counts come from a database oracle, so the assertion fails loudly if the fixture ever stops discriminating.
| Suite | Result |
|---|---|
| Local — all-products counts the whole catalogue, a category promo lists exactly its products (no leak), an empty category reads "No items"/disabled, one panel open at a time | 6/6 |
| Staging — the deployed Worker resolves Lumière's real promotion to exactly its products | 3/3 |
| Staging smoke | 5/5 |
tsc --noEmit (nix-cafe) | clean |
nix-cafe staging 7e5a0ec (Worker 5c5dbdf7) · localization main
a192e7e (three strings; km falls back to English until Narong fills it). No migration.
Parked for the scheduled prod promote.