# `Chimeway.DeliveryAttempt`
[🔗](https://github.com/jonlunsford/chimeway/blob/v1.0.0/lib/chimeway/delivery_attempt.ex#L1)

Ecto schema for chimeway_delivery_attempts — immutable append-only record of each
provider call for a delivery. No updated_at — attempts are never mutated.

## REL-02 fields (Phase 14 D-07)

- `attempt_number` :integer — 1-indexed ordinal of this attempt for its delivery,
  computed at insert time inside the same `Ecto.Multi` as the attempt insert.
  Plan 14-02 leaves this in `@optional_fields`; Plan 14-04 Task 3 promotes it to
  `@required_fields` after `Deliveries.record_attempt/2` is wired to inject the
  value via the new `:next_attempt_number` Multi step. The two-step landing keeps
  `mix test` green between Plan 14-02 and Plan 14-04.
- `error_class` :string — one of `"temporary" | "permanent" | "bounced"` for
  `:failed | :rejected | :bounced` outcomes; `nil` for `:succeeded`. Persisted
  as a plain string with changeset whitelist validation (NOT `Ecto.Enum`) to
  match the project's string-channel idiom from Phase 11.

# `t`

```elixir
@type t() :: %Chimeway.DeliveryAttempt{
  __meta__: term(),
  adapter_module: term(),
  attempt_number: term(),
  delivery: term(),
  delivery_id: term(),
  error_class: term(),
  id: term(),
  inserted_at: term(),
  outcome: term(),
  provider_message_id: term(),
  provider_response: term()
}
```

# `changeset`

# `error_classes`

```elixir
@spec error_classes() :: [String.t()]
```

Returns the canonical list of allowed error_class string values.
Used by the dispatch executor to validate that the dispatcher
only emits whitelisted classifications. `"unknown_classification"` is the BL-02
fallback value emitted by `classify/1` for unexpected adapter return shapes.

---

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