Accept writes a Postgres outbox row, then returns 202. A publisher drains pending rows to Kafka. If the process dies mid-send, stuck rows return to pending and retry.
why · Avoids “accepted but lost” when the stream is briefly down.
Retries + dead-letter topic
The consumer retries a failing event up to 3 times. Persistent failure copies the payload + error to player.events.dlq, then commits the original offset.
why · Bad events don’t block the whole tenant stream forever.
Ledger — credit once
Bonus rows are unique on (tenant_id, event_id). Kafka may redeliver; the second credit attempt is rejected so balance doesn’t jump twice.
why · Idempotency is the product promise, not a footnote.
try it live
Ignite the Arena demo, then watch this page — ingested / processed / rule hits should move as the pipeline runs.