Public facade for the Outbox transactional event bus.
Producers call publish/2 from inside their domain transactions to
emit events that subscribers (registered in application config) react
to via Outbox.SubscriberJob after the dispatcher fans them out.
See Outbox.Subscriber for the subscriber contract and the README for
the full architecture overview.
Summary
Types
Event name. Convention: <entity>.<past-tense-verb> (lowercase, dot-separated).
JSON-serializable payload. Atom keys are converted to strings on insert.
Types
Functions
@spec child_spec(keyword()) :: Supervisor.child_spec()
Returns a Supervisor child_spec for Outbox.Application.
@spec publish(name(), payload()) :: {:ok, Outbox.OutboxEvent.t()} | {:error, Ecto.Changeset.t()}
Publish a domain event.
This function performs a single Repo.insert/1 and does not open
its own transaction. The caller is responsible for wrapping the
domain write and the publish/2 call in Repo.transaction/1 if
atomicity-with-the-domain-write is required (it almost always is).
Atom keys in the payload are converted to strings so subscribers always see string keys (consistent with what JSONB round-trips produce).
Examples
Repo.transaction(fn ->
{:ok, product} = Repo.insert(changeset)
{:ok, _event} = Outbox.publish("product.created", %{"id" => product.id})
product
end)