Skip to content

refactor(audit): single recordAuditLog() seam for audit writes (#110)#111

Draft
f-amine wants to merge 1 commit into
masterfrom
feat/110-audit-log-seam
Draft

refactor(audit): single recordAuditLog() seam for audit writes (#110)#111
f-amine wants to merge 1 commit into
masterfrom
feat/110-audit-log-seam

Conversation

@f-amine

@f-amine f-amine commented Jun 29, 2026

Copy link
Copy Markdown
Owner

Closes #110

What

Deepen the Audit bounded context: replace 17 scattered db.insert(auditLog)...onConflictDoNothing() blocks with a single recordAuditLog() seam in @vibestack/db.

Why

CONTEXT.md says audit rows are written server-side, never by clients, and are append-only — but nothing enforced it; every writer hand-rolled the insert (id gen, conflict policy, field mapping all copy-pasted). Any change to the write contract meant editing ~17 sites. The seam makes the context deep: a one-line interface over the id + insert + conflict + invariant.

Changes

  • New packages/db/src/audit.tsrecordAuditLog(event) + AuditEvent type, exported from @vibestack/db.
  • New packages/db/src/audit.test.ts — 3 unit tests (id generated + unique, conflict tolerated, optional fields default null). Audit writes had no test before; the interface is now the test surface.
  • Migrated 9 handlers: api/{affiliate,gdpr,referral}, auth/welcome, web onboarding + polar/resend webhooks, admin users + feature-flags actions. Dropped the now-dead randomUUID / auditLog / db imports where they were only feeding the insert.
  • Seed script left untouched (bulk insert of pre-built rows, not an action handler).
  • CONTEXT.md — Audit entry + invariant now name recordAuditLog() as the only sanctioned write path.

Verify

  • pnpm typecheck ✅ (6/6)
  • pnpm test ✅ (db audit 3/3; all suites green)
  • pnpm check ✅ (no new findings; pre-existing warnings in scripts/agents/video/* untouched)
  • No insert(auditLog) remains outside the seam + seed.

🤖 Generated with Claude Code

Replace 17 hand-rolled `db.insert(auditLog)...onConflictDoNothing()` blocks
across 9 server-side action handlers with one `recordAuditLog()` seam in
`@vibestack/db`. The id strategy, conflict policy, and append-only invariant
now live in one place instead of being copy-pasted; callers no longer import
`randomUUID`, the `auditLog` schema, or `db` just to record an event.

- New `packages/db/src/audit.ts` + unit test (the interface is now the test
  surface; audit writes previously had no test).
- Migrated: api/{affiliate,gdpr,referral}, auth/welcome, web onboarding +
  polar/resend webhooks, admin users + feature-flags actions.
- Seed script left as-is (bulk insert, not an action handler).
- CONTEXT.md: name the seam as the only sanctioned write path.

Closes #110

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deepen the Audit context: one recordAuditLog() seam instead of 17 scattered inserts

1 participant