In lesson 4.4.1 you decided that sales stores its deals as a sequence of events. In this lesson you build the aggregate
for it: the Deal with its commands, events and rules. It will consist of two pure functions that know neither a database
nor a clock. Storing comes only in the next lesson; here it is just about the model and its tests.
You know the building blocks from module 4.3: an aggregate with invariants, expected errors as Result<T>, domain events in the past tense.
What is new is that the state is no longer stored but built from events. That changes what the aggregate looks like, and it makes
the tests simpler.
The path of a deal
You know the course of events from the event storming in lesson 4.2.3. A deal begins as a tip about an opportunity, gets checked, gets one
quote or several, and ends won or lost. In the glossary the sales opportunity is called Deal, and its stages are called this:
| Stage | in the code | how to get there |
|---|---|---|
| New | Lead |
open the deal |
| Qualified | Qualified |
estimate the value and the expected closing |
| Quote | Proposal |
attach a quote |
| Won | Won |
win with an attached quote |
| Lost | Lost |
lose with a reason |
The rules that the office owner named in lesson 4.2.3:
- A deal has a customer and a title of at most 200 characters. The title names a project, never a person.
- A deal is qualified once, from the stage New, with a value above zero and an expected closing that is not in the past.
- A quote is attached only to a qualified deal. Attaching the same quote twice changes nothing.
- A deal is won only with a quote that is attached to it, and with an amount above zero.
- An open deal is lost in any stage, with a known reason.
- A won or lost deal never changes again.