docs(d23): SMS rate-card D-record; catalogue additions; test count 372

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat/client-detail-redesign
Thomas Joise 4 days ago
parent e91e1741b8
commit 0e85163b68

@ -43,7 +43,7 @@ distilled to what applies to HQ. A change that breaks one does not land.
| 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 (363 tests) |
| 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 (372 tests) |
## Running it
@ -66,7 +66,7 @@ cd apps/hq-web && npm run dev
- Postgres integration tests: `HQ_PG_TEST_URL=postgres://hq:hq_dev@localhost:5432/hq_test npm test`
(wipes that database each run — never point it at real data).
- Health check: `GET /api/health``{ ok: true }`.
- Verified state: `npm install` + typecheck clean, 363 tests pass. Exercise real flows end
- Verified state: `npm install` + typecheck clean, 372 tests pass. Exercise real flows end
to end before claiming done.
## Docs (kept in `docs/`)

@ -34,7 +34,7 @@ document and conversation we've had with them.
## Build state (start here)
Working codebase, not a plan. `npm install` + typecheck are clean and **346 tests pass**.
Working codebase, not a plan. `npm install` + typecheck are clean and **372 tests pass**.
Current state and run-vs-pending detail live in **[STATUS.md](STATUS.md)**; the go-live
runbook (server, HTTPS, backups, Gmail/AWS/import wiring, the Postgres switch) is in
**[docs/DEPLOY-HQ.md](docs/DEPLOY-HQ.md)**.

@ -25,7 +25,7 @@ section-per-module quotation PDF — then closed all 8 findings from its review.
| --- | --- |
| `npm install` | clean |
| `npm run typecheck` (root + workspaces) | clean, no errors |
| `npm test` (`vitest run`) | **346 tests pass across 66 files** |
| `npm test` (`vitest run`) | **372 tests pass across 70 files** |
The 346 figure is the live `vitest run` count measured 2026-07-17, after the
D18 go-live cluster **and its post-delivery review pass** (8 reviewer findings

@ -343,3 +343,26 @@ and NO migration — the founder's flexibility mandate, delivered. Built **addit
D20 (login trio keeps its columns; retiring them into field_spec is a later cleanup after the
direction is confirmed). Verified on the real re-import: RTGS 13 fields / SMS 6 / MobileApp
1, 53/53 RTGS + 102/105 SMS links carrying structured values. Suite 363 green.
## D23 — SMS volume-band billing (dated rate card) ✅ DELIVERED (2026-07-17)
SMS packs are the majority of billing, so they get first-class quantity-tiered pricing.
`usage_rate_band` is a dated per-module rate card (generic — any usage-billed module can
have one). `resolveUsageRate(module, count, date)` picks the band with the highest
`min_qty <= count`; a count below the lowest band is under the minimum order. `buildLines`
resolves a line's unit price as: explicit per-line override > tiered rate card > dated price
book — so an SMS line prices by count automatically, a save below the minimum is refused,
and the live preview warns instead of throwing. Founder card seeded (effective 2026-04-01):
≥50k → ₹0.40, ≥100k → ₹0.37, ≥200k → ₹0.34, ≥300k → ₹0.30 per SMS, minimum 50,000 — money
locked to the paisa in tests (50k→₹23,600, 100k→₹43,660, 200k→₹80,240, 300k→₹1,06,200 incl
18% GST). Owner routes GET/POST /modules/:id/rate-card. Rates are integer paise; a new card
is a new dated set of rows, so issued invoices keep the rate they were billed at.
## Catalogue additions (2026-07-17) — CloudBackup + RecoverX configured as data
Two recently-developed modules set up entirely as configuration (no code), proving the D20/
D21 flexible model: **CloudBackup & Disaster Management** (8 fields incl. AWS creds as a
secret; subscription ₹36k/yr + setup ₹25k + integration ₹10k) and **RecoverX / Recovery
Module** (7 fields incl. CBS server IP, APEX URL, field-officer count, GPS consent, admin
secret; app ₹35k + implementation ₹10k + integration ₹5k + AMC ₹15k/yr). Quote content
seeded from the real quotations for the section-per-module PDF.
Suite at 372 tests / 70 files after D21 + D23.

Loading…
Cancel
Save