Conversation
apps/ewallet/lib/ewallet/gates/transaction_consumption_confirmer_gate.ex
Outdated
Show resolved
Hide resolved
b440d40
to
2e19f73
Compare
|
||
config :activity_logger, ActivityLogger.Repo, | ||
adapter: Ecto.Adapters.Postgres, | ||
url: {:system, "DATABASE_URL", "postgres://localhost/ewallet_dev"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this use different database from ewallet
? 🤔
{:ok, config} | ||
end | ||
|
||
defp secret_key(:prod), do: decode_env("EWALLET_SECRET_KEY") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this use eWallet's secret key? 🤔
50904a2
to
b9c2932
Compare
f195326
to
a535a8f
Compare
Added log test in controller, please check this commit |
@@ -0,0 +1,41 @@ | |||
defmodule ActivityLogger.Repo.Migrations.RenameIdPrefixFromAdtToLogInActivityLog do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was thinking if you'd do this migration. 👍
79bbfd5
to
c967f15
Compare
assert log.target_encrypted_changes == %{ | ||
"encrypted_metadata" => %{"something" => "secret"} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:mindblown:
) | ||
end | ||
|
||
test "generates an activity log when minting" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:mindblown:
Can we add some tests to
|
b5f2cf3
to
a21414d
Compare
a21414d
to
6f597bc
Compare
Issue/Task Number: 463
closes #463
Overview
This PR completes the Activity Log system (formerly known as Audit system) added for users to the whole system to keep track of all data changes (
insert
,update
,delete
). The logic has now been split into its own sub application, theActivityLogger
. Due to the need of its usage in both theEWalletDB
and theEWalletConfig
(to keep track of changes to the settings), the move to a new sub application was required.To reduce the amount of duplicated code between sub applications, a new sub app, named
Utils
, has also been introduced and can be used by any other sub app. It contains modules that don't deal with business logic and can be reused throughout the application.This is a big PR. Changes had to be made to every single sub application due to the nature of the feature. Luckily, the commits have been split in a way that reviewing the changes shouldn't be too annoying, since each sub app gets its own commit (yeah, I rewrote the history and went down from 25+ meaningless commits with stuff moving around all the time to those 10 digestible (yet big) commits.
Changes & Implementation Details
The main change is the introduction of the
ActivityLog
system, which tracks changes to records and who is responsible for them. Currently, this system does not involve reversing to previous states but it could be implemented easily on top of the existing feature.Changes have been made to tests throughout the application to add the new mandatory parameter,
originator
. Any record supported by the system (and defined in the configuration) can be passed to theoriginator
field.%ActivityLogger.System{}
and%EWalletDB.Seeder{}
can also be used in tests and seeds, respectively.I originally wanted to keep the
ActivityLog
sub app completely separated with its own GenServer receiving log requests and storing them asynchronously, without increasing the duration of the requests. Sadly, due to the complexity of having asynchronous features spanning multiple sub-applications, I had to give up for now. Doing it for theEWalletConfig
sub-app was a requirement due to the state that needs to be kept (the list of sub-apps that need their configs to be refreshed), but here we don't have any state. Therefore, simply calling the insert synchronously is "good enough" (yet unsatisfying). I'd like us to revisit this in the future.Note that adding one GenServer running in the
ActivityLogger
sub-application is easy - the problems rise when running the tests. Due to some weird ExUnit stuff, it doesn't seem possible to reuse the GenServer started as part of another sub-application, so it becomes necessary to boot a new GenServer for each test. That's what we did for the configuration system and it was alright, because it could be done in thesetup
step by initiating a new GenServer, getting its PID, initiating the configuration with that specific PID and doing any update by passing that PID every time.Doing the same thing for the Activity Log system would require being able to pass that PID for every single call: controllers, gates, etc. We would have to send the PID of the Activity Log server to use to the controllers which would send it all the way down to the schemas which finally call the
ActivityLogger
functions through their Repos.If anyone has any suggestions, I'm all ear.
Usage
The system is meant to be as easy to use as possible. Here are the steps to add it to a new schemas.
application.ex
of the sub-app:ActivityLogger.ActivityRepo
in your RepoActivityLogger.ActivityLogging
in your schemaactivity_logging()
in the schema definitioncast_and_validate_required_for_activity_log
in your changesetsThis function will check for the originator.
insert:
Repo.insert_record_with_activity_log(changeset)
update:
Repo.update_record_with_activity_log(changeset)
delete:
Repo.delete_record_with_activity_log(changeset)
Finished reading the wall of text above
Review
Utils
sub appTo Do
An endpoint to retrieve those logs will be added in another PR.