@factory/database-client
TASK-0135 multi-client Postgres routing (per the Phase 15 spec,
docs/tasks/phase-15-production.md; implementation in prisma/clients.ts).
The factory reads and writes through two Prisma clients so read-heavy traffic can be pinned to a replica without touching call sites:
| Traffic | Client | Target |
|---|---|---|
Writes (and all $transactions) |
PRIMARY (db.write()) |
DATABASE_URL |
| Permission / version reads (must see latest committed state) | PRIMARY | DATABASE_URL |
| Tree / listing / search-index reads | READER (db.read()) |
DATABASE_REPLICA_URL when set, otherwise the primary (single-node dev/CI fallback) |
Usage
import { createDatabaseClients } from "@factory/database-client";
const db = createDatabaseClients({
databaseUrl: process.env.DATABASE_URL!,
databaseReplicaUrl: process.env.DATABASE_REPLICA_URL, // optional
});
db.write().page.create({ data }); // primary, always
db.read().block.findMany({ where }); // replica when configured
await db.disconnect();
db.read() is deliberately NOT a general substitute for the primary: reader
reads are only acceptable for tree/listing/search traffic. Permission
decisions and optimistic-concurrency version checks must stay on the primary
(a lagged membership or version read is a security bug) — the hot-path call
sites are the only places wired to it (see
tests/integration/replica-routing.integration.test.ts).
Dependencies
@prisma/client only. No new runtime dependencies are introduced.
Tests
pnpm --dir packages/database-client test # vitest
pnpm --dir packages/database-client typecheck