# inwebo/doctrine-event-sourcing architecture

> Architecture diagram of the GitHub repository inwebo/doctrine-event-sourcing, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-10-19). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/inwebo/doctrine-event-sourcing
- Repository: https://github.com/inwebo/doctrine-event-sourcing

## Overview

This is a Doctrine event-sourcing library: applications mark aggregate roots and tracked properties, then Doctrine lifecycle events create state snapshots; the library also applies snapshots and resolves historical changes. The graph preserves configuration, state management, and history as distinct capabilities. Source excerpts show the listener, mapping, aggregation, and diff behavior; README statements support the documented Doctrine setup and persistence workflow. The resolver and DTOs are represented, but no storage implementation is shown—the application’s Doctrine setup owns persistence.

Main entry points: [`src/Model/MappingFactory.php`](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/MappingFactory.php) (Mapping factory), [`src/Model/Aggregator.php`](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/Aggregator.php) (State aggregator), [`src/Resolver/DiffResolver.php`](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Resolver/DiffResolver.php) (History diff resolver), [`src/Listener/AbstractStoreListener.php`](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Listener/AbstractStoreListener.php) (Store listener)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_configuration["Mapping configuration"]
  node_root_attribute["Aggregate root attribute<br/>[AggregateRoot.php]"]
  node_source_attribute["Tracked property attribute"]
  node_mapping_factory["Mapping factory<br/>[MappingFactory.php]"]
  node_mapping["Property mapping<br/>[Mapping.php]"]
  node_mapping_exceptions["Mapping validation errors"]
  node_interface_errors["Interface validation error"]
end

subgraph group_state["Snapshot lifecycle"]
  node_state_interfaces["Aggregate and state contracts"]
  node_aggregator["State aggregator<br/>[Aggregator.php]"]
  node_store_listener["Store listener"]
  node_default_listener["Default listener<br/>[StoreListener.php]"]
  node_state_records[("State snapshots")]
end

subgraph group_history["History and changes"]
  node_diff_resolver["History diff resolver<br/>[DiffResolver.php]"]
  node_change_dto["Individual change<br/>[ChangeDto.php]"]
  node_change_set["Change set<br/>[ChangeSetDto.php]"]
end

node_app(("Application entities"))
node_doctrine["Doctrine ORM"]

node_app -->|"marks root"| node_root_attribute
node_app -->|"marks properties"| node_source_attribute
node_doctrine -->|"dispatches lifecycle events"| node_default_listener
node_default_listener -->|"inherits behavior"| node_store_listener
node_store_listener -->|"creates snapshots"| node_aggregator
node_store_listener -->|"persists snapshots"| node_state_records
node_mapping_factory -->|"reads configuration"| node_root_attribute
node_mapping_factory -->|"reads configuration"| node_source_attribute
node_mapping_factory -->|"builds mappings"| node_mapping
node_mapping_factory -->|"reports invalid mapping"| node_mapping_exceptions
node_mapping_factory -->|"checks contract"| node_interface_errors
node_mapping_factory -->|"validates contracts"| node_state_interfaces
node_aggregator -->|"uses mappings"| node_mapping_factory
node_aggregator -->|"transfers property values"| node_mapping
node_aggregator -->|"creates and applies states"| node_state_interfaces
node_diff_resolver -->|"builds current snapshot"| node_aggregator
node_diff_resolver -->|"reads state history"| node_state_interfaces
node_diff_resolver -->|"records differences"| node_change_dto
node_diff_resolver -->|"assembles changes"| node_change_set

click node_root_attribute "https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Mapping/AggregateRoot.php"
click node_source_attribute "https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Mapping/AggregateSource.php"
click node_mapping_factory "https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/MappingFactory.php"
click node_mapping "https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/Mapping.php"
click node_mapping_exceptions "https://github.com/inwebo/doctrine-event-sourcing/tree/master/src/Exception/Mapping"
click node_interface_errors "https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Exception/MissingHasStatesInterfaceException.php"
click node_state_interfaces "https://github.com/inwebo/doctrine-event-sourcing/tree/master/src/Model/Interface"
click node_aggregator "https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/Aggregator.php"
click node_store_listener "https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Listener/AbstractStoreListener.php"
click node_default_listener "https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Listener/StoreListener.php"
click node_diff_resolver "https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Resolver/DiffResolver.php"
click node_change_dto "https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/Dto/ChangeDto.php"
click node_change_set "https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/Dto/ChangeSetDto.php"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_root_attribute,node_source_attribute,node_mapping_factory,node_mapping,node_mapping_exceptions,node_interface_errors toneBlue
class node_state_interfaces,node_aggregator,node_store_listener,node_default_listener,node_state_records toneAmber
class node_diff_resolver,node_change_dto,node_change_set toneMint
class node_app,node_doctrine toneIndigo
```

## Components

### Mapping configuration

- [Aggregate root attribute](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Mapping/AggregateRoot.php): `src/Mapping/AggregateRoot.php`
- [Tracked property attribute](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Mapping/AggregateSource.php): `src/Mapping/AggregateSource.php`
- [Mapping factory](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/MappingFactory.php): `src/Model/MappingFactory.php`
- [Property mapping](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/Mapping.php): `src/Model/Mapping.php`
- [Mapping validation errors](https://github.com/inwebo/doctrine-event-sourcing/tree/master/src/Exception/Mapping): `src/Exception/Mapping`
- [Interface validation error](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Exception/MissingHasStatesInterfaceException.php): `src/Exception/MissingHasStatesInterfaceException.php`

### Snapshot lifecycle

- [Aggregate and state contracts](https://github.com/inwebo/doctrine-event-sourcing/tree/master/src/Model/Interface): `src/Model/Interface`
- [State aggregator](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/Aggregator.php): `src/Model/Aggregator.php`
- [Store listener](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Listener/AbstractStoreListener.php): `src/Listener/AbstractStoreListener.php`
- [Default listener](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Listener/StoreListener.php): `src/Listener/StoreListener.php`
- **State snapshots**

### History and changes

- [History diff resolver](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Resolver/DiffResolver.php): `src/Resolver/DiffResolver.php`
- [Individual change](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/Dto/ChangeDto.php): `src/Model/Dto/ChangeDto.php`
- [Change set](https://github.com/inwebo/doctrine-event-sourcing/blob/master/src/Model/Dto/ChangeSetDto.php): `src/Model/Dto/ChangeSetDto.php`

### Other components

- **Application entities**
- **Doctrine ORM**

## Connections

- Application entities → Aggregate root attribute: marks root (evidence: `README.md`)
- Application entities → Tracked property attribute: marks properties (evidence: `README.md`)
- Doctrine ORM → Default listener: dispatches lifecycle events (evidence: `README.md`)
- Default listener → Store listener: inherits behavior (evidence: `src/Listener/StoreListener.php`)
- Store listener → State aggregator: creates snapshots (evidence: `src/Listener/AbstractStoreListener.php`)
- Store listener → State snapshots: persists snapshots (evidence: `README.md`)
- Mapping factory → Aggregate root attribute: reads configuration (evidence: `src/Model/MappingFactory.php`)
- Mapping factory → Tracked property attribute: reads configuration (evidence: `src/Model/MappingFactory.php`)
- Mapping factory → Property mapping: builds mappings (evidence: `src/Model/MappingFactory.php`)
- Mapping factory → Mapping validation errors: reports invalid mapping (evidence: `src/Model/MappingFactory.php`)
- Mapping factory → Interface validation error: checks contract (evidence: `src/Model/MappingFactory.php`)
- Mapping factory → Aggregate and state contracts: validates contracts (evidence: `src/Model/MappingFactory.php`)
- State aggregator → Mapping factory: uses mappings (evidence: `src/Model/Aggregator.php`)
- State aggregator → Property mapping: transfers property values (evidence: `src/Model/Aggregator.php`)
- State aggregator → Aggregate and state contracts: creates and applies states (evidence: `src/Model/Aggregator.php`)
- History diff resolver → State aggregator: builds current snapshot (evidence: `src/Resolver/DiffResolver.php`)
- History diff resolver → Aggregate and state contracts: reads state history (evidence: `src/Resolver/DiffResolver.php`)
- History diff resolver → Individual change: records differences (evidence: `src/Resolver/DiffResolver.php`)
- History diff resolver → Change set: assembles changes (evidence: `src/Resolver/DiffResolver.php`)
