saveDisplayBranding UPSERT PROD -- GATE 2
Shipped 2026-05-18. Pre-existing bug surfaced by Slice M's first prod run:
saveDisplayBranding did a naked UPDATE WHERE tenant_id=...
which silently no-oped for tenants without a cafe.tenant_config row.
Starter tenants (lumiere-coffee on prod) don't get a row at provisioning time --
getTenant synthesizes a fallback. Net effect: those tenants couldn't save
any display branding (logo, primary color, promo text, slideshow, screensaver).
Single file change. saveDisplayBranding in
lib/db/display_branding.ts rewritten from
db.update(...).set(...).where(...) to
db.insert(...).onConflictDoUpdate(...).
INSERT path populates: tenantId (PK),
storeName (looked up from tenants.name, fallback "NIX Cafe"),
empty-string defaults for required Odoo fields (odooUrl,
odooDatabase, odooLogin, odooApiKeyEnc) --
Starter tenants don't use Odoo so empty is correct. Plus all the
display_* branding fields the caller wants to save.
UPDATE path set clause is display-only -- Pro tenants'
Odoo creds + currency + posMaster + bypass_odoo_pos all preserved. Verified by a Gate-1
source assertion that the set: { ... } block doesn't include any non-display
fields.
display_screensaver_seconds nullable integer + CHECK constraint landedscreensaverSeconds=300 (5 min) -- DB persists (first save = UPSERT INSERT path; row didn't exist before)Raw: result.json
| 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 (shop scoping) | 10/10 |
| test-r7-prod.mjs (dashboard + manager-live) | 14/14 |
| test-r8-prod.mjs (auth/security trio) | 4/4 |
All Slice G features (slideshow images, slideshow speed, slideshow enabled) and Slice M
(screensaver) now also work for Starter tenants without a pre-existing
cafe.tenant_config row. Before this fix, lumiere-coffee couldn't save ANY of
these settings -- the Settings/Display form appeared to work in the UI but the DB never
updated.
Modified:
nix-cafe/lib/db/display_branding.ts -- saveDisplayBranding
rewritten as db.insert(...).onConflictDoUpdate(...).
Commit: 3d2c32b