Commit Graph

2 Commits

Author SHA1 Message Date
Sravan dbd209ac2b feat(db): async DB adapter with swappable sqlite backend (Phase 1)
server/dbx.js selects a backend by DB_BACKEND (default sqlite; pg added at cutover).
server/db/sqlite.js wraps the synchronous node:sqlite instance in the async
interface repos will call — prepare(sql).{get,all,run}, exec(sql), tx(fn), init().
Results come back as resolved Promises so identical repo code runs on synchronous
SQLite (dev/test) and asynchronous Postgres (prod).

tx() gives multi-statement atomicity that stays correct on both engines (sqlite is
single-connection; the pg backend will run it on one pooled client) — needed for the
account-merge transaction in repos.

Verified: get/all/run/tx all work end-to-end; confirmed no code reads
.changes/.lastInsertRowid, so the repo conversion is purely sync->Promise. Unwired —
nothing requires dbx.js yet; prod path untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 21:10:53 +05:30
Sravan 1709a331d1 feat(db): Postgres target schema (Phase 1 of the migration)
server/db/schema.pg.sql — the full Postgres DDL, every column defined up front (no
ALTER-ordering fragility). SQLite→PG type mapping documented in-file (epoch-ms
INTEGER→BIGINT, 0/1 flags→SMALLINT kept numeric so app code is unchanged, sizes→
BIGINT, audit rowid→GENERATED IDENTITY). Mirrors the three existing FKs and adds a
new idx_messages_attachment (the /files auth scan we cached earlier becomes a keyed
lookup).

Validated against a throwaway Postgres 16: loads with no errors, 24 tables + 44
indexes created. Unwired — nothing uses it yet; the SQLite path is untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 19:46:04 +05:30