@accounter/server
Version:
Accounter GraphQL server
18 lines (17 loc) • 1.04 kB
TypeScript
import type { Pool, PoolClient } from 'pg';
/**
* Run `fn` inside a single transaction whose RLS context is pinned to the given
* tenant. `set_config(..., true)` is transaction-local (SET LOCAL), so the
* context is cleared on COMMIT/ROLLBACK and never leaks to the pooled
* connection's next user.
*
* Control-plane and gateway-initiated ingestion present an auth session with an
* empty businessId, so TenantAwareDBClient (which derives the tenant from the
* auth session) cannot be used. The authoritative tenant instead comes from the
* resolved alias / cryptographically-validated grant and is pinned here so the
* `tenant_isolation` RLS policies (USING / WITH CHECK `owner_id =
* get_current_business_id()`) on the email_ingestion_* tables are satisfied —
* these tables use FORCE ROW LEVEL SECURITY, so even the table owner is subject
* to them and the raw pool cannot bypass the policy.
*/
export declare function withTenantContext<T>(pool: Pool, tenantId: string, fn: (client: PoolClient) => Promise<T>): Promise<T>;