03 — Backend Architecture

Express, routes, middleware, services

See also Master Map for the full stack (edge → middleware → services → DBs); Platform Features for the business-facing capability list.

CEO Summary

The backend is the API layer that powers all tenant operations — POS, invoicing, inventory, HR, etc. It runs on Node.js/Express, connects to MySQL, and enforces tenant isolation on every request. Business value: Every feature depends on it. Key metrics: Response time, error rate, request volume. If this breaks: All tenant operations stop; POS cannot process sales.

Request Flow (Top to Bottom)

sequenceDiagram participant Browser participant Nginx participant Express participant Middleware participant Route participant Service participant DB Browser->>Nginx: HTTPS request Nginx->>Express: Proxy to :4000 Express->>Middleware: CORS, body, session Middleware->>Middleware: tenantResolver Middleware->>Middleware: requireSessionAuth Middleware->>Route: Handler Route->>Service: Business logic Service->>DB: Query DB-->>Service: Result Service-->>Route: Data Route-->>Browser: JSON response

Overview

Stack: Node.js, Express, MySQL (raw queries + Sequelize). Entry: backend/server.js. Port: 4000.

Middleware Order

  1. CORS, body parsing, session
  2. Tenant resolver (on API routes)
  3. Auth: requireSessionAuth, optionalSessionAuth, requireFlexibleAuth, deviceAuth
  4. Idempotency (middleware/idempotency.js) — mounted on the POS router (pos.routes.js): reads Idempotency-Key and optional X-PPO-* headers, dedupes replays, attaches req.ppoMutation for handlers/logging
  5. Feature gates (where applicable)
  6. Route handlers

Idempotency & POS mutation envelope

Mutating POS and related calls from the browser SPA and the Node bridge send a stable Idempotency-Key (aligned with client mutation id) plus optional X-PPO-Client-Mutation-Id, X-PPO-Device-Id, X-PPO-Register-Id, X-PPO-Sequence so that offline queue replay does not double-apply business actions. backend/middleware/idempotency.js records keys and exposes structured context on req.ppoMutation where applied.

Frontend: frontend/src/lib/offline/mutationEnvelope.js, tryOnlineThenQueue.js, frontend/src/pos/api.js — see 14 — Frontend and Appendix: Data Flows.

Route Groups

AreaRoutes
Authauth.routes, staffAuth, tenantStaffAuth, users
POSpos.routes, pos-register, pos-analytics
Catalogcatalog.routes.NEW, menus, preparables
Devicesdevices, deviceCodes, kds
Inventoryinventory, inventory.items, inventory.ledger
Customerscustomers, customerAnalytics
Paymentstransactions, invoices, giftcards, loyalty
Cryptodoge, ltc, crypto-config, crypto-wallet
HRhr, payroll, time, staff
Ticketstickets, admin.tickets, appointments
SaaStenants, master-admin, plans
Publicpublic.signup, public.barcode-lookup, webhooks.*, signage playlist (GET only)
Signagesignage.routes — folders, ads, displays; public playlist
Platform catalogplatformCatalog (tenant lookup), master-admin platform-catalog (CRUD)

Public signup API

File: backend/routes/public.signup.routes.js (mounted under /api/public with tickets and appointments).

Platform barcode catalog — who gets what

Same master DB (platform_product_catalog), three surfaces — different billing and limits:

SurfaceWhoBillingNotes
GET /api/platform-catalog/lookup Logged-in tenant (session + tenant headers) Included in Basic / Premium / normal subscriptions Enrichment when POS or inventory scans a barcode and no local match — not an “external API product.” Unlimited for normal app use (subject to general API health).
GET /api/public/barcode-lookup Anonymous visitors (public marketing site) Free, tiny quota Strict per-IP hourly limit (PUBLIC_BARCODE_LOOKUP_MAX_PER_HOUR / window). Abuse prevention only.
Future: Enterprise barcode API (e.g. API key + metering) Paying integrators / Enterprise tier Metered (e.g. per-call plans like Starter / Advanced / …) Not the same as tenant session lookup. Implement with issued API keys, usage counters, and plan limits; optional separate route prefix (e.g. /api/v1/partner/...).

Positioning: Basic/Premium merchants do not need a separate “barcode API” — they get catalog enrichment inside the app. Charged API usage targets external systems that call your platform programmatically (Enterprise / partner).

Key Services

ServicePurpose
comprehensiveTenantProvisioningTenant DB creation
tenantEmployeeRoutingEmail → tenant
bridgeConnectionManagerWebSocket registry; sendRequest, pushEnvelope (signage)
cart.servicePOS cart logic
catalog.serviceCatalog management
inventoryLedger.serviceLedger posting
coreInvoicing.serviceInvoice creation
dogeWallet.service, ltcClientCrypto
webhookDispatcherWebhooks
audit.serviceAudit

Controllers

Path: backend/controllers/

auth.controller, staff.controller, time.controller, payroll.controller, products.controller, catalog.controller, inventory.controller, reports.controller, etc. Map route handlers to business logic.

Validation

Backend: backend/validation/ — Joi schemas for request validation. Used by validate() middleware.

Payments: backend/payments/validators/ — webhooks.schemas.js, invoices.schemas.js for webhook and invoice validation.

POS: backend/schemas/pos.schemas.js — POS cart, items, tender schemas.

Auth Flows

Platform: POST /api/auth/login → Session → X-Tenant-Slug, X-Org-Id on requests.

POS Register: POST /api/pos/register/authenticate — email + PIN. Requires platform session first.

API Client: frontend/src/api/client.js — Axios, withCredentials, X-Tenant-Slug, X-Org-Id from localStorage.