7.9 KiB
Build Status — 2026-07-09 (post-slice)
54 screens across 2 surfaces (46 back office + 8 POS), on 7 tested logic packages
(54 tests green), and a store-server with a real data layer (SQLite behind portable
repositories; Oracle 12c adapter slots in when the Classic DDL arrives — D12).
Product form: web app served by the store-server (D2) — back office at /,
POS at /pos/, printing via /api/print.
The vertical slice is LIVE and verified end-to-end: PIN login (server-side scrypt +
lockout) → item cache from DB → bill commit in one transaction (GST series allocation,
bill + lines, stock movements, dormant outbox row, audit entry) with server-side
engine re-verification (client and server must agree to the paisa) → bill visible in
Back Office Bills, stock derived correctly, audit trail written. Verified by driving
both UIs in a real browser: bill ST1C2/26-000001, ₹600.00.
The foundation (packages/ — real, tested code, not wireframe)
| Package | What it does | Tests |
|---|---|---|
@sims/domain |
Tenancy (tenant→store→counter→user), integer-paise money + ₹ Indian grouping, UUIDv7 ids, Day-Begin business day + FY, per-counter GST doc series (16-char rule), GSTIN checksum validation, immutable document types, dormant outbox (D14) | ✅ |
@sims/billing-engine |
Dated GST rates, inclusive/exclusive prices, CGST/SGST vs IGST, cess, pro-rata bill discounts, rupee round-off — golden-tested to the paisa | ✅ |
@sims/auth |
PIN policy + scrypt hashing, lockout reducer, role→action matrix with supervisor-PIN gates, POS session bound to business date | ✅ |
@sims/scanning |
EAN-13 validation, weighing-scale (2x) barcodes, scan-box grammar (3* qty, code, search), wedge scanner vs human-typing detector |
✅ |
@sims/printing |
ESC/POS byte builder, receipt renderer (42/32 col), drawer kick | ✅ |
@sims/config |
Settings hierarchy resolver (system→tenant→store→counter→user, effective-dated), message catalog with language fallback | ✅ |
@sims/ui |
Design system: light/dark themes, 6 accents, Inter + JetBrains Mono bundled, wireframe component kit, ThemeSwitcher | — |
POS — 7 screens (/pos/) — FUNCTIONAL
| # | Screen | State |
|---|---|---|
| 1 | Login — user tiles + PIN pad | Functional (seed users) |
| 2 | Shift Open — denomination count → opening float | Functional |
| 3 | Billing screen — scan box, lines grid, totals, quick keys, status bar | Functional end-to-end: real engine, barcode/multiplier/scale-barcode entry, hold/resume, per-counter GST series, one-key cash close (F12/Numpad+) |
| 4 | Payment overlay (F11) — Cash/UPI/Card/Khata | Functional (modes recorded; QR/split later) |
| 5 | Bill history (F10) | Functional (day log) |
| 6 | Day-End summary — totals by payment mode | Functional (variance calc later) |
| 7 | Settings (Ctrl+,) — printer IP/port/width, test print, drawer kick | Functional (prints via store-server) |
Also live: customer attach (F6); server-backed history (F10); commit failures keep the
cart; live search suggestions (visible-before-add, ↑/↓+Enter); F2 qty / F3 price
inline cell edits (price>MRP blocked); unknown-code quick-add (draft item created
server-side, billable immediately). Verified: bill ST1C2/26-000002.
P1 pass done (verified): tendered-cash change flash (type 100 F12 → CHANGE ₹20),
Ctrl+B repeat-last-bill (current prices, never resurrected), instant * multiplier with
qty chip, F4 line discount (4 = ₹4, 5% = percent; Disc column appears on demand),
audio feedback (ok/warn/err beeps), ok-notices auto-clear, stock chips in suggestions
(live counts, out-of-stock warn-not-block). Bill ST1C2/26-000003 proves the chain.
Purchase Entry P1: crash-proof localStorage draft with resume banner; glance strip on
cell focus (stock · sale · MRP · live margin · last-3 costs via /purchases/cost-history).
Still pending: returns flow, supervisor PIN overlay (needs /auth/verify-pin), phonetic
@sims/search-core, purchase schema P1s (free-qty, disc%, interstate split — one
migration pass together), history-R repeat, customer display, offline queue.
Purchase Entry — LIVE (the second crown jewel)
/purchases/entry: supplier type-ahead → invoice no/date → scan-grammar line entry
(barcode / code / name / 48*surf) → qty→cost cell flow (Enter-advances) → last-cost
prefill + cost-changed price-revision prompt → printed-total cross-check → F12 post.
Server: transactional commit (stock IN, price/MRP updates + audit, duplicate-invoice
rejection, totals re-verification). Purchase List page live too. Verified end-to-end:
HD/2651 ₹6,988.83 posted, duplicate rejected, stock 118→166. Full P1/P2 backlog:
docs/13-SPEC-PURCHASE-ENTRY.md.
Back office — 46 screens (/) — WIREFRAME (sample data)
Login (1) + Dashboard (1, custom) + 44 module pages:
| Module | Pages | Count |
|---|---|---|
| Catalog | Items · Categories · Price Lists · Schemes & Offers · Label Printing | 5 |
| Sales | Bills · Returns & Credit Notes · Customers · Khata & Collections · Loyalty | 5 |
| Purchases | Purchase List · Purchase Entry · Purchase Inbox (custom split-review) · Suppliers · GSTR-2B Reconciliation | 5 |
| Inventory | Stock · Adjustments · Transfers · Stock Take · Expiry Dashboard | 5 |
| Accounting | Vouchers · Ledgers · Day Book · P&L/Balance Sheet · Tally Export | 5 |
| GST | GSTR-1 · GSTR-3B · e-Invoice Queue · e-Way Bills · HSN Summary | 5 |
| Reports | Sales Reports · Margins · Stock Aging · Day-End Digest | 4 |
| Admin | Users & Roles (custom matrix) · Stores & Counters · Settings (custom hierarchy) · Print Templates · Integrations · Subscription & Plan · Audit Log · Sync & Devices · Backups · Data Import | 10 |
5 pages are now LIVE on real data: Items (list + search + New Item — billable at the counter immediately), Customers, Bills, Stock (derived from movements), Audit Log. Login is real (server-verified). 36 pages render from the data-driven registry; 4 are custom wireframes (Dashboard, Purchase Inbox, Settings hierarchy, Users & Roles). Edition-locked pages render as upsells; everything themed and role/edition-aware.
Store-server (apps/store-server) — RUNNING SERVICE with DATA LAYER
Serves both web apps + POST /api/print + GET /api/health, and now the data API:
/api/auth/pin, /api/auth/login (scrypt + lockout), /api/bootstrap, /api/items
(GET/POST), /api/parties (GET/POST), /api/bills (GET/POST with engine
re-verification), /api/stock, /api/audit. SQLite (WAL) at apps/store-server/data/
behind portable repositories (src/repos.ts) — the Oracle 12c adapter reimplements
those signatures when the Classic DDL arrives; nothing above them changes.
Port 5181 (8080–85 are Windows-reserved).
Not built yet (per roadmap)
- Store-server data layer: Oracle repository, real auth, item/bill APIs → needs the Classic Oracle DDL (→ docs/12-DATA-MODEL.md, to be written once the DDL arrives)
- Owner mobile app (Phase 3) · Customer display · HQ console (doc 11): ops slice now spec'd to start early as
apps/hq(docs/14-SPEC-HQ-CONSOLE.md, D15); fleet half still waits for the cloud tier (D14) - Purchase Inbox backend (AI parsing) · e-Invoice/e-Way GSP · WhatsApp/UPI integrations
- Sync agent + cloud tier (D14: deliberately later) · Classic migration tool
- Onboarding wizard · i18n content (mechanism exists, Hindi/Malayalam strings pending)
Decisions: resolved vs open
Resolved: D2 web-first · D5 DB-driven plans/prices · D8 Android later · D12 Oracle 12c for now · D14 local-first-then-cloud · D15 HQ ops console early, in-monorepo. Open: D1 product name · D4 GSP vendor · D5 ₹ amounts · D11 builder headcount · D13 helpdesk.
How to run
cd apps/store-server && npm start # http://localhost:5181 (/ and /pos/)
npm test && npm run typecheck # from repo root