kura_audit (kura v1.19.2)

View Source

Audit trail for Kura schema operations.

Tracks inserts, updates, and deletes in an audit_log table. Uses the process dictionary for actor context (who made the change) and for stashing old data during updates.

Setup

Create the audit_log table via migration:

up() -> kura_audit:migration_up().
down() -> kura_audit:migration_down().

Usage in schema hooks

-export([before_update/1, after_insert/1, after_update/1, after_delete/1]).

before_update(CS) ->
    kura_audit:stash(CS),
    {ok, CS}.

after_insert(Record) ->
    kura_audit:log(my_repo, ?MODULE, insert, Record),
    {ok, Record}.

after_update(Record) ->
    kura_audit:log(my_repo, ?MODULE, update, Record),
    {ok, Record}.

after_delete(Record) ->
    kura_audit:log(my_repo, ?MODULE, delete, Record),
    ok.

Actor context

kura_audit:set_actor(<<"user-123">>).
kura_audit:set_actor(<<"user-123">>, #{ip => <<"1.2.3.4">>}).
kura_audit:with_actor(<<"admin">>, fun() -> my_repo:delete(CS) end).

Summary

Functions

Clear the audit actor from the current process.

Get the current audit actor, or undefined if not set.

Write an audit log entry. Call from after_insert/1, after_update/1, or after_delete/1 hooks.

Migration operations to drop the audit_log table.

Migration operations to create the audit_log table.

Set the audit actor for the current process.

Set the audit actor and metadata for the current process.

Stash the changeset's current data for later diff computation. Call this in before_update/1 so that log/4 can compute the changes.

Execute a function with a temporary actor, restoring the previous actor after.

Execute a function with a temporary actor and metadata.

Functions

clear_actor()

-spec clear_actor() -> ok.

Clear the audit actor from the current process.

get_actor()

-spec get_actor() -> binary() | undefined.

Get the current audit actor, or undefined if not set.

log(Repo, SchemaMod, Action, Record)

-spec log(module(), module(), insert | update | delete, map()) -> ok.

Write an audit log entry. Call from after_insert/1, after_update/1, or after_delete/1 hooks.

For updates, call kura_audit:stash/1 in the corresponding before_update/1 hook to capture the old data for diff computation.

migration_down()

-spec migration_down() -> [kura_migration:operation()].

Migration operations to drop the audit_log table.

migration_up()

-spec migration_up() -> [kura_migration:operation()].

Migration operations to create the audit_log table.

set_actor(ActorId)

-spec set_actor(binary()) -> ok.

Set the audit actor for the current process.

set_actor(ActorId, Metadata)

-spec set_actor(binary(), map()) -> ok.

Set the audit actor and metadata for the current process.

stash/1

-spec stash(#kura_changeset{valid :: boolean(),
                            schema :: module() | undefined,
                            data :: map(),
                            params :: map(),
                            changes :: map(),
                            errors :: [{atom(), binary()}],
                            types :: #{atom() => kura_types:kura_type()},
                            required :: [atom()],
                            action :: atom() | undefined,
                            constraints ::
                                [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                  constraint :: binary(),
                                                  field :: atom(),
                                                  message :: binary()}],
                            assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                            prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                            optimistic_lock :: atom() | undefined}) ->
               ok.

Stash the changeset's current data for later diff computation. Call this in before_update/1 so that log/4 can compute the changes.

with_actor(ActorId, Fun)

-spec with_actor(binary(), fun(() -> T)) -> T when T :: term().

Execute a function with a temporary actor, restoring the previous actor after.

with_actor(ActorId, Metadata, Fun)

-spec with_actor(binary(), map() | undefined, fun(() -> T)) -> T when T :: term().

Execute a function with a temporary actor and metadata.