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.
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
- Upgrade the package and clear the Symfony container cache.
- Run a schema migration before production traffic reaches v4 code.
- Update custom code that compares raw action strings to use
Rcsofttech\AuditTrailBundle\Enum\AuditAction. - Review custom implementations of bundle contracts in
src/Contract, especially transports, scheduled audit managers, exporters, and entity ID resolvers. - Update imports for
TrackableCollectionInterfaceto theContractnamespace if your application imports it directly. - Use nullable unresolved entity IDs; code that needs a concrete ID should call
hasResolvedEntityId()orrequireEntityId(). - Verify one same-flush collection add scenario in your application.
- Review custom AI processors and any admin UI that renders
context.aimetadata. In 4.3 and newer, preferAuditLogReadModelAiProcessorInterface; the legacyAuditLogAiProcessorInterfaceremains available for 4.x compatibility but is deprecated for removal in 5.0. - If custom code manually instantiates
EntityProcessor,AuditQuery,AuditReader,AuditLogMessageFactory, orAuditLogWriter, update that wiring or prefer Symfony DI. - Historical revert rows created on v3 remain recognized after upgrade, even when
reverted_log_idonly exists insidecontext. - If HTTP or queue transport is enabled, review
fail_on_transport_errorandfallback_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_idcolumn and unique constraint before workers consume messages. - Custom transports must implement
send(AuditTransportContext): AuditDeliveryResultandsupports(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.