# Database Migrations


The SDK does **not** ship its own migration runner — the old
`applyPatches()`/`DatabasePort` helpers were deleted. Database migrations
are owned by the **dal-pg engine** (`runMigrations` +
`primebrick-db` CLI), documented in the **dal-pg dev-guide → Database
migrations** page.

This page covers what the SDK does around that engine: the boot wiring
inside `createMicroservice`.

## Boot ordering

`createMicroservice` accepts a `dbPatches` option. When present, the
engine runs **before any domain traffic is served** — HTTP routes,
NATS subscriptions and the registry heartbeat only come up after the
migration step completes. The script `scripts/database-patch-apply.ts`
in each microservice invokes the same `runMigrations` code path for
manual runs (`pnpm db:migrate`).

The migration step needs a raw `pg.Pool` handle — this is the one
sanctioned `getPool()` seam in service code:

```ts
// index.ts — the only standards-exempt getPool() call site
dbPatches: { pool: () => getDal().getPool(), /* … */ }
```

## Degraded mode

`runMigrations` returns `{ mode, degraded, applied[], failed[],
pendingReview[], skipped[], securityEvents[] }`. A failed patch does
**not** stop the service from booting — the boot continues degraded and
**domain routes return 503** until an admin remediates through the FE
`/system/migrations` page (retry / approve / resolve). Later patches in
the module are not executed after a failure (ordering is mandatory).

## The reload invariant

**The migration engine is the only component allowed to read DB state
before itself — and whatever it reads, it re-reads after applying ≥1
patch.** Concretely today: the engine re-reads `db_migration.mode` from
`<schema>.config_entries` post-apply (a patch may have changed it) and
logs the effective next-run mode. Everything else (ConfigLoader, shield
registries, translations) runs after the step and sees fresh state by
construction.

Any future boot-stage read added *before* the migration step must
implement the same reload — otherwise it can observe pre-patch schema
or config.
