SellVia Docs — menu
DocsDatabaseAudit Log Design

Audit Log Design

Database/Audit Log Design.md
backendUpdated Aug 23, 2026

Audit Log Design

Purpose

What gets logged for accountability/dispute-resolution purposes, separate from application error logging.

What Gets an Audit Log Entry

  • Every Offer commission_rate change (who changed it, from what, to what, when) — directly relevant to the still-open re-consent question in State Machines
  • Every Application status change (pending → approved/rejected) — who acted, when
  • Every Sale acceptance_status change, especially accepted → rejected — needed to resolve any dispute about whether a sale should have been accepted
  • Every Admin action (offer vetting override, account suspension, manual refund) — Admin actions carry the most "why did this happen" risk and need the clearest trail
  • Every Payout status change, including failures and retries

Schema (proposed)

FieldTypeNotes
iduuid, PK
actor_user_iduuid, nullablenull for system/webhook-triggered changes
entity_typetexte.g. "offer", "sale", "payout"
entity_iduuid
actiontexte.g. "commission_rate_changed", "status_changed"
beforejsonb
afterjsonb
created_attimestamptz

Why a Separate Table, Not Just updated_at

A single updated_at timestamp tells you that something changed, not what changed, who changed it, or why — all of which matter the moment a merchant or creator disputes a commission amount or a payout. This is standard practice for any system moving real money, not SellVia-specific over-engineering.

Open Questions

  • Retention period for audit logs — recommend indefinite retention for anything in the financial chain (Sale/Commission/Payout/refund-related entries), given potential future tax/legal need to reconstruct history

Update (2026-08-04): initiated_via Field Added

FieldTypeNotes
initiated_viatext"dashboard" / "ai_console" / "api" — distinguishes standard Admin UI actions from 10. Operations → Founder AI Command Console actions, so an investigation can always tell how a given change was triggered

Every action taken through the AI Command Console logs here identically to a direct Admin UI action, just with this field set to ai_console — same audit rigor, distinguishable origin.

Update (2026-08-23): Reconciled to the Offer Entity Model and Current Sale-Status Vocabulary

This doc previously referred to "Campaign" (retired, merged into Offer — see 01. Domain Model) and to a Sale verified → refunded/clawback framing that no longer exists (clawback was eliminated 2026-08-07; sales now move through acceptance_status: reportedaccepted/rejected, per State Machines). Both are corrected above.