The database
The database is AWS RDS Postgres 17 on adb.t4g.micro instance. It has 20 GB of storage, and the storage grows automatically. Storage is encrypted, and deletion protection is on.
Backups run every day. RDS keeps them for 14 days, with point-in-time recovery inside that window. A restore ran on September 18, 2026. See Monitoring and recovery.
The database is in a private subnet. Only the API’s tasks can reach it. To run a query in production, see Run a command inside AWS.
Tables
The schema is inpackages/db/src/schema.ts and uses Drizzle.
The schema follows these rules:
- One
requeststable for every form. Thetypecolumn and the subject columns carry the differences. - One
taxonomy_termstable for every facet, such as disease states and report types. - Event tables are append-only. Nobody edits or deletes a row in
request_eventsorbilling_events. The admin shows these rows as the history. - Request history is permanent. Database triggers refuse a delete on
requestsandquotes, and an edit or delete onrequest_events. Test cleanup lifts this for one transaction with theoncoeverything.allow_history_deletesetting. - No generic item table. Each catalog has its own typed table.
docs/architecture/content-model.md explains these rules in full. Read it before you add a table or a route.
Migrations
1
Change the schema
Edit
packages/db/src/schema.ts.2
Generate the migration
packages/db/migrations.3
Apply it locally
4
Push
In production the API applies pending migrations when a new task starts, before its port opens. The health check cannot pass until they are done.
Directory data
The recruiter, education, podcast and other directory listings are not in the database.packages/directories builds them as JSON files from the client’s spreadsheets. The web app reads the files at build time.
