Skip to main content

Overview

Project Zoe uses PostgreSQL with TypeORM. Schema management differs by environment:
Never set DB_SYNCHRONIZE=true in staging or production. It can silently drop columns or tables. All staging and production schema changes must go through a migration file.

Running migrations


Creating a migration

After modifying a TypeORM entity, generate a migration automatically:
TypeORM diffs the current database schema against the entity definitions and writes a migration file with up() and down() methods. Always review the generated file before committing — TypeORM occasionally generates destructive statements (e.g. dropping a column it thinks was removed) that need to be corrected manually.

Migration workflow

  1. Make your entity change.
  2. Generate the migration: npm run migration:generate -- src/migrations/<Name>.
  3. Review the generated file in src/migrations/.
  4. Test locally: npm run migration:run then npm run migration:revert to confirm both directions work.
  5. Commit the entity change and the migration file together in the same PR.
CI applies pending migrations (npm run migration:run) on every deploy to staging and production before restarting the app.

Migration files location


Multi-tenancy indexing

All major entities have composite indexes on (tenant, id) and other frequently-queried columns:
This ensures queries are always scoped efficiently to a single tenant and never scan the full table.

Data source

The TypeORM DataSource is configured in src/data-source.ts and used by both the app and the migration CLI:

Seeding

Demo data is seeded via NestJS commands (not migrations) so seeding can be run independently of schema management:
See the Quickstart for a full seeding walkthrough.