|
|
|
@ -263,3 +263,29 @@ client-book filter UI; 4 minor — typed contact roles absent, dashboard/aging s
|
|
|
|
anchored on doc_date, non-atomic dbPassword PATCH, audit-outside-txn on three new
|
|
|
|
anchored on doc_date, non-atomic dbPassword PATCH, audit-outside-txn on three new
|
|
|
|
write paths) — all confirmed and fixed in one pass (`fix(review)` commit).
|
|
|
|
write paths) — all confirmed and fixed in one pass (`fix(review)` commit).
|
|
|
|
Suite at 345 tests / 66 files after the review pass.
|
|
|
|
Suite at 345 tests / 66 files after the review pass.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## D19 — Postgres switch executed (D15 delivered) ✅ DELIVERED (2026-07-17)
|
|
|
|
|
|
|
|
The engine slice queued after D18, done BEFORE the real APEX cutover so production data
|
|
|
|
|
|
|
|
is born in Postgres and nothing is ever migrated. Spec:
|
|
|
|
|
|
|
|
`superpowers/specs/2026-07-17-postgres-switch-design.md`. The calls that matter:
|
|
|
|
|
|
|
|
- **One async DB interface, two engines.** Every repo/route/scheduler/test awaits
|
|
|
|
|
|
|
|
`db.all/get/run/exec/transaction`. better-sqlite3 stays for dev + the fast suite
|
|
|
|
|
|
|
|
(`SqliteDb`, statement-cached, manual BEGIN/SAVEPOINT); Postgres (`PgDb`, node-pg Pool)
|
|
|
|
|
|
|
|
is selected by `DATABASE_URL`. Repos keep `?` placeholders and portable SQL; the pg
|
|
|
|
|
|
|
|
adapter rewrites `?`→`$n`, pins transactions to one pooled client via AsyncLocalStorage
|
|
|
|
|
|
|
|
(nested = savepoints), and parses int8/numeric to JS numbers (paise stay integer math).
|
|
|
|
|
|
|
|
- **Postgres schema choices:** bigint for every paise column (int4 overflows at ₹2.15
|
|
|
|
|
|
|
|
crore), 0/1 flags stay INTEGER (repos say `active=1` on both engines), JSON stays TEXT
|
|
|
|
|
|
|
|
(node-pg auto-parses jsonb — would break JSON.parse at the repo edge), dates stay TEXT
|
|
|
|
|
|
|
|
ISO. Numbered migrations + schema_migrations runner (migrations-pg.ts), applied
|
|
|
|
|
|
|
|
atomically; the reminder rule_kind CHECK is born in its final widened form.
|
|
|
|
|
|
|
|
- **Proof:** default suite 346/346 on SQLite (zero behavior change); 5-test pg
|
|
|
|
|
|
|
|
integration suite (opt-in `HQ_PG_TEST_URL`, wipes its target) green on local
|
|
|
|
|
|
|
|
PostgreSQL 17 — migrations-from-zero, series numbering + due-date stamp, paisa-exact
|
|
|
|
|
|
|
|
payment→paid, ON CONFLICT exactly-once reminders, savepoint rollback, HTTP boot smoke.
|
|
|
|
|
|
|
|
- **Known nuance before go-live:** LIKE is case-insensitive on SQLite, case-sensitive on
|
|
|
|
|
|
|
|
Postgres — client search will match case-sensitively in prod until repos switch to
|
|
|
|
|
|
|
|
`LOWER(...) LIKE LOWER(?)`.
|
|
|
|
|
|
|
|
- Local dev Postgres: PostgreSQL 17 Windows service, superuser `postgres`, role `hq`,
|
|
|
|
|
|
|
|
databases `hq` (runtime) + `hq_test` (integration suite). Prod = RDS at go-live, same
|
|
|
|
|
|
|
|
`DATABASE_URL` mechanism.
|
|
|
|
|