Changelog
Release notes for Go Audit.
adapters/gorm v1.1.2
Patch release for the GORM adapter only — core v1.1.0 is unchanged.
Bug fixes (correctness)
-
adapters/gorm (issue #1, "A2b"): a parent
Updatethat still carries its loaded HasMany associations no longer double-audits the children ascreate. Callingdb.Model(&order).Update(...)whileorder.Itemsis still attached makes GORM re-upsert the children (ON CONFLICT DO UPDATE), which runs the create-callback chain a second time — so each child was recorded ascreateagain (order_items/create == 4instead of2). Because this happens in the Update's transaction (separate from the original Create), the v1.1.1 transaction-scoped dedup could not see it.The adapter now distinguishes a genuine insert from an association re-save: a re-saved child already has a non-zero primary key before the statement runs, and the operation's root is an update/delete rather than a create. Such rows are skipped for
createauditing. Genuinely new children added during an update (PK still zero) and all top-level / nested creates remain fully audited.Workaround on
v1.1.1and earlier:db.Model(&order).Omit("Items").Update(...).
Upgrade
go get github.com/gopackx/go-audit/adapters/gorm@v1.1.2adapters/gorm v1.1.1
Patch release for the GORM adapter only — core v1.1.0 is unchanged.
Bug fixes (correctness)
- adapters/gorm: nested
Createno longer double-audits child rows on GORM ≥ v1.31 (the "2 items → 4 rows" report). Thev1.1.0dedup was scoped to a single GORM statement, but on GORM ≥ v1.31 onedb.Create(&parent)runs the child create-callback chain twice within its auto-transaction — an initial INSERT and an FK-backfill upsert, in two separate statements — so the per-statement set never caught the repeat. Dedup is now scoped to the transaction, shared across every statement of one logical write, with a depth counter so it is freed when the outermost operation completes (no leak) and two explicit sequential writes of the same row are each still audited.
Upgrade
go get github.com/gopackx/go-audit/adapters/gorm@v1.1.1If you installed adapters/gorm@v1.1.0, upgrade to pick up this fix.
No schema change and no core upgrade required.
v1.1.0
Bug fixes (correctness)
- adapters/gorm:
db.Where("…").Update/Deleteno longer emitsWHERE WHERE …(PostgreSQL42601, which previously cancelled the user's write). The pre-write snapshot SELECT now unwraps theclause.Whereexpression so the SQL builder writes exactly oneWHERE. - adapters/gorm:
Createwith nested associations no longer duplicates child audit rows (2 items → was 4 rows). The callback keeps a per-statement(entity_type, entity_id)dedup set. - core:
old_valuesoncreateis now persisted as SQLNULLinstead of the literal JSON token"null". Affected callers that passed a typed-nilmap[string]any.
New
APIEntry.ResponseHeaders(map[string]string) — redacted using the sameRedactHeaderslist asRequestHeaders, persisted into a newresponse_headerscolumn onaudit_api_logs.RedactBodyFieldsnow redacts struct and pointer payloads, not onlymap[string]any. The auditor JSON-round-trips the value first; matching is on JSON tag names.
Docs
- README pulled to parity with the docs site:
ExcludeEntities,SkipOldValues, per-tableOnError,gorm.Session{SkipHooks: true}, adapter pseudo-version install, and a dedicated*sql.DBproduction tip.
AI integration
- Claude Skill (
skills/go-audit/SKILL.md) — drop into~/.claude/skills/go-audit/and Claude Code knows how to integrate go-audit from a cold prompt. See Claude Skill. - MCP server (
mcp/) — read-only Model Context Protocol server exposingquery_data_logs,query_api_logs,query_by_transaction,snapshot_entity, andrecent_changesso AI hosts can investigate audit history conversationally. See MCP Server.
⚠️ Migration
AutoMigrate uses CREATE TABLE IF NOT EXISTS, so the new
response_headers column is only created on fresh installs. Existing
deployments must run a one-shot ALTER TABLE per dialect — see
audit_api_logs → Upgrading from v1.0.x.
v1.0.0
- Initial stable release
- Core auditor backed by
database/sql; zero network dependencies - Auto-diff on UPDATE — only changed fields stored
- Manual entry point (
RecordDataChange) for raw-SQL code paths - API call logging with header and JSON body redaction
- Body truncation marker for oversized payloads
- Transaction correlation via
transaction_idand context helpers - Snapshot and Restore — reconstruct entity state at a past time
- Retention via
Purge(ctx, before) - Configurable error modes (
ErrorFailLoud/ErrorFailSilent) - Custom table names for both audit tables
- Field and entity exclusion
- Dialects: PostgreSQL, MySQL, SQLite (with
RegisterDialectfor custom) - GORM adapter — full auto-hooks, soft-delete detection
- Bun adapter —
QueryHookwith snapshot via WHERE-clause parsing - Ent adapter — mutation hook with single-row old-values
- Query builder with typed filters (
DataFilter,APIFilter) - In-memory
Storefor tests