> ## Documentation Index
> Fetch the complete documentation index at: https://archie.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migration history

> An audit trail of every merge operation — who ran it, when, what changed, and the backup taken alongside.

The History view is the audit trail of every [merge](/features/backend/environments/merge) operation that has touched an environment. It records what was changed, who applied it, when it ran, and the SQL that executed — useful for compliance, debugging drift, and understanding how an environment got to its current state.

## What's in a history entry

Each merge produces one history entry on the target environment with these fields:

| Field                  | What it records                                                                               |
| ---------------------- | --------------------------------------------------------------------------------------------- |
| **Migration ID**       | Stable identifier for the merge operation.                                                    |
| **Source environment** | Where the changes originated.                                                                 |
| **Target environment** | Where the changes were applied (this environment).                                            |
| **Status**             | `succeeded`, `failed`, or `rolled_back`.                                                      |
| **Applied by**         | The user (or API key holder) who initiated the merge.                                         |
| **Applied at**         | Timestamp when the merge ran.                                                                 |
| **Changes applied**    | The list of selected changes — each with `changeType`, `objectName`, `sql`, and `isBreaking`. |
| **Backup ID**          | Reference to the pre-merge backup taken automatically.                                        |

Failed merges also record the failure reason and the index of the offending change.

## Where history lives

History is per-environment. Open an environment from the switcher and look at its History view to see every merge that has been applied to it. The same operation appears in the source environment's history record only as the merge's source, not as a target — history is "what happened to me", not "what I sent elsewhere".

For the chronological view across the whole project, query the `migrationHistory` GraphQL endpoint with the project ID and no environment filter.

## Use cases

| Goal                          | How to use history                                                                                                                                                             |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Debug drift**               | Two environments are out of sync. History shows which merges touched which targets and when. Cross-reference with [diff](/features/backend/environments/diff) to find the gap. |
| **Compliance and audit**      | Every schema change is recorded with the user who applied it. Export the history for an environment to satisfy audit requirements.                                             |
| **Roll back a bad merge**     | Find the merge in History, follow the backup ID into [Backups](/features/backend/environments/backups), and restore the pre-merge snapshot.                                    |
| **Confirm a merge succeeded** | After running a merge, the new entry should show `succeeded` with the expected change count.                                                                                   |
| **Trace an outage**           | If something broke in production, the most recent merge in history is usually the first thing to inspect.                                                                      |

## Inspecting via GraphQL

```graphql theme={null}
query MigrationHistory($projectId: ID!, $environment: String) {
  migrationHistory(projectId: $projectId, environment: $environment) {
    id
    sourceEnvironment
    targetEnvironment
    status
    appliedBy
    appliedAt
    changes {
      changeType
      objectName
      sql
      isBreaking
    }
    backupId
  }
}
```

| Argument      | Behavior                                                                                    |
| ------------- | ------------------------------------------------------------------------------------------- |
| `projectId`   | Required. Scopes to the project.                                                            |
| `environment` | Optional. Returns only the history entries for this target. Omit for the project-wide view. |

The `changes` array carries the same shape as the [diff output](/features/backend/environments/diff#reading-the-diff-output) — `changeType`, `objectName`, the executed `sql`, and the `isBreaking` flag.

## Retention

History entries are durable and not subject to a retention window — they're part of the project's audit trail. Backups referenced by `backupId` follow the [backup retention policy](/features/backend/environments/backups#retention) and may age out independently.

## Permissions

Reading history is governed by [Role-Based Access](/features/backend/app-services/role-based-access). Viewing audit data is typically restricted to admin or operator roles — grant the necessary permissions on the system audit resources to make History visible to additional roles.

## FAQ

<AccordionGroup>
  <Accordion title="Can I delete a history entry?">
    No. History is append-only by design — that's what makes it useful for audit and compliance. To suppress a misconfigured environment from production audits, archive or delete the environment instead.
  </Accordion>

  <Accordion title="What if the backup referenced by a history entry has been pruned?">
    The history entry remains intact. The `backupId` will resolve to "not found" when you try to restore it. For long-lived rollback windows, copy the pre-merge backup to a manual backup that's exempt from retention pruning before the window expires.
  </Accordion>

  <Accordion title="Does history show data changes too?">
    No — history records schema changes (DDL) only. Data changes go through the auto-generated APIs and aren't audited at the environment level. For data-level audit logging, build it into your custom functions or use database-level triggers.
  </Accordion>

  <Accordion title="Can I get a CSV or JSON export of history?">
    Query `migrationHistory` over GraphQL — the response is JSON. Pipe it through `jq` for a flat dump, or feed it into your audit tooling.
  </Accordion>

  <Accordion title="What does `rolled_back` status mean?">
    The merge succeeded initially but the pre-merge backup was later restored, effectively undoing the merge. Status flips from `succeeded` to `rolled_back` when the matching backup is restored.
  </Accordion>
</AccordionGroup>
