docs: HQ project identity (README, STATUS, CLAUDE) + fix cross-repo doc links
Adds the front-page README, a first STATUS.md build-state doc (the console had none), and a CLAUDE.md with the house rules that govern this repo. De-links four references to Store-only planning docs (04-ROADMAP, 08-MARKET-ARCHITECTURES, 09-UX-FLOWS-AND-MENUS) that now live in the Store repo, and regenerates the lockfile to drop the removed Store workspace entries. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>feat/client-detail-redesign
parent
7e1c93cee0
commit
115f2e6c41
@ -0,0 +1,72 @@
|
||||
# CLAUDE.md — HQ Ops Console
|
||||
|
||||
This repo (`C:/SiMS/hq`) is the **internal console for running our own software business** —
|
||||
NOT software we ship to clients. It manages our ~300 existing Classic clients: client book,
|
||||
sellable modules with a dated price book, documents (quotation / proforma / invoice / credit
|
||||
note) on editable letterhead templates with PDF rendering and shareable public links,
|
||||
call/interaction tracking, AMC contracts, AWS cost recovery, payments + allocations,
|
||||
recurring plans, and reminders emailed via Gmail with bounce handling — plus reports, a
|
||||
dashboard, an append-only audit log, an APEX importer, and a scheduler.
|
||||
|
||||
> **The Store/POS retail product is a SEPARATE repo.** It is local-first software installed
|
||||
> in shops. Do **not** add Store/POS/counter/retail features here, and do not reference them.
|
||||
> This app is vendor-side cloud only (the "HQ Console" of doc 11, started early per D15).
|
||||
|
||||
## Layout
|
||||
|
||||
| Part | Where | Notes |
|
||||
|---|---|---|
|
||||
| Backend | `apps/hq/src` | Express over `better-sqlite3`, DB at `data/hq.db` (WAL) |
|
||||
| Frontend | `apps/hq-web/src` | React + Vite; pages Dashboard / Clients / ClientDetail / Documents / Modules / Reports |
|
||||
| Repos | `apps/hq/src/repos-*.ts` | one file per domain; plain functions over a `DB` handle |
|
||||
| Schema | `apps/hq/src/db.ts` + `apps/hq/schema.sql` | `CREATE TABLE IF NOT EXISTS` + additive `migrate()` |
|
||||
| Shared packages | `packages/*` | trimmed forks — see below |
|
||||
|
||||
**Shared packages** (generic on purpose — keep them so): `@sims/domain` (`ids`/UUIDv7,
|
||||
`money`/paise, `business-day`, `doc-series`, `gstin`, `documents`), `@sims/auth` (scrypt PIN
|
||||
+ lockout), `@sims/billing-engine` (`compute`, `tax`), `@sims/ui`. HQ owns its own
|
||||
document/payment types (quotation, proforma, credit note; NEFT/cheque/UPI modes) — do not
|
||||
push those into the shared packages.
|
||||
|
||||
## Non-negotiable rules
|
||||
|
||||
These are the house hard rules (`docs/16-PROJECT-RULES.md`, `docs/07-DB-AND-CONFIG.md`)
|
||||
distilled to what applies to HQ. A change that breaks one does not land.
|
||||
|
||||
| # | Rule | In this repo |
|
||||
|---|---|---|
|
||||
| Money is integer paise | Every amount is `Paise` (integer). Fractional-rupee floats never enter the domain; convert at the edge with `fromRupees`, format with `formatINR`. Every rounding step is explicit. | all `*_paise` columns; `@sims/domain/money` |
|
||||
| One billing engine, re-verified | GST is computed **only** through `@sims/billing-engine` `computeBill` — save and preview run the same path so they cannot drift. The server recomputes to the paisa; a mismatch is rejected. | `repos-documents.ts` |
|
||||
| Config over code, dated | Anything that varies — prices, tax rates/slabs, settings, doc-series prefixes, SAC codes, templates, message text — is a **DB row resolved by business date**, never a constant in code. A price or rate change is a new dated row, not a release. | `module_price_book`, `tax_class` (`effective_from`/`_to`), `doc_series`, `setting`, `template`, `reminder-templates` |
|
||||
| Documents immutable once issued | Issuing assigns the number; after that the document is never edited or deleted. Corrections are **credit notes** (own per-FY series, links the invoice via `ref_doc_id`, CGST Act s.34). Cancel keeps the number consumed; only issued, unpaid, unallocated docs may cancel. QT→PI→INV convert by carrying lines forward into a new draft. | `repos-documents.ts` — `issueDocument`, `raiseCreditNote`, `cancelDocument`, `convertDocument` |
|
||||
| Portable-repo pattern | All data access is plain exported functions taking the `DB` handle first arg — no ORM, no repo classes, no ambient singletons. Multi-write operations wrap in `db.transaction(...)`. Keep SQL portable (SQLite today, **Postgres is the locked production engine** — D15); avoid engine-specific SQL. | every `repos-*.ts` |
|
||||
| Append-only audit | Every mutation calls `writeAudit(db, userId, action, entity, id, before, after)` in the **same transaction** as the change. The audit log is append-only — never update or delete rows. Previews and the public share route write nothing. | `audit.ts` |
|
||||
| Client id is the future tenant id | `client.id` is a client-generated UUIDv7 that becomes `tenant_id` when the cloud tier stands up — same rows, promoted once. Never re-key clients. | `repos-clients.ts` |
|
||||
| No silent caps | Every list that can grow paginates or warns; never silently truncate. | reports, directory queries |
|
||||
| Strict TS, green before landing | Strict TypeScript everywhere; `npm run typecheck` and `npm test` both clean before anything lands. Money math is locked by tests — a rounding change without a test change does not land. | `tsc`, vitest (177 tests) |
|
||||
|
||||
## Running it
|
||||
|
||||
```
|
||||
npm install # workspace root, once
|
||||
# backend (serves API on :5182, and the built web UI + public /share links)
|
||||
cd apps/hq && npm start # build-server.mjs → dist/server.cjs; first boot prints a one-time owner password
|
||||
# frontend dev (Vite on :5183, proxies /api and /share to :5182)
|
||||
cd apps/hq-web && npm run dev
|
||||
```
|
||||
|
||||
- Owner login on first boot: `admin@tecnostac.com` + the one-time password printed in the
|
||||
server log (change it immediately). The "Gmail disconnected" banner is expected until Gmail is connected.
|
||||
- Env: `HQ_DATA_DIR` (DB location), `SIMS_PIN_PEPPER` (set once, never change), `HQ_SECRET_KEY`
|
||||
(before Gmail), `GOOGLE_*` (Gmail), `AWS_*` (Cost Explorer), `HQ_PORT` (default 5182).
|
||||
- Health check: `GET /api/health` → `{ ok: true }`.
|
||||
- Verified state: `npm install` + typecheck clean, 177 tests pass. Exercise real flows end
|
||||
to end before claiming done.
|
||||
|
||||
## Docs (kept in `docs/`)
|
||||
|
||||
`14-SPEC-HQ-CONSOLE.md` (the HQ spec — read first), `11-ADMIN-SUPPORT-CONSOLE.md` (the console
|
||||
this grows into), `16-PROJECT-RULES.md` (hard rules), `07-DB-AND-CONFIG.md` (config-over-code +
|
||||
DB strategy), `06-DECISIONS.md` (every decision has a D-number — add one when you decide
|
||||
something), `DEPLOY-HQ.md` (go-live runbook). Follow **The Tables Rule**: anything that can be a
|
||||
table IS a table, in docs and UI.
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue