Skip to content

Automatic Rollback feature#471

Open
PedroCamata wants to merge 12 commits intoseppevs:masterfrom
PedroCamata:master
Open

Automatic Rollback feature#471
PedroCamata wants to merge 12 commits intoseppevs:masterfrom
PedroCamata:master

Conversation

@PedroCamata
Copy link

Description

This PR introduces an automatic rollback feature that when enabled, migrate-mongo tracks all write operations during migration up execution and stores inverse operations that can undo the changes, allowing the migration down to be done with minimal coding.

This feature is not intended to completely replace manual migration down scripts. Instead, it serves as a productivity tool that enables developers to:

  • Deliver simple migrations faster - Skip writing down() logic for straightforward CRUD operations
  • Reduce boilerplate code - Eliminate repetitive inverse operation logic
  • Prototype quickly - Test migrations with automatic rollback during development

When to use auto-rollback:

  • Simple insert, update, delete operations
  • Development and staging environments
  • Migrations with straightforward inverse operations

When to write manual down() scripts:

  • Complex data transformations
  • Operations involving aggregations or computed values
  • Production-critical migrations requiring explicit control
  • Scenarios where rollback logic differs from simple inverse operations

Auto-rollback is designed to complement your workflow, not replace careful migration planning.

How it works?

When auto rollback feature is enabled:

  1. During Migration Execution: Each collection operation is intercepted and wrapped to:

    • Capture the current state (for updates/replaces/deletes) or result (for inserts)
    • Generate the inverse operation needed to undo the change
    • Store the inverse operation in the autoRollbackCollectionName collection with ordering metadata
  2. On Migration Down: during migration.down() if script calls await db.autoRollback();:

    • All stored inverse operations are retrieved
    • Operations are executed in reverse order (LIFO)
    • The rollback collection is cleaned up after successful rollback
  3. Operation Mapping:

    • insertOnedeleteOne (using inserted ID)
    • insertManydeleteMany (using inserted IDs)
    • updateOne/updateManyreplaceOne (restoring complete original document)
    • replaceOnereplaceOne (restoring complete original document)
    • deleteOne/deleteManyinsertOne (restoring deleted documents)

Configuration in migrate-mongo.js

module.exports = {
  // Collection to store rollback operations
  autoRollbackCollectionName: "auto_rollback_migrations",
};

Example

module.exports = {
  async up(db) {
    // Enable auto-rollback for this migration
    db.autoRollbackEnabled = true;
    
    // 1. insertOne - Add a single user
    await db.collection('users').insertOne(
      {
        name: 'Pedro',
        role: 'admin'
      });

    // 2. updateOne - Update a single user's role
    await db.collection('users').updateOne(
      { name: 'Alexandra' },
      { $set: { role: 'moderator' } });

    // 3. deleteOne - Remove a single user
    await db.collection('users').deleteOne({
      name: 'Bruno'
    });
  },

  async down(db) {
    // Automatically rollback all operations above in reverse order
    await db.autoRollback();

    // Rollback order will be:
    // 3. Restore deleted user Bruno (deleteOne inverse)
    // 2. Restore Alexandra's original role (updateOne inverse)
    // 1. Remove Pedro (insertOne inverse)
  }
};

@PedroCamata PedroCamata marked this pull request as draft December 15, 2025 19:07
@PedroCamata PedroCamata marked this pull request as ready for review December 15, 2025 20:09
@PedroCamata PedroCamata marked this pull request as draft December 15, 2025 20:28
@PedroCamata PedroCamata marked this pull request as ready for review December 15, 2025 21:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant