Files
continuum-backend/src/db/index.ts
T
octoturge c312e37b4a Drop the pooler from the MVP: point everything straight at Postgres
.env.example and the README still told people to use pgCat on :6432, the
exact setup that hangs on every parameterised query. With no prod and one
backend instance there is nothing for a pooler to multiplex, and
postgres-js already pools in-process, so DATABASE_URL now points at
Postgres on :5432 in .env.example, dev-env.sh and drizzle.config.ts.

prepare:false is kept in src/db/index.ts on purpose, so adding
PgBouncer later (tested working) is a config change rather than a code
change. The long measurement narrative in that file's comment is cut to
the decision and the pointer to PLAN.md, where the numbers now live.
2026-10-20 10:24:19 +00:00

28 lines
1.1 KiB
TypeScript

import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import * as schema from "./schema";
// No pooler in front of this for the MVP: DATABASE_URL points straight at
// Postgres, and postgres-js already pools connections in-process (`max`).
//
// `prepare: false` is kept deliberately so a transaction-mode pooler can be
// added later without touching this file. Which one matters - measured
// 2026-10-20: through pgCat 1.2.0 any query with a bind parameter hangs
// forever (every Drizzle query has one), while PgBouncer 1.22 in transaction
// mode runs the same queries and passes scripts/e2e-authz.sh. See PLAN.md.
//
// Migrations go straight at Postgres either way: drizzle.config.ts cannot
// pass `prepare: false`, and drizzle-kit hung at commit through pgCat.
const connectionString = process.env.DATABASE_URL;
if (!connectionString) {
throw new Error("DATABASE_URL is not set");
}
const client = postgres(connectionString, {
prepare: false,
max: Number(process.env.DATABASE_POOL_MAX ?? 10),
});
export const db = drizzle(client, { schema });
export type Database = typeof db;