Add provenance audit log + admin reports

Add provenance audit log + admin reports

#53 in Riparion/riparion-cms — merged 2026-06-03

What

Adds a provenance audit trail — who changed what, and when — plus two admin report screens.

App content/settings audit log

  • New metadata-only audit_log table (parallel sqlite + postgres migrations); nullable actor_id ON DELETE SET NULL + denormalized actor_name so a deleted user's trail survives.
  • A best-effort server::admin::audit(...) hook called after each successful mutation in posts, pages, media, comments, taxonomy, and the settings/appearance setters. A failed audit write only tracing::warn!s — it never rolls back or fails the user's operation.
  • New report at /admin/audit-log (gated by a new audit:read token): newest-first table with Type/Action filters and prev/next pagination.
  • In-product help article at /help/audit-log.

arium auth/access audit log

  • New page /admin/security-log (labeled Auth log) mounts arium's own arium_dioxus::ui::AuditLog component (gated by admin:audit:read), surfacing arium's authentication/authorization trail — logins, sign-ups, role grants — the events this app can't capture because they originate in arium.
  • No new migration: arium's 0006_audit.sql (already run at boot) creates the table and grants admin:audit:read to the ADMIN role.

Scope notes

  • Metadata only — no before/after field diffs, no IP/user-agent. By design.
  • User-account-change auditing isn't done app-side (those mutations live in arium); the Auth log page covers them via arium's component instead.

Verification

  • cargo fmt --all -- --check
  • clippy -D warnings on server+sqlite, server+postgres, and wasm/web
  • cargo test --no-default-features --features server,sqlite — 42 pass; the new migration applies cleanly on test DB boot ✓
  • Manual end-to-end steps recorded in TODO_VERIFICATION.md (local, gitignored).

🤖 Generated with Claude Code

Last updated 2026-06-04