Build the admin audit log viewer with CSV export #37

Open
opened 2026-07-28 04:57:33 +00:00 by claude-bot · 0 comments

Context

AuditEvent has been append-only since v0.1.0 and every mutation writes to it, but there
is no way to read it. The spec states admins can view and export the audit log. An audit
trail nobody can read provides no accountability — only the theoretical possibility of it.

Scope

Admin audit log viewer with filtering and CSV export.

Implementation notes

  • Paginated viewer over AuditEvent, newest first, built for a table that will grow large.
  • Filters that match how the log is actually used: by actor, entity type, entity id, action,
    and date range. Investigating "what happened to this photo" and "what did this user do"
    are the two real queries.
  • Render old_value / new_value JSON as a readable diff rather than raw JSON blobs.
  • Link entity references through to the photo or entity in question.
  • CSV export of the filtered view, per the spec.
  • The viewer must be strictly read-only. No edit or delete path may exist, in the UI or the
    API — an editable audit log is not an audit log.
  • Admin-only, enforced server-side.
  • Ensure the query paths are indexed; an unindexed scan over a large audit table will make
    this page unusable exactly when it is most needed.

Done when

  • Admins can browse the audit log with pagination
  • Filtering by actor, entity, action, and date range works
  • Value changes render as readable diffs
  • Filtered results export to CSV
  • No mutation path to audit records exists anywhere
  • Queries are indexed and perform acceptably on a large log

References

  • backend/app/models/models.py (AuditEvent)
  • docs/circa-spec.md section 6.5, section 11

Depends on: #22 (multi-user roles).

## Context `AuditEvent` has been append-only since v0.1.0 and every mutation writes to it, but there is no way to read it. The spec states admins can view and export the audit log. An audit trail nobody can read provides no accountability — only the theoretical possibility of it. ## Scope Admin audit log viewer with filtering and CSV export. ## Implementation notes - Paginated viewer over `AuditEvent`, newest first, built for a table that will grow large. - Filters that match how the log is actually used: by actor, entity type, entity id, action, and date range. Investigating "what happened to this photo" and "what did this user do" are the two real queries. - Render `old_value` / `new_value` JSON as a readable diff rather than raw JSON blobs. - Link entity references through to the photo or entity in question. - CSV export of the filtered view, per the spec. - The viewer must be strictly read-only. No edit or delete path may exist, in the UI or the API — an editable audit log is not an audit log. - Admin-only, enforced server-side. - Ensure the query paths are indexed; an unindexed scan over a large audit table will make this page unusable exactly when it is most needed. ## Done when - [ ] Admins can browse the audit log with pagination - [ ] Filtering by actor, entity, action, and date range works - [ ] Value changes render as readable diffs - [ ] Filtered results export to CSV - [ ] No mutation path to audit records exists anywhere - [ ] Queries are indexed and perform acceptably on a large log ## References - `backend/app/models/models.py` (`AuditEvent`) - `docs/circa-spec.md` section 6.5, section 11 Depends on: #22 (multi-user roles).
claude-bot added this to the v0.5.0 milestone 2026-07-28 04:57:33 +00:00
Sign in to join this conversation.
No description provided.