How specific should administrative compensating events be in a CQRS/ES system?

by Steven Grimm   Last Updated September 11, 2019 17:05 PM - source

Are there any best practices around how specific to make events that are generated administratively, say to clean up after one-off operational issues?

For example: Say you have a credit card processing application. Payments are authorized (which deducts from the available balance) then posted (which deducts from the current balance). You had a bug that caused a few payments to have multiple authorization events, so the available balance is now lower than it should be.

You've fixed the bug and now you want to increase the available balance to recover from it. If you follow the ES pattern of keeping history immutable, that means you want compensating events. But what should those events look like? It seems like there are a few choices:

  • A generic "available balance credited by administrator" event that includes a (possibly human-readable) reason. This can be used for future one-off cleanup if needed, but the event type doesn't carry any business meaning.
  • A very specific "canceling bogus double-authorization" event. This will be used on exactly one occasion because the bug has been fixed already. The event type has business meaning here but it becomes permanent unused legacy code.
  • The standard "authorization cancelled" event that would normally be issued when a payment doesn't post. This is more meaningful than the generic event and doesn't become dead weight in the code base, but is arguably misleading since the cancellation wasn't normal.

Which of these is the preferred approach? Or is there a fourth option?

Related Questions

How to create new aggregate root in CQRS?

Updated February 21, 2017 13:05 PM

CQRS - Passing aggregate root as argument

Updated February 25, 2017 23:05 PM

Sharing data between bounded contexts

Updated May 01, 2015 21:02 PM