# `Chronicle.Events.Migration`
[🔗](https://github.com/Cratis/Chronicle.Elixir/blob/main/lib/chronicle/events/migration.ex#L4)

Behaviour and macro for defining event type migrations.

Event type migrations define how to upcast and downcast between different
generations of the same event type. This enables schema evolution while
maintaining backward compatibility with historical events.

## Defining a migration

Use `Chronicle.Events.Migration` in a module and implement the `upcast/1`
and `downcast/1` callbacks. These functions receive a migration builder
that provides a fluent API for transforming event properties.

    defmodule MyApp.Migrations.AccountOpenedV2Migration do
      use Chronicle.Events.Migration,
        from: {MyApp.Events.AccountOpenedV1, generation: 1},
        to: {MyApp.Events.AccountOpened, generation: 2}

      alias Chronicle.Events.MigrationBuilder

      @impl true
      def upcast(builder) do
        builder
        |> MigrationBuilder.default_value(:account_tier, "standard")
        |> MigrationBuilder.rename_property(:owner_name, :full_name)
      end

      @impl true
      def downcast(builder) do
        builder
        |> MigrationBuilder.rename_property(:full_name, :owner_name)
      end
    end

## Required options

  * `:from` — a tuple `{EventTypeModule, generation: generation_number}`
    specifying the source event type and generation.
  * `:to` — a tuple `{EventTypeModule, generation: generation_number}`
    specifying the target event type and generation.

The `from` and `to` event types must have the same event type ID, and the
`to` generation must be exactly one higher than the `from` generation.

## Migration chain

Multiple migrations can be chained to migrate across multiple generations.
Chronicle automatically composes these migrations when replaying or
projecting historical events.

## Registering with Chronicle.Client

Migrations are automatically discovered when using the `:otp_app` option:

    {Chronicle.Client,
      ...
      otp_app: :my_app}

Or register them explicitly:

    {Chronicle.Client,
      ...
      migrations: [MyApp.Migrations.AccountOpenedV2Migration]}

# `__chronicle_migration__`

```elixir
@callback __chronicle_migration__(
  key ::
    :from_module
    | :from_generation
    | :to_module
    | :to_generation
    | :event_type_id
) :: term()
```

Returns metadata for this migration module.

# `downcast`

```elixir
@callback downcast(builder :: Chronicle.Events.MigrationBuilder.t()) ::
  Chronicle.Events.MigrationBuilder.t()
```

Defines the downcast transformation from a newer generation to an older one.

Receives a `Chronicle.Events.MigrationBuilder` and must return it after
applying property transformations.

# `upcast`

```elixir
@callback upcast(builder :: Chronicle.Events.MigrationBuilder.t()) ::
  Chronicle.Events.MigrationBuilder.t()
```

Defines the upcast transformation from an older generation to a newer one.

Receives a `Chronicle.Events.MigrationBuilder` and must return it after
applying property transformations.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
