# `Mailglass.OptionalDeps.Oban`
[🔗](https://github.com/szTheory/mailglass/blob/v1.0.0/lib/mailglass/optional_deps/oban.ex#L1)

Gateway for the optional Oban dependency (`{:oban, "~> 2.21"}`).

When Oban is present, `available?/0` returns `true` and callers may safely
reference `Oban`, `Oban.Worker`, and `Oban.Job`. When absent,
`Mailglass.Outbound.deliver_later/2` falls back to `Task.Supervisor` with a
`Logger.warning` emitted at boot (see `Mailglass.Application`).

Oban integration lands in Phase 3 (Outbound). This gateway is delivered in
Phase 1 so Config/Telemetry can reference it without forward-reference pain.

## Phase 2 addition — TenancyMiddleware (D-33)

`Mailglass.Oban.TenancyMiddleware` (defined as a sibling module in this
file, conditionally compiled when `Oban.Worker` is loaded) serializes
`Mailglass.Tenancy.current/0` into job args on enqueue and restores it via
`put_current/1` in `perform/1`. Mitigates process-dict-leakage risk across
background boundaries. The module is absent when Oban is not loaded —
`mix compile --no-optional-deps --warnings-as-errors` passes cleanly.

OSS Oban 2.21 has no first-class middleware behaviour (that lives in Oban
Pro). Mailglass ships the middleware as a plain module exposing `call/2`
(the shape an adopter using Oban Pro can register directly) PLUS a
`wrap_perform/2` helper that adopters using OSS Oban invoke inside their
worker's `perform/1`. Both paths converge on the same
`Mailglass.Tenancy.with_tenant/2` wrap.

## Lint Enforcement (Phase 6)

The Credo check `NoBareOptionalDepReference` flags direct `Oban.*` calls
outside this module. All Oban interaction routes through the Outbound
facade, which consults `available?/0` before dispatching.

# `available?`
*since 0.1.0* 

```elixir
@spec available?() :: boolean()
```

Returns `true` when `:oban` is loaded in the current runtime.

Backed by `Code.ensure_loaded?/1`, so purge-aware and safe to call from
compile-time callbacks (e.g. `Application.start/2`).

# `insert`
*since 0.1.0* 

```elixir
@spec insert(Ecto.Multi.t(), atom(), (map() -&gt; term())) :: Ecto.Multi.t()
```

Gateway wrapper for `Oban.insert/3` used from `Ecto.Multi` pipelines.

Returns the original multi unchanged when Oban is not loaded.

# `insert_all`
*since 0.1.0* 

```elixir
@spec insert_all([term()]) :: term()
```

Gateway wrapper for `Oban.insert_all/1`.

---

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