# `DDD.Aggregate`
[🔗](https://github.com/blackuprise/vicander/blob/v0.1.1/lib/ddd/model/aggregate.ex#L1)

Behaviour and macros for Domain-Driven Design Aggregate Roots.

An aggregate is a consistency boundary: the root is the only entry point, and
nested entities are stored inside it (one row for the whole aggregate).
Aggregates collect domain events; the repository persists them with the state.

Same rules as `DDD.Entity` (field rules, `invariant`, `defop`, sealing).

## Usage

    defmodule MyApp.Order do
      use DDD.Aggregate

      aggregate do
        identity :id,          :uuid
        field    :customer_id, :string, required: true
        field    :status,      :atom, default: :pending
        field    :items,       {:list, MyApp.OrderItem}, default: []

        invariant MyApp.Specs.MaxItems, max: 10
      end

      defop confirm(order), requires: MyApp.Specs.OrderIsPending do
        order
        |> Map.put(:status, :confirmed)
        |> emit_event(MyApp.Events.OrderConfirmed.new(%{order_id: order.id}))
      end
    end

Events emitted inside a `defop` are discarded when the result is invalid.

Nested types: `{:list, EntityModule}` and `{:one, EntityModule}`.

# `new`

```elixir
@callback new(attrs :: map() | keyword()) :: {:ok, struct()} | {:error, DDD.Error.t()}
```

# `update`

```elixir
@callback update(
  aggregate :: struct(),
  changes :: map() | keyword() | (struct() -&gt; struct())
) ::
  {:ok, struct()} | {:error, DDD.Error.t()}
```

# `aggregate`
*macro* 

---

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