Live on prod 2026-05-20. Three small unblocked carry-overs from the recent slices bundled into one Gate cycle. Each fixes a tracked caveat or footgun guard. No backend migration, no new deps.
0ccb15b) with three independent items. Item 2 (pgView guard) caught a
real regression in the Lumière demo seed script during the conversion — refactored
in the same commit. Test-side fix mid-Gate-2: variant-row testids are name-suffixed,
not plain — used prefix matcher.
aggregateRevenueByPosConfig + view SELECT against prod DBnull / [] / undefined all return same result on prodPRODUCT_VIEW_COLS nested projection both work/cafe/reports renders on Pro (no 5xx after the pgView conversion)/cafe/settings/attributes template list rendersvariant-image-url input + preview when http(s) URL pasted/cafe/reports renders| test-phase1-prod.mjs | 11/11 |
| test-phase2-sso-outdoor-prod.mjs | 6/6 |
| test-phase2-cafe-multishop-prod.mjs | 6/6 |
| test-m1-prod.mjs | 10/10 |
| test-r7-prod.mjs | 14/14 |
| test-r8-prod.mjs | 4/4 |







First prod run failed 5/12 — the variant-row interaction tests couldn't find any
variant row to click. Root cause: template-card testids on prod are
name-suffixed (template-toggle-${"${"}name${"}"},
template-variant-row-${"${"}defaultCode${"}"}), but my test used plain
prefix-only locators (data-testid="template-toggle" exactly). Fix:
switched to prefix matchers ([data-testid^="template-toggle-"]). After
fix: 12/12. No code change in nix-cafe — just test scaffolding.
Item 1 — Multi-shop Ranking of POS —
aggregateRevenueByPosConfig now accepts shopIds: string[] |
string | null. R1's "Ranking only filters when 0/1 shop selected" caveat is
gone. Dashboard + daily callers still pass single strings (back-compat).
Item 2 — cafeProducts
pgTable → pgView — INSERT/UPDATE/DELETE against
the view are now compile-time TS errors. The conversion caught a stale
db.insert(schema.cafeProducts) in the Lumière demo seed script that
H4-X had missed; refactored to call createProduct(…) (the H4-X DAO).
Three nested-projection callsites in lib/db/products.ts use a shared
PRODUCT_VIEW_COLS column object. cafeOrderLines.productId
FK ref retargeted to cafeProductProduct.id for typing accuracy.
Item 3 — Per-variant image edit field —
VariantEditModal at /cafe/settings/attributes now exposes
imageUrl + live preview. Threaded through TemplateVariantRow + DAO row
builder + onSaved patch + optimistic update. Action + DAO already supported
imageUrl from H4-X — pure UI gap close, verified round-trip on prod
(set + save + re-open shows saved value).