Since the last lesson, sales has been storing its deals as events. But the owner of the office doesn't want to read events; she wants to see two things: the pipeline board with all deals by stage, and the forecast per month, what is expected to come in and in which month. Both are read models, and both come into being from the same events.
In this lesson you build the projections, a projector that fills them, and the rebuild from the stream. Then comes the lab: a projector that looks perfectly reasonable loses events under load, and only in Azure, not on your machine. You demonstrate the bug and fix it.
What a read model is
A read model is a table that exists only for a display. It has exactly the columns a page needs, and no rules. Its content is derived: you can empty it at any time and fill it again from the events. The Azure Architecture Center calls this a materialized view.
The Kladde gets two:
sales.PipelineBoard: one row per deal with title, stage, value (the estimate, after a win the amount) and the point in time of the last change. The page groups by stage.sales.Forecast: one row per deal with the month in which it brings money, the amount and whether it is already won. A lost deal has no row. The totals per month are aGROUP BYover this table.
Why not a table “total per month” right away? Because a deal can change its month: it is estimated for May and won in March. With one row per deal, that is a change to one row. With a total per month, the projector would have to remember what it added where before. Keep read models so that every event changes exactly one row.