I have a bounded context for domain-specific task management. Some user (called coordinator) can create task and assign it to another user (called executor). Executor can complete task at some time later. In the meantime coordinator can reassign the task to different executor, which becomes in charge of completion of that task. First executor looses ability to work with the task.
Now the situation is complicated by the fact that coordinators work at web-app (backend) and executors work at their mobile apps (clients). So that bounded context effectively distributed between many nodes. Moreover mobile apps may work completely offline for pretty large time period (a few days).
So it could be a situation when coordinator assigns a task to executor A
, then the executor went offline. In the meatime coordinator decided he didn't want to wait for completion of the task by executor A
and reassigned the task to executor B
. However executor A
for some reasons didn't know it and completed the task anyway. Some time later executor A
becomes online and now we have to synchronize state consistently between his mobile app and backend, following business rule that claims that tasks could be completed only by their actual executors. Executor A
tells backend "Hey, I completed the task with that result". Backend listened to executor A
then he sees that task currently assigned to executor B
. Backend must answer to executor A
: "Sorry, currently the task is not yours. Please delete the task on your phone. I reject your result of completion of the task."
Real scenarios are much more complex: executors and coordinators can do many kinds of actions with tasks completely independently of each other. Then at some time later they should properly synchronize state following business rules.
How would you implement such synchronizations inside distributed bounded context which assume conflict resolution (rejections, compensations and so on)?
The most important starting point for "data entry" systems is that the model isn't the book of record, the outside world is. Messages from the occasionally connected systems tell you what happened on those devices; it's the job of the model to compute the implications.
The real world doesn't always follow the happy path.
That's still, potentially, a valid response from your model. I wouldn't say "reject your result"; we're not denying the result provided by the executor -- we're merging that information in with other data we have collected and describing the current state of the finite state machine.
In other words, we add more paths and more states to the model, rather than insisting that the real world follow only the happy path.