This is an example application aimed at teaching basic event sourcing.
To run this application, you will need:
The tools that we are going to use are:
- Zend Expressive a simple PSR-7/HTTP routing framework
- Prooph Components abstraction for common CQRS + Event Sourcing concerns
The domain of the application is quite limited, but sufficient to explain how and when to effectively use CQRS and EventSourcing.
The MVP of the application has following specification:
- assume that each person interacting with the system has a badge with a username on it
- assume that the username is given: we assume that the input data is already validated against existing users
- track people entering (check-in) a building
- track people leaving (check-out) a building
- prevent people from double-entering a building (security concern)
- prevent people from double-leaving a building (security concern)
- allow querying a list of people that are currently in the building
Following steps are to be implemented:
- Ability to register a new building (already provided)
- Ability to check-in with a username and a building identifier (skeleton code provided)
- Ability to check-out with a username and a building identifier (skeleton code provided)
- Provide console output (STDERR) every time a check-in happens (event handler)
- Provide console output (STDERR) every time a check-out happens (event handler)
- Provide a file per building (accessible via HTTP) with usernames of currently checked-in persons
- Prevent people from double check-in
- Prevent people from double check-out
- Write BDD tests written in Gherkin for Behat
- Command (contains only a payload) is registered in the container
- Command registration returns a callable for latter execution
- Command gets passed to the CommandBus (web layer)
- CommandBus calls listener
- Listener executes code from the command registered callable
- Callable gets an aggregate and performs an action
- The action creates an domain event
Specify one "when" method per domain event, otherwise the framework will crash. These methods are for hydrating the aggregate from the event store.
Checking-in a user calls its "when" method:
- Before check-in. By getting aggregate that is going to be hydrated, thus can be called multiple times
- After check-in, one time again for ensuring the state change on this aggregate