I have been asking a lot of questions on event sourcing so apologies on that but I would like to nail this right from the get go.
SETUP
| p_key | invoice_id | EmployeeId | Event type | Version | Data |
|-------|------------|------------|-------------------|---------|------|
| 1 | 12345 | E456 | Invoice_Generated | 1 | JSON |
| 2 | 12345 | E567 | Invoice_Reviewed | 2 | JSON |
| 3 | 12345 | E456 | Invoice_Paid | 3 | JSON |
| 4 | 12345 | E142 | Invoice_Comment | 4 | JSON |
| 5 | 12345 | E412 | Invoice_Comment | 5 | JSON |
| 6 | 12346 | E999 | Invoice_Paid | 7 | JSON |
| 7 | 12345 | E456 | Invoice_Refunded | 8 | JSON |
I am assuming the invoiceId is the aggregate . Since the version numbers will increment for every change made to invoice.
Use Case:
The event store contains all events applied on invoice and also contains info on which employee applied it. In the current scenario an invoice is generated,reviewed,paid. Someone noticed some issue made a few comments and then we decide to post a new payment before we refunded the old one[the event that is being undone is earlier in history].
API CALL:
refund/invoice/{invoiceid}/{employeeid}
FLOW OF THINGS
Option 1
- Retrieve all events for a given invoice
- Save all events in event stream with the latest version saved.
- Loop through all events to find the required instance of event.
- Apply an "UNDO" action on that event and give it version number of (latest+1)
- make a call to database to check the latest version in event store. Validate it is same as that saved in Event Stream.
- Ensure that the new event is larger than last version in stream. We assume that is it also a higher version that "DO ACTION".
ISSUES
- Retrieving and saving all events in application every time can start to get expensive.
- Seems like a hell lot of work for just "UNDO" action.
OPTION 2:
- I make 2 calls to database
- Call to get event based on invoice Id and employeeId
- Call to get latest version of last event applied on invoice.
- Undo changes based on data in event
- Create an "UNDO" event with version no 1 greater than latest.
- make another call to database to get the latest version again.
- ensure the "UNDO" version is exactly 1 greater than latest version
ISSUES
Not sure if this is right. Should we have things added to event stream multiple times.
Also is it okay to query event database twice once with only invoice id and once with invoice id and employee id
Please let me know if I am missing something or if my version style is wrong or if my assumption of aggregate is wrong.