prooph/event-sourcing
59.7
Adequate · 22 September 2026
1.3k
lines of production code
PHP
primary language
7
measurements over time
What this system is
This system is an event-sourcing library for PHP that provides a structured way to manage aggregate roots and their associated domain events. It offers core abstractions for tracking state changes, persisting events to a store, and reconstructing aggregates from their history. The library includes utilities for dependency injection, exception handling, and integration with event stores, all supported by comprehensive test coverage.
How it got here
2014–2015 — Core event-sourcing implementation
8 changes.
This period focused on establishing the core event-sourcing architecture, introducing key classes like AggregateRoot and AggregateChanged to manage state and domain events. The work included building integration components for event stores and providing a practical example to demonstrate the library's usage. Comprehensive unit tests were added to validate the new functionality.
2016 — Aggregate namespace and repository implementation
5 changes.
This period focused on introducing the new Aggregate namespace, which includes the AggregateRepository class for managing event-sourced aggregates with features like an identity map and configurable stream-per-aggregate behavior. The release also added supporting interfaces, exception types, and a container factory to facilitate dependency injection, accompanied by comprehensive test coverage for these new components.
Features
Add AggregateRepositoryFactory for container-based instantiation
A new factory class, AggregateRepositoryFactory, has been added to the Container/Aggregate namespace. This class implements the Interop Config interfaces (RequiresConfigId, RequiresMandatoryOptions, ProvidesDefaultOptions) to facilitate the creation of AggregateRepository instances via a PSR-11 compatible container. It resolves dependencies such as the event store, aggregate type, and optional snapshot store from the container, allowing for more flexible and decoupled repository instantiation within the dependency injection container.
src/Container · medium confidence
Add PHP quickstart example for event sourcing
A new quickstart example (examples/quickstart.php) is added to demonstrate how to use the Prooph event-sourcing library. The example defines a User aggregate root, domain events (UserWasCreated, UserWasRenamed), and an in-memory repository implementation, illustrating the basic patterns for creating, saving, and retrieving aggregate roots using the library's API.
examples · high confidence
Introduce core event-sourcing classes for aggregate management
Added the AggregateChanged and AggregateRoot classes to the src directory. AggregateChanged extends DomainEvent and manages aggregate state with a version number stored in metadata, while AggregateRoot is an abstract class that uses traits for event production and sourcing.
src · high confidence
Introduce new Aggregate namespace with repository and translator interfaces
Added the \Prooph\\EventSourcing\\Aggregate\ namespace containing the \AggregateRepository\ class, which manages loading and saving event-sourced aggregates via an \EventStore\ and optional \SnapshotStore\. The \AggregateRepository\ now supports an identity map (cacheable aggregate instances), configurable stream-per-aggregate behavior, and metadata enrichment for domain events. Supporting classes include the \AggregateTranslator\ interface, \AggregateType\ for type mapping, \AggregateTypeProvider\ interface, and traits (\EventProducerTrait\, \EventSourcedTrait\) that provide core event-sourcing mechanics like versioning, event recording, and history replay.
src/Aggregate · high confidence
New Aggregate exception types introduced
The library now provides a dedicated set of exception classes for the Aggregate namespace, including an AggregateException interface and specific exceptions such as AggregateTranslationFailedException, AggregateTypeException, InvalidArgumentException, and RuntimeException. These allow for more granular error handling and type-specific exception catching within the event-sourcing aggregate layer.
src/Aggregate/Exception · high confidence
New aggregate translation and decoration classes for EventStore integration
Added three new classes to the \Prooph\\EventSourcing\\EventStoreIntegration\ namespace: \AggregateRootDecorator\, \AggregateTranslator\, and \ClosureAggregateTranslator\. These classes provide mechanisms to extract aggregate metadata (version, ID, events) and reconstruct aggregates from history, supporting both standard and closure-based translation strategies for event store integration.
src/EventStoreIntegration · high confidence
Behavioural changes
Repository configuration and metadata updates
Added configuration files for Travis CI (.travis.yml), code coverage (.coveralls.yml, phpunit.xml.dist), and PHP CS Fixer (.php\_cs) to automate testing and linting. Updated the project's license header (.docheader) and copyright notices (LICENSE, .docheader) to reflect current ownership. Updated the README with installation and usage instructions, and added a CHANGELOG.md to track version history.
(repo-wide) · high confidence
Test coverage
Add unit tests for AggregateChanged and AggregateRoot; Added mock classes for testing event-sourcing aggregates; Added test coverage for Aggregate and AggregateType components; Added tests for AggregateRepositoryFactory; Added tests for EventStoreIntegration components.
Dependencies
Update PHP and Prooph/Event-Store dependencies
The composer.json file has been updated to require PHP 7.3 or 8.0 and Prooph/Event-Store version 7.0 or higher. Additionally, development dependencies such as PHPUnit 9.3, Prophecy, and various Prooph tools have been updated to their latest compatible versions.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 56 → 60 (+3.5)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 100 → 100 (+0.0)
- Architecture 69 → 69 (+0.0)
- Maturity 41 → 49 (+7.7)
- Readiness 50 → 50 (-0.0)
- Security 100 → 100 (+0.0)
- Domain Modelling 100 → 100 (+0.0)
- Event Sourcing 100 → 100 (+0.0)
Resolved (6)
- Coverage not included — suite not readable by the collector
- Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
- LLM evaluation failed
- No exposed public API
- Test reliability not included
- dormant codebase — no living knowledge left to concentrate
New (10)
- Dependency hygiene PARTLY measured — Composer dependencies read, no committed lock to grade for currency
- Documentation: no installation or build instructions (README.md)
- Documentation: no licence statement (README.md)
- Documentation: no usage examples (README.md)
- Duplicate method extractAggregateId exists in both the base AggregateTranslator and the EventStoreIntegration.AggregateTranslator (and its closure variant). While inheritance might explain this, the presence of ClosureAggregateTranslator which duplicates the interface of AggregateTranslator suggests a confusing split between 'standard' and 'closure-based' implementations that offer no clear advantage other than implementation detail, leading to API fragmentation.
- Duplicate method extractPendingStreamEvents across three translator classes. This is a critical operation for saving aggregates, and having it duplicated increases the risk of inconsistent event extraction logic.
- Duplicate method replayStreamEvents across three translator classes. This is the core mechanism for applying events to an aggregate. Duplication here is high-risk for consistency.
- No dependency advisory monitoring
- Severe duplication of core logic across multiple classes. The method extractAggregateVersion exists on the Repository, the main Translator, the EventStoreIntegration Translator, the ClosureTranslator, and the Decorator. This violates DRY and creates a maintenance nightmare where version extraction logic must be synchronized across five different places.
- The method reconstituteAggregateFromHistory is duplicated across three translator classes. This indicates that the core logic for rebuilding an aggregate from events is not centralized, risking divergence in behavior between the standard translator and the event-store integration translator.
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
prooph/event-sourcing was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 22 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 4b8e2e50f9029f0e8006f7c3bbb5c60519f3f4f7 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-821afab8930d.