Database Migrations — ayunis-core-backend
Golden Rule
Never write migration files by hand. Always auto-generate them from TypeORM entity changes.
Working Directory
cd ayunis-core-backend
Workflow
1. Modify the TypeORM Entity (Record)
Change the schema definition in the relevant infrastructure/persistence/postgres/schema/ file.
All records must extend BaseRecord (src/common/db/base-record.ts), which provides id, createdAt, and updatedAt columns automatically:
// e.g. src/domain/agents/infrastructure/persistence/postgres/schema/agent.record.ts
import { BaseRecord } from 'src/common/db/base-record';
@Entity('agents')
export class AgentRecord extends BaseRecord {
@Column({ type: 'varchar', length: 255, nullable: true })
marketplaceSlug: string | null;
}
2. Generate the Migration
Run the generate command with the full output path (no file extension):
npm run migration:generate:dev -- src/db/migrations/DescriptiveMigrationName
Example:
npm run migration:generate:dev -- src/db/migrations/AddMarketplaceSlugToAgents
TypeORM will diff the current database schema against your entities and produce a timestamped migration file, e.g.:
src/db/migrations/1770650039552-AddMarketplaceSlugToAgents.ts
3. Review the Generated Migration
Read the generated file and verify:
- •It contains only the expected changes (no unrelated drift)
- •
up()anddown()are symmetric (whatupcreates,downdrops)
If the migration contains unexpected changes, your local database may be out of sync. Run npm run migration:run:dev first, then regenerate.
4. Run the Migration
npm run migration:run:dev
5. Validate
npx tsc --noEmit # Types still compile npm run test # Tests pass npm run docker:dev # Service starts
Naming Convention
Use PascalCase describing the change:
| Change | Migration Name |
|---|---|
| Add a column | AddMarketplaceSlugToAgents |
| Create a table | CreateTeamSharesTable |
| Add an index | AddIndexOnThreadCreatedAt |
| Remove a column | RemoveUserShareScope |
| Add a constraint | CascadeDeleteSharesOnScopeDelete |
Commands Reference
npm run migration:generate:dev -- src/db/migrations/Name # Generate from entity diff npm run migration:run:dev # Apply pending migrations npm run migration:revert:dev # Revert last migration npm run migration:show:dev # List migration status
Anti-Patterns
| Don't | Why | Instead |
|---|---|---|
| Write migration SQL by hand | Drift between entities and schema | Modify the entity, then auto-generate |
| Run generate without a path | File lands in wrong location | Always pass src/db/migrations/Name |
| Skip reviewing the generated file | May include unrelated schema drift | Read and verify before running |
| Commit a migration without running it | May fail at runtime | Always migration:run:dev first |
| Edit a migration that's already been run in shared environments | Breaks migration history | Create a new migration instead |