Skip to content

Feature: Add Outbox Event Relay and Handler Registry #153

Description

@3m1n3nc3

Description

The outbox delivered by #122 has a complete producer side — transactional writes, typed status, leasing, backoff, dead-letter, and versioned payload validation — but only one consumer. src/workers/wallet-provisioning.worker.ts is bound directly to WalletProvisioningOutboxHandler, so it drains only wallet provisioning work. event-schema.ts already registers UserCreated alongside the wallet events, and nothing consumes it: those rows are written inside the request transaction and then stay PENDING forever. Every new domain event today needs its own bespoke worker process.

Add a single relay that leases any pending outbox event and dispatches it by eventType to registered handlers, so domains subscribe to events instead of shipping a worker each.

File Location

learnault-api/src/lib/transactions/, learnault-api/src/jobs/, learnault-api/src/workers/, and learnault-api/docs/domains/REQUEST_AND_EVENT_FLOWS.md

Design Reference

API Roadmap Phase 1.1: Add Outbox Event Relay and Handler Registry. Consumes the primitives delivered by #122.

Dependencies

Tasks

  • Define a handler interface keyed by eventType and eventVersion
  • Add a registry that rejects duplicate registrations and unknown event types at startup
  • Build a relay that leases pending events, dispatches by type, and records each JobAttempt
  • Re-register the wallet provisioning handler through the registry and retire its bespoke worker
  • Add a UserCreated handler so the already-emitted event stops accumulating unconsumed
  • Mark events PUBLISHED only when every registered handler for that type succeeds
  • Route exhausted events to dead-letter and add an operator replay path
  • Document the subscribe-to-events flow for new domains

Acceptance Criteria

  • A new domain event needs a registered handler, not a new worker process
  • UserCreated events are consumed and no longer accumulate in PENDING
  • An event with no registered handler fails loudly at startup rather than silently stalling
  • A failing handler retries with backoff and dead-letters without blocking other event types
  • Replayed dead-letter events produce no duplicate side effects

Verification Evidence

  • Attach relay logs showing dispatch by type, a dead-lettered event, and a clean replay

Difficulty

Advanced

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions