Event Sourcing

Overview

Traditional applications persist only the current state of an entity. In contrast, Event Sourcing persists every change as an immutable sequence of domain events.

The current state of an aggregate is reconstructed by replaying its event history.

This reference implementation uses Event Sourcing to provide a complete audit trail, enable temporal analysis, and support scalable event-driven processing.


Why Event Sourcing?

Event Sourcing provides several benefits over traditional CRUD-based persistence.

Complete Audit History

Every business decision is permanently recorded.

Rather than simply storing the latest state, the system records how that state was reached.

For example:

BlastPlanCreated
BlastPatternUpdated
ChargeDesignCompleted
BlastApproved
BlastExecuted

Each event becomes part of the permanent business history.


Immutable Data

Events are never modified.

Corrections are represented by new events rather than updates to existing records.

This ensures the integrity and traceability of historical business activity.


Temporal Queries

Since historical events are preserved, it becomes possible to answer questions such as:


Event Replay

The complete state of an aggregate can be rebuilt by replaying its event stream.

This capability enables:


Event Lifecycle

A typical command follows the sequence below.

Command
    │
    ▼
Command Handler
    │
    ▼
Aggregate
    │
Business Rules
    │
    ▼
Domain Events
    │
    ▼
Cosmos DB Event Store
    │
    ▼
Azure Service Bus
    │
    ▼
Projection Workers
    │
    ▼
Azure SQL Read Models

Event Store

The Event Store is implemented using Azure Cosmos DB.

Each aggregate maintains an ordered stream of immutable events.

Example:

BlastPlan
│
├── Event 1
├── Event 2
├── Event 3
├── Event 4
└── Event 5

No event is ever updated or deleted.

The current aggregate state is reconstructed by replaying these events in order.


Aggregate Reconstruction

When processing a command:

  1. Load the aggregate’s event stream.
  2. Replay all events.
  3. Reconstruct the current aggregate state.
  4. Execute business rules.
  5. Produce new domain events.
  6. Persist new events.
Load Events
      │
      ▼
Replay Events
      │
      ▼
Current Aggregate
      │
      ▼
Execute Command
      │
      ▼
New Events

Optimistic Concurrency

Multiple users may attempt to update the same aggregate simultaneously.

The Event Store uses optimistic concurrency to ensure that new events are only appended if the aggregate version has not changed.

If another command has already committed additional events, the command must be retried using the latest aggregate state.

This prevents lost updates without requiring long-running database locks.


Event Versioning

As systems evolve, event schemas inevitably change.

Although this reference implementation currently uses a single event version, production systems commonly support:

Support for event versioning is planned as a future enhancement.


Event Replay

One of the major advantages of Event Sourcing is the ability to rebuild read models.

Event Store
      │
Replay Events
      │
      ▼
Projection Worker
      │
      ▼
Azure SQL

Replay allows new projections to be introduced without changing historical data.


Benefits

This architecture provides:


Trade-offs

Event Sourcing also introduces additional complexity.

Advantages

Challenges

For systems requiring auditability and historical traceability, these trade-offs are often worthwhile.


Implementation in this Project

This reference implementation demonstrates:

Future iterations will introduce: