Files
Croissant Le Doux 14200edb60 feat: scaffold outreach engine monorepo on the novelpad-desktop stack
Workspaces: config (copied), outreach-core (schema + actions/queries +
hard gates), outreach-ai (Gemini client + embeddings copies, profiler and
mission-fit-judge agent stubs), outreach-worker (DBOS executor with
nightly ingest + hourly expiry workflows), outreach-review (RR7 review
queue v0). Initial drizzle migration incl. pgvector extension.

Stack contract: Yarn 4.5.0 + Turbo, Node 22.16, Drizzle 0.44.6 +
pgvector, DBOS 4.17.6, @google/genai on Vertex, gemini-embedding-001
@1536, React Router v7. Files copied from novelpad-desktop carry
provenance headers @ 62c56b87.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 11:08:24 -04:00

34 lines
1.1 KiB
TypeScript

// Copied/adapted from novelpad-desktop apps/website/app/db/db.server.ts @ 62c56b87
import { schema, type NpOutreachDatabase } from '@novelpad/outreach-core';
import { drizzle } from 'drizzle-orm/node-postgres';
import pkg from 'pg';
const { Pool } = pkg;
// HMR-safe singleton. Without this, Vite re-evaluates this module on hot
// reload and instantiates a fresh Pool, while the previous pool lingers with
// open connections until idleTimeoutMillis fires — see the equivalent note
// in novelpad-desktop's apps/website/app/db/db.server.ts.
const g = globalThis as unknown as {
__outreachPool?: InstanceType<typeof Pool>;
__outreachDb?: NpOutreachDatabase;
};
const pool =
g.__outreachPool ??
(g.__outreachPool = new Pool({
connectionString: process.env.DATABASE_URL,
application_name: 'outreach-review',
max: Number(process.env.PG_POOL_MAX ?? 10),
idleTimeoutMillis: 30000,
connectionTimeoutMillis: Number(
process.env.PG_CONNECTION_TIMEOUT_MS ?? 15000,
),
}));
const db =
g.__outreachDb ??
(g.__outreachDb = drizzle(pool, { schema }) as unknown as NpOutreachDatabase);
export { db, pool };