# Rollback & Recovery

Entity Builder provides comprehensive rollback support for recovering from failed or unwanted operations.

## How Rollback Works

When operations are executed, Entity Builder stores the data needed to reverse each operation:

```mermaid
flowchart LR
    Apply[Apply Definition] -->|Stores| RB[(EbRollback)]
    RB -->|Contains| OP1[Operation 1 Data]
    RB -->|Contains| OP2[Operation 2 Data]
    RB -->|Contains| OP3[Operation 3 Data]

    Rollback[Execute Rollback] -->|Reverses| OP3
    Rollback -->|Reverses| OP2
    Rollback -->|Reverses| OP1
```

**Key Points:**

- Operations are rolled back in **reverse order**
- Each operation type knows how to undo itself
- Rollback data is stored in the database (not config)

## Rollback Storage

### EbRollback Entity

Parent record for each definition apply:

| Field | Description |
|-------|-------------|
| `definition_id` | Source definition |
| `status` | pending, completed, failed |
| `operation_count` | Number of operations |
| `created` | When apply started |
| `uid` | User who applied |

### EbRollbackOperation Entity

Individual operation rollback data:

| Field | Description |
|-------|-------------|
| `rollback_id` | Parent rollback |
| `operation_type` | Plugin ID |
| `original_data` | Serialized undo data |
| `sequence` | Execution order |

## Using Rollback

### Via Drush

```bash
# List available rollbacks
drush eb:list-rollbacks

# Rollback by ID
drush eb:rollback 42

# Rollback all for a definition
drush eb:rollback-definition my_definition

# Filter rollbacks
drush eb:list-rollbacks --definition=my_definition
drush eb:list-rollbacks --status=pending
```

### Via UI

1. Navigate to **Configuration > Development > Entity Builder > Rollback**
2. Find the rollback in the list
3. Click **Execute Rollback**
4. Confirm the action

## Rollback Scenarios

### Scenario 1: Undo Recent Apply

```bash
# Applied definition created wrong fields
drush eb:apply my_definition

# Oops! Need to undo
drush eb:list-rollbacks --definition=my_definition
# ID: 42, Status: pending

drush eb:rollback 42
# All operations reversed
```

### Scenario 2: Partial Failure Recovery

When an apply partially fails:

```
Executing definition...
✓ Created bundle: Article
✓ Created field: field_body
✗ Failed: field_category (widget not found)

Rollback available for successful operations.
```

You can rollback to return to the previous state:

```bash
drush eb:rollback 43
```

### Scenario 3: Clean Slate

To completely undo all applies of a definition:

```bash
drush eb:rollback-definition my_definition
# Rolls back all pending rollbacks for this definition
```

## What Gets Rolled Back

| Operation | Rollback Behavior |
|-----------|-------------------|
| `create_bundle` | Delete the bundle |
| `update_bundle` | Restore original label/settings |
| `create_field` | Delete field instance (and storage if unused) |
| `update_field` | Restore original configuration |
| `delete_field` | Recreate the field |
| `configure_form_mode` | Restore original widget settings |
| `configure_view_mode` | Restore original formatter settings |
| `create_field_group` | Delete the field group |
| `create_pathauto_pattern` | Delete the pattern |

## Limitations

### Content Loss

!!! warning
    Rolling back `create_bundle` will delete all content of that bundle type.

### Storage Cleanup

Field storage is only deleted during rollback if:

- No other field instances use it
- The operation that created it is being rolled back

### Partial Data

Some data may not be fully restorable:

- Uploaded files referenced by deleted fields
- Entity references to deleted content
- Custom configuration made outside Entity Builder

## Rollback Retention

By default, rollback data is kept for 30 days. Configure in settings:

```yaml
eb.settings:
  rollback_retention_days: 30
```

### Cleanup

```bash
# Purge rollbacks older than 30 days (default)
drush eb:purge-rollbacks

# Purge rollbacks older than 7 days
drush eb:purge-rollbacks 7
```

## Best Practices

### Before Applying

1. **Preview** operations first: `drush eb:preview definition.yml`
2. **Validate** the definition: `drush eb:validate definition.yml`
3. **Backup** your database for major changes

### After Applying

1. **Test** the created entities
2. **Don't** immediately purge rollbacks
3. **Document** what was applied

### Recovery Strategy

1. **Identify** the rollback ID
2. **Verify** it's the correct one (check operation count, date)
3. **Execute** rollback
4. **Confirm** entities were restored
5. **Fix** the definition
6. **Re-apply** when ready

## Rollback Status

| Status | Meaning |
|--------|---------|
| `pending` | Can be executed |
| `completed` | Already rolled back |
| `failed` | Rollback failed |

## Troubleshooting

### "Rollback not found"

The rollback may have been:

- Already executed
- Purged due to retention policy
- Never created (apply failed before storing)

### "Cannot rollback - content exists"

Some operations fail rollback if dependent content exists. Options:

1. Delete dependent content first
2. Use Drupal UI to manually remove

### "Partial rollback failure"

If some operations fail to rollback:

1. Check the error messages
2. Manually fix the failed items
3. The rollback status will be `failed`
