I'm trying to use the cqrs package to set up an event sourced application. To do this I am going to write all changes to a journal (differentiating between Commands and Events). In order to deal with system upgrates, I will take snapshots from the read store and and replay Events from the journal. From what I can see, the distinction between Commands and Events is subtly different to what I've seen in other systems in an important way and I'm not sure how best to continue.
Aggregate root creation is split into a 2-step operation: a CreateCommand is issued and, if it's sucessful, an ObjectCreated event is published. During event playback, the system skips over the Command and processes the ObjectCreated event. Now, my issue here is with the way that nestjs ties the ObjectCreated event to the aggregate root. mergeObjectContext is called in the CommandHandler to get and modify the latest version of the aggregate root, but in order to create the aggregate root in the first place, you need a create Event of some type (so there's a chicken and egg problem). The hero demo project skips over this issue in 2 ways: it uses the read model on the write side, and it also assumes the objects have already been created elsewhere. So my first question is, what is the right way of modeling this with nestjs?
Next, it seems like the author intends that all inbound events and commands go through the command bus, but I'm used to seeing Commands represent requests and Events represent domain facts. Recreating object state requires playback of Events for the object; not Commands . That's why the CommandHandler has an async execute function and the EventHandler is pure. What I'm not understanding is how the read store, particularly the AggregateRoot object, is supposed to get persisted in this model -- if all functions are pure, then am I supposed to create a Saga to listen to all Events and then persist them from the Saga?
Thank you!