Three kinds of message: command, event, query
Keep commands, events, and queries separate to buy cheap clarity throughout the system.
Three kinds of message move through the core, and keeping them distinct is the cheapest clarity you’ll ever buy.
A command is an instruction to change something. It’s imperative, and it’s named that way — InviteTeammate. It expresses intent, it can be refused (the seats are full), and exactly one piece of code is responsible for handling it. A command is a request, not a guarantee.
An event is a statement that something already happened — TeammateInvited, past tense, a fact. It can’t be refused, because it’s history. And unlike a command it has no single owner: zero, one, or many parts of the system may react to it. Hold that thought — it’s the seed of everything in Module 5.
A query asks to read and promises to change nothing. How many seats remain? It returns data and has no business enforcing rules or causing effects. Keeping reads strictly apart from writes — queries that never change state, commands you don’t read back through — is one of those distinctions that costs nothing to hold and saves you constantly.
This does not oblige you to build separate databases for each. That’s a heavier move with its own trigger condition. The cheap win is the conceptual separation.