Skip to content

Feat/add outbox event relay and handler registry - #156

Merged
Kaylahray merged 4 commits into
learnault:mainfrom
Ezeh20:feat/Add-Outbox-Event-Relay-and-Handler-Registry
Aug 30, 2026
Merged

Feat/add outbox event relay and handler registry#156
Kaylahray merged 4 commits into
learnault:mainfrom
Ezeh20:feat/Add-Outbox-Event-Relay-and-Handler-Registry

Conversation

@Ezeh20

@Ezeh20 Ezeh20 commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Closes #153

Summary

The outbox from #122 had a complete producer side but only one consumer, bound directly to wallet provisioning. This adds a registry and a relay that leases any pending event and dispatches it by eventType, so domains subscribe to events instead of shipping a worker each.

  • Handler interface keyed by eventType + eventVersion
  • Registry rejects duplicate handler names, handlers for unknown event types, and emitted event types with no handler. All at startup
  • Relay materialises one JobAttempt per (event, handler), leases via job-lease.service.ts, and dispatches
  • An event is PUBLISHED only once every handler for its type succeeds; one failing handler doesn't block other types
  • Exhausted events dead-letter; pnpm outbox:replay list|replay <id> is the operator path
  • Wallet provisioning is now event-driven and src/workers/wallet-provisioning.worker.ts is deleted
  • Subscribe-to-events flow documented in docs/domains/REQUEST_AND_EVENT_FLOWS.md

Evidence

pnpm relay:verify

A. Dispatch by event type
[relay] dispatched UserCreated v1 -> wallet.reserve-on-user-created
[relay] dispatched WalletProvisioningRequested v1 -> wallet.provision
  UserCreated                  PUBLISHED    wallet.reserve-on-user-created=COMPLETED
  WalletProvisioningRequested  PUBLISHED    wallet.provision=COMPLETED

B. Event type with no registered handler
[relay] no handler registered for ModuleCompleted v1; dead-lettering event ...
  relay summary: {"materialized":0,"dispatched":0,"failed":0,"unhandled":1}
  ModuleCompleted -> DEAD_LETTER (dead-lettered, not left PENDING)

C. Failing handler dead-letters, then replays cleanly
[relay] handler wallet.reserve-on-user-created failed ... attempt 5: CUSTODIAL_CONSENT_REQUIRED
  event -> DEAD_LETTER
  Operator grants the missing consent, then replays:
  event -> PUBLISHED

D. Re-delivering an already-published event is idempotent
  wallets for user: 1 before re-delivery, 1 after; provisioning jobs: 1
image image

@Kaylahray
Kaylahray requested a review from 3m1n3nc3 August 30, 2026 09:51
@Kaylahray
Kaylahray merged commit adb0fc2 into learnault:main Aug 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Add Outbox Event Relay and Handler Registry

3 participants