Operations
Known gaps & drift
What's missing, what's risky, and which in-repo documents no longer match the code. This was collected while writing these docs in October 2026.
Fix before a wider launch
| Gap | Where | Impact |
|---|---|---|
| OTP send throttle is off | OTP_SEND_THROTTLE_ENABLED = false in auth.service.ts | Unlimited code emails per address |
| Internal key has owner authority over every shop | /internal/merchant/*, require-internal-acting-as.ts | A leaked key exposes every tenant. It was accepted only for non-production use. |
otp_bypass (fixed code 0000) can be set by the catalogue importer | auth, catalogue-import | A bypassed address signs in with a fixed code |
| Ledger has no write-restricted database role | ledger | Immutability rests on a trigger alone |
| Staff location scope isn't enforced on inventory writes | inventory router | A branch-scoped stock clerk can adjust any branch |
ownerScoped routes are closed to staff | ~41–54 routes: order detail/actions, refunds, returns, fulfilment, customer detail (check_later.md #7) | Staff with the right permission still can't use them, and order detail is owner-only in the dashboard |
Functional gaps
Accounting
- Refunds don't post journal entries, so the books overstate sales by refunded amounts.
- No COGS posting, so Profit doesn't reconcile with the Trial Balance.
- Item Shipments and purchase columns are absent or zero, because there's no purchasing module.
POS
- No held/parked sales.
- No reprint from history.
- No refunds at the till.
- No order-level note.
- No supervisor close of another cashier's drawer.
- Past sales in drawer history don't show their discount (blocked on the contract).
- The shift doesn't return its currency, so the till assumes its own.
- English only.
Orders
- No live courier labels or rates;
carrierCodereturns 400. - No preorder fulfilment hold.
- No order timeline endpoint.
- Partner-storefront order sources (
the_circle*) have no write path yet.
Discounts
- No free shipping, customer eligibility, one-use-per-customer, combination rules, or loyalty.
Search
- Stock-tab counts ignore a selected category (
todo.md#1).
Notifications
- Only order cancellation generates a notification. There's no delivery channel and no dashboard inbox.
Dashboard
- No shifts screen, although
/merchant/shift/v1/get-shiftsexists. - The refund panel doesn't expose
paidFromDrawer. - Overview analytics are computed client-side from at most 4 pages of orders.
- Product import is create-only.
- Staff deep links fail beyond the first page of staff.
- The entry-type field editor is commented out.
- New reference fields can't be created.
- The AI assistant is a stub.
Billing
- The plan catalogue is empty and nothing is gated by plan.
- Stripe isn't implemented.
Documentation drift
These in-repo documents disagree with the code. The code is correct:
| Document | What's stale |
|---|---|
api-v2/README.md | Port status counts. "Staff are records, not accounts" (staff sign in now). /pos "rest pending" (fully implemented). |
api-v2/.claude/ORIENTATION.md | Says 26 modules (there are 34). Missing the storefront audience and the app, inventory-screen, jarde, modifier, places, reports and till-section modules. |
api-v2/HANDOVER.md, remaining.md | Say Heroku runs refactor/module-boundaries. It was merged 2026-08-10. |
api-v2/CLAUDE.md | Test suite size and timing |
merchant-dashboard-v2/README.md | Says there's no create-order (there is), no multi-variant editing or image upload (both exist), no staff sign-in or role enforcement (both live). Mentions weekly shifts (UI removed) and a local file: contracts install (published package now). |
merchant-dashboard-v2/CONTEXT.md | Says "Kiln" shows in index.html and Login.tsx (both say Totlob now) |
merchant-dashboard-v2/src/App.tsx:93 | "Cannot submit an order". Stale. |
totlob-pos/README.md, index.html | Stock Vite template text and title |
totlob-pos/src/api/client.ts | The comment says the base URL defaults to same-origin; the code defaults to http://localhost:3000 |
Housekeeping
- Unused code:
- POS:
PaymentPanel.tsx,SaleReceipt.tsx,src/assets/hero.png,vite.svg - Dashboard:
useGuide,ScopeRail.tsx
- POS:
totlob-pos/scripts/style-gate.mjsisn't wired into any script.totlob-pos/.env(with the production API URL) is committed.- Check local
.claude/settings.local.jsonfiles for pasted bearer tokens before sharing a machine or a screen recording.