# `Chronicle.Seeding`
[🔗](https://github.com/Cratis/Chronicle.Elixir/blob/main/lib/chronicle/seeding.ex#L4)

Accumulates and registers seed events with Chronicle.

This module provides a builder API for accumulating events during seeder
discovery, then organizing and sending them to the Chronicle server.

## Usage

Typically used within a `Chronicle.Seeding.Seeder.seed/1` callback:

    def seed(builder) do
      builder
      |> Chronicle.Seeding.for(MyEvent, "aggregate-1", [%MyEvent{...}])
      |> Chronicle.Seeding.for_event_source("aggregate-2", [%Event1{...}, %Event2{...}])
    end

## Lifecycle

1. **Discovery** — `discover/2` finds all seeder modules
2. **Accumulation** — Each seeder's `seed/1` is called, populating the builder
3. **Registration** — `register/1` organizes entries and sends them to Chronicle

Events are organized by:
  * Global vs. namespaced
  * Event type and event source (dual organization for server efficiency)

# `append_many_fun`

```elixir
@type append_many_fun() :: (event_source_id(), [struct()], keyword() -&gt;
                        :ok | {:error, term()})
```

# `event_source_id`

```elixir
@type event_source_id() :: String.t()
```

# `has_events_for_fun`

```elixir
@type has_events_for_fun() :: (event_source_id(), keyword() -&gt;
                           {:ok, boolean()} | {:error, term()})
```

# `namespace`

```elixir
@type namespace() :: String.t()
```

# `seeding_entry`

```elixir
@type seeding_entry() :: %{
  event_source_id: event_source_id(),
  event_type_id: String.t(),
  event: struct(),
  tags: [String.t()],
  is_global: boolean(),
  target_namespace: namespace() | nil
}
```

# `t`

```elixir
@type t() :: %Chronicle.Seeding{
  append_many: append_many_fun() | nil,
  client: atom() | nil,
  connection: atom(),
  entries: [seeding_entry()],
  event_store: String.t(),
  event_types: module(),
  has_events_for: has_events_for_fun() | nil,
  namespace: String.t(),
  seed_events: (map() -&gt; :ok | {:error, term()}) | nil
}
```

# `build_seed_request`

```elixir
@spec build_seed_request(t()) :: map()
```

Builds the kernel's `SeedEventsRequest` from the accumulated entries: global entries grouped by
event type and by event source, namespaced entries grouped per namespace.

# `discover`

```elixir
@spec discover(t(), [module()]) :: t()
```

Discovers seeder modules and invokes them to populate the builder.

Iterates through all provided seeder modules, instantiates each, calls
`seed/1`, and accumulates their events.

Returns the populated builder struct.

# `for`

```elixir
@spec for(t(), module(), event_source_id(), [struct()]) :: t()
```

Seeds events of a specific type for an event source.

## Parameters

  * `builder` — the seeding builder
  * `event_type` — the event type module (must `use Chronicle.Events.EventType`)
  * `event_source_id` — the event source (aggregate) ID
  * `events` — list of event structs

## Example

    builder
    |> Chronicle.Seeding.for(MyApp.Events.AccountOpened, "account-1", [
      %MyApp.Events.AccountOpened{account_id: "account-1", owner_name: "Alice"}
    ])

# `for_event_source`

```elixir
@spec for_event_source(t(), event_source_id(), [struct()]) :: t()
```

Seeds multiple event types for a single event source.

## Parameters

  * `builder` — the seeding builder
  * `event_source_id` — the event source (aggregate) ID
  * `events` — list of event structs (can be different types)

## Example

    builder
    |> Chronicle.Seeding.for_event_source("account-1", [
      %MyApp.Events.AccountOpened{account_id: "account-1", owner_name: "Alice"},
      %MyApp.Events.FundsDeposited{account_id: "account-1", amount: 500}
    ])

# `for_namespace`

```elixir
@spec for_namespace(t(), namespace(), (t() -&gt; t())) :: t()
```

Scopes subsequent events to a specific namespace.

Returns a scoped builder that targets the given namespace.

## Parameters

  * `builder` — the seeding builder
  * `namespace` — the target namespace
  * `fun` — a function receiving a scoped builder

## Example

    builder
    |> Chronicle.Seeding.for_namespace("production", fn scoped ->
      scoped
      |> Chronicle.Seeding.for(MyEvent, "aggregate-1", [%MyEvent{...}])
    end)

# `register`

```elixir
@spec register(t()) :: :ok | {:error, term()}
```

Registers all accumulated seed events with Chronicle.

Organizes entries by global/namespaced, then by event type and event source,
and hands them to the kernel's seeding service, which owns the rest: it tracks what it has
already applied (by event source, event type, content and tags), so a **new entry added to an
event source that was seeded before is applied**, an entry that was applied is not applied
again, and global entries reach every namespace the kernel knows - exactly as with the .NET
client. Re-running on every start is therefore safe.

A seeder whose `seed/1` raises is logged as an error and contributes **none** of its entries
(a seeder is applied whole or not at all); the other seeders still run. Tags declared on the
event type (`tags:`) are sent with each entry.

This is typically called automatically by `Chronicle.Client` during startup.

---

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