swap-read-replicas
Send read queries to Postgres read replicas. Use when the user decides the primary needs relief from reads, or asks about read replicas or splitting reads and writes. Not for debugging; when something
SKILL.md.claude/skills/swap-read-replicas/SKILL.md
GitHubAdd read replicas
- Interface:
Database(read,write,disconnect) inpackages/db/src/client.ts. - Today:
createDatabasereturns the same primary client forreadandwrite. Repositories already choose per query:readfor lists and dashboards that tolerate lag,writefor changes and any read that must see them. - Provided by
DatabaseModule.forRoot(packages/nest-common/src/database.ts), called in each service'ssrc/app.module.ts(api, worker, notifications, webhooks). - Env:
<SERVICE>_DATABASE_URLand<SERVICE>_DATABASE_POOL_MAXfromdatabaseEnvinpackages/nest-common/src/env.ts.
Swap
- In
createDatabase, buildreadfrom a replica URL when one is given (a secondcreateDb, or Prisma's read-replicas extension on the primary), and disconnect both. Row-level security works the same: policies and grants replicate. - Add an optional
<SERVICE>_DATABASE_REPLICA_URLtodatabaseEnv, pass it throughDatabaseModule.forRootin each service that wants it, and document it in.env.exampleanddocs/environment.md. Unset keeps today's behaviour. - Deployed: the replica's URL per role in the
db-<role>secrets (the data chart,deploy/charts/data) and its pooler. - Audit reads that follow a write in the same request: they must use
write(database.writeor inside thetenantTx), or the user sees stale data.
The Python service (apps/ai/app/db/session.py) has one engine; it's separate.
Tests
packages/db/test/security.test.ts (row-level security and privileges). Integration
suites run with read equal to write; add a test that points read at a separate
client and checks a repository's read-after-write paths use write.
Finish
- The verify skill.
- Ask the
revieweragent to review the change, and thesecurity-revieweragent: a new implementation brings its own credentials and sends data somewhere new. If you wrote a migration, themigration-revieweragent too. - Update the seam's row in the README's "Scaling path" table if what's "Now" changed.