Migration List

Applied and pending migrations, sorted by version. A migration applied after a later version is flagged — that is the signature of two branches merged without a rebase, and it means this schema matches no single branch.

src/components/ui/migration-list.tsx

About

From the component's own source, where it was written.

Database migrations, applied and pending.

Order is the version string, never the array order. Migrations are named by timestamp precisely so they sort deterministically, and a list that trusts the order it was handed will show a rebase artefact as the real sequence.

A migration applied *out of order* — one whose version predates an already-applied migration — is flagged. That is the signature of two branches merged without rebasing, and it means the schema on this database is not the schema any single branch describes.

Irreversible migrations are marked. Knowing there is no down-path before you run something is the difference between a rollback and a restore from backup.

Install

npx astralyx-ui add migration-list

Usage

import { MigrationList } from '@/components/ui/migration-list'

<MigrationList migrations={migrations} />

Composer

Change the props and the source below follows.

2 pending
  • 20260714093000create users

    Applied84ms

  • 20260801121500add accounts

    Applied122ms

  • 20260810140000add sessions indexout of order

    Applied610ms

    Applied after a later version — the usual sign of two branches merged without a rebase.

  • 20260815090000backfill account_idirreversible

    Applied41200ms

  • 20260828101500drop legacy_sessions

    Failed

    ERROR: cannot drop table legacy_sessions because other objects depend on it

  • 20260901080000add role default

    Pending

  • 20260902093000add deleted_at

    Pending

Props
tsx
<MigrationList migrations={migrations} />

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

MigrationList

Database migrations, applied and pending.

Extends ComponentProps<'div'>.

PropTypeDefaultDescription
migrationsMigration[]required{ version, name, state, appliedAt?, duration?, irreversible?, error? }.
nowDate——
localestring'en-GB'—
emptyLabelReactNode'No migrations'—
irreversibleLabelReactNode'irreversible'—
outOfOrderLabelReactNode'out of order'—
outOfOrderNoteReactNode'Applied after a later version — the usual sign of two branches merged without a rebase.'—
pendingSummary(count: number) => ReactNodeDEFAULT_PENDING_SUMMARY—
orderdetected—Applied after a higher version — a merge without a rebase.

Types

Migration

FieldTypeDescription
versionstringSortable identifier — usually a timestamp prefix.
nameReactNode—
stateMigrationState—
appliedAt?Date—
duration?numberExecution time in milliseconds.
irreversible?booleanKnowing there is no down-path before you run something is the difference between a rollback and a restore from backup.
error?ReactNode—
TypeDefinitionDescription
MigrationState
'applied' | 'pending' | 'failed' | 'rolled-back'
—

Behaviour

TopicDetailDescription
orderingby versionNever by array order. Migrations are timestamp-named precisely so they sort deterministically, and trusting the supplied order shows a rebase artefact as the real sequence.