Threadline.Capture.AuditChange (Threadline v1.0.0)

Copy Markdown View Source

An AuditChange is one row mutation in one audited table.

An AuditChange records a single row-level mutation (INSERT, UPDATE, or DELETE) on an audited table. Records are created automatically by PostgreSQL triggers; you do not insert them from application code.

Each AuditChange belongs to exactly one AuditTransaction. Multiple changes in the same database transaction share a transaction_id.

Key fields

  • :table_schema / :table_name — the schema and table where the mutation occurred.
  • :table_pk — primary key of the mutated row, stored as a JSON map so composite keys are supported.
  • :op — "INSERT", "UPDATE", or "DELETE".
  • :data_after — full row snapshot after the mutation (nil for deletes).
  • :changed_fields — list of column names that changed (populated for updates; nil for inserts and deletes).
  • :changed_from — sparse JSON map of prior column values on UPDATE when a per-table opt-in capture function is installed; otherwise nil.
  • :captured_at — trigger execution timestamp (microsecond precision).

Stable 1.x fields

The stable struct fields for 1.x are id, transaction_id, table_schema, table_name, table_pk, op, data_after, changed_fields, changed_from, and captured_at. The t() type may gain fields; this list does not make every current schema field or virtual relationship a promise.

data_after and changed_from are additive JSONB maps: keys and shapes may be added in 1.x. changed_fields is an additive list of text column names. These promises do not guarantee byte-stable JSON serialization or key order, and existing rows are not rewritten when a shape grows.

Relationships

  • belongs_to :transaction, Threadline.Capture.AuditTransaction — the DB transaction that produced this change.

Setup

Triggers are installed per table by mix threadline.gen.triggers, which emits SQL calling threadline_capture_changes() from mix threadline.install. See guides/domain-reference.md for the domain model for the capture contract.

Summary

Types

t()

One persisted row mutation with its captured table, row key, operation, and JSON snapshots.

Types

t()

@type t() :: %Threadline.Capture.AuditChange{
  __meta__: Ecto.Schema.Metadata.t(),
  captured_at: DateTime.t(),
  changed_fields: [String.t()] | nil,
  changed_from: Threadline.json_map() | nil,
  data_after: Threadline.json_map() | nil,
  id: Ecto.UUID.t() | nil,
  op: String.t(),
  table_name: String.t(),
  table_pk: Threadline.json_map(),
  table_schema: String.t(),
  transaction:
    Threadline.Capture.AuditTransaction.t() | Ecto.Association.NotLoaded.t(),
  transaction_id: Ecto.UUID.t() | nil
}

One persisted row mutation with its captured table, row key, operation, and JSON snapshots.

:data_after is nil for deletes, and :changed_fields is nil when no update fields were captured.