4 eyes principle with CQRS

146 views
Skip to first unread message

Ben Goldin

unread,
Feb 27, 2018, 5:54:45 AM2/27/18
to DDD/CQRS
Hi Guys,

Have an interesting challenge on how to model Commands with 4 eyes principle enabled, i.e. when the same action should be approved by a second person (i.e. Checker) before it gets executed. I think of two ways to implement that, e.g.

1) Maker initiates PostJournalEntry command
2) Whenever the PostJournalEntry requires checker, the command goes into PENDING CHECK state (validated in command handler)
3) Checker sees the command in the inbox and checks / approves it
4) Command gets delivered to the handler for execution

The issue with this approach is that the "intent" to approve the action is not captured as a separate command and the initial command is broken into two actions. 

Second option would be to implement two separate commands for each action, i.e. InitiateJournalEntryPost and ApproveJournalEntryPost, but this approach would move the complexity to keep intermediate state of the "command" into each an every domain, whilst in fact, domain is not concerned whenever the action itself was approved or not. Moreover, the idea is to keep this concern on the upper level of the architecture to make it generic for all type of actions, without the need to model it and maintain in every domain separately. 

Any thoughts would be highly appreciated.

Thanks,
Ben

Alexander Langer

unread,
Feb 27, 2018, 6:04:18 AM2/27/18
to ddd...@googlegroups.com
If the domain is not concerned, why do you need 4 eyes principle?

Yes, I would make the 4 eyes principle explicit, e.g., use separate
commands and events. In particular, don't do magic on a technical level
(like holding back the command until it's approved), but rather:

- deliver "DoXY" command to command handler
- raise "XYApprovalRequired" event
- fill the approval inbox (projection on XYApprovalRequired events)
- send "ApproveXY" command
- do XY in the command handler

Note that you can probably make a generic approval process that works
with arbitrary commands and sits elsewhere than the actual domain
handling code (or in the "upper level of the architecture"). Simply
replace "DoXY" by "Do<XY>" or similar.

HTH

Ben Goldin

unread,
Feb 27, 2018, 10:24:34 AM2/27/18
to DDD/CQRS
Thanks, Alexander! This does make sense. Elaborating on top of what you suggested, it would make sense to create a separate Domain, that would maintain Checker Requests and orchestrate actual command initiation as soon as Checker Request is approved. 

I.e. "POST /journalentries" -> RequestCheckerReview -> (CheckerReviewAR) -> CheckerReviewRequested -> ApproveCheckerReviewRequest -> (CheckerReviewAR) -> CheckerReviewRequestApproved -> PostJournalEntry
Reply all
Reply to author
Forward
0 new messages