ADR-0011: Outbox event catalogue, no relay yet
Status: Accepted · Date: 2026-10-19 · Resolves: OQ-5 · Refines: ADR-0004
Context
No consumer of payment events is known (OQ-5). The outbox must still be written correctly now, so a relay can be added later without a backfill. Implementers need fixed event names and payloads.
Decision
- Working assumption A13: no consumer needs these events within milestones M1–M3. The relay
(Kafka via Debezium or a polling publisher) is deferred until a consumer exists. Until then
published_atstaysNULLand the outbox is the audit trail. - Event row:
aggregate_id = paymentId,event_typefrom the catalogue below, and apayloadwith this shape:{"schemaVersion":1,"paymentId","accountNo","amount":{"minorUnits","currency"},"decisionMode","state","declineReason"?,"occurredAt"}. Events may add fields. They never rename or remove them.
event_type |
Written when | Task |
|---|---|---|
PaymentApproved |
Decision APPROVED (debit, hold, or lookup found) | M1-T4 |
PaymentDeclined |
Decision DECLINED, including WALLET_TIMEOUT and the stale sweeper |
M1-T4 |
PaymentReversalRequested |
An approved payment moves to REVERSAL_PENDING because of a till reversal |
M1-T5 |
PaymentReversed |
→ REVERSED |
M1-T7 |
StandInApproved |
→ STANDIN_APPROVED |
M2-T2 |
StandInDebitPosted / StandInUnrecovered |
Post-recovery debit result | M2-T3 |
ReconciliationDriftDetected |
The reconciler finds a contradiction or an orphan it cannot repair | M2-T4 |
PaymentCaptured / PaymentCaptureFailed |
Capture result, or the hold reaper's finding | M3-T3, M3-T4 |
Consequences
- + The relay later is pure plumbing, with no schema or backfill work.
- − The outbox table grows unbounded until the relay or archival exists (deferred, roadmap). Revisit trigger: a consumer is named, or the outbox exceeds 50 M rows.