import { PrismaClient } from "@prisma/client"; import { PrismaPg } from "@prisma/adapter-pg"; /* The console's database clients. Two, and the difference between them is the whole design. * * opsDb() connects as `ops_ro`, a Postgres role granted SELECT on control-plane columns only — * counts, dates, configuration — and nothing on customer content: no wearer's name, no photo, no * request text, no coordinator's email. The grants are in the ops_ro_grants migration and are * proven on production by scripts/ops-ro-probe.cjs. The point is that the guard is the database, * not code review: there is no row-level security in this product and no linter, so a query * written against the wrong table in some future screen must fail with a permission error rather * than return data. * * revealDb() connects as `ops_reveal`, which may read exactly four columns of one table: a * facility's id and its three coordinator contacts. It exists so that revealing a contact is not an * exception carved into code but a second, narrower door with its own key — widening the reveal's * SELECT fails at the database too. Only lib/ops/reveal.ts may use it. * * Both are read-only by construction. The console's own tables — Operator, OperatorEvent, * RevealGrant — are written through lib/db.ts, because they are the console's records. * * Both are lazy: nothing runs at import time, so a box without the variables still starts the * product; only the console fails, and it fails closed. Small pools — this is a small box, and * lib/db.ts already holds the main one. */ const g = globalThis as unknown as { __opsDb?: PrismaClient; __revealDb?: PrismaClient }; function make(envVar: "OPS_DATABASE_URL" | "OPS_REVEAL_DATABASE_URL", max: number): PrismaClient { const url = process.env[envVar]; if (!url) throw new Error(`${envVar} not set`); return new PrismaClient({ adapter: new PrismaPg({ connectionString: url, max }), log: ["error"] }); } export function opsDb(): PrismaClient { if (!g.__opsDb) g.__opsDb = make("OPS_DATABASE_URL", 2); return g.__opsDb; } export function revealDb(): PrismaClient { if (!g.__revealDb) g.__revealDb = make("OPS_REVEAL_DATABASE_URL", 1); return g.__revealDb; }