fix(db): isolate billing and auth connection pools, release the redeploy-check transaction early, cache integration tool schemas
Merged
WA
6d ago+622+622+012345678901234567890123456789-216-216-012345678901234567890123456789
Summary
- Billing writes and auth lookups get their own connection pools (
dbFor('billing'), 4 connections;dbFor('auth'), 3). When slow work saturates a process's 10-connection pool, postgres.js pipelines new queries onto busy connections, so a billing transaction'sBEGINcould wait behind a large result and be killed by its 4stransaction_timeout. Settlement transactions (recordCumulativeUsage,recordUsagefallback, threshold billing, the execution-logger usage reconcile, job spend) and the auth adapter,getAuthDatabase()fallback and API-key lookup now run on their own clients. App-wide billing reads stay ondbso they don't crowd a small pool isPrimaryPoolClient()in@sim/dbreplaces theexecutor === dbchecks that gate the auth policy caches and the reporting usage cache, so those caches still apply on a sub-pool client and never on a transaction or the replicaDATABASE_URL_BILLING/DATABASE_URL_AUTHare optional; unset, the pools fall back to the process URL, which already gives the client-side isolationcheckNeedsRedeploymentkeeps every read in its REPEATABLE READ snapshot but runs the state diff after commit, so the connection is no longer held idle in transaction during the comparison- Integration tool schemas are built once per process per surface/mode, frozen and shared, instead of per viewer with a 5s TTL (every call rebuilt ~5.3k schemas, stringified them to size the cache and deep-cloned them). Viewer gating and the plan-dependent email tagline still apply per request; output is byte-identical. BM25 term counts are memoized per shared schema
Type of Change
- Bug fix
Testing
- New
lib/db/pool-isolation.integration.ts: fills every connection of the realdbpool, then requires a cumulative usage write, an auth adapter session read and an API-key lookup to finish within 1.5s. Fails on the pre-fix code (all three stall), passes with the fix - Integration:
pool-isolation,usage-log,reporting-usage-cache,get-organization-plan-seats(57 tests) against disposable Postgres - Unit: new
deployment-status.test.ts(diff no longer runs while the transaction is open; red pre-fix),db.test.ts, auth cache-identity case insecurity-policy.test.ts(red withexecutor === db), payload tests (one build per process, cross-viewer isolation, tagline per viewer; red pre-fix), plus 54 neighbouring files (635 tests) check:tool-registry-boundary,check:schema-mock,check:test-patterns,check:utils,check:comment-hygiene,check:unused-exports,check:file-names; generators in sync. Type-check and full audits run in CI
Checklist
- Code follows project style guidelines
- Self-reviewed my changes
- Tests added/updated and passing (new tests pass the
test-auditauthoring gate) - No new warnings introduced
- I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)