Database & migrations
Merinaa's DatabaseModule wraps Deepkit ORM with a migration runner
that picks up files from each module's migrations/ folder.
Where migrations live
modules/bank/
├── entities/
│ └── bank-account.entity.ts
└── migrations/
├── 0001-create-bank-accounts.ts
└── 0002-add-pin-column.ts
Migration file shape
// modules/bank/migrations/0001-create-bank-accounts.ts
import { Migration } from '@merinaa/server';
export default class extends Migration {
up = async () => {
await this.sql.exec(`
CREATE TABLE bank_accounts (
id INT AUTO_INCREMENT PRIMARY KEY,
owner_id VARCHAR(36) NOT NULL,
balance DECIMAL(12,2) NOT NULL DEFAULT 0
);
`);
};
down = async () => {
await this.sql.exec(`DROP TABLE bank_accounts;`);
};
}
Running migrations
pnpm run db:migrate # apply pending migrations
pnpm run db:migrate:create add-xyz # scaffold a new migration file
Migrations run automatically on server start when autoMigrate: true
is set (default in DatabaseModule.forRoot). For production, consider
running them from CI before deploying a new build.
Naming convention
NNNN-kebab-case-description.ts where NNNN is a zero-padded sequence.
The migration runner picks them up in lexicographic order across every
module, so the prefix disambiguates order across modules.
Rollback
pnpm run db:migrate down # undo the last applied migration
Schema generation
Entities decorated with @entity + @PrimaryKey / @AutoIncrement can
also be used with Deepkit's schema generator — but for anything beyond
"scaffold the table", hand-written migrations give you control over
column order, indexes and foreign keys.