Reference

Upgrade and architecture notes.

Use this page when moving from v3 to v4 or when extending the bundle through supported contracts instead of patching internals.

4.x Upgrade guide Extension points

Upgrade Guides

v4 changes a few public APIs and fixes collection-audit behavior for same-flush relation creation. If your application only uses built-in services and transports, the upgrade is usually small.

v3 To v4 Checklist

  1. Upgrade the package and clear the Symfony container cache.
  2. Run a schema migration before production traffic reaches v4 code.
  3. Update custom code that compares raw action strings to use Rcsofttech\AuditTrailBundle\Enum\AuditAction.
  4. Review custom implementations of bundle contracts in src/Contract, especially transports, scheduled audit managers, exporters, and entity ID resolvers.
  5. Update imports for TrackableCollectionInterface to the Contract namespace if your application imports it directly.
  6. Use nullable unresolved entity IDs; code that needs a concrete ID should call hasResolvedEntityId() or requireEntityId().
  7. Verify one same-flush collection add scenario in your application.
  8. Review custom AI processors and any admin UI that renders context.ai metadata. In 4.3 and newer, prefer AuditLogReadModelAiProcessorInterface; the legacy AuditLogAiProcessorInterface remains available for 4.x compatibility but is deprecated for removal in 5.0.
  9. If custom code manually instantiates EntityProcessor, AuditQuery, AuditReader, AuditLogMessageFactory, or AuditLogWriter, update that wiring or prefer Symfony DI.
  10. Historical revert rows created on v3 remain recognized after upgrade, even when reverted_log_id only exists inside context.
  11. If HTTP or queue transport is enabled, review fail_on_transport_error and fallback_to_database.
use Rcsofttech\AuditTrailBundle\Enum\AuditAction;

if ($log->action === AuditAction::Update) {
    // v4 action comparison
}

v4 Contract Changes To Preserve

Area What Changed
Actions AuditLog::$action and public contracts use AuditAction instead of raw strings.
Exporter AuditExporterInterface::exportToStream() returns the exported record count as int.
Scheduled work ScheduledAuditManagerInterface supports pending audit plans for collection-sensitive create and update flows; failed-dispatch replace methods live behind the internal FailedAuditDispatchRetainerInterface.
Queue/toggle internals Queue scheduling and enable/disable responsibilities are split internally into AuditQueueManagerInterface and AuditToggleInterface.
Entity IDs AuditLogInterface::$entityId and EntityIdResolverInterface now use nullable unresolved IDs instead of placeholder strings.
Collections Same-flush relation creation now stores final related identifiers instead of placeholder class-name payloads.
Query layer AuditQuery and AuditReader are thin facades over query state, execution, and page materialization services.
UUID ordering Manual construction of ordering-sensitive services should provide a UUID v7 factory so cursor and latest-first reads keep their ordering guarantees.

Legacy v2 To v3 Notes

If an application still upgrades through v3 first, preserve these migration checks even if the package repo docs are slimmed down.

  • Async database transport requires the audit_log.delivery_id column and unique constraint before workers consume messages.
  • Custom transports must implement send(AuditTransportContext): AuditDeliveryResult and supports(AuditTransportContext): bool.
  • EasyAdmin access should be verified against the configured admin permission after upgrade.
  • Custom scheduled audit managers need the full public queue/toggle surface and pending deletion handling expected by the current contract.
  • Audit event subscribers should subscribe by event class, for example AuditLogCreatedEvent::class.

For versions older than 4.x, use the matching README and docs from the GitHub tag unless archived public docs are added later.

Architecture

Most audit work happens in onFlush and postFlush. The split keeps change detection close to Doctrine while allowing deferred transport delivery where appropriate.

Flush Processing

AuditSubscriber, AuditOnFlushProcessor, AuditPostFlushProcessor, and focused entity processors detect and schedule audit work.

Creation & Dispatch

AuditLogFactory, AuditLogMessageFactory, AuditDispatcher, EntityAuditDispatchManager, ScheduledAuditManager, and AuditLogWriter build, schedule, and deliver audit logs.

Query Layer

AuditReader, AuditQuery, AuditQueryState, AuditQueryExecutor, and AuditQueryPage split fluent state from execution.

Admin & Revert

EasyAdmin services handle presentation, while AuditReverter, RevertPlanBuilder, and action handlers manage recovery.

For async database delivery, the message factory preserves the audit row UUID before Messenger dispatch and the writer reuses it in the worker. This keeps UUID-sorted readers, keyset pagination, and transaction drilldowns aligned with creation order rather than worker processing order.

Extension Points

Prefer supported contracts when customizing behavior. They are easier to keep stable across package upgrades than internal services.

Contract Use Case
AuditVoterInterface Skip or allow audit records based on runtime logic.
AuditContextContributorInterface Add correlation IDs, app versions, feature flags, or request metadata.
AuditTransportInterface Deliver audit logs to custom storage or external systems.
AuditLogReadModelAiProcessorInterface Attach optional AI-derived metadata under your own namespace using a read-only audit-log snapshot.
RevertActionHandlerInterface Customize revert behavior for specific actions or entity shapes.
ScheduledAuditManagerInterface Customize scheduled audit work handling.

Contributor Testing Map

  • Service logic changes usually need unit tests.
  • Doctrine lifecycle, flush, or collection behavior needs functional tests.
  • Container wiring, compiler passes, or extension config changes need integration tests.
  • Signing and verification changes need compatibility checks against already persisted logs.

Project Links