The audit trail is not court-grade
The audit trail is the product's core value — a disciplinary process stands or falls on being able to show who did what, when. The PoC's audit trail has four independent weaknesses, each of which alone would disqualify it as evidence.
-
Client-authored and client-trusted.
case_audit_eventsrows are inserted by the browser (useAuditLog.useLogEvent,useChecklistOperations,useWorkflow) with client-suppliedactor_user_id,actor_identifier,event_type, andmetadata. A malicious or buggy client can forge, omit, or backdate entries. A real audit log must be server-authored from the authenticated identity, append-only, ideally hash-chained. -
Best-effort / fire-and-forget. In
useChecklistOperations, thecase_audit_eventsinsert is.then()-chained, never awaited, with no error handling. If it fails, the user action still succeeds — silently unlogged. -
Conditional on
companyId. Those same inserts only runif (companyId). Because the active company is held in memory only (company context is in-memory only), after a page refreshcompanyIdisnulland audit logging silently no-ops while the user keeps working. -
Truncated.
useAuditEventshard-caps atlimit(200)(andlimit(50)for entity audit) with no pagination. On a long case the "complete" log is silently cut off. The dossier export caps audit atlimit(1000).
There are also two parallel audit systems that must be reconciled: the case-level
event stream case_audit_events and the item-level checklist_audit_log
(old/new value). See Two audit systems.
What breaks: in a dispute, the log is challengeable on every axis — authenticity, completeness, and reliability. The marketing video promises "Audit trail completo" (intent vs reality); the implementation does not deliver it.
Rebuild implication
Server-authored, awaited, unconditional, paginated, append-only, tamper-evident. One canonical audit stream.