Events and Projections
Event sourcing keeps the write model as an append-only log of domain events. Projections fold that log into query-friendly read models. Production PostgreSQL persistence uses es-entity on the shared PgPool; multi-projection rebuild order uses id_effect_graph.
What This Chapter Covers
EventStore— append and read stream eventsEsEntityEventStore(featurees-entity) — production PG journalProjectionRunner— graph-ordered multi-projection rebuildsMemoryEventStore/FileJournal— dev/test persistencedispatch_command_es_entity— async CQRS write pathtopological_sort— projection dependency ordering
Production path (es-entity)
#![allow(unused)] fn main() { use id_effect_events::{EsEntityEventStore, EsEntityPgBackend, EventStore}; // pool from id_effect_sql_pg::PgPool let store = EsEntityEventStore::new(EsEntityPgBackend::new(pool)); }
Apply ES_ENTITY_EVENT_JOURNAL_DDL at startup. See ADR docs/platform/adrs/adr-es-entity-event-persistence.md.
ProjectionRunner
Register projection nodes with dependencies; plan() uses id_effect_graph::topological_sort:
#![allow(unused)] fn main() { use id_effect_events::{ProjectionNode, ProjectionRunner}; let mut runner = ProjectionRunner::new(); runner.register(ProjectionNode::new("summary", [])); let order = runner.plan()?; }
Dev stores
[MemoryEventStore] and [FileJournal] remain for unit tests and local spikes without PostgreSQL.
See also Part VI ch31 (obix outbox) and ch32 (duroxide workflow).