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.
sims-hq/BUILDING.md

102 lines
5.8 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Building SiMS Next
## Layout
```
Store Software/
├─ docs/ planning docs 0011 (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.
- **`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.