Event sourcing and how to change business rules

283 views
Skip to first unread message

jwoets

unread,
May 31, 2018, 8:57:27 AM5/31/18
to DDD/CQRS

In CQRS + ES how to change business rules (or a business rules parameter) affecting the state of an aggregate. 


Simple example, the rule :

Pass account to prenium when the order count is more than 10 orders


Obviously, there is  : 


- AccountAggregate

- AddOrderCommand

- OrderAddedEvent

- AccountPassedPreniumEvent


(there are other commands et events but not mentioned here for simplify)


the rule is applied in AccountAggregate and generate AccountPassedPreniumEvent after a test on order count. This event is projected to a read model


this rule come with the first deployement. Ok, now there are 1000 prenium. The boss change the rule because the business is impacted, and want to pas prenium where the order count is more than 20.

How to pass to standard account the account with more than 10 orders but less than 20 ?


Thanks for your help.

Brad Irby

unread,
May 31, 2018, 9:12:51 AM5/31/18
to DDD/CQRS
If you are using ES, the core requirement  is to create the proper events to adjust the state of the aggregates.  Depending on business rules, that can be done in a few ways.

There is no requirement that code generating events needs to be permanent.  If you want to "fix the data", creating a small utility that cycles through all aggregates testing each one and generating AccountPassedStandardEvent events is acceptable.  Once complete you can throw that utility away.

If the business rule is that you must have 20 orders per rolling 12 months, then the logic should be baked into the Aggregates to create the AccountPassedStandardEvent when appropriate.  

jwoets

unread,
May 31, 2018, 9:40:22 AM5/31/18
to DDD/CQRS
So if the business logic change , i must get all events to apply a command for generate new event aind thus update the read model...

it's complex for a simple update of business parameter. 

A solution can not be apply this rule on read side and on the write side ?

On a read side : 
    when access to the read model from ui, i apply  the rule (dynamicly) => the read side is always up to date according the rule

On the write side:
    classically when apply the command...

I don't know if it's a good solution 

Greg Young

unread,
May 31, 2018, 9:46:46 AM5/31/18
to ddd...@googlegroups.com
Business rules don't normally change retroactively this seems a bit confused. If it did change retroactively then you would issue correcting events.

--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/dddcqrs.
For more options, visit https://groups.google.com/d/optout.



--
Studying for the Turing test

Brad Irby

unread,
May 31, 2018, 9:56:20 AM5/31/18
to DDD/CQRS
Adding business logic to the read side is a bad way to go.  The event store should reflect the current state of the aggregates and reads should always reflect that state.  If your read side reflects different data than the write side, your business logic will make decisions which make no sense when looking at the data on the read side.

I wouldn't think of this as a business rule change.  Look at it more like the old rule has expired and a new rule is being introduced. The proper approach becomes more apparent this way.

jwoets

unread,
May 31, 2018, 9:56:48 AM5/31/18
to DDD/CQRS

Yes it's better... In my concrete case, my domain expert is not very expert... and it's a problem with event sourcing.

To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.

Visit this group at https://groups.google.com/group/dddcqrs.
For more options, visit https://groups.google.com/d/optout.

Greg Young

unread,
May 31, 2018, 10:12:55 AM5/31/18
to ddd...@googlegroups.com
Its not a problem with eventsourcing.. When they retroactively change rules you write events that compensate the original this is explicit what else must now change because you changed the original how would you track this? Now anyone who has made decisions based upon the original "in error" events can be notified that the book of record has changed. In other words it handles the cascade of changes.

Perfect example from another domain (finance). A trade was given at an incorrect price and recorded. You now are retroactively changing it a week later.

1) How does the retroactive change effect last week's P&L?
2) How does the change effect the cheque that was issued to the trader on Monday?
3) There was a trading competition last week which this trader won by a small amount, did he still win?

To have some more fun, when this retroactive change went in it actually retroactively stated that the trader was really in a short position which are banned by compliance in many places. He was never knowingly in a short position but the books now say he was. Is this a compliance violation, should it be reported?


There are loads of examples like this.

To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.

Visit this group at https://groups.google.com/group/dddcqrs.
For more options, visit https://groups.google.com/d/optout.

jwoets

unread,
May 31, 2018, 10:16:43 AM5/31/18
to DDD/CQRS
yes i agree with this assumption, but in some case, rule as strong impact on read model. Example : do not call customer if there are already X calls. if X is increased, when the read model is requested for get customer to call, the list is bigger...

Greg Young

unread,
May 31, 2018, 10:19:05 AM5/31/18
to ddd...@googlegroups.com
For a really simple example of what I am talking about ... Try marking that a trade from 2 weeks ago was actually an invalid trade that was falsely reported. Now... what all is effected by that? ;-)

jwoets

unread,
May 31, 2018, 10:44:12 AM5/31/18
to DDD/CQRS
thank you greg for your example. If i anderstand correctly, and like Brad also saying, i must enumerate all aggregate concerned by the change and apply command to write new events  ?

Because in my previous example 

 do not call customer if there are already X calls. if X is increased, when the read model is requested for get customer to call, the list should be bigger...

the change of rule impact the list of customers to call. But in your example the issue is bounded to the concerned aggregate (if i understand...)

jwoets

unread,
May 31, 2018, 10:46:12 AM5/31/18
to DDD/CQRS
thank you greg for your example. If i anderstand correctly, and like Brad also saying, i must enumerate all aggregate concerned by the change and apply command to write new events  ?

Because in my previous example 

 do not call customer if there are already X calls. if X is increased, when the read model is requested for get customer to call, the list should be bigger...

the change of rule impact the list of customers to call. But in your example the issue is bounded to the concerned aggregate (if i understand...)

jwoets

unread,
Jun 1, 2018, 1:59:04 PM6/1/18
to DDD/CQRS
I rethinking this problem and finally i think it's simply a validation logic.
Indeed, in the aggregate, the command CallCustomerCommand can be executed only if "any state condition" and the count of previous call < X. X is loaded dynamically from settings.
In case of a UI, the validation logic must be duplicate on the UI because based on read model (could be inconsistent). So i can also load X from settings.
So i can do the same thing for the getCustomerToCall query, right ?
Reply all
Reply to author
Forward
0 new messages