import "server-only"; import { Pool } from "pg"; // Die einzige Stelle im Projekt, die `pg` importieren darf. // // Der Grund steht in lib/db/index.ts: eine Abfrage ausserhalb von withUser() // läuft ohne Sitzungskontext und damit — je nachdem, was die vorherige // Anfrage auf derselben gepoolten Verbindung hinterlassen hat — im Namen // einer fremden Person. Deshalb wird der Pool nicht exportiert, sondern nur // die Kysely-Instanz, die ihn benutzt, und eine ESLint-Regel verbietet den // Import von `pg` und von dieser Datei überall sonst. let instance: Pool | undefined; /** * Der Verbindungspool — erst beim ersten Zugriff angelegt, nicht beim Import. * * Der Unterschied ist nicht kosmetisch: `next build` importiert jedes Route- * Modul, um die Seitendaten einzusammeln. Entstünde der Pool dabei, bräuchte * schon der Bau Zugangsdaten zur Datenbank — ein Container-Abbild liesse sich * in einer Baustrecke ohne Produktionsgeheimnisse nicht mehr erzeugen. */ export function getPool(): Pool { if (instance) return instance; const connectionString = process.env.DATABASE_URL; if (!connectionString) { throw new Error( "DATABASE_URL fehlt. Erwartet wird ein PostgreSQL-Verbindungsstring — " + "die Anwendung spricht direkt mit der Datenbank, nicht über eine API-Schicht." ); } instance = new Pool({ connectionString, // Der Standard sind 10; bei serverseitigem Rendering hängt an jeder // Anfrage genau eine Transaktion, und mehr Verbindungen als die Datenbank // zulässt bringen nur Wartezeit an einer anderen Stelle. max: Number(process.env.DATABASE_POOL_MAX ?? 10), // Eine Anfrage, die länger braucht, ist kaputt und soll das melden statt // eine Verbindung zu belegen. statement_timeout: 20_000, idle_in_transaction_session_timeout: 20_000, connectionTimeoutMillis: 10_000, // Verwaltete Anbieter (Azure, RDS, Supabase) verlangen TLS; lokal nicht. ssl: process.env.DATABASE_SSL === "false" ? undefined : { rejectUnauthorized: false }, }); // Ein Fehler auf einer Leerlaufverbindung beendet sonst den Prozess. instance.on("error", (err) => { console.error("Unerwarteter Fehler auf einer Leerlaufverbindung:", err); }); return instance; }