feat(versionresolver): support skip-forward resume for orphan ledger versions

This commit is contained in:
2026-04-08 13:36:38 +00:00
parent 5ffeeefc7a
commit 4e3fd845d4
6 changed files with 104 additions and 15 deletions

View File

@@ -244,6 +244,22 @@ export class SmartMigration {
const stepStart = Date.now();
let entry: IMigrationLedgerEntry;
try {
// Detect skip-forward resume: the running ledger cursor is past
// this step's fromVersion but hasn't yet reached its toVersion.
// The step handler is being run against data that may already be
// partially in the target shape — handlers must be idempotent.
const isSkipForward = VersionResolver.greaterThan(
currentVersion,
step.fromVersion,
);
if (isSkipForward) {
this.log.log(
'info',
`smartmigration: step "${step.id}" running in skip-forward mode ` +
`(ledger at "${currentVersion}", step starts at "${step.fromVersion}"). ` +
`Step handler must be idempotent.`,
);
}
this.log.log(
'info',
`smartmigration: running step "${step.id}" (${step.fromVersion}${step.toVersion})`,
@@ -273,6 +289,8 @@ export class SmartMigration {
data.steps[step.id] = entry;
data.currentVersion = step.toVersion;
await ledger.write(data);
// Advance the running cursor used by skip-forward detection.
currentVersion = step.toVersion;
applied.push({ ...entry });
this.log.log(
'info',