Model
Four pieces, each with one job.
Registering a migration is a seed data row, not an application change.
componentName exists so sibling components can register into the same registry rather than each growing a private one.
Status values
The ledger records four statuses, and only one of them means “done”.
That
DRY_RUN never counts as applied is the property that makes previewing safe: an operator can preview a migration as often as they like without ever convincing the supervisor the work is done.
Why the ledger commits separately
record#MigrationRun runs in a forced-new transaction. A migration that fails rolls its own work back; if the ledger row were written in that same transaction it would roll back with it, and the installation would have no record that the attempt happened.
Committing the ledger independently means a failure leaves evidence behind. This is the difference between diagnosing a broken migration and rediscovering it.
Running migrations
run#PendingMigrations applies everything with no success recorded, in sequence order. It is idempotent — a second call applies nothing — which is what makes it safe to run on every deployment rather than only when someone remembers.
Three gates apply, to the sweep and to a targeted run alike:
- A parked migration is skipped. Parking exists so one broken migration does not strand every migration behind it — the rest of the sweep proceeds, and the parked one is dealt with on its own.
- A migration whose prerequisites have not succeeded is refused and recorded as blocked, rather than run against the state it was not written for.
- An already-applied migration is skipped.
run#Migration runs one named migration for targeted remediation, under the same gates. dryRun#Migration previews one.
Operator surface
get#MigrationStatus returns registry and ledger state for every migration in sequence order, including the most recent attempt’s detail. get#MigrationHistory returns every attempt at one migration, newest first, each with its own sanitized failure detail — which is how a failed migration is diagnosed without shell access to the installation.
Both are exposed to the admin application through admin.MigrationAdminServices, behind the DARPAN_ADMIN_API artifact fence and a super-admin content gate. The component also ships a Migrations screen carrying the same status, dry-run and run-pending actions.
Failure detail is sanitized before it is stored, because it is read by an operator through a remote surface.
Registered migrations
The seed registry currently declares six, in sequence:Adding a migration
- Write the service that performs the work. Accept a
dryRunparameter if the work can be meaningfully previewed. - Add a
DarpanMigrationseed row naming the component, the service, a description an operator can decide from, and a sequence number. - Add
DarpanMigrationPrereqrows for anything that must have succeeded first. - Set
supportsDryRuntoYonly once the service genuinely honours it.