CQRS Event Sourcing Pattern

SEA™ DSL pattern for Command Query Responsibility Segregation with Event Sourcing.

Flow Annotation Requirements

Kind Required Recommended
command @cqrs { "kind": "command" } @tx, @idempotency
query @cqrs { "kind": "query" } @read_model
event @cqrs { "kind": "event" } @outbox

Complete Pattern

@namespace "com.example.orders"
@version "1.0.0"

// ============================================================================
// AGGREGATES (Entities)
// ============================================================================

Entity "OrderAggregate" in orders
Entity "CustomerAggregate" in orders
Entity "InventoryAggregate" in orders

// ============================================================================
// READ MODELS (Projections)
// ============================================================================

Entity "OrderProjection" in orders
Entity "CustomerOrdersProjection" in orders
Entity "InventoryProjection" in orders

// ============================================================================
// INFRASTRUCTURE
// ============================================================================

Entity "CommandBus" in kernel
Entity "QueryBus" in kernel
Entity "EventBus" in kernel
Entity "EventStore" in kernel
Entity "ReadStore" in kernel
Entity "OutboxPort" in kernel

// ============================================================================
// COMMANDS
// ============================================================================

Flow "CreateOrder"
  @cqrs { "kind": "command" }
  @tx { "transactional": true }
  @idempotency { "enabled": true, "key": "orderId" }
from "CommandBus" to "OrderAggregate"

Flow "UpdateOrder"
  @cqrs { "kind": "command" }
  @tx { "transactional": true }
  @idempotency { "enabled": true, "key": "orderId" }
from "CommandBus" to "OrderAggregate"

Flow "CancelOrder"
  @cqrs { "kind": "command" }
  @tx { "transactional": true }
from "CommandBus" to "OrderAggregate"

// ============================================================================
// EVENTS
// ============================================================================

Flow "OrderCreated"
  @cqrs { "kind": "event" }
  @outbox { "mode": "required" }
from "OrderAggregate" to "EventBus"

Flow "OrderUpdated"
  @cqrs { "kind": "event" }
  @outbox { "mode": "required" }
from "OrderAggregate" to "EventBus"

Flow "OrderCancelled"
  @cqrs { "kind": "event" }
  @outbox { "mode": "required" }
from "OrderAggregate" to "EventBus"

// ============================================================================
// EVENT STORE PERSISTENCE
// ============================================================================

Flow "StoreEvent"
  @cqrs { "kind": "command" }
  @tx { "transactional": true }
from "EventBus" to "EventStore"

// ============================================================================
// PROJECTIONS (Event Handlers)
// ============================================================================

Flow "ProjectOrderCreated"
  @cqrs { "kind": "command" }
from "EventBus" to "OrderProjection"

Flow "ProjectOrderToCustomer"
  @cqrs { "kind": "command" }
from "EventBus" to "CustomerOrdersProjection"

// ============================================================================
// QUERIES
// ============================================================================

Flow "GetOrderById"
  @cqrs { "kind": "query" }
  @read_model { "name": "OrderProjection" }
from "QueryBus" to "ReadStore"

Flow "GetCustomerOrders"
  @cqrs { "kind": "query" }
  @read_model { "name": "CustomerOrdersProjection" }
from "QueryBus" to "ReadStore"

// ============================================================================
// POLICIES
// ============================================================================

Policy event_must_be_stored
  per Constraint Obligation priority 10
  @rationale "All domain events must be persisted"
as: forall e in flows where e.kind = "event":
    exists s in flows where s.name = "StoreEvent": true

Policy commands_are_idempotent
  per Constraint Obligation priority 10
as: forall c in flows where c.cqrs.kind = "command" and c.critical = true:
    (c.idempotency.enabled = true)

Key Patterns

  1. Command → Aggregate → Event: State changes emit events
  2. Event → Projection: Events build read models
  3. Query → Read Model: Queries use dedicated projections
  4. Outbox: Reliable event delivery

Last Updated: January 2026