Skip to content

audit_log

File: schema/tables/audit_log.yaml

Field-level change history for audited entities. Populated by the audit_log mixin’s trigger (audit_diff). The changed_by actor FK is supplied by the audit_log_actor mixin so it can be parameterized to the app’s identity table.

The table does not carry the audit / audit_log mixins itself — that would attach the triggers recursively. changed_by + changed_at are recorded inline by the inserting trigger.

ColumnTypeNullNotes
audit_log_idbigserialNOT NULLprimary key
entity_typevarchar(50)NOT NULLtable name of the audited entity (e.g. producers)
entity_idtextNOT NULLPK of the audited row, stringified — serial-int or text PKs both supported
fieldvarchar(50)NOT NULLcolumn that changed; __row__ marks lifecycle transitions
previous_valuetextNULLold value (NULL on create)
new_valuetextNULLnew value
changed_bybigintNOT NULLactor FK (via audit_log_actor)
changed_attimestamptzNOT NULLDEFAULT CURRENT_TIMESTAMP
IndexColumns
audit_log_entity_idx(entity_type, entity_id, changed_at)
audit_log_changed_at_idx(changed_at)

The composite index serves the common query — the history of one entity, in order — and the changed_at index serves time-range scans across all entities.

When field = '__row__', the row records a lifecycle transition rather than a column diff:

previous_valuenew_valueMeaning
NULLcreatedrow inserted
activearchivedsoft-deleted (deleted_at set)
archivedrestoredun-deleted (deleted_at cleared)
existedhard-deletedrow DELETEd

This package ships no grants on audit_log — role names are app-specific. Append-only semantics are recommended: grant SELECT + INSERT, withhold UPDATE + DELETE so history can’t be rewritten. Add them in the consuming app via extend: against this table:

extend: audit_log
grants:
- to: app_user
privileges: [SELECT, INSERT]