# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

While the version is in the `0.x` range, any release MAY contain breaking
changes; the minor version is bumped for each one. See
[CONTRIBUTING.md](CONTRIBUTING.md) for the full policy.

## [Unreleased]

## [0.1.0-beta.2] - 2026-06-14

### Added

- Ambient context envelope. `Outbox.publish/3` accepts a `:context` option
  and a new `context` jsonb column stores an opaque, host-defined map on
  every event. `Outbox.put_context/1`, `get_context/0`, and `clear_context/0`
  set a per-process ambient context (e.g. in a plug) that is attached to
  every subsequent publish; per-call `:context` overrides ambient keys. The
  context is surfaced to subscribers as `meta.context` and on the PubSub
  broadcast. Atom keys are stringified. **Upgrade:** add the `context`
  column — re-run `mix outbox.gen.migration` for the canonical table, or
  `ALTER TABLE outbox_events ADD COLUMN context jsonb NOT NULL DEFAULT '{}'`.
- Pattern matching in subscriber `events/0`. Entries may be exact names,
  prefix wildcards (`"order.*"`), or `"*"` (all events). A subscriber
  matched by multiple patterns is dispatched once. Exact strings behave as
  before.
- Sampling and transient publishing. `Outbox.publish/3` accepts `:sample`
  (keep with probability `0.0..1.0`, returns `{:ok, :sampled_out}` when
  dropped) and `:transient` (PubSub-only, no row/Oban fan-out, returns
  `{:ok, :transient}`) — for high-volume, loss-tolerant telemetry.
- `Outbox.Idempotency.run_once/3` — exactly-once execution guard for the
  at-least-once delivery contract. Claims `(consumer, event_id)` in a new
  `outbox_consumed_events` table and runs the side-effect only on the first
  delivery; a returned `{:error, _}` or a raise rolls the claim back so a
  retry re-runs. **Upgrade:** create the table via `mix outbox.gen.migration`
  (the canonical migration now includes it).
- Per-event payload schema validation. `config :outbox, Outbox, schemas:
  %{"order.placed" => validator}` registers a 1-arity function or
  `{module, function}` validator (returning `:ok` / `{:error, reason}`)
  run against the stringified payload at publish time. A failure returns
  `{:error, {:schema, reason}}` and persists/broadcasts nothing. The
  library stays dependency-free — hosts supply the validator (e.g. wrapping
  their own schema library).

## [0.1.0-beta.1] - 2026-06-06

### Added

- `Outbox.publish/2` — publish a named domain event into the
  `outbox_events` table. Participates in the caller's `Repo.transaction/1`
  (does not open its own).
- `Outbox.Subscriber` behaviour — `events/0` + `handle_event/3` for
  declaring subscribers.
- Built-in Phoenix.PubSub broadcasting — when `pubsub:` is configured,
  the dispatcher broadcasts every dispatched event on the configured
  topic. Consumers pattern-match the events they care about. No
  separate subscriber module to register.
- `Outbox.Testing` — `assert_published/2` and `with_sync_dispatch/1`
  helpers for ExUnit tests.
- `mix outbox.gen.migration` — generator for the `outbox_events` table
  migration. Greenfield-host install path.
- `Outbox.Oban` — library-owned Oban instance with queues
  `[outbox: 10, outbox_prune: 1]` and a cron entry for
  `Outbox.Pruner` (nightly). Host's existing Oban untouched.
- `config :outbox, oban: MyApp.Oban` opt-in escape hatch for hosts that
  want a single Oban instance — validates required queues + cron at
  boot.
