AuditTrail.Schema (audit_trail v0.1.1)

Copy Markdown

Marks an Ecto schema for automatic field-level change tracking.

Usage

defmodule MyApp.Items.Item do
  use Ecto.Schema
  use AuditTrail.Schema, track: [:status, :price, :approved_by]

  schema "items" do
    field :name,        :string
    field :status,      :string
    field :price,       :decimal
    field :approved_by, :string
  end
end

Pass track: :all to track every field (default when track: is omitted). Pass a list of field atoms to track only those fields.

track: :all is a footgun

Tracking every field means every field added later — a password hash, an API token, free-text PII — gets logged automatically with no review. Using track: :all (or omitting track:) emits a compile-time warning unless you explicitly acknowledge it:

use AuditTrail.Schema, track: :all, unsafe_track_all: true

Prefer an explicit list of fields wherever you can.

An explicit list isn't automatically safe either

track: [:status, :password_hash] still logs password_hash in full on every change — an explicit list only protects you from future fields, not from tracking something sensitive today. If a field name in your track: list looks like it could hold a secret (matches password, token, secret, pin, ssn, etc.) and isn't already covered by AuditTrail.Config.sensitive_fields/0, this also emits a compile-time warning. Add the field to that config if it's genuinely sensitive:

config :audit_trail, sensitive_fields: ~w(password token password_hash)

This is a heuristic on the field name, not its contents — it can't see what a field actually holds, so false positives/negatives are both possible. Treat the warning as "double check this," not a guarantee.

Naming the resource (optional)

By default the audited resource is the schema module name (e.g. "Elixir.MyApp.Payments.Payment"). Pass resource: to log a shorter, business-facing name instead — useful for filtering logs by resource type:

use AuditTrail.Schema, track: [:status, :amount], resource: "payment"