Skip to content

F23: Audit log for critical changes — same-transaction append-only events + admin viewer #93

Closed

Description

@mforce

Phase 1.1 "audit log for critical changes" line. Tech spec rule: the audit log is domain data, written in the same transaction as the change it records — explicit writes in the handlers, never telemetry/interceptors. Append-only: no update, no delete, no Version.

Model

AuditEvent: account, occurredAtUtc (IClock), actor (user id + email snapshotted — user rows can change later), action code ("DailyEntry.Adjust", "SalesOrder.Void", …), entityType + entityId, optional reason (copied from the command), DetailsJson (text, provider-portable; small curated payload — replaced/new values where the handler already has them).

Capture points (the corrective/destructive/config set — every action that's already admin-gated and reason-carrying)

  • Daily entry: adjust, void
  • Sales order: void; payment: void
  • Expense: adjust; expense category: update (rename/toggle)
  • Water record correction; inventory stock adjustment
  • Bird movements (cull/adjustment); flock: edit, deplete, archive, reactivate
  • User creation
  • Egg grade: update, deactivate/activate

Actor identity via a new ICurrentUser accessor (JWT sub + email claims), resolved per request beside TenantContext. Handlers append through an IAuditWriter port; the row commits or rolls back with the change itself — a failed adjust writes nothing.

Viewer

GET /api/v1/audit (AdminOnly; paged newest-first; filters: action, entityId, date range). SPA /audit page (admin nav): table with time, actor, action, entity, reason; details on hover/expand. Read-only — there is deliberately no mutation surface at all.

Docs (same PR)

Help (Who-can-do-what + new section), GLOSSARY (Audit log, Audit event). The various "kept as an audit snapshot until the audit log lands" comments get their follow-up noted (snapshots stay — they're the entity-local view).

Out of scope

Locked-entry override-with-reason (spec §507 — owner concept doesn't exist yet), audit of plain creates (normal work), retention/pruning, export (rides the CSV slice).

Part of #14.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions