Level 5: Event Sourcing & CQRS
The highest complexity architectural pattern requiring expert support and sophisticated ontology.
Characteristics
- Read/Write separation (CQRS)
- Event Store
- Complex projections (Read Model)
- Event replay
CQRS, event sourcing, and distributed transactions are independent design choices, so they need not all be applied together. L5 addresses the complexity of their combination, but a given project may adopt only some of them.
AIDLC Application
Figure 1. AIDLC application flow for Level 5 Event Sourcing & CQRS
Ontology Level
Knowledge Graph: SemanticForge pattern
- Event store schema
- Explicit projection logic
- Event version management
Example Ontology (Event Sourcing):
# ontology/banking-account.yaml
aggregateRoot: BankAccount
events:
AccountOpened:
version: v1
schema:
accountId: string
customerId: string
initialBalance: decimal
openedAt: timestamp
MoneyDeposited:
version: v1
schema:
accountId: string
amount: decimal
transactionId: string
depositedAt: timestamp
MoneyWithdrawn:
version: v1
schema:
accountId: string
amount: decimal
transactionId: string
withdrawnAt: timestamp
eventStore:
partitionKey: accountId
sequenceKey: aggregateSequence # monotonic sequence per accountId
snapshotStrategy: every 100 events
retentionPolicy: 7 years # must cover the oldest point any projection may replay from (relative to snapshots)
projections:
AccountBalanceView:
source: [AccountOpened, MoneyDeposited, MoneyWithdrawn]
target: read_db.account_balance
updateStrategy: eventually_consistent
TransactionHistoryView:
source: [MoneyDeposited, MoneyWithdrawn]
target: read_db.transaction_history
updateStrategy: eventually_consistent
invariants:
- Balance cannot be negative
- Events must be ordered by per-aggregate sequence number (not wall-clock timestamp)
- TransactionId must be unique (idempotency)
Harness Checklist
The required and optional harness set for L5 is identical to the L5 row of Table 1 in the Harness Checklist.
Required harnesses:
- Event schema verification (version management)
- Projection verification (Read Model consistency)
- Event replay tests
- Event migration harness
Optional harnesses:
- Snapshot strategy verification
- Performance tests
Harness Implementation Examples
Projection Verification Harness
# harness/projection_test.py
def test_projection_consistency():
"""Verify event sourcing projection accuracy"""
# 1. Create events
events = [
AccountOpenedEvent(accountId="A1", balance=1000),
MoneyDepositedEvent(accountId="A1", amount=500),
MoneyWithdrawnEvent(accountId="A1", amount=200),
]
# 2. Store events
for event in events:
event_store.append(event)
# 3. Update projection
projection_service.rebuild("AccountBalanceView")
# 4. Verify Read Model
balance_view = read_db.get_account_balance("A1")
assert balance_view.balance == 1300 # 1000 + 500 - 200
assert balance_view.version == 3
Idempotency Harness
# harness/idempotency_test.py
def test_duplicate_event_handling():
"""Verify identical results when receiving same event multiple times"""
event = OrderCreatedEvent(orderId="123", userId="U1", items=[])
# First processing
result1 = event_handler.handle(event)
state1 = get_order_state("123")
# Second processing (duplicate)
result2 = event_handler.handle(event)
state2 = get_order_state("123")
# Results must be identical
assert result1 == result2
assert state1 == state2
Application Strategy
- DDD + Event Storming required
- Knowledge Graph level ontology
- Event version management strategy
- Automate projection logic verification
- Event replay tests required
- Expert team recommended
SemanticForge Pattern
Level 5 projects apply the SemanticForge pattern from Ontology Engineering. The mappings below are proposed analogies for applying it to event sourcing at L5, not the SemanticForge definition itself.
Proposed analogies (L5 only):
- Event = atomic unit of domain knowledge
- Express event relationships as Knowledge Graph
- Projection = Knowledge Graph query
Reference: See Ontology Engineering for detailed guide