Skip to content

yangboxin/mortgage-event

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mortgage Event Pipeline

1. Business Context

This project simulates a mortgage processing pipeline commonly seen in regulated financial institutions (e.g. Fannie Mae / Freddie Mac style environments).

Mortgage workflows are long‑running, event‑driven, and failure‑prone by nature:

  • Multiple systems participate (origination, underwriting, payment, notification)
  • Strong requirements on auditability, consistency, and replayability
  • Failures must be recoverable, not hidden

This system is intentionally designed as an event‑first backend, prioritizing correctness, traceability, and operational clarity over synchronous performance.


2. System Overview

The system models a simplified mortgage lifecycle using asynchronous events:

  • Mortgage / Order creation
  • Payment initiation and processing
  • Success / failure events
  • Downstream notification handling

All state transitions are driven by immutable domain events.


3. Architecture

High‑Level Components

  • Order Service

    • Owns mortgage/order state
    • Persists source‑of‑truth records in PostgreSQL
    • Emits domain events
  • Payment Service

    • Consumes order events
    • Simulates payment processing
    • Emits success / failure events
  • Notification Service

    • Subscribes to payment outcome events
    • Represents downstream integrations (email, audit, reporting)
  • Event Broker

    • Kafka‑style topic abstraction
    • Decouples producers and consumers

4. Data Consistency & Reliability Design

4.1 Event Envelope

All events are wrapped in a standardized envelope:

  • eventId (UUID)
  • eventType
  • version
  • occurredAt
  • payload

This enables:

  • Idempotent processing
  • Replay support
  • Backward‑compatible evolution

4.2 Idempotency

Financial systems must assume duplicate delivery.

Each consumer:

  • Tracks processed eventIds
  • Ensures side effects are applied at most once

This protects against:

  • Broker retries
  • Consumer restarts
  • Manual replays

4.3 Delivery Semantics

The system is designed around:

  • At‑least‑once delivery
  • Idempotent consumers

This trade‑off is intentional:

  • Avoids the complexity of distributed transactions
  • Matches common industry practice in regulated systems

4.4 Outbox Pattern (Design Consideration)

To guarantee consistency between database writes and event publication, the system is designed to support the Outbox Pattern:

  • Domain state change and outbox insert occur in the same DB transaction
  • A background publisher forwards events to the broker

This prevents:

  • Lost events
  • Partial commits

5. Failure Handling Strategy

Failures are treated as first‑class states, not exceptions.

5.1 Payment Failures

Payment processing may fail due to:

  • Timeouts
  • Validation errors
  • Downstream unavailability

Failures result in explicit domain events:

  • PAYMENT_FAILED

State transitions remain traceable and auditable.


5.2 Retry & Backoff

Consumers are designed to:

  • Retry transient failures
  • Apply exponential backoff

Retries are bounded to avoid cascading failures.


5.3 Dead‑Letter Queue (DLQ)

Events that repeatedly fail processing are routed to a DLQ for:

  • Manual inspection
  • Reprocessing
  • Reconciliation

This aligns with operational practices in financial institutions.


6. Observability & Operations

The system is designed with production observability in mind:

  • Structured logging per service

  • Event‑level traceability via eventId

  • Metrics suitable for:

    • Throughput
    • Failure rate
    • Retry counts

This enables:

  • Incident investigation
  • Regulatory audits
  • Operational dashboards

7. Replay & Recovery

Because all domain changes are event‑driven:

  • Historical events can be replayed
  • New consumers can be introduced safely
  • State can be rebuilt if necessary

Replay is a feature, not an afterthought.


8. Trade‑offs & Design Decisions

Why Asynchronous Events?

  • Mortgage workflows are long‑running
  • Strong consistency across services is impractical
  • Eventual consistency is acceptable and expected

Why Not Synchronous APIs?

  • Tight coupling increases blast radius
  • Failure propagation becomes harder to control

Why Simple, Explicit Design?

  • Prioritizes correctness over cleverness
  • Mirrors real‑world financial systems

9. Intended Use

This project is designed to demonstrate:

  • Event‑driven backend design
  • Financial‑grade reliability thinking
  • Contractor‑ready system architecture

It intentionally avoids UI and non‑essential features to focus on core backend responsibilities.


10. Future Extensions

  • Persistent idempotency store
  • Schema registry for event evolution
  • Stronger audit log integration
  • Deployment via AWS (RDS, MSK, ECS)

Author: Boxin Yang

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors