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>
34 lines
1.1 KiB
TypeScript
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 };
|