Skip to content

audit

File: schema/mixins/audit.yaml

Adds the four stamp columns and the trigger pair that maintains them. Tables that carry change-attribution include this mixin and do not redeclare the columns.

ParameterDefaultPurpose
user_tableusersidentity table the actor columns FK to
user_pkuser_idprimary-key column of user_table
actor_gucapp.actor_idGUC audit_stamp reads the actor id from
lenient_gucapp.audit_lenientGUC that, when 'true', lets audit_stamp tolerate a missing actor (bootstrap)

All default to the convention, so the common case is param-free. See Parameters.

ColumnTypeNullNotes
created_attimestamptzNOT NULLstamped on INSERT
updated_attimestamptzNOT NULLrefreshed on every write
created_bybigintNOT NULLFK → {user_table}.{user_pk}, ON DELETE RESTRICT / ON UPDATE CASCADE
updated_bybigintNOT NULLFK → {user_table}.{user_pk}, ON DELETE RESTRICT / ON UPDATE CASCADE

Triggers fire in name order, so the numeric prefixes set the sequence:

  1. 00_audit_skip_noop (BEFORE UPDATE) — cancels no-op UPDATEs (NEW IS NOT DISTINCT FROM OLD) so they don’t generate an MVCC tuple or bump updated_at. See audit_skip_noop.
  2. 10_audit_stamp (BEFORE INSERT/UPDATE) — stamps created_at / updated_at / created_by / updated_by from the actor GUC (set per request by the app, or per-tx during bootstrap). Raises a clear error if no actor is set, unless lenient_guc is 'true'. See audit_stamp.

When paired with audit_log, that mixin’s 20_audit_log_diff runs after 10_, so created_* / updated_* are already populated when audit_diff fires.

# tables that need change-attribution
mixins: [audit]

Pair with audit_log on tables whose change history should be queryable, and with soft_delete on tables that need archive semantics rather than DELETE.