package store import ( "context" "encoding/json" "fmt" "time" ) // AppendAudit records an audit log entry. func (s *Store) AppendAudit(ctx context.Context, e AuditEntry) error { if len(e.Payload) == 0 { e.Payload = json.RawMessage("{}") } _, err := s.db.ExecContext(ctx, `INSERT INTO audit_log (id, user_id, actor, action, target_kind, target_id, ts, payload) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, e.ID, nullable(e.UserID), e.Actor, e.Action, nullable(e.TargetKind), nullable(e.TargetID), e.TS.UTC().Format(time.RFC3339Nano), string(e.Payload)) if err != nil { return fmt.Errorf("store: append audit: %w", err) } return nil } // nullable returns nil for nil/empty *string so SQLite stores NULL. // SQLite's driver treats Go nil as NULL but treats *string("") as ”. // We want NULL semantics for "absent." func nullable(p *string) any { if p == nil || *p == "" { return nil } return *p }