You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
3.2 KiB
Markdown
61 lines
3.2 KiB
Markdown
# 16 — Project Hard Rules
|
|
|
|
Founder-ratified (2026-07-10). These are **hard rules** — a PR that violates one does not
|
|
merge; an exception requires a written note in 06-DECISIONS.
|
|
|
|
## Documentation & communication
|
|
|
|
| # | Rule |
|
|
|---|---|
|
|
| R1 | **The Tables Rule:** anything that can be a table IS a table — in docs, specs, and UI. Prose only for what tables cannot say. |
|
|
| R2 | STATUS.md updated the same day anything ships; docs never lag the code. |
|
|
| R3 | Every decision gets a D-number in 06-DECISIONS with date and rationale. |
|
|
|
|
## Money & correctness
|
|
|
|
| # | Rule |
|
|
|---|---|
|
|
| R4 | Integer paise only; every rounding step explicit; float rupees never enter the domain. |
|
|
| R5 | One shared billing engine everywhere; the server re-verifies every document to the paisa (mismatch = reject). |
|
|
| R6 | Committed documents are immutable; corrections are new documents referencing the original. |
|
|
| R7 | Stock and balances are derived from movements — never stored, never trusted as numbers. |
|
|
| R8 | Golden tests lock all money math; a rounding change without a golden-test change does not merge. |
|
|
|
|
## Configuration over code
|
|
|
|
| # | Rule |
|
|
|---|---|
|
|
| R9 | Anything that varies by tenant/edition/store/counter/user is a DB row (settings hierarchy), never a constant. |
|
|
| R10 | Tax rates, thresholds, and compliance values are dated config — resolved by business date, never hard-coded. |
|
|
| R11 | Editions, privileges, limits, and prices are rows (`plan_feature`, `price_book`) — see 15-EDITIONS. |
|
|
| R12 | Every user-facing string is a `message_catalog` row (language fallback chain); no literals in UI code. |
|
|
| R13 | No silent caps: every LIMIT paginates or warns visibly (the 2000-SKU truncation class of bug is forbidden). |
|
|
|
|
## Data & sync (D12/D14 guardrails)
|
|
|
|
| # | Rule |
|
|
|---|---|
|
|
| R14 | `tenant_id` on every row; client-generated UUIDv7 ids; no server-assigned identity. |
|
|
| R15 | The outbox row is written in the same transaction as the change — from the first build, even while dormant. |
|
|
| R16 | All data access goes through portable repositories; Oracle-specific SQL needs a written justification. |
|
|
| R17 | Every mutation writes its audit row in the same transaction (who, what, before, after). |
|
|
|
|
## Counter experience
|
|
|
|
| # | Rule |
|
|
|---|---|
|
|
| R18 | The counter is never blocked: errors warn inline, never modal, never trap; the cart is never lost. |
|
|
| R19 | Keyboard-first; scan-box focus is sacred; nothing steals it mid-bill. |
|
|
| R20 | Feature gates render as visible upsells; role gates hide navigation but in-flow actions raise the supervisor PIN. |
|
|
| R21 | Fonts and assets are bundled — never CDN, never trust shop-machine fonts. |
|
|
|
|
## Engineering discipline
|
|
|
|
| # | Rule |
|
|
|---|---|
|
|
| R22 | Strict TypeScript everywhere; typecheck + all tests green before merge. |
|
|
| R23 | Nothing is "done" until exercised end-to-end in a real browser (the /verify discipline). |
|
|
| R24 | New features ship with their edition mapping, settings rows, and message rows in the same change. |
|
|
| R25 | Scale targets (15-EDITIONS capacity table) are validated by load test, not assumed — "likely" is not "verified". |
|
|
| R26 | Integrations go behind our own interface (GSP, UPI, WhatsApp…) so vendors are config, not surgery. |
|