Skip to content

feat(laravel): make the audit transaction requirement optional - #19

Merged
albertovincenzi merged 1 commit into
mainfrom
feat/audit-optional-transaction
Oct 19, 2026
Merged

albertovincenzi merged 1 commit into
mainfrom
feat/audit-optional-transaction

Conversation

@albertovincenzi

Copy link
Copy Markdown
Contributor

Summary

LogsAudit and AuditOutbox::record() throw a LogicException when a write runs outside an explicit transaction. That keeps the business write and its outbox row atomic, but it blocks adoption in applications that save models outside transactions. cb3-backend is the first case: it will replace its spatie activity log with the Traceflow audit log, and its models are saved from controllers, jobs, imports and webhooks without transactions.

This adds an opt-in policy:

  • New setting traceflow.audit.require_transaction (TRACEFLOW_AUDIT_REQUIRE_TRANSACTION), default true: existing installations keep the current behaviour.
  • With false:
    • a write outside a transaction stores the outbox row right after the model write. This is the same guarantee as an activity log written from model events: a crash or database error between the two writes loses that event;
    • a write inside a transaction stays atomic (the outbox insert joins it);
    • AuditOutbox::record() follows the same setting.
  • AuditOutbox::requireTransaction() keeps always enforcing a transaction, for callers that rely on it. The trait and record() now go through AuditOutbox::guardTransaction().
  • README: new "Writes outside transactions" section.
  • composer.json version 2.7.2 → 2.8.0. No tag contains the audit API yet (v2.7.2 was created before it, and its split to traceflow-laravel failed in May, so Composer only sees v2.7.1). After merge, tag v2.8.0 so split-laravel publishes it.

Test plan

  • vendor/bin/phpunit --testsuite Unit: 155 tests pass (same 8 PHPUnit notices as main)
  • New tests: unwrapped create/update/delete/restore are recorded with the setting off; wrapped writes still roll back together; manual record() follows the policy; requireTransaction() still throws. The two behaviour tests fail without the change.
  • Default behaviour unchanged: the existing "unwrapped writes are rejected" test still passes
  • pint --test on the changed files
  • PHPStan level 5: 40 errors before and after, none in src/Audit
  • Tag v2.8.0 after merge and check traceflow-laravel gets the tag

LogsAudit and AuditOutbox::record() throw when a write runs outside an
explicit transaction. That protects atomicity, but it blocks adoption in
applications that save models outside transactions, such as cb3-backend
replacing its spatie activity log.

New setting traceflow.audit.require_transaction
(TRACEFLOW_AUDIT_REQUIRE_TRANSACTION), default true, so existing
installations keep the current behaviour. With false, a write outside a
transaction stores the outbox row right after the model write (the same
guarantee as an activity log written from model events); writes inside a
transaction stay atomic. AuditOutbox::requireTransaction() still always
enforces a transaction.

Bumps the Laravel package to 2.8.0, the first release with the audit API.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@albertovincenzi
albertovincenzi merged commit 10df145 into main Oct 19, 2026
5 checks passed
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.

1 participant