2026-04-24 on prod (get-coffee.nixtech.app). Tenant-configurable
branding for the secondary customer screen — logo URL, primary color,
promo text, promo image. Admin form at /cafe/settings/display
with live preview; public Customer Display idle screen renders the saved
branding. URL-field MVP (R2/S3 upload deferred).
cafe.tenant_config (DB ground-truth match on all 4 fields),
public /cafe/display/[sessionId] idle screen renders the saved
logo (<img>), promo text card, promo image, and primary-color
gradient. validateBranding bad-hex rejection surfaces a clear
error in the UI. No 5xx during the flow. Cleanup restores original branding.
| test-nix-os-70-prod.mjs — NIX-OS-70 Personalize Customer Display (new) | 10/10 |
| test-phase1-prod.mjs — SSO smoke + route auth | 11/11 |
| test-phase2-sso-outdoor-prod.mjs — Outdoor SSO bridge | 6/6 |
| test-phase2-cafe-multishop-prod.mjs — Cafe multi-shop | 6/6 |
| test-m1-prod.mjs — Dashboard/Orders/Reports shop scoping | 10/10 |
| test-r1-9-daily-report-prod.mjs — NIX-OS-72 Daily Sale Report | 11/11 |
| test-r1-10-cash-movements-prod.mjs — NIX-OS-71 Cash In/Out | 12/12 |
| test-r1-11-telegram-events-prod.mjs — NIX-OS-73 Telegram Events | 11/11 (after 1 retry) |
| test-nix-os-69-1-prod.mjs — NIX-OS-69.1 Kitchen foundation | 10/10 |
| test-nix-os-69-2-prod.mjs — NIX-OS-69.2 Kitchen Display | 11/11 (after 1 retry) |
| test-r1-1-cashiers-prod.mjs — R1.1 cashier admin (transient) | 8/9 |
| test-r1-4-drafts-prod.mjs — R1.4 drafts (transient — Odoo 429) | 5/9 |
Odoo HTTP 429: Too Many Requests — Odoo backend is
rate-limited from the parallel test traffic across all the suites today.
r1-9 / r1-10 / r1-11 / 69.1 / 69.2 all pass against the same Odoo, so the
integration is fine; r1-4 just gets unlucky on Odoo's rate window.
Neither is a 70 regression.
649d1ea — migration applied via
node migrate.js against Render DB; 4 nullable columns
added to cafe.tenant_config.4ea0026 — auto-deployed to the
nix-cafe Worker.nix_cafe.settings.edit
gate, audit-log entry, hex/URL/length validation./cafe/settings/display — two-column
layout: form on the left + live PreviewIdle on the right
that updates as you type.