feat(server): vendor createPool in-repo, drop dead @lilith/quinn-db-pg
Some checks are pending
Server Typecheck & Test / bun typecheck + test (push) Waiting to run
Swift Build & Test / swift build + test (push) Waiting to run

The @lilith/quinn-db-pg@1.0.1-dev.* snapshot was only ever published to the
retired black.lan Verdaccio and resolves nowhere now (not on the DO forge, no
local cache, no source). Replace the single `createPool` import with a faithful
in-repo pg.Pool factory (service-name -> QUINN_<SERVICE>_DB_URL) and add `pg`
as a direct dependency (was transitive via the dead package).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Natalie 2026-06-29 17:49:03 -04:00
parent 144571d042
commit e84b878cea
3 changed files with 40 additions and 2 deletions

View file

@ -10,8 +10,8 @@
"test": "bun test"
},
"dependencies": {
"@lilith/quinn-db-pg": "1.0.1-dev.1776900251",
"hono": "^4.6.0",
"pg": "^8.13.0",
"zod": "^3.23.0"
},
"devDependencies": {

View file

@ -1,5 +1,5 @@
import { Pool, type QueryResultRow } from 'pg';
import { createPool } from '@lilith/quinn-db-pg';
import { createPool } from './pool';
export type Sql = Pool;

View file

@ -0,0 +1,38 @@
import { Pool } from 'pg';
import { logger } from '@/shared/logger';
/**
* Service-keyed Postgres pool factory.
*
* Each service reads its own connection string from `QUINN_<SERVICE>_DB_URL`
* (e.g. service `macsync` `QUINN_MACSYNC_DB_URL`). The URL points at the local
* pgBouncer (`127.0.0.1:6432`), which terminates TLS to the DO Managed PG
* upstream so the appbouncer hop is plaintext on the loopback and needs no
* `ssl` block here.
*
* Vendored in-repo (was `@lilith/quinn-db-pg`) that registry lived on the
* retired `black` host and is gone; this is the faithful, self-contained pool.
*/
export function createPool(serviceName: string): Pool {
const envKey = `QUINN_${serviceName.toUpperCase().replace(/-/g, '_')}_DB_URL`;
const connectionString = process.env[envKey];
if (!connectionString) {
throw new Error(`${envKey} is required (no default — set the connection string in env)`);
}
const pool = new Pool({
connectionString,
max: Number(process.env['DB_POOL_MAX'] ?? 10),
idleTimeoutMillis: 30_000,
connectionTimeoutMillis: 10_000,
});
// An idle backend dropping the connection emits 'error' on the pool; without a
// handler node-postgres rethrows and crashes the process. Log and let the pool
// evict/replace the client on next checkout.
pool.on('error', (err) => {
logger.error(`db: idle client error`, { service: serviceName, err: err.message });
});
return pool;
}