@alexify/migronaut 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +190 -0
- package/README.md +41 -3
- package/bullmq.d.ts +484 -8
- package/index.d.ts +1264 -9
- package/migronaut.schema.json +93 -1
- package/package.json +9 -2
- package/src/bullmq/background-processor.js +541 -0
- package/src/bullmq/index.js +12 -0
- package/src/bullmq/jobs.js +254 -7
- package/src/bullmq/processor.js +348 -21
- package/src/bullmq/producer.js +185 -13
- package/src/bullmq/service.js +484 -45
- package/src/cli/commands/background.js +500 -0
- package/src/cli/commands/create.js +6 -0
- package/src/cli/exit-codes.js +6 -0
- package/src/cli/index.js +2 -0
- package/src/core/audit.js +11 -1
- package/src/core/background-audit.js +139 -0
- package/src/core/background-drift.js +126 -0
- package/src/core/background-dry-run.js +375 -0
- package/src/core/background-engine.js +849 -0
- package/src/core/background-kit.js +432 -0
- package/src/core/background-partition.js +298 -0
- package/src/core/background-runner.js +305 -0
- package/src/core/background-sandbox.js +701 -0
- package/src/core/background-shard.js +542 -0
- package/src/core/background-spec.js +597 -0
- package/src/core/background-store.js +951 -0
- package/src/core/background-throttle.js +269 -0
- package/src/core/background-watch-plan.js +164 -0
- package/src/core/background-watch-store.js +78 -0
- package/src/core/background-watch.js +610 -0
- package/src/core/background.js +1127 -0
- package/src/core/bson-peer.js +23 -0
- package/src/core/changelog.js +32 -0
- package/src/core/collections.js +78 -8
- package/src/core/config.js +102 -12
- package/src/core/converge-plan.js +86 -7
- package/src/core/converge.js +88 -0
- package/src/core/lock.js +48 -21
- package/src/core/migration-logger.js +279 -0
- package/src/core/migrator.js +1027 -22
- package/src/core/options.js +36 -0
- package/src/core/run-recorder.js +6 -1
- package/src/core/run.js +26 -12
- package/src/core/runner.js +34 -8
- package/src/core/server-info.js +9 -2
- package/src/core/shard-info.js +76 -0
- package/src/core/versioning-spec.js +181 -0
- package/src/errors/index.js +88 -0
- package/src/index.js +16 -0
- package/src/utils/error.js +11 -2
- package/src/utils/job-ref.js +44 -0
- package/src/utils/loader.js +77 -9
- package/src/utils/migration-name.js +33 -1
- package/src/utils/redact.js +140 -3
- package/src/utils/telemetry.js +110 -0
- package/src/utils/template.js +62 -1
- package/src/versioning/config.js +155 -0
- package/src/versioning/document.js +326 -0
- package/src/versioning/index.js +50 -0
- package/src/versioning/internal.js +279 -0
- package/src/versioning/mongoose.js +151 -0
- package/src/versioning/occ.js +318 -0
- package/src/versioning/registry.js +187 -0
- package/src/versioning/upcaster.js +213 -0
- package/versioning.d.ts +666 -0
- package/versioning.js +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,196 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
Release headings carry the publish date (`## vX.Y.Z — YYYY-MM-DD`).
|
|
5
5
|
|
|
6
|
+
## v2.4.0 — 2026-10-07
|
|
7
|
+
|
|
8
|
+
Migration logs for the application's users. Additive: a migration that never touches the new
|
|
9
|
+
context fields, and a kit with no `migration:log` listener, behave as before. Everything new is
|
|
10
|
+
experimental — its shape may still change in a minor release (named here).
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`ctx.logger` in every migration** — the kit's logger with the run's correlation bound into the
|
|
15
|
+
fields of every line: `runId`, `migration`, `direction`, `batch`, `attempt`, and `jobId` /
|
|
16
|
+
`groupId` when a queue job runs it. Pino's `(fields, msg)` order is accepted too.
|
|
17
|
+
- **`ctx.run`** — that correlation as a frozen object: `{ id, direction, migration?, batch?,
|
|
18
|
+
attempt?, jobId?, groupId?, requestedBy?, reason? }`. `attempt` is 2 or more when the driver
|
|
19
|
+
retried the transaction and the body runs again (each attempt gets a context of its own).
|
|
20
|
+
- **The `migration:log` event** — a `ctx.logger` call whose fields hold `userland: true` is also
|
|
21
|
+
emitted, for the application to store and show its users; calls without the marker emit
|
|
22
|
+
nothing. The payload is `{ kind, runId, …correlation, level, msg, data, at, seq, truncated? }`:
|
|
23
|
+
`data` a bounded, redacted copy of the fields (8 levels, 1000 entries, 4096-character strings;
|
|
24
|
+
an `Error` as `{ name, message, code?, codeName? }` with the values a server error quotes masked,
|
|
25
|
+
as in `msg`; BSON values and binary data up to 4096 bytes kept as they are),
|
|
26
|
+
`seq` increasing within a run, `at` a `Date` (TTL-ready). It fires whatever the logger's level,
|
|
27
|
+
and with `logger: null`. Migronaut stores none of it — the
|
|
28
|
+
[Migration Logs](https://migronaut.vercel.app/guide/migration-logs) guide has the recipe.
|
|
29
|
+
- **Hooks get it too** — `beforeAll`/`afterAll` the run's logger and `ctx.run` (no migration, no
|
|
30
|
+
attempt), `beforeEach`/`afterEach`/`onError` the migration's.
|
|
31
|
+
- **`job: { id, groupId? }` on `up`, `down` and `redo`** — the queue job a run works for, bound into
|
|
32
|
+
`ctx.run`, its lines (the kit's own included) and its events; and `job: { id }` on
|
|
33
|
+
`runBackgroundSlice`.
|
|
34
|
+
- **Queue adapter** — the processor passes each job's id and group to its run, and writes the
|
|
35
|
+
migration's `userland: true` lines into the job's log as one-line `✎ …` rows (matched by job and
|
|
36
|
+
run id, so a timed-out body never writes into the next job's log — nor into a later run of the
|
|
37
|
+
same job). A background lane does the same for its slice, into the lane job's log. The new
|
|
38
|
+
`userlandLogRows` option (`createMigrationQueue`, both processors; default 1000) caps the rows one
|
|
39
|
+
job's log takes — the rest are counted in one closing row.
|
|
40
|
+
- **Background migrations** — `ctx.logger` is bound to `ctx.background`, which gains the lane's
|
|
41
|
+
`runId`, its `jobId` (and, for a lane an `up` drives with `backgroundInline`, the run's job and
|
|
42
|
+
`groupId` — its lines land in that migration job's log) and the transaction `attempt`; a
|
|
43
|
+
`userland: true` call emits `migration:log` with `kind: 'background'`. A dry run marks its lines
|
|
44
|
+
`dryRun: true` and emits nothing.
|
|
45
|
+
- **Retried transactions, visible** — when the driver retried a migration's transaction and its
|
|
46
|
+
body ran again, `migration:success` / `migration:error` and the kit's `✔ Applied` / `✖ Error`
|
|
47
|
+
lines carry `attempts`, a failure's context too, and the `migronaut.migration` span always has
|
|
48
|
+
`migronaut.migration.attempts`. A run that names a `job` puts `migronaut.job.id` /
|
|
49
|
+
`migronaut.job.group_id` on its `migronaut.run` span.
|
|
50
|
+
- **A `ctx.logger` call that is dropped** (a field whose getter throws) **or cut to the event's
|
|
51
|
+
bounds** leaves one debug line per run — never one per call.
|
|
52
|
+
- **Types** — `MigrationRunInfo`, `JobRef`, `MigrationLogEvent` (`OrdinaryMigrationLogEvent |
|
|
53
|
+
BackgroundMigrationLogEvent`), `MigrationLogEventBase`, `MigrationLogLevel`,
|
|
54
|
+
`BackgroundRunInfo`, `MigrationLogger` (`ctx.logger`: `(msg, fields?)`, pino's `(fields, msg?)`
|
|
55
|
+
and an `Error` as the message — any `MigronautLogger` or pino instance is one); `logger?` and
|
|
56
|
+
`run?` on `MigrationContext` (optional, so a context built by hand still type-checks);
|
|
57
|
+
`attempts?` on `MigrationEvent`.
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
|
|
61
|
+
- `ctx.background` of a background migration is now frozen, and typed as `BackgroundRunInfo`.
|
|
62
|
+
**A type change on an experimental API:** its `generation` is now `number | undefined` (as it
|
|
63
|
+
always was at runtime for the live drift watcher), so strict TypeScript that reads it as a
|
|
64
|
+
`number` needs a check; `ctx.logger` is typed `MigrationLogger`, which every `MigronautLogger`
|
|
65
|
+
still fits.
|
|
66
|
+
- The kit's log lines of a run that names a `job` carry `jobId` / `groupId`.
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
- **An `async` event listener that rejects no longer crashes the process.** The kit is an
|
|
71
|
+
`EventEmitter` with `captureRejections`: a listener's rejected promise is logged at debug level,
|
|
72
|
+
like a listener that throws, instead of surfacing as an `unhandledRejection`.
|
|
73
|
+
|
|
74
|
+
### Documentation
|
|
75
|
+
|
|
76
|
+
- **How It Works** — a new guide page with architecture diagrams: the engine and its entry points,
|
|
77
|
+
the life of a run, the lock, where the state lives, which tool fits which change, background
|
|
78
|
+
migrations and what a run reports.
|
|
79
|
+
- **Diagrams across the guides** — Core Concepts (a migration's states, batches, a run), Transactions,
|
|
80
|
+
Declared Collections (a converge run), Document Versioning (the contract, optimistic concurrency,
|
|
81
|
+
the revision invariant, expand → background → contract), Background Migrations (statuses, one
|
|
82
|
+
lane's batches, passes, drift), the queue adapter (the line, a failure, background jobs) and
|
|
83
|
+
Migration Logs. They are Mermaid, drawn in the browser by a small theme component; `mermaid` is a
|
|
84
|
+
docs-only devDependency, loaded only by a page that has a diagram.
|
|
85
|
+
- **The home page** shows what 2.1 – 2.4 added — declared collections, Atlas Search, document
|
|
86
|
+
versioning, background migrations, OpenTelemetry, migration logs — with a diagram of how the parts
|
|
87
|
+
fit together.
|
|
88
|
+
|
|
89
|
+
## v2.3.0 — 2026-10-06
|
|
90
|
+
|
|
91
|
+
Document versioning and background migrations. Additive: nothing changes for a project that
|
|
92
|
+
declares no `versioning` and writes no `background` file. Everything new is experimental — its
|
|
93
|
+
shape may still change in a minor release (named here).
|
|
94
|
+
|
|
95
|
+
### Added
|
|
96
|
+
|
|
97
|
+
- **Document versioning** — a collection definition takes `versioning: { current, min?, field?,
|
|
98
|
+
revision?, revisionField?, index? }`: the shape version (`__v`) and the optimistic-concurrency
|
|
99
|
+
revision (`__rev`) as one contract. Converge folds it into the validator (the version an `int`
|
|
100
|
+
with a `minimum` of `min` and no `maximum`; the revision `int|long`; `moderate` when the
|
|
101
|
+
validator exists for versioning alone) and an index `{ __v: 1, _id: 1 }` — on a sharded
|
|
102
|
+
collection `{ __v: 1, …shard key, _id: 1 }`, the ordinary one kept with a row that says why.
|
|
103
|
+
Raising `min` over documents still below it is refused before any write (a `conflict` row, no
|
|
104
|
+
id named).
|
|
105
|
+
- **`@alexify/migronaut/versioning`** — a third entry point, with no engine behind it, for the
|
|
106
|
+
repository layer: `defineShapes` (`stamp`, `onInsert`, `stampUpsert`, `upcaster`, `plugin`),
|
|
107
|
+
`updateWithRevision` / `replaceWithRevision` / `findOneAndUpdateWithRevision`
|
|
108
|
+
(`RevisionConflictError` with `reason: 'conflict' | 'not-found' | 'unknown'`),
|
|
109
|
+
`retryOnConflict`, `bumpRevision`, the in-memory `upcaster` (`ShapeVersionError`),
|
|
110
|
+
`isVersion`, and `versioningPlugin` for Mongoose (its version key moved to `__rev`, optimistic
|
|
111
|
+
concurrency on). Per-version shape types without codegen: `AnyShape`, `CurrentShape`,
|
|
112
|
+
`ShapeAt`, `Stamped`, `Body`, `BackgroundMigrationFor`, a typed `defineShapes<Shapes>()(…)`
|
|
113
|
+
(`versioning.d.ts` needs TypeScript ≥ 5.0).
|
|
114
|
+
- **Background migrations** — a migration file with `export const background = { collection,
|
|
115
|
+
from, to, migrate | migrateBatch, revert?, … }` (or a free-form `step(ctx)`), which `up`
|
|
116
|
+
registers without running; the rewrite runs beside the migration line, never holding the
|
|
117
|
+
migration lock:
|
|
118
|
+
- **partitions and lanes**: the collection split into `_id` ranges from a sampled quantile per
|
|
119
|
+
BSON type — or, on a sharded collection, into runs of chunks per shard, with targeted reads
|
|
120
|
+
and writes, a shard-key guard (`shard-key-changed`) and `shardConcurrency`; leases are slots,
|
|
121
|
+
capped by a unique index at `maxParallel` across every process, every checkpoint fenced;
|
|
122
|
+
- **a coordinator** that plans passes, finalizes them and completes when nothing matches any
|
|
123
|
+
more (`maxPasses` against an old release that keeps writing); writes are `stampedDiff`s under
|
|
124
|
+
the optimistic filter, so an application write in between is never lost and untouched fields
|
|
125
|
+
keep their BSON types;
|
|
126
|
+
- **transactional batches** (`transaction: true`) with side writes through `ctx.session`;
|
|
127
|
+
- **pacing**: `pauseMs`, a `throttle` hook, replication lag and an adaptive (AIMD) controller;
|
|
128
|
+
- **`requires`** between background migrations (a DAG, unblocked as they complete) and from
|
|
129
|
+
ordinary migrations, which wait (`BackgroundPendingError`, or `onBackgroundPending: 'stop'`);
|
|
130
|
+
`backgroundInline` runs them inside `up`;
|
|
131
|
+
- **controls**: pause, resume, cancel, retry (`fromStart`), repin, unlock; **dry runs** on a
|
|
132
|
+
sample (`--validate` through the real write path in an always-aborted transaction) and of
|
|
133
|
+
`step` migrations in a sandbox (refusals exit 34);
|
|
134
|
+
- **drift after completion**: the drift watch (`verifyBackground`, every 10 minutes in each
|
|
135
|
+
runtime, `backgroundOnDrift: 'reopen' | 'report'`) and the **live drift watcher**
|
|
136
|
+
(`watchBackground`, change streams, one leader per collection, `backgroundDrift: 'poll' |
|
|
137
|
+
'stream' | 'both'`);
|
|
138
|
+
- **three runtimes**: `migronaut background run`, `startBackgroundRunner()` in the application,
|
|
139
|
+
and the queue (below); `status()`, `background status --partitions`, an audit check, events
|
|
140
|
+
`background:*`, and OpenTelemetry spans `migronaut.background.slice` /
|
|
141
|
+
`migronaut.background.coordinate` with their metrics.
|
|
142
|
+
- **`migronaut background <action>`** — status, run, pause, resume, cancel, retry, repin,
|
|
143
|
+
dry-run, unlock, verify and watch; `create --background`.
|
|
144
|
+
- **Background migrations on the queue** — `createMigrationQueue({ background: true | {…} })`: a
|
|
145
|
+
queue of their own, a coordinator job per background migration with its lanes as children,
|
|
146
|
+
heals from MongoDB (worker start, every sync tick, every drift-watch tick) and a stall
|
|
147
|
+
takeover; `startBackgroundWorker()`, `enqueueBackground()`, the `background-verify` schedule,
|
|
148
|
+
`createBackgroundProcessor()`. An `up` plan stops before a migration that waits for a
|
|
149
|
+
background one.
|
|
150
|
+
- **Config**: `backgroundCollection`, `backgroundInline`, `backgroundOnDrift`, `backgroundDrift`,
|
|
151
|
+
`backgroundShardAware`, each with its `MIGRONAUT_*` variable.
|
|
152
|
+
- **Errors and exit codes**: `REVISION_CONFLICT` (29), `SHAPE_VERSION_UNSUPPORTED` (30),
|
|
153
|
+
`BACKGROUND_PENDING` (31), `BACKGROUND_FAILED` (32), `BACKGROUND_CONFLICT` (33),
|
|
154
|
+
`SANDBOX_REFUSED` (34).
|
|
155
|
+
- **`shapes.occ(name)`** — the revision guards and `bumpRevision` bound to a collection's field
|
|
156
|
+
names; `RevisionConflictContext` types an error's `context`.
|
|
157
|
+
- **`startBackgroundRunner().stop({ timeoutMs })`**, `RunnableBackground` (what
|
|
158
|
+
`runnableBackground()` now returns: live leases, last progress, coordinator), `previous` on a
|
|
159
|
+
background status (the registration a re-registration replaced), `plan.atLeast`.
|
|
160
|
+
|
|
161
|
+
### Changed
|
|
162
|
+
|
|
163
|
+
For code written against 2.2 — the queue adapter's types and results, and two type-level details:
|
|
164
|
+
|
|
165
|
+
- **`SyncJobResult.held` means a failure again, only.** A tick whose next migration waits for a
|
|
166
|
+
background migration reports `waiting: { migration, waitsFor }` instead; while it still waits
|
|
167
|
+
for the same thing, later ticks say so without planning. A group that stops at such a migration
|
|
168
|
+
has `upToDate: false` (`MigrationGroup.waiting` says why).
|
|
169
|
+
- **`JOB_NAMES` has three more values** (`background`, `background-lane`, `background-verify`) and
|
|
170
|
+
`MigrationJobView.returnvalue` three more result types: an exhaustive `Record` over either needs
|
|
171
|
+
them.
|
|
172
|
+
- **`MigronautErrorCode` has six more members** (above): an exhaustive `switch` with a `never`
|
|
173
|
+
default needs a case for each — as with the codes 2.1 added.
|
|
174
|
+
- **`CollectionDefinition.indexes` and `searchIndexes` are `readonly` arrays**, so a definition
|
|
175
|
+
declared `as const` type-checks; code that pushes into a typed definition's array must copy it.
|
|
176
|
+
- **Background metric names** (experimental): `migronaut.background.throttled`,
|
|
177
|
+
`migronaut.background.drift.detected`, `migronaut.background.transaction.retried`.
|
|
178
|
+
|
|
179
|
+
### Notes
|
|
180
|
+
|
|
181
|
+
- A typed `current` past the highest declared shape is a compile error. Written inline it reads
|
|
182
|
+
"Type 'number' is not assignable to type 'never'"; from an imported `as const` definition, it
|
|
183
|
+
names the two versions ("Type '3' is not assignable to type '2'").
|
|
184
|
+
- The shard-aware mode needs `clusterMonitor` (it reads `config.collections` and
|
|
185
|
+
`config.chunks`); without it, a sharded collection is partitioned by `_id`.
|
|
186
|
+
- Fail-closed limits: `maxDocumentErrors` is at most 1000 (the ids a state keeps); a revision
|
|
187
|
+
guard refuses an `_id` given as an operator; a background `filter` may not run server-side
|
|
188
|
+
JavaScript; `create --background`'s placeholder collection (`'TODO'`) is refused by `up`;
|
|
189
|
+
`watchBackground`, `enqueueBackground` and `createBackgroundProcessor` refuse options they do
|
|
190
|
+
not know.
|
|
191
|
+
- A lane stopped by its process (a shutdown, a deploy) is not a failed slice, and
|
|
192
|
+
`maxSliceFailures` counts failed slices in a row. `down` of a one-way background migration pauses
|
|
193
|
+
it and waits for its lanes before it decides; a `step` migration counts as having rewritten
|
|
194
|
+
documents once one step was checkpointed.
|
|
195
|
+
|
|
6
196
|
## v2.2.0 — 2026-10-05
|
|
7
197
|
|
|
8
198
|
Atlas Search and Vector Search indexes in declared collections. Additive: a definition without
|
package/README.md
CHANGED
|
@@ -66,6 +66,10 @@ change before it touches your database.
|
|
|
66
66
|
- **Zero config files required** — drive everything from env vars if you prefer.
|
|
67
67
|
- **Pino-friendly logging** — the `logger` option is pino-compatible; pass a pino instance directly
|
|
68
68
|
and migronaut logs through it (with a `component: 'migronaut'` child binding).
|
|
69
|
+
- **Migration logs for your users (experimental)** — every migration gets `ctx.logger`, bound to its
|
|
70
|
+
run (run id, migration, attempt, queue job), and `ctx.run`; a line marked `userland: true` is also
|
|
71
|
+
emitted as `migration:log` for your service to store and show — migronaut stores none of it
|
|
72
|
+
([guide](https://migronaut.vercel.app/guide/migration-logs)).
|
|
69
73
|
- **Your id format** — run ids and queue group ids are random UUIDs by default; pass
|
|
70
74
|
`generateId: ulid` (or cuid2, nanoid, UUIDv7 — any `() => string`) and every id migronaut mints
|
|
71
75
|
comes from your generator.
|
|
@@ -75,6 +79,15 @@ change before it touches your database.
|
|
|
75
79
|
- **Migrations as a queue (optional)** — `@alexify/migronaut/bullmq` runs each migration as its own
|
|
76
80
|
BullMQ job, in order, so migronaut can be a migration service: trigger it over HTTP, on a
|
|
77
81
|
schedule, or from a deploy hook that waits for the result.
|
|
82
|
+
- **Document versioning (experimental)** — declare a collection's shape version (`__v`) and
|
|
83
|
+
optimistic-concurrency revision (`__rev`) once; converge enforces them, and
|
|
84
|
+
`@alexify/migronaut/versioning` gives your repository layer `updateWithRevision`, typed
|
|
85
|
+
per-version shapes, an upcaster and a Mongoose plugin ([guide](https://migronaut.vercel.app/guide/versioning)).
|
|
86
|
+
- **Background migrations (experimental)** — long data rewrites (`export const background = {…}`)
|
|
87
|
+
that `up` only registers and that run beside the migration line: partitions and parallel lanes
|
|
88
|
+
across pods, checkpoints, pause/resume, transactional batches, shard-aware on sharded clusters,
|
|
89
|
+
dry runs, and a drift watcher that upgrades old-shape writes after completion — from the CLI,
|
|
90
|
+
inside your app, or on the queue ([guide](https://migronaut.vercel.app/guide/background-migrations)).
|
|
78
91
|
|
|
79
92
|
### How it compares to `migrate-mongo`
|
|
80
93
|
|
|
@@ -180,7 +193,7 @@ Full docs, guides, and the API reference live at
|
|
|
180
193
|
- [Core Concepts](https://migronaut.vercel.app/guide/concepts) — migrations, batches, the changelog, locking
|
|
181
194
|
- [Getting Started](https://migronaut.vercel.app/guide/getting-started) & [Tutorial](https://migronaut.vercel.app/guide/tutorial)
|
|
182
195
|
- [Configuration](https://migronaut.vercel.app/guide/configuration) · [Writing Migrations](https://migronaut.vercel.app/guide/writing-migrations) · [Transactions](https://migronaut.vercel.app/guide/transactions) · [Hooks](https://migronaut.vercel.app/guide/hooks)
|
|
183
|
-
- [Programmatic API](https://migronaut.vercel.app/guide/api) · [Migrations as a Queue (BullMQ)](https://migronaut.vercel.app/guide/bullmq) · [OpenTelemetry](https://migronaut.vercel.app/guide/opentelemetry) · [CI/CD](https://migronaut.vercel.app/guide/ci-cd) · [Troubleshooting](https://migronaut.vercel.app/guide/troubleshooting)
|
|
196
|
+
- [Programmatic API](https://migronaut.vercel.app/guide/api) · [Migrations as a Queue (BullMQ)](https://migronaut.vercel.app/guide/bullmq) · [Migration Logs](https://migronaut.vercel.app/guide/migration-logs) · [OpenTelemetry](https://migronaut.vercel.app/guide/opentelemetry) · [CI/CD](https://migronaut.vercel.app/guide/ci-cd) · [Troubleshooting](https://migronaut.vercel.app/guide/troubleshooting)
|
|
184
197
|
- Reference: [CLI Cheatsheet](https://migronaut.vercel.app/reference/cli) · [Error Codes](https://migronaut.vercel.app/reference/error-codes)
|
|
185
198
|
|
|
186
199
|
---
|
|
@@ -200,6 +213,7 @@ Every command accepts the global flags `--uri`, `--db`, `--dir`, `--config`, `--
|
|
|
200
213
|
| `migronaut down [file]` | Roll back the last batch, a chosen batch, the last N steps, one file, or to `--to <file>` |
|
|
201
214
|
| `migronaut redo [file]` | Roll back then re-apply (the last migration, or one file) |
|
|
202
215
|
| `migronaut converge` | Bring declared collections — indexes, search indexes and validators — to their declared state |
|
|
216
|
+
| `migronaut background <action> [name]` | Background migrations: `status`, `run`, `pause`, `resume`, `cancel`, `retry`, `repin`, `dry-run`, `unlock`, `verify`, `watch` |
|
|
203
217
|
| `migronaut status` | Print the full migration status table (`--check` to fail CI on pending) |
|
|
204
218
|
| `migronaut list` | List migrations, filtered by status |
|
|
205
219
|
| `migronaut dry-run <up\|down> [file]` | Preview a run without touching the database |
|
|
@@ -207,8 +221,8 @@ Every command accepts the global flags `--uri`, `--db`, `--dir`, `--config`, `--
|
|
|
207
221
|
| `migronaut lock` | Show who currently holds the migration lock |
|
|
208
222
|
| `migronaut unlock` | Force-release a stuck lock left behind by a crashed run |
|
|
209
223
|
|
|
210
|
-
Most data commands (`up`, `down`, `redo`, `converge`, `status`, `list`, `dry-run`,
|
|
211
|
-
`baseline`, `create`, `audit`, `lock`, `unlock`) accept **`--json`** for machine-readable output — see
|
|
224
|
+
Most data commands (`up`, `down`, `redo`, `converge`, `background`, `status`, `list`, `dry-run`,
|
|
225
|
+
`import`, `baseline`, `create`, `audit`, `lock`, `unlock`) accept **`--json`** for machine-readable output — see
|
|
212
226
|
[CI & automation](#ci--automation).
|
|
213
227
|
|
|
214
228
|
<details>
|
|
@@ -285,6 +299,15 @@ migronaut converge --yes # no confirmation (required for drops/rebuild
|
|
|
285
299
|
migronaut converge --no-lock # skip the concurrency lock (local dev only)
|
|
286
300
|
migronaut converge --json # machine-readable output (the converge result)
|
|
287
301
|
|
|
302
|
+
# background — background migrations (registered by up, rewritten in partitions)
|
|
303
|
+
migronaut background status # every background migration
|
|
304
|
+
migronaut background status --check # exit 32 if one failed, 31 if one is not completed
|
|
305
|
+
migronaut background run <name> # drive it from here (--concurrency N, --once, --all)
|
|
306
|
+
migronaut background pause <name> --wait # stop its lanes at the next batch
|
|
307
|
+
migronaut background dry-run <name> --validate # on a sample, in an always-aborted transaction
|
|
308
|
+
migronaut background verify # look for old-shape documents after completion
|
|
309
|
+
migronaut background watch # upgrade old-shape writes as they land (Ctrl-C stops)
|
|
310
|
+
|
|
288
311
|
# status — full status table
|
|
289
312
|
migronaut status # the full status table
|
|
290
313
|
migronaut status --check # exit 2 if any migration is pending (CI gate)
|
|
@@ -734,6 +757,9 @@ await mq.enqueueConverge(); // declared indexes and validators, as
|
|
|
734
757
|
failed one. Duplicate enqueues are deduplicated; an already-applied migration completes as
|
|
735
758
|
`skipped`.
|
|
736
759
|
- **Bring your own Worker** with `createMigrationProcessor()` (NestJS, BullMQ Pro).
|
|
760
|
+
- **What a migration logs for your users** (`logger.info(…, { userland: true })`) lands in the
|
|
761
|
+
job's log and reaches `mq.kit.on('migration:log', …)` with the job's id — keep it in a
|
|
762
|
+
collection of your own ([Migration Logs](https://migronaut.vercel.app/guide/migration-logs)).
|
|
737
763
|
|
|
738
764
|
→ **[Migrations as a Queue](https://migronaut.vercel.app/guide/bullmq)** ·
|
|
739
765
|
[runnable example service](examples/migration-service)
|
|
@@ -786,6 +812,13 @@ export default {
|
|
|
786
812
|
// onSearchUnavailable: 'fail', // 'skip' → converge without search indexes where Search is absent
|
|
787
813
|
// waitForSearchIndexes: false, // true → converge waits until search indexes are queryable
|
|
788
814
|
|
|
815
|
+
// ── Background migrations (experimental) — see `migronaut background` ───
|
|
816
|
+
// backgroundCollection: '_migronaut_background', // state (+ _partitions, _watch)
|
|
817
|
+
// backgroundInline: false, // true → run it to the end inside the registering `up`
|
|
818
|
+
// backgroundOnDrift: 'reopen', // 'report' → only report old-shape documents after completion
|
|
819
|
+
// backgroundDrift: 'poll', // 'stream' | 'both' → watch drift with change streams
|
|
820
|
+
// backgroundShardAware: 'auto', // 'off' → no shard-key partitions on sharded collections
|
|
821
|
+
|
|
789
822
|
// ── Code-only options (omit in migronaut.config.json) ─────────────────────────
|
|
790
823
|
// hooks: { beforeAll, afterAll, beforeEach, afterEach, onError },
|
|
791
824
|
// mongoose: myMongooseInstance, // pass if your migrations use Mongoose models
|
|
@@ -923,6 +956,11 @@ optional rather than merely discouraged:
|
|
|
923
956
|
| `MIGRONAUT_ON_SEARCH_UNAVAILABLE` | `onSearchUnavailable` | `fail` |
|
|
924
957
|
| `MIGRONAUT_WAIT_FOR_SEARCH_INDEXES` | `waitForSearchIndexes` | `false` |
|
|
925
958
|
| `MIGRONAUT_SEARCH_INDEX_WAIT_TIMEOUT_MS` | `searchIndexWaitTimeoutMs` | `600000` |
|
|
959
|
+
| `MIGRONAUT_BACKGROUND_COLLECTION` | `backgroundCollection` | `_migronaut_background` |
|
|
960
|
+
| `MIGRONAUT_BACKGROUND_INLINE` | `backgroundInline` | `false` |
|
|
961
|
+
| `MIGRONAUT_BACKGROUND_ON_DRIFT` | `backgroundOnDrift` | `reopen` |
|
|
962
|
+
| `MIGRONAUT_BACKGROUND_DRIFT` | `backgroundDrift` | `poll` |
|
|
963
|
+
| `MIGRONAUT_BACKGROUND_SHARD_AWARE` | `backgroundShardAware` | `auto` |
|
|
926
964
|
| `MIGRONAUT_ENV_FILE` | `envFile` | `.env` |
|
|
927
965
|
|
|
928
966
|
`fileExtensions`, `clientOptions`, `collections`, `client`, `mongoose`, `hooks`, `logger`,
|