Part 10 · 1 chapters · ~8 min

Capstone: The Ledger API in Elixir

The shared ledger API capstone built with Phoenix, Ecto and Oban: idempotent transfers under 100 concurrent requests, double-entry postings that sum to zero, payouts with unknown outcomes tracked by supervised processes, a LiveView balance page, and chaos testing by killing processes and nodes.

11

Acceptance

code
mix test test/acceptance                       # the three shared checks
#  ✓ 100 concurrent identical POST /v1/transfers → exactly 1 transfer, 99 replays
#  ✓ Σ postings = 0 for every transfer (property test, 1,000 runs)
#  ✓ payout timed out at the rail → state :unknown → only a rail confirmation moves it to :settled

# chaos: during a 2-minute load test, kill random PayoutTrackers every second
for _ <- 1..120 do
  DynamicSupervisor.which_children(Payouts.Sup) |> Enum.random() |> elem(1) |> Process.exit(:kill)
  Process.sleep(1_000)
end
# then: re-run the acceptance checks and reconcile the ledger against the mock rail: zero differences
CAPSTONE: THE LEDGER API IN ELIXIR
the shared acceptance tests from every language course
idempotency100 concurrent identical requestsproduce exactly one transfer.double entryPostings for every transfer sum tozero.unknown outcomesA timed-out payout never completeswithout rail confirmation.per-payout processA PayoutTracker GenServer pollseach rail with backoff.live balanceA LiveView page updates on everyposting via PubSub.crash testKilling trackers and nodes losesno money.
swipe the figure sideways, or tap expand for full screen
1/4
shared contract
The same three acceptance tests as the Go, Python, Java, Rust and Rails capstones: idempotency under concurrency, balanced postings, and safe unknown outcomes.
the shared acceptance testscompare languages directly