AshHooks.Worker (AshHooks v1.0.0)

Copy Markdown View Source

The host-injected Oban worker (ADR-0004): the consuming app defines ONE module, and the Oban beam compiles only where Oban exists — this macro expands use Oban.Worker inside the HOST's compilation, so the package itself never references a loaded Oban module and compiles Oban-free (the CI no-optional leg's proof).

defmodule MyApp.WebhookDeliveryWorker do
  use AshHooks.Worker,
    deliveries: MyApp.OutboundDelivery,
    endpoints: MyApp.WebhookEndpoint,
    secret_resolver: {MyApp.Secrets, :webhook_secret},
    queue: :webhooks,
    oban: MyApp.Oban
end

Consumers pass enqueue: {MyApp.WebhookDeliveryWorker, :enqueue} to AshHooks.dispatch/4 — the generated enqueue/2 IS that seam.

Options:

  • :deliveries, :endpoints (required) — the consumer's resource modules carrying the AshHooks.OutboundDelivery / AshHooks.Endpoint extensions.
  • :secret_resolver (required, {m, f}) — resolves an endpoint's secret REFERENCE: f(ref) :: {:ok, secret_binary} | {:error, term}. The returned value ALWAYS signs the Standard Webhooks envelope (its whsk_/whsec_ prefix only selects the key slot for rotation); legacy envelopes, when the signing mode uses them, are signed from the endpoint's legacy_secret_ref / legacy_previous_secret_ref references through this same resolver.
  • :snippet_redactor ({m, f}, optional) — a consumer callback run on the RAW captured body ahead of the package's snippet floor (domain-specific tokens need raw input). Only consulted on per-call snippet_capture: true diagnostic runs; a crash or invalid return degrades to the sanitized summary, never raw bytes. The capture flag itself is deliberately NOT a macro option (ADR-0005's snippet amendment: compile-time knobs are broad and quiet) — pass it in the AshHooks.Delivery.run/2 config for a one-row diagnostic re-drive.
  • :http — the AshHooks.Http adapter (default AshHooks.Http.Bounded).
  • :oban — the Oban instance name (default the unnamed instance).
  • :queue, :timeout, :max_attempts — Oban Worker options (the job's timeout defaults to 30s; its max_attempts is advisory only — snoozes extend it, the ROW's ceiling governs dead-letter).
  • :delivery_max_attempts (default 10), :base_backoff_seconds (2), :max_backoff_seconds (3600), :retry_after_cap_seconds (86_400) — the row-driven retry policy.

Uniqueness (verified against deps/oban 2.23.1, ADR-0007): fields: [:args], keys: [:endpoint_id, :event_uuid], period: :infinity, states: :all — the defaults (60s / :successful) would re-admit a duplicate trigger after success or window expiry; both are overridden. A uniqueness conflict is {:ok, %Oban.Job{conflict?: true}} — the generated enqueue/2 maps it to :ok (a conflict IS dedup success).