import pg from 'pg'; import pino from 'pino'; import { config } from '../config/index.js'; const logger = pino({ name: 'data' }); export const pool = new pg.Pool({ connectionString: config.DATABASE_URL }); /** * RLS tenant isolation wrapper. * Sets `app.tenant_id` for the duration of the callback, then resets. * Prevents connection pool tenant context leakage (BMad must-have). */ export async function withTenant(tenantId: string, fn: (client: pg.PoolClient) => Promise): Promise { const client = await pool.connect(); try { await client.query('BEGIN'); await client.query(`SET LOCAL app.tenant_id = '${tenantId}'`); const result = await fn(client); await client.query('COMMIT'); return result; } catch (err) { await client.query('ROLLBACK'); throw err; } finally { await client.query('RESET app.tenant_id'); client.release(); } }