← All tests

Multi-register Bundle 2 — feature enablement (local)

2026-05-13 Gate 1 local. Second of two bundles toward multi-register per shop. Bundle 2 ships the user-visible feature: register admin at /cafe/settings/registers, multi-card Starter POS landing, top-bar register picker, sequence_prefix in order numbers, plus dual-write of pos_config_uuid on every new session + order INSERT.

8/8 local probe PASS.

Probe results (DAO + migration integrity)

Loading…

Local diagnostic counts

Loading…

Files touched

nix-outdoor-sales-backend:
  migrations/20260513110000_cafe_multi_register_features.ts  (new)
  migrate.js                                                  (entry added)

nix-cafe:
  lib/db/schema.ts                                            (posConfigIntId column)
  lib/db/pos_configs.ts                                       (5 new DAOs)
  lib/db/starter_landing.ts                                   (N cards per shop)
  lib/db/cafe_sessions.ts                                     (posConfigUuid on OpenSessionInput)
  lib/db/orders.ts                                            (posConfigUuid on CreateOrderInput)
  lib/db/pos_sequences.ts                                     (formatPosOrderNumber + registerPrefix)
  lib/actions/registers.ts                                    (new — 4 server actions)
  lib/actions/starter_shift.ts                                (openStarterShift accepts posConfigUuid)
  lib/actions/drafts.ts                                       (registerPrefix in order-number mint)
  app/(authed)/settings/registers/page.tsx                    (new — admin page)
  app/(authed)/settings/registers/registers-client.tsx        (new — client component)
  app/(authed)/settings/_components/settings-nav.tsx          (Registers entry)
  app/(authed)/pos/page.tsx                                   (Pro createOpenNixSession dual-writes uuid)
  app/(authed)/pos/starter-register-page.tsx                  (resolves register from ?config or first active)
  app/(authed)/pos/_components/starter-top-bar.tsx            (register picker)
  app/(authed)/pos/_components/open-shift-form.tsx            (register picker + posConfigUuid in submit)
  app/(pos-fullscreen)/pos/register/[configId]/page.tsx       (resolve via getRegisterByIntId)
  app/api/cafe/orders/route.ts                                (registerPrefix lookup + dual-write)
  lib/actions/register.ts                                     (Pro openShift dual-writes uuid)

Gate 1 local evidence

1. Migration applied locally (Batch 38, 1 migration).
2. Drizzle schema typechecks (npx tsc --noEmit, clean).
3. DAO + landing probe — 8/8 green:
     - pos_config_int_id column exists (bigint)
     - sequence start = 1_000_000_000
     - unique (tenant, pos_config_int_id) partial index in place
     - unique (tenant, shop, name) partial index in place
     - 100% of pos_configs have pos_config_int_id
     - listRegistersForShop + createRegister + rename + setPrefix + deactivate
       + duplicate-name rejection: all round-trip cleanly
     - buildStarterLanding emits a card per pos_config (verified by creating
       a 2nd register and confirming both appear in the landing)
     - formatPosOrderNumber precedence: registerPrefix > shopCode > POS{n}
4. Local dev-server route smoke not run — dev server hangs on first compile
   on this Win machine (known issue per project_dev_server_bypass_routes_500.md);
   visual verification of /cafe/settings/registers + multi-card landing
   happens at Gate 2 on prod where the full SSO + Worker stack is healthy.

Gate 2 plan

1. Commit backend (migration + migrate.js) + cafe (everything else).
2. Push to karouna-dev on both repos.
3. Apply prod migration via `node migrate.js` against Supabase.
4. Wait for CF Pages auto-deploy (~90s).
5. Run prod multi-register flow on demo (Starter):
   - Login as owner@demo.com
   - Navigate to /cafe/settings/registers
   - Verify Register 1 exists for demo's single shop
   - Add a 2nd register named "TEST-FRONT" with prefix "F"
   - Navigate to /cafe/pos — verify 2 cards under demo's shop
   - Click TEST-FRONT card → lockable fullscreen opens
   - Cleanup: deactivate the test register
6. Verify on get-coffee (Pro):
   - /cafe/settings/registers shows 5 Pro registers (Bakery Shop, CM, TK, TSP,
     Fresh Clean) all linked to get-coffee's single shop (enrichment step worked)
   - Redundant 'Register 1' for get-coffee is gone
7. Full regression sweep (51 + new):
   - phase1, phase2-sso-outdoor, phase2-cafe-multishop, m1, r7, r8 (sequential).
8. Publish multi-register-bundle2-prod gallery.
9. Stop for approval.

Bundle 3 (deferred):
  - Set NOT NULL + FK on pos_config_uuid for sessions/shop_pos_configs/pos_sequences.
  - Drop legacy int pos_config_id columns from those tables.
  - Rename pos_config_uuid → pos_config_id throughout.
  - Drop shopToConfigId helper.

Out of scope:
  - The Odoo connector that pushes new NIX-created Pro registers to pos.config.create.
    Bundle 2 creates Pro registers with sync_state='pending_create'; the future
    connector picks them up and writes odoo_pos_config_id (mirrors R11.5's
    session-close-move drain).