Order
A buyer's order and its state machine, after the classic eShop's:
SUBMITTED -> AWAITING_VALIDATION -> STOCK_CONFIRMED -> PAID -> SHIPPED
\______________\_____________________\__________-> CANCELLEDSubmitOrder creates it; the basket context sends it on checkout. The order belongs to its buyer: its owner is the owner of the checkout's basket, whose scope the basket's saga carries on.
AwaitStockValidation moves it on, and OrderProcessSaga then reserves its stock in the inventory context.
ConfirmOrderStock confirms one product, as OrderProcessSaga learns from the receipt of its reservation. The last one confirms the order's stock and schedules its cancellation once the payment grace period of the PaymentPolicy has passed: a durable scheduled command, written with the events.
PayOrder pays it and cancels that schedule; ShipOrder ships it.
CancelOrder cancels an order not paid yet: the saga's compensation when the inventory rejects a reservation, or the scheduled command when the grace period has passed. Once the order is paid, the scheduled cancellation is rejected when it is due, which is a normal guard.
Types
The codes the aggregate rejects a command with, by their local names: the compiler and the kernel name them <context>.order.<code>, as its peers read them from the api's generated contract.
Functions
Moving on an order that is no longer submitted, one cancelled meanwhile say, changes nothing.
Cancelling a cancelled order changes nothing: the saga cancels once for each product the inventory refused.
Confirms one product. A confirmation the order does not wait for changes nothing: one read again from the stock stream, or one that arrives after another product's shortage cancelled the order (that reservation is released when the inventory hears of the cancellation).