/** * Shared withTenant() RLS helper. * Copy into each product's src/data/db.ts or import from shared. * * CRITICAL (BMad must-have): Always RESET app.tenant_id in finally block * to prevent connection pool tenant context leakage. */ import pg from 'pg'; export async function withTenant( pool: pg.Pool, 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(); } } /** * Health check query — verifies DB connectivity. */ export async function healthCheck(pool: pg.Pool): Promise { try { await pool.query('SELECT 1'); return true; } catch { return false; } }