# `Accrue.Dunning.Engine.Oban`
[🔗](https://github.com/szTheory/accrue/blob/accrue-v1.5.1/lib/accrue/dunning/engine/oban.ex#L1)

Built-in dunning engine backed by Oban (DUN-03, D-02).

This is the always-on default engine. No additional configuration is
required — it wraps the existing Oban-backed `Accrue.Workers.DunningStep`
worker. It is the value `Accrue.Config.dunning_engine/0` returns when no
explicit engine is configured.

## Responsibilities

- `start_campaign/3` — enqueues the day-0 `DunningStep` job for the
  configured `after_days: 0` step (or no-ops when none is configured).
- `cancel_campaign/3` — bulk-cancels all `DunningStep` jobs keyed on
  `subscription_id` + `campaign_started_at`. Always returns `:ok` even on
  failure (the anchor-clear is already committed; the per-step cancel-guard
  backstops any step that races this cancel — D-12 contract).

## Isolation

This module only references always-on dependencies (`Oban`,
`Accrue.Workers.DunningStep`, `Accrue.Config`) and compiles and loads
unconditionally, whether or not the optional `:chimeway` dependency is
present. No Chimeway references appear here.

# `cancel_campaign`

Bulk-cancels all `Accrue.Workers.DunningStep` Oban jobs matching
`sub.id` + `iso_anchor`.

Always returns `:ok` — a cancel failure is logged as a warning but never
propagated (D-12). The anchor-clear is already committed at the time this
is called; the per-step cancel-guard backstops any job that races this
bulk cancel.

# `start_campaign`

Enqueues the day-0 `DunningStep` job for the configured `after_days: 0`
step, threading the campaign anchor and `invoice_id` from `opts`.

Returns `:ok` immediately when no day-0 step is configured (the first
cadence step has `after_days > 0`). The `DunningStep` `unique` contract
(D-16) backstops the atomic campaign-start elector against duplicate
enqueues.

Note: `emit_campaign_started/1` (telemetry + ledger) is NOT called here —
it is Accrue's responsibility and is called in `default_handler.ex` BEFORE
this dispatch (RESEARCH Pitfall 3).

---

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