Skip to main content
Decisions
DraftLast reviewed 2026-06-24

ADR-001: Event-sourced state

Status

Accepted

Context

A trade and risk platform needs to answer more than "what is the current state?" It also needs to answer:

  • what changed
  • in what order it changed
  • what the platform believed at the time it acted

A mutable row model is good at the first question and weak at the rest. It also makes it harder to rebuild downstream projections deterministically after a bug fix or schema change.

Decision

OpenTRMS uses an append-only event store as the source of truth for aggregate state. Commands validate input, append one or more domain events, and update read-optimized projections in the same transaction. Queries read from those projections rather than replaying the event log on every request.

In practice, that means:

  • event order is authoritative
  • optimistic concurrency is enforced on aggregate version
  • projections are rebuildable from the recorded event stream
  • write paths do not mutate domain history in place

Consequences

This design gives the platform three important properties:

  • current state is explainable as a fold over recorded facts
  • read models can be dropped and rebuilt deterministically
  • audit trails are first-class, not reconstructed after the fact

The tradeoff is that every state transition must be modeled explicitly as an event. Engineers do not get a "just patch the row" escape hatch for core domain state.

It also raises the testing bar. Strong write-path tests should assert both the event-store result and the projection result, because the platform promises both to stay aligned.