8.8 KiB
Split SiMS into two independent projects: HQ and Store
Date: 2026-07-16 Status: Approved, pending implementation plan
Why
C:/SiMS/Store Software currently holds two products that are not one product.
HQ (apps/hq, apps/hq-web) is internal: our client book, their projects,
proforma-invoice billing, call tracking, AMC contracts, AWS cost recovery,
payments and reminders. It is the commercial record of the business.
Store (apps/pos, apps/store-server, apps/backoffice) is the product we
sell: GST retail management deployed on client premises.
They are independent projects and should be developed, deployed and released as such:
- Different audiences. HQ is internal-only; Store ships to ~300 clients.
- Different databases. Two SQLite schemas with no conceptual overlap. HQ:
client,module,document,interaction,amc_contract,aws_usage,payment,reminder,staff_user. Store:item,batch,bill,purchase,stock_movement,party,counter,store,tenant. Four names collide (audit_log,doc_series,setting,tax_class) but they are different definitions in different DBs — shared in appearance only. - Different cadences. Of 75 commits, 60 touch HQ and 2 touch Store. The repo is already HQ wearing a Store name.
- Confidentiality. A single tree means every Store branch, contractor handout, or repo copy carries our client book and revenue data in its history.
Decisions
| # | Decision | Choice |
|---|---|---|
| 1 | Split shape | Two separate git repos |
| 2 | Shared code | Fork into each repo, trimmed to what each uses |
| 3 | History | HQ inherits the existing 60 commits; Store starts fresh |
| 4 | Docs | Trim each side to only what that repo needs |
| 5 | Repo name | C:/SiMS/hq (keep — matches docs/14, DEPLOY-HQ.md, @sims/hq, 60 commits) |
| 6 | Project tracking | Out of scope — split first, build after |
Rejected: a third shared repo and a private npm registry. Both add versioning overhead to solve a divergence risk the evidence says does not exist (see below).
Target layout
C:/SiMS/
├── hq/ ← current repo, 60 commits preserved
│ ├── apps/{hq, hq-web}
│ ├── packages/{domain, auth, billing-engine, ui} ← trimmed, names kept
│ ├── docs/ ← HQ-only, renumbered
│ ├── DEPLOY-HQ.md
│ └── README.md, STATUS.md ← STATUS.md is new
└── store/ ← fresh git init
├── apps/{pos, store-server, backoffice}
├── packages/{domain, billing-engine, auth, ui, config, scanning, search-core}
├── docs/ ← the remaining 15 docs
└── README.md, STATUS.md, BUILDING.md
Each repo gets its own package.json (sims-hq / sims-store), tsconfig,
vitest.config, .gitignore, and CLAUDE.md. Neither references the other at
any point — no workspace links, no relative paths across roots, no doc citing a
file it does not contain.
Shared code: fork, trimmed
HQ's dependency on shared packages is shallow and fully verified — utilities and a design system, no shared schema or business logic.
HQ keeps the package names (@sims/domain, @sims/auth,
@sims/billing-engine, @sims/ui) and removes files underneath. Import
specifiers are unchanged, so no import statement in HQ's app source changes —
not one of apps/hq's 75 files or apps/hq-web's 14. What changes is narrow and
enumerable: the four index.ts barrels (drop the removed export * lines), and
apps/hq-web's package.json + vite.config.ts (drop the dead @sims/printing
dependency and alias).
| Package | HQ keeps | HQ drops |
|---|---|---|
domain |
ids, money, business-day, doc-series, gstin, documents |
tenancy, masters, batch, outbox |
auth |
pin |
lockout, permissions, session |
billing-engine |
compute, tax |
returns, gst-returns (588 lines) |
ui |
all 5 files | — |
printing |
— | whole package |
Store's packages/ is untouched.
Closure verification (done, 2026-07-16)
Every trim is a clean cut — verified by reading the imports, not by assumption:
compute.tsimports./taxand four types from@sims/domain(BillLine,BillTotals,Paise,IsoDate) — all in files HQ keeps.tax.tsimports onlyIsoDate.documents.tsimports only frommoneyandbusiness-day.pin.tsimports onlynode:crypto— no@simsdeps.uihas no@simsdeps at all (react+ its owntheme).- Nothing HQ retains imports
tenancy,masters,batch, oroutbox. The reverse edges (batch → business-day,masters → money) are one-way and drop cleanly. @sims/printingis declared inapps/hq-web/package.jsonand aliased in itsvite.config.ts, but imported by no source file — a dead dependency.
Why forking is safe
The divergence risk for forked code is GST computation. It does not apply:
tax rates are dated DB rows, not code. tax_class rows carry
effective_from/effective_to and resolve by the bill's business date, with
the Sept-2025 GST 2.0 slab change cited in tax.ts as the precedent. HQ reads
its own tax_class table; Store reads its own. A rate change is a row insert
per DB, never a code edit.
What remains in compute.ts is stable arithmetic — CGST/SGST/IGST split,
rounding. It has no reason to change often, and the two products are entitled to
diverge: HQ invoices software modules, Store bills retail goods.
History
The current repo becomes C:/SiMS/hq: all 60 HQ commits preserved, then one
commit removing Store paths. No filter-repo surgery.
C:/SiMS/store gets git init and one clean initial commit. It loses only 2
commits (one titled wip) and gains a guarantee: zero HQ bytes in its history,
permanently. This is the confidentiality boundary, and it is only real if the
Store history starts empty.
Docs
Trimmed per repo — each doc cut to what that side actually needs.
HQ (renumbered 00–04):
| New | From | Treatment |
|---|---|---|
00-HQ-CONSOLE-SPEC.md |
14-SPEC-HQ-CONSOLE.md |
As-is |
01-ADMIN-SUPPORT-CONSOLE.md |
11-ADMIN-SUPPORT-CONSOLE.md |
As-is |
02-PROJECT-RULES.md |
16-PROJECT-RULES.md |
Trimmed: keep money, config-over-code, document rules; drop counter/POS rules |
03-DECISIONS.md |
06-DECISIONS.md |
Extract D15 + HQ-only calls |
04-DB-AND-CONFIG.md |
07-DB-AND-CONFIG.md |
Trimmed: D12 portable-repo pattern, dated tax-class config |
Plus DEPLOY-HQ.md as-is, a rewritten README.md, and a new STATUS.md.
Store: the remaining 15 docs, with D15/HQ references pruned from
06-DECISIONS.md and the HQ rows removed from README.md's doc table.
HQ has no STATUS.md
The largest app in the repo (75 files, at go-live per DEPLOY-HQ.md) has no
build-state doc. STATUS.md covers only the Store product. HQ's current state
had to be reconstructed from source and git log. Write one during the split,
covering the built surface: clients, modules and price book, documents
(QT/PI/INV/CN) with templates/PDF/share links, interactions, AMC, AWS usage,
payments, recurring plans, reminders with Gmail send and bounce handling,
reports, dashboard, audit, APEX import, scheduler.
Verification
The split is done when, for each repo independently:
node_modulesremoved andnpm installrun freshnpm run typecheckpassesnpm testpasses- No path resolves outside its own root
Typecheck is the real proof of the fork closure — a missed dependency fails immediately and loudly.
Additionally, confirm the confidentiality boundary holds rather than assuming it:
searching C:/SiMS/store/.git for client, AMC, and AWS-cost terms must return
nothing.
Out of scope
- Project tracking. Listed as a core HQ concept but not built — no
projecttable, no repo module, no UI. It is a feature to design and build, not code to move. Deferred so the split stays mechanical: pure move-and-verify, with no new feature to confuse a failure with. - Conversion reporting.
client.status(lead/active/dormant/lost) exists but has no lead-to-won reporting on it. Wanted alongside the existing conversation log (interaction), but after the split. - Oracle 12c adapter (Store, pending Classic DDL) and the 46 wireframe back-office screens (Store) are unaffected by this work.
Risks
| Risk | Mitigation |
|---|---|
| A trimmed file is needed by something unread | Typecheck on a fresh install in each repo catches it immediately |
| Store history retains HQ data | Fresh git init, verified by searching .git |
| Docs cite files that no longer exist in their repo | Grep each repo's docs for cross-references to removed paths |
HQ's dead @sims/printing alias breaks its Vite build when dropped |
Remove from both package.json and vite.config.ts together; build verifies |