In a true warehouse management system, the handling of orders is much more complicated than you describe, but I understand you are simply trying to play with a simple scenario.
Restricting my answer exclusively to the systems you're mentioning I would do it like this:
When a customer places an order in the frontend a command to PlaceOrder
could be sent to the order management system, which will simply record the order in its database in a "pending" state and broadcast an OrderPlaced
event.
In this status, the order won't yet appear in the fulfillment systems yet, since the order inventory is not reserved, payments are not guaranteed, shipments are not created, etc. The order could still be canceled by the customer.
The inventory management system would listen for OrderPlaced
events and respond to those events by trying to find the best inventory possible for an order. This is more complicated than it sounds in real life. The retailer may have multiple facilities in different places in the country. You want the inventory that is closest to the final destination to reduce delivery costs. If the order is international, you want the inventory from a facility closest to the airport. If you have inventory in primary locations, you should prefer that over the one in back stock, etc. So, the algorithm is more complicated than just deducting one in the count of an SKU.
Another system that could intervene is the one responsible for customer notification since you'd like your customer to receive a notification of the order being accepted.
Once the inventory management is done tying inventory to an order, it could broadcast an event InventoryTied
which other systems could listen to. At this point, I think the fulfillment system would need to intervene, but since it is not in your example I will leave it out of the answer. You could use this event to decide to change the order status in the order, perhaps make it impossible to cancel at this point, e.g. change to a "Shipping" state.
However, you must know this is an oversimplification of what happens in real life. In real life, for me, an order management system works as a state machine. That's why microservices tend to fit well with this domain since every stage is somewhat complex and requires the orchestration of many services to finally fulfill an order.
Regarding your second question about storing events. Supposing you're talking about something beyond what Kafka already offers, I would not do so unless I was writing an event sourcing system, but that's not necessary to have a fully function event-driven architecture. You can simply react to the events as they happen. If you build your services in an idempotent way, you still have some room for replayability of e.g. failed events.