|
|
# 06 — Open Decisions (founder calls)
|
|
|
|
|
|
Each has a recommendation; none is blocking to *start* Phase 0, all must be locked to *exit* it.
|
|
|
|
|
|
## D1 — Product name & positioning vs "SiMS Classic"
|
|
|
New name, or "SiMS" with a generation marker? **Recommendation:** keep the SiMS brand
|
|
|
(it carries your existing base's trust), market the rebuild as *SiMS Next* or *SiMS 2* —
|
|
|
the migration pitch is easier when it's "your SiMS, reborn" rather than a stranger.
|
|
|
|
|
|
## D2 — POS shell ✅ REVISED (2026-07-09): web app first
|
|
|
Founder call: **the product is a web app.** POS and back office are browser apps served
|
|
|
by the store-server on LAN (later the same apps served from cloud). Zero installs at
|
|
|
counters — the Oracle Forms deployment model, modernized. Consequences:
|
|
|
- **Hardware routes through the store-server**: web POS → HTTP → store-server → ESC/POS
|
|
|
over TCP 9100 (printers + drawer). Scanners are keyboard-wedge (browser-native).
|
|
|
Weighing scales: Web Serial API (Chrome/Edge) or a store-server serial bridge — spike item.
|
|
|
- **Electron shell is kept as an optional kiosk wrapper** (~100 lines, already built) for
|
|
|
counters that need true offline billing or locked-down kiosk mode; same web bundle inside.
|
|
|
- **Browser key conflicts** (F11 fullscreen, F12 devtools): keymaps are DB config —
|
|
|
the web preset leans on Numpad+ for cash-close and Chrome kiosk mode at counters.
|
|
|
- Offline story for browser POS (PWA + IndexedDB bill queue) is a Phase-2 hardening item;
|
|
|
v1 counters depend on the store-server over LAN, exactly like Classic depends on the
|
|
|
Oracle server today.
|
|
|
|
|
|
## D3 — Sync: buy (PowerSync / ElectricSQL) vs build (custom outbox)
|
|
|
**Recommendation:** spike both in Phase 0; prefer buying the transport if it handles
|
|
|
per-tenant partial sync cleanly. The domain rules (immutable documents, per-counter
|
|
|
series, derived stock) are ours regardless.
|
|
|
|
|
|
## D4 — GSP vendor for e-Invoice / e-Way
|
|
|
ClearTax vs Masters India vs others. Decide on: API reliability, per-document pricing at
|
|
|
your volume, sandbox quality. **Recommendation:** shortlist two, integrate behind our own
|
|
|
interface so switching is a config change.
|
|
|
|
|
|
## D5 — Pricing tiers ✅ RESOLVED (direction)
|
|
|
Founder call (2026-07-08): prices aren't fixed yet and must be **addable/changeable in the
|
|
|
DB** so they reflect in the app without a release. Design adopted: `plan`, `plan_feature`,
|
|
|
and `price_book` tables (see [07-DB-AND-CONFIG.md](07-DB-AND-CONFIG.md) §2) — new plans and
|
|
|
₹ amounts are rows, the license token is a signed snapshot of them. Actual ₹ amounts get
|
|
|
decided whenever you're ready; nothing blocks on it.
|
|
|
|
|
|
## D6 — Accounting depth at launch
|
|
|
Full books (P&L/BS) in-app from Phase 2, or ledgers + **Tally export** first?
|
|
|
**Recommendation:** ledgers + Tally export in Phase 2, full statements later. Most shops'
|
|
|
CAs live in Tally; export buys goodwill for a fraction of the effort. Classic parity data
|
|
|
should confirm how many customers actually used full accounting.
|
|
|
|
|
|
## D7 — Store Hub (LAN sync box) as requirement or option
|
|
|
Multi-counter stores need counters to see shared stock/bills when internet is down.
|
|
|
**Recommendation:** ship Store Hub as an optional role of the main billing PC
|
|
|
(a checkbox, not a separate device) from Phase 2.
|
|
|
|
|
|
## D8 — Android POS terminals (Sunmi-style) in scope? ✅ RESOLVED
|
|
|
Settled by the market-architecture brainstorm (08-MARKET-ARCHITECTURES.md, in the Store repo):
|
|
|
every player winning high-throughput counters is desktop + local-first; Android wins
|
|
|
micro-merchants and mobility. **Decision:** v1 = Windows desktop POS; Phase 3–4 = Android
|
|
|
*companion* app (line-busting, stock-take, approvals) sharing the billing-engine package;
|
|
|
full Android POS only if we later go down-market deliberately. D2 (Electron) stands.
|
|
|
|
|
|
## D9 — Purchase Inbox channels at launch
|
|
|
Email-in + manual upload first; WhatsApp-forward intake later (needs WhatsApp Business
|
|
|
API setup). **Recommendation:** email + upload in Phase 3, WhatsApp intake fast-follow.
|
|
|
|
|
|
## D10 — Cloud region & provider
|
|
|
Any major provider with a Mumbai region works. Deciding inputs: managed-Postgres quality,
|
|
|
egress pricing, your team's familiarity. **Recommendation:** pick boring; revisit never.
|
|
|
|
|
|
## D13 — Support ticketing: build vs integrate (raised by 11-ADMIN-SUPPORT-CONSOLE.md)
|
|
|
The diagnostic bundle, error-code playbooks, and Store 360° are ours; the ticket queue
|
|
|
itself is commodity. **Recommendation:** integrate a boring helpdesk in Phase 2; build
|
|
|
only if the integration fights the error-code workflow.
|
|
|
|
|
|
## D14 — Cloud staging ✅ RESOLVED: local-only first, cloud layered on later
|
|
|
Founder call (2026-07-09): v1 runs fully local (counters + in-store Oracle 12c per D12),
|
|
|
then the cloud tier is added and switched on per store. Accepted consequences: owner app,
|
|
|
Purchase Inbox, WhatsApp, central backup, silent auto-update, and HQ fleet features all
|
|
|
wait for the cloud workstream. Guardrail (non-negotiable): client UUIDs + dormant outbox
|
|
|
rows are written from the first local build, so cloud enablement is switch-on, not
|
|
|
migration. See the staging note atop 04-ROADMAP.md (in the Store repo).
|
|
|
|
|
|
## D11 — Existing team & hiring plan (partially answered)
|
|
|
Founder input (2026-07-08): a support team exists for Classic and continues; the product
|
|
|
principle is a **stable frontend** with changes flowing from backend/DB, handled by the
|
|
|
team — adopted as the config-driven design in [07-DB-AND-CONFIG.md](07-DB-AND-CONFIG.md).
|
|
|
Still needed to calibrate the roadmap: builder headcount and skill mix for the new stack.
|
|
|
|
|
|
## D12 — Local DB engine ✅ RESOLVED (for now): Oracle 12c stays at the store tier
|
|
|
Founder call (2026-07-09): the in-store DB remains **Oracle 12c** — it is already deployed
|
|
|
shared infrastructure with multiple other systems running on it, so for the existing base
|
|
|
the license and operations cost is sunk. Analysis and the adapted design are in
|
|
|
[07-DB-AND-CONFIG.md](07-DB-AND-CONFIG.md) §3.
|
|
|
|
|
|
**Consequences accepted with this call:**
|
|
|
- **D3 resolves to "build"**: off-the-shelf sync engines (PowerSync/ElectricSQL) speak
|
|
|
Postgres/SQLite only — sync is a custom outbox, with outbox tables living in Oracle and
|
|
|
a store-side sync agent draining them to the cloud.
|
|
|
- **Counters still carry a local SQLite buffer** (offline bill queue + item-search cache)
|
|
|
so a counter survives store-server or LAN death — the "counter never stops" goal is
|
|
|
independent of the store engine.
|
|
|
- Backend connects via node-oracledb **thin mode** (no Oracle client install needed;
|
|
|
supports 12.1+).
|
|
|
- **New code stays engine-portable**: repository/DAL layer, portable SQL by default,
|
|
|
Oracle-only features only with a written justification — "for now" must stay cheap to
|
|
|
revisit.
|
|
|
|
|
|
**Revisit triggers (any one reopens this decision):** onboarding NEW customers who don't
|
|
|
already have Oracle in-store (license cost is no longer sunk); the other systems sharing
|
|
|
the DB migrate off 12c or upgrade (19c/23ai); a security/compliance audit flags the
|
|
|
unpatched engine; or sync friction in Phase 0–1 proves materially costlier than an
|
|
|
engine port. Risk register entries in 07 §3 remain on record.
|
|
|
|
|
|
## D15 — Internal HQ ops console: build now ✅ RESOLVED (2026-07-09; split to its own repo 2026-07-16)
|
|
|
Founder call (2026-07-09): an **internal tool for running our own ~300-client business** —
|
|
|
quotations/proforma/invoices in minutes, recurring billing with auto/manual email
|
|
|
reminders, per-module payment + AMC tracking, per-client AWS usage & cost, and the full
|
|
|
client interaction memory (installation, training, visits, calls, meetings, sales
|
|
|
outcomes) in a system instead of heads. **Decision:** start the
|
|
|
[doc-11 HQ Console](11-ADMIN-SUPPORT-CONSOLE.md) **early**, as `apps/hq` (built in the shared
|
|
|
monorepo at the time; **split into its own repo `C:/SiMS/hq` on 2026-07-16**) —
|
|
|
spec in [14-SPEC-HQ-CONSOLE.md](14-SPEC-HQ-CONSOLE.md). Cloud-hosted **vendor-side**
|
|
|
(D14 untouched — the store product stays local); SQLite behind portable repositories with
|
|
|
S3 backup; **Gmail API** sending from the company mailbox; automated AWS cost attribution;
|
|
|
**full replacement of the internal Oracle APEX app** — one-time verified migration, then
|
|
|
APEX goes read-only, no double entry. Reuses `@sims/billing-engine` (our invoices are GST
|
|
|
documents), `@sims/domain` (paise money, FY, doc series), `@sims/ui`, and the `@sims/auth`
|
|
|
patterns.
|
|
|
|
|
|
**Alternatives rejected:** fully separate codebase (rebuilds the engine/UI/patterns and
|
|
|
builds doc-11 twice); off-the-shelf CRM (no module-level tracking against our catalog, no
|
|
|
AWS attribution, no path to the fleet console).
|
|
|
|
|
|
**Consequences accepted:**
|
|
|
- This shipped as **two deployables with different release rhythms**. On **2026-07-16 they
|
|
|
were split into two independent repos** (`C:/SiMS/hq` and `C:/SiMS/store`) — separate
|
|
|
histories, deploy scripts, and versioning; the shared packages were forked into each.
|
|
|
- Doc-11's phase mapping **splits**: the ops slice ships early (HQ-1…3 in
|
|
|
[14-SPEC-HQ-CONSOLE.md](14-SPEC-HQ-CONSOLE.md) §6); the fleet half is unchanged and
|
|
|
waits for the cloud tier per D14.
|
|
|
- **One repo, two runtime-independent applications** (founder re-confirmed 2026-07-10
|
|
|
after weighing a full split): separate servers, DBs, builds and deploys; only source
|
|
|
packages are shared. Guardrails: a bundle-isolation check in the test suite (store
|
|
|
bundle contains no HQ code and vice versa), per-app version tags, and the rule that
|
|
|
**HQ's DB is the cloud tier's nucleus** — the tenant registry is born from HQ's client
|
|
|
table (same UUIDs, promoted once), never built beside it. **Postgres locked as the
|
|
|
production engine (founder, 2026-07-10)** — swap runs as its own task after HQ-2,
|
|
|
before the real-data import, so live data never migrates engines; SQLite stays the
|
|
|
dev/test engine behind the same repositories. Physical repo split stays a cheap,
|
|
|
reversible option if practice ever demands it.
|
|
|
|
|
|
## D16 — Quote-to-close funnel slice (2026-07-17)
|
|
|
Founder-approved design in
|
|
|
`superpowers/specs/2026-07-17-quote-to-close-funnel-design.md`; decisions locked
|
|
|
with it:
|
|
|
|
|
|
- **Employee foundation rides `staff_user`.** The Employee entity is **backed by the
|
|
|
existing `staff_user` table** — renaming it would churn `session.staff_id`,
|
|
|
`interaction.staff_id` and audit entity names for zero gain; "Employee" lives in the
|
|
|
repo/API/UI vocabulary only. Roles widened to `owner | manager | staff` via a guarded,
|
|
|
transactional table rebuild (SQLite cannot ALTER a CHECK); the enum is validated in
|
|
|
the repo. Session hardening rode along: `verifySession` requires `active=1`, and
|
|
|
deactivation / password reset purge sessions in the same transaction.
|
|
|
- **Chase-list over kanban (option B).** The pipeline is **one cross-client ranked
|
|
|
list** — most-overdue on top, colour bands, an explicit next action per row,
|
|
|
`All | Mine | Overdue | Lost` filters — not a kanban board.
|
|
|
- **Derived pipeline stages, zero new pipeline storage.** Stage (Enquiry / New
|
|
|
Project / Quoted-Waiting / Won / Lost) is **never stored** — computed from
|
|
|
`client.status` + the client's latest live quotation; age anchors on the first
|
|
|
`sent` document event. The only new column anywhere in the slice is
|
|
|
`client.owner_id` (a bare lead has no creator to derive an owner from — A4).
|
|
|
- **Escalating owner+client reminders on the dated `reminder_schedule` table.** New
|
|
|
sendable `quote_followup` rule kind: the queued reminder row **is** the owning
|
|
|
employee's nudge (owner derived `doc_id → document.created_by`), and its send **is**
|
|
|
the client email with a public share link. Cadence **and** message text are dated
|
|
|
config rows (rule 3) resolved by `resolveSchedule` — defaults 3/7/14 (quote) and
|
|
|
7/15/30 (invoice) ship as seeded rows plus code-constant fallbacks, so a cadence
|
|
|
change is a new dated row, never a release. Catch-up fires only the highest crossed
|
|
|
milestone; accept / lose / convert / cancel dismisses open nudges per-row (audited)
|
|
|
in the same transaction; previews resolve shares read-only — minting happens only in
|
|
|
the send path (60-day expiry, live links reused).
|
|
|
- **Convert recompute + duplicate-invoice guard (F3/F4).** PROFORMA → INVOICE rebuilds
|
|
|
the carried lines through `computeBill` on the **invoice's own `doc_date`** (a tax
|
|
|
invoice uses the rate that is law on its issue date), and `convertDocument` rejects
|
|
|
any source with a live (non-cancelled) forward child — one sale, one invoice number.
|
|
|
- **Proforma supersede matrix.** Corrections stay firewalled by document type: a draft
|
|
|
PI is simply re-drafted; an issued, unallocated PI may cancel (number stays consumed)
|
|
|
and be recreated as a `ref_doc_id`-linked supersede; an issued INVOICE is **never**
|
|
|
recreated — cancel-if-unpaid or credit note only.
|
|
|
- **Assumptions A1–A7 (defaulted, flagged in the spec):** A1 module roster balances
|
|
|
support and revenue; A2 employees are a plain table (no org chart); A3 document
|
|
|
owner = `created_by` for v1 (no `document.owner_id` until a handoff feature is
|
|
|
real); A4 `client.owner_id` is the one genuinely new owner column; A5 notify-all
|
|
|
text is owner-typed ad-hoc, not dated config; A6 roster visible to all staff,
|
|
|
notify-all owner/manager only; A7 invoice-overdue anchors on `doc_date` (no
|
|
|
due-date column exists).
|
|
|
|
|
|
**Recorded deviation from the funnel spec's blanket pagination rule (§5 / rule 8):**
|
|
|
`GET /employees` returns the full set with `total` and **no `page`/`pageSize`** —
|
|
|
console users are a small bounded set (single-digit headcount), the count is displayed,
|
|
|
and nothing is silently truncated, which is the intent of rule 8. If the team ever
|
|
|
grows past a screenful, paginate it like every other list.
|
|
|
|
|
|
**Delivery state (2026-07-17, final):** all ten phases landed. Phases 1–6 (employee
|
|
|
foundation + management surface, owner plumbing, dated schedule, pipeline chase-list,
|
|
|
escalating quote follow-up) plus the F3/F4 convert hardening, then 7–10 in the same
|
|
|
day's second pass: one-click `POST /documents/:id/convert-and-send` (guards → one txn
|
|
|
convert+issue → post-commit email), proforma `POST /documents/:id/supersede`, invoice
|
|
|
`dN` milestone escalation (d7/d15/d30 from the dated schedule, F7 highest-only
|
|
|
catch-up), and the module → client roster (`GET /modules/:id/clients` + CSV export +
|
|
|
owner/manager Notify-all with per-recipient audit). Suite at 293 tests / 57 files.
|