ngs-doo / revenj

DSL Platform compatible backend
https://dsl-platform.com
BSD 3-Clause "New" or "Revised" License
267 stars 44 forks source link

Auditing #83

Open alvelig opened 7 years ago

alvelig commented 7 years ago

What is the most conscious way to implement auditing in revenj? Ideally 'envers' like, but any idea would be welcome.

zapov commented 7 years ago

DSL has a concept of history. This will log all versions of an aggregate to a separate history table. Eg:

aggregate Table { 
  persistence { history; }
}

will create a separate history table. Though, API for reading this is not yet synchronized across different languages :( But it should be soon.

alvelig commented 7 years ago

Great. Thanks a lot! May history track user who made the change? It would be great to have an example of that.

zapov commented 7 years ago

Yeah, I guess I should write small tutorial about that.

For now, the short answer is: you put them in you model. Depending what means for you to track user who made the change that can be either

string modifiedBy;

or

User *modifiedBy;

A somewhat longer and confusing answer is:

Ideally when you want to track some specific information in audit log, you create a mixin for it, such as:

mixin Audited {
  User *modifiedBy;
  IP remoteAddress;
  ...
}

now you can apply that mixin to appropriate aggregates, either manually though has mixin Audited or in some other manner such as apply on all aggregates

If you have your own repositories you can set those properties before passing them along to Revenj repositories, either manually in specific repository, or in somewhat generic manner during deserialization, or something along those lines.

If you don't have your custom layer above Revenj and it's not easy to setup such generic application of audited properties, you can simulate (to a degree) such behavior via expressions on versioning concept:

string user { versioning 'it => Thread.CurrentPrincipal.Identity.Name'; }
alvelig commented 7 years ago

The mixin idea also seems the best for me. Both ways are clear.

I'll try it myself, but will be looking forward to a tutorial, as this approach is new for me, although it seems much faster and clearer than everything that I've seen with type safety.

Thank you very much for your explanations. Feel free to close the issue, or you may have it open as a reminder to make a tutorial. If I manage to make a workable solution with auditing, I'll share it as a tutorial.