I’m having an hard time with one use case I have in my application.
As an example speaks better than words :
I’m dealing with warehouse items that are stored in a warehouse. Ultimately, these warehouse items will be put in auction.
One requirement is that each warehouse item has to be evaluated ( price + grade) beforehand.
The evaluation process itself has some rules :
- the item has to be evaluated at least by 2 diffferent staffs
- the difference between 2 evaluation price must be within a specifc range
- the final price is set by a manager
- The 2 staffs can edit their evaluations as much as they want as soon as the final price is not confirmed by the manager.
- The item can be reevaluated later on but it’s a new instance of the evaluation process, obeying the same rules.
So far, so good, right now I already have WarehouseItem as an AR.
As these temporary evaluations are not part of the warehouse item state for me (only the final price and grade matter), I don’t feel comfortable to store them into it and to handle the process through the WarehouseItem AR.
My first idea was the following :
- Create a Evaluation Aggregate Root that references the Warehouse item aggregate ( created directly via a command or by the following saga upon the first evaluation). This way, I can edit each evaluation (rule #4)
- Use a Saga as the evaluation process tracker, handling the transitions and the associated business rules
- Set the final price and grade by sending a command from the Saga whenever the manager confirms the price 2) Mark the Evaluations as Read-only
The problem I see in that case is that I have to reach the Saga before knowing whether the Evaluation is valid or not, as it’s the only place where we have a reference to all evaluations for a particular warehouse item (to check rule #2)
It means I have to adjust the state of the evaluation afterwards (mark it as invalid, and update the read model accordingly). This is not as convenient and efficient as rejecting the command creating the evaluation at the first place.
I’m starting to think that it might be better to have an AR EvaluationRound for example, that centralizes all the evaluations for the specific item.
This way, when the EvaluationRound is completed, I would use a stateless event handler to update the warehouse item final price and grade.
Am I on the right track, or would you have any suggestions, best practices to handle this kind of (common) case ?
Thank you in advance,