# Database Migrations

This folder holds versioned, incremental database migrations for environments
that already have a populated schema (UAT / production). On a fresh dev box,
`npm run migrate` (destructive `sync({ force: true })`) is still the fastest
route — the model definitions in `src/database/models/` remain the source of
truth for the desired schema.

## Workflow

| Goal                                                | Command |
|-----------------------------------------------------|---------|
| Fresh / dev: drop everything, recreate from models  | `npm run migrate` |
| Mark every migration file here as already-applied   | `npm run migrate:baseline` |
| Apply only the migrations not yet recorded in DB    | `npm run migrate:up` |
| List applied vs pending                             | `npm run migrate:status` |
| Scaffold a new migration file                       | `npm run migrate:create -- <snake_case_name>` |

A typical post-fresh-setup sequence is therefore:

```bash
npm run migrate           # drop + recreate
npm run migrate:baseline  # stamp this folder's files as already applied
npm run seed:all          # seed master data
```

After every subsequent deploy on the same DB:

```bash
npm run migrate:up        # apply only the new migrations
```

## File naming convention

```
<YYYYMMDDHHMMSS>_<snake_case_description>.ts
```

Examples:
- `20260526143000_add_finance_kyc_column.ts`
- `20260601090000_drop_legacy_questionnaire_column.ts`

The runner sorts files lexicographically, so the timestamp prefix dictates
execution order. Always use UTC when manually creating timestamps; the
scaffolder (`npm run migrate:create`) emits a current-time UTC stamp for you.

## Authoring a migration

1. Run `npm run migrate:create -- add_finance_kyc_column`.
2. Edit the generated file — implement `up({ sequelize })`.
3. Update the corresponding Sequelize model so fresh `migrate` runs produce
   the same end state.
4. Commit both the migration and the model changes in the same PR.
5. On every environment that holds real data, run `npm run migrate:up`.

The runner records each successful migration in the `migrations` table
(`{ name, appliedAt, checksum }`) so re-runs are safe and idempotent at the
runner level — independently of the migration's own SQL.
