# Building SiMS Next ## Layout ``` Store Software/ ├─ docs/ planning docs 00–11 (read 00-VISION first) ├─ packages/ pure, tested business logic — no UI, no DB, no hardware │ ├─ domain/ tenancy (tenant→store→counter→user), money (integer paise, │ │ ₹ Indian grouping), uuidv7 ids, business day (Day Begin │ │ idiom from the OG apps), GST doc series, GSTIN validation, │ │ immutable document types, dormant outbox rows (D14) │ ├─ billing-engine/ deterministic GST math: dated rate resolution, inclusive/ │ │ exclusive prices, CGST/SGST vs IGST, cess, pro-rata bill │ │ discounts, rupee round-off — locked by golden tests │ ├─ auth/ PIN policy + scrypt hashing, lockout reducer, role→action │ │ permission matrix with supervisor-PIN gates, POS session │ │ bound to the Day-Begin business date │ ├─ scanning/ EAN-13 validation, label-scale (2x-prefix) weight/price │ │ barcodes, the scan-box grammar (qty*, code, search), │ │ wedge scanner vs human-typing detector │ └─ config/ settings hierarchy resolver (system→tenant→store→counter │ →user, effective-dated) + message catalog with language │ fallback — the everything-in-DB principle as code └─ apps/ thin shells over the packages (in build order) ├─ pos/ Electron + React counter (Phase-0 hardware spike next) ├─ store-server/ Node service beside the existing Oracle 12c (D12) └─ backoffice/ React SPA, served locally by store-server in v1 ``` ## Commands ``` npm install # once; workspaces link @sims/* packages npm test # vitest across all packages npm run typecheck # tsc strict over every src + test file # THE WEB APP (the product, per D2 revision) — one process serves everything: cd apps/pos && npm run build cd apps/backoffice && npm run build cd apps/store-server && npm start # Back office: http://localhost:5181/ (thomas / sims) # POS: http://localhost:5181/pos/ (counters browse here; zero installs) # Printing: POST /api/print → ESC/POS over TCP 9100 (browsers can't open sockets) # Optional Electron kiosk wrapper for the POS (same web bundle, direct print bridge): cd apps/pos && npm start ``` ## Design system (packages/ui) - **Tokens** (`tokens.css`): light + dark themes, six switchable accents (indigo, blue, emerald, violet, rose, amber), semantic status colors, shadows, radii — applied via ``. References: Stripe (light clarity), Linear (dark). - **Fonts bundled, never CDN** (shops are offline): Inter Variable for UI + tabular money digits, JetBrains Mono Variable for codes/receipts — via fontsource, built into each app's dist. - **`ThemeSwitcher`** sits in both app headers; prefs persist in localStorage now and become user-scope settings rows later (config-driven principle). - Restyle rule: pages consume tokens/classes only — changing `tokens.css` restyles the entire product; no page edits. ## Wireframe status (v0.1) - **POS**: login (PIN tiles) → shift open (denomination count) → billing screen — functional: real billing engine, scanner wedge detection, scale barcodes, hold/resume, per-counter GST series, payment overlay, day-end summary, ESC/POS printing over network (Ctrl+, to configure; test print + drawer kick). Runs in a browser too (`npm run dev`) with printing stubbed. - **Back office**: full menu tree (09-UX §2), ~40 pages as data-driven wireframes with realistic sample data; custom builds of the Purchase Inbox (split review), Settings hierarchy, Users & Roles matrix, Dashboard. Edition-locked pages render as upsells. - Revamp path: pages are `PageConfig` rows rendered by one `GenericPage` — restyling the kit restyles the app; promoting a page to "real" means swapping its config for a component fed by the store-server API. ## Rules the structure enforces 1. **Logic lives in packages, apps are shells.** The same billing engine must produce byte-identical bills on POS, store server, and cloud — that's why it is pure TS with golden tests, and why the frontend can stay stable (founder principle) while behavior evolves as data. 2. **Tenancy from row one.** Classic has no tenant concept; here `tenantId` is on every record even though a v1 install holds one tenant. Retrofitting this later is the single most expensive migration there is — so it is never retrofitted. 3. **Documents are immutable, ids are client-generated (uuidv7), outbox rows are written from day one** even though nothing drains them yet (D14): cloud enablement must be a switch-on, not a migration. 4. **Nothing user-facing is hard-coded.** Rates, settings, messages, plans resolve from rows (see `@sims/config`); the packages define the resolution semantics and the DB supplies the rows once the Oracle schema mapping (docs/12-DATA-MODEL.md) exists. ## Next steps (in order) 1. **Phase-0 hardware spike** in `apps/pos`: Electron shell, ESC/POS print, drawer kick, wedge scanner wired to `@sims/scanning`, one weighing scale. 2. **Golden bills from Classic**: 100 real bills re-computed through the engine to the paisa — extend `packages/billing-engine/test`. 3. **Classic schema mapping** (needs the Classic Oracle DDL export) → docs/12-DATA-MODEL.md, then the repository layer in store-server. 4. Billing screen prototype against the item cache, timed with real cashiers.