Architecture & decisions
A vertical-slice CQRS / Event-Sourcing system: Ash is the command + read-model surface, Commanded + EventStore are the source of truth, Oban runs durable out-of-band work.
Flow
A process-manager saga drives reserve → settle → credit → complete, then requests QRC settlement via an Oban job.
Money invariant (Option A)
Stateless aggregates; conservation is enforced by an atomic, CHECK-guarded projector update, with a compensating ReservationRejected event if a race slips past command-time validation. It is impossible to persist a negative balance.
Why event sourcing
Loyalty value is money-like: an append-only event log gives audit, replay, and reconciliation by construction; balances are projections, not the source of truth.
Vertical slices
Each use-case is one file (command + versioned event + build_event/1). Read models live in _lookups; the realtime feed is a projection. Mirrors a proven in-house pattern.
Deliberately deferred
Explicit fee/spread postings, token burning on exchange, and auth-gated admin — scoped out to keep the demo focused; documented in the README.