Audit from domain events

An event-sourced aggregate retains the events used to derive its state. This allows the application to explain recorded state transitions.

Audit history is also possible in a conventional database. The distinction is that Event Sourcing uses events as the authoritative record rather than maintaining them as a separate account of state updates.

Audit usefulness depends on the event model. Record the necessary actor, correlation, and decision context explicitly; the event store cannot infer information the application never supplied.

Replay and read-model recovery

Reprocess events to rebuild a read model after changing or correcting projection logic. Start from the beginning or from a valid saved state and its matching position.

Rebuilding derived data requires the relevant event history to be available. Replay does not replace backups of the event store.

Keep projection handlers deterministic where possible. Avoid repeating external side effects during rebuilds, and define how consumers handle duplicate delivery.

Event stream
Order read model
Audit read model
The same event history can be replayed into multiple projections and read models without changing the stored events.

Aggregate persistence

Store an aggregate instance's events in its stream. Reconstruct its state before executing behavior that depends on that state.

Append the resulting events with the version used for the decision. If another command has already changed the stream, reload and re-evaluate the command or return a conflict.

The aggregate defines the consistency boundary. If an operation spans multiple aggregates, explicitly design its coordination rather than assuming that stream version checks provide a cross-stream transaction.

Event-driven integration

Use a durable subscription to process committed events in another application component and retain processing progress.

For integration between bounded contexts, define a stable contract. It may be appropriate to translate internal domain events into separate integration events.

Design consumers for retries and duplicate delivery. A saved position helps recovery, but it does not make an external side effect execute exactly once.

Application
Chronacta
Postgres
NATS / Kafka
Chronacta stores the event history the application designates as authoritative. Postgres and message brokers may remain external read-model stores or transport.

When a simpler approach is sufficient

A conventional state-based model may be simpler when retaining an authoritative event sequence offers little benefit. Audit or optimistic concurrency requirements alone do not make Event Sourcing mandatory.

Use a queue for job delivery and an analytical store for analytical workloads when those are the actual requirements. Choose an event store when the application uses events as its persisted model.