The writer half of the bypass-Odoo-POS arc. Auto-provisions the dedicated "NIX Cafe Sales" Odoo journal + heuristically resolves the 2 chart accounts (sales income + AR/PoS clearing) on first eligible session. closeShiftAction unchanged — the R11.2 partial index surfaces pending sessions to the sync worker's new session-move drain loop. No tenant has bypass_odoo_pos=true yet — pos.order/pos.session sync runs unchanged for all 3 tenants. Real account.move writes happen at R11.5 cutover (separate session).
0931e92 (cafe) — direct account.move writer + auto-provision + session-move drain loop. 6 files changed (3 new + 1 extended DAO + 1 extended worker + 1 new push DAO), +861/-3.162 (40100 Sales of Products) + AR/PoS 107 (10501 AR/Trade Debtors (PoS)) exactly matching R11.1 recon.48 "NIX Cafe Sales" (general type, code NIXCS) now exists in get-coffee Odoo. Re-calling returned same id from the lookup path.resolved.* = true. Caller (sync worker) would persist these to cafe.tenant_config.48 "NIX Cafe Sales" now exists in get-coffee Odoo. This is intended — the journal is part of the bypass design and would be created at R11.5 cutover anyway; doing it here is idempotent and pre-positions us. No flag flip, no account.move written, no behavior change for any tenant. Demo + lumiere Odoo remain untouched by this probe (only get-coffee got hit).
| Suite | Result | Notes |
|---|---|---|
| test-r11-3-provision-prod.mjs (this fix) | 4/4 | Chart resolver + journal idempotent + provisionBypassConfig + tenant_config unchanged |
| test-launchpad-fix-prod.mjs | 8/8 | Outdoor SSO bridge fix sanity |
| test-r7-prod.mjs | 14/14 | Dashboard + manager-live |
| test-r8-prod.mjs | 4/4 | Auth/security trio |
| test-cash-carryover-prod.mjs | 9/9 | cafe.sessions read path |
| test-phase2-cafe-multishop-prod.mjs | 6/6 | Cafe multi-shop |
nix-cafe/
lib/odoo/journal.ts (NEW) — ensureNixCafeSalesJournal: idempotent lookup-or-create
for the dedicated "NIX Cafe Sales" general journal
lib/odoo/accounts.ts (NEW) — resolveStandardAccounts: heuristic chart search
(code='40100' OR name~'Sales of Products' for income;
code='10501' OR name~'Trade Debtors (PoS)' for AR)
lib/odoo/account_move.ts (NEW) — buildAccountMovePayload (pure) +
createAccountMoveForSession (account.move.create + post) +
provisionBypassConfig (auto-resolve + error gating)
lib/db/cafe_sessions.ts (EXT) — aggregateSalesAndPaymentsForSession +
markSessionMoveSynced + markSessionMoveFailed
lib/db/session_move_push.ts (NEW) — listPendingSessionMovePushes (joins cafe.tenant_config
to filter bypass_odoo_pos=true) +
tenantsWithPendingSessionMovePushes +
persistResolvedTenantConfig (COALESCE write-once)
app/api/cafe/cron/odoo-sync/route.ts (EXT) — per-tenant session-move push loop runs after
the customer-create loop. One provisionBypass call
per tenant per run; each session → aggregate → build
payload → create + post. Retry counter capped at 10.
No migration. Builds on R11.2's schema. closeShiftAction unchanged.
- Flipping cafe.tenant_config.bypass_odoo_pos=true for get-coffee - Closing a real shift on get-coffee POS to trigger the writer - Verifying the account.move appears in Odoo backoffice with the right lines - Side-by-side reconcile against the Odoo-auto-created moves from existing pos.session.close history (Strategy A from scoping memo) - Watching one week of bypass-mode operation - Eventually disabling the legacy pos.order/pos.session push for that tenant
loading…