You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.8 KiB
5.8 KiB
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<html data-theme data-accent>. 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.
ThemeSwitchersits 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.cssrestyles 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
PageConfigrows rendered by oneGenericPage— 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
- 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.
- Tenancy from row one. Classic has no tenant concept; here
tenantIdis 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. - 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.
- 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)
- Phase-0 hardware spike in
apps/pos: Electron shell, ESC/POS print, drawer kick, wedge scanner wired to@sims/scanning, one weighing scale. - Golden bills from Classic: 100 real bills re-computed through the engine to the
paisa — extend
packages/billing-engine/test. - Classic schema mapping (needs the Classic Oracle DDL export) → docs/12-DATA-MODEL.md, then the repository layer in store-server.
- Billing screen prototype against the item cache, timed with real cashiers.