2026-04-29 on prod. Two non-blocking items surfaced during R4.1's multi-shop activation, bundled into one Gate cycle. (A) Idempotent admin-operator seed in migrate.js so any future fresh DB ships with Cpanel access from minute zero — no more silent 24h lockout like the one R4.1 caught after the 04-28 Supabase migration. (B) is_active filter sweep on the two remaining shop-read surfaces flagged in R4.1's hand-off: the Kitchen Display secret (saved URL stops authenticating when ops disables the shop) and the cashier-create shop validation (can't assign a cashier to a freshly retired shop).
node migrate.js against the live Supabase URL before pushing; the new entry printed = admin_operators already populated (1 rows) — skipping seed. Existing operator row untouched. The seed code only fires on a truly empty admin_operators table.test-r4-1-prod.mjs after deploy; the full create-shop → switch → soft-disable → picker-collapse path still works end-to-end.pin_identities.ts::listPinIdentities leftJoin. The Team page benefits from showing the historical shop name even of a soft-disabled shop (manager wants to know where the cashier was assigned before re-assigning). Not a correctness issue.nix-outdoor-sales-backend @ 0749a17:
migrate.js — appended migration
20260429100000_seed_default_admin_operator.js
Counts admin_operators, inserts the default
super_admin only when table is empty. Bcrypt
hash hardcoded — same value currently in prod.
nix-cafe @ 9922b6e:
lib/db/kitchen.ts
ensureShopKitchenDisplaySecret(shopId) — return type widened to string|null;
soft-disabled shops can no longer mint or
rotate kitchen secrets. Caller already
handles null (page.tsx:154).
getShopByKitchenSecret(shopId, secret) — added is_active=true filter; saved Kitchen
Display URLs stop authenticating the moment
ops disables the shop.
lib/actions/cashiers.ts
createCashierAction shop validation — added is_active=true to the shop existence
check; "Selected shop not found or inactive"
error replaces the old "not found" so
deactivated shops surface a clear reason.
| test-r4-1-prod.mjs | 9/9 |
| test-phase1-prod.mjs | 11/11 |
| test-receipt-preview-prod.mjs | 6/6 |
| test-r2-followups3-prod.mjs | 7/7 |
| test-r2-followups2-prod.mjs | 11/11 |
| test-r2-followups-prod.mjs | 19/19 |
| test-nix-os-r2-4b-prod.mjs | 12/12 |
| test-nix-os-70-2-prod.mjs | 10/10 |
| test-cafe-followups-prod.mjs | 5/5 |
R4.1 ─ Multi-shop activation E2E ✓ shipped (2026-04-29) R4.x ─ Carried-forward follow-ups bundle ✓ shipped (2026-04-29) — admin seed + is_active sweep R4.2 ─ Impersonation pending (next up) R4.3 ─ Per-product usage endpoint pending R4.4 ─ Drop legacy tenant_limits/plan_code pending (last)