Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Entity Audit Bundle Laravel Package

simplethings/entity-audit-bundle

Doctrine 2 auditing/versioning bundle inspired by Hibernate Envers. Tracks entity changes and associations over time, stores revisions, and lets you inspect historical states for debugging, compliance, and change history in Symfony/Doctrine apps.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Pros:

    • Seamless Doctrine Integration: Leverages Doctrine ORM’s event system, requiring minimal architectural changes. Works transparently with existing entity lifecycle events (pre-persist, pre-update, pre-remove).
    • Mirror Table Design: Creates audit tables (*_audit) with minimal overhead, avoiding complex triggers or stored procedures. Aligns with Laravel’s relational database patterns.
    • Symfony/Laravel Compatibility: While Symfony-centric, the core logic (Doctrine events + mirror tables) is framework-agnostic. Laravel’s Doctrine Bridge or native Eloquent could adapt similar patterns.
    • Revision Tracking: Global revision system with timestamps/usernames enables granular change history, useful for compliance or debugging.
    • Query Flexibility: AuditReader provides methods to fetch historical states, revisions, and diffs—critical for audit logs or rollback scenarios.
  • Cons:

    • Schema Coupling: Audit tables are auto-generated during schema updates, which may conflict with Laravel’s migrations or third-party schema tools (e.g., Laravel Schema Builder).
    • No Native Eloquent Support: Requires Doctrine ORM, limiting adoption in pure Laravel projects without Doctrine integration (e.g., doctrine/dbal + custom ORM).
    • Performance Overhead: Mirror tables and revision tracking add write overhead (e.g., duplicate inserts/updates). May impact high-write systems.
    • Limited Laravel Ecosystem: No native Laravel service providers, event listeners, or Artisan commands (e.g., no php artisan audit:generate).

Integration Feasibility

  • Laravel Compatibility:
    • Doctrine Bridge: If using doctrine/dbal or laravel-doctrine/orm, integration is straightforward (replace Symfony’s EntityManager with Laravel’s Doctrine instance).
    • Eloquent: Would require a custom wrapper to intercept Eloquent events (e.g., saving, updating) and delegate to the bundle’s AuditManager. Higher effort but feasible.
    • Migrations: Audit tables must be manually added to Laravel migrations or via a post-install script (e.g., SchemaTool equivalent).
  • Symfony-Like Features:
    • The bundle’s AuditReader and controllers can be adapted into Laravel routes/services (e.g., Route::get('/audit/{entity}', [AuditController::class, 'index'])).
    • Security (e.g., username resolution) would need Laravel-specific logic (e.g., Auth::user()->name).

Technical Risk

  • Schema Conflicts:
    • Risk of audit tables clashing with existing migrations or third-party packages (e.g., spatie/laravel-activitylog). Mitigate via:
      • Custom table naming (e.g., prefix_audit).
      • Explicit migration control (skip auto-generation, use raw SQL).
  • Performance:
    • Write amplification (1→2 DB operations per entity change). Test with benchmarks in staging.
    • Read performance for large audit histories (e.g., findRevisions()). Consider indexing rev and timestamp.
  • Maintenance:
    • Bundle updates may break Laravel-specific adaptations (e.g., Symfony service containers). Monitor changelogs (e.g., Symfony 8 deprecations).
    • No Laravel-specific support means troubleshooting falls to the TPM/team.
  • Edge Cases:
    • Soft Deletes: Audit bundle tracks DEL revisions, but Laravel’s SoftDeletes may conflict. Requires explicit handling (e.g., ignore deleted_at in global_ignore_columns).
    • Complex Associations: Many-to-Many or inherited entities may need manual configuration (see TODOs in README).
    • Multi-DB: Custom connection/entity_manager config may not map cleanly to Laravel’s multi-connection setup.

Key Questions

  1. ORM Strategy:
    • Will the project use Doctrine ORM (native integration) or Eloquent (custom wrapper)?
    • If Eloquent, how will entity events (e.g., saved) be intercepted to trigger audits?
  2. Schema Management:
    • How will audit tables be handled in migrations? Manual SQL? A custom migration class?
    • Will the project use the bundle’s SchemaTool or Laravel’s Schema Builder?
  3. Performance Trade-offs:
    • What’s the acceptable write overhead (e.g., 50% slower for high-write entities)?
    • Are there plans for read-heavy audit queries (e.g., caching AuditReader results)?
  4. Security/Compliance:
    • Who owns audit data access? Will Laravel’s gates/policies control /audit routes?
    • Are there GDPR/retention requirements for audit logs (e.g., purging old revisions)?
  5. Testing:
    • How will audit functionality be tested? Mocking AuditReader or seeding audit tables?
    • Are there plans for integration tests with Doctrine events?
  6. Alternatives:
    • Has spatie/laravel-activitylog been considered? It’s Laravel-native but lacks full entity versioning.
    • Would a lighter solution (e.g., trigger-based audits) suffice for non-critical use cases?

Integration Approach

Stack Fit

  • Core Stack:
    • Doctrine ORM: Native fit. Replace Symfony’s EntityManager with Laravel’s Doctrine instance (if using laravel-doctrine/orm).
    • Eloquent: Requires custom event listeners to bridge Eloquent events → Doctrine audits. Example:
      // app/Providers/EventServiceProvider.php
      public function boot(): void {
          Eloquent::getEventDispatcher()->listen('saved', function ($model) {
              // Manually trigger Doctrine audit via AuditManager
              app('doctrine')->getManager()->getAuditManager()->logEntity($model);
          });
      }
      
    • Database: Supports PostgreSQL, MySQL, SQLite (auto-increment required). No native support for SQL Server.
  • Laravel-Specific:
    • Service Container: Register the bundle’s services manually (e.g., AuditReader, AuditManager) in config/app.php.
    • Routing: Replace Symfony’s XML routes with Laravel’s Route::resource or controller bindings:
      Route::prefix('audit')->group(function () {
          Route::get('/', [AuditController::class, 'index']);
          Route::get('/revision/{id}', [AuditController::class, 'showRevision']);
      });
      
    • Authentication: Use Laravel’s Auth facade to resolve usernames (override username_callable):
      # config/services.php
      'simple_things_entity_audit.username_callable' => \App\Services\AuditUsernameResolver::class
      
      // App/Services/AuditUsernameResolver.php
      class AuditUsernameResolver {
          public function __invoke() {
              return Auth::check() ? Auth::user()->name : null;
          }
      }
      
  • Testing:
    • Use Laravel’s testing helpers (e.g., refreshDatabase()) to reset audit tables.
    • Mock AuditReader in unit tests:
      $this->partialMock(AuditReader::class, function ($mock) {
          $mock->shouldReceive('findRevisions')->andReturn([/* ... */]);
      });
      

Migration Path

  1. Assessment Phase:
    • Audit current entity structure (identify candidates for versioning).
    • Review existing migrations to plan audit table integration.
  2. Proof of Concept:
    • Install the bundle in a staging environment with a subset of entities.
    • Test schema generation (doctrine:schema:update --dump-sql) and manual migration creation.
    • Verify event listeners (e.g., prePersist, preUpdate) trigger audits.
  3. Incremental Rollout:
    • Phase 1: Enable audits for non-critical entities (e.g., User, Product).
    • Phase 2: Integrate with Laravel’s security (e.g., gate access to /audit routes).
    • Phase 3: Optimize performance (e.g., index audit tables, cache frequent queries).
  4. Fallback Plan:
    • If integration proves too complex, consider:
      • Hybrid Approach: Use the bundle for core entities + custom audit logic for others.
      • Alternative: Implement a lighter audit system (e.g., JSONB column for changes).

Compatibility

Feature Compatibility Workaround
Doctrine ORM ✅ Native support Use laravel-doctrine/orm package.
Eloquent ❌ No native support Custom event listeners or Doctrine Bridge.
Laravel Migrations ⚠️ Manual integration required Create raw SQL migrations for audit tables or extend SchemaTool.
Soft Deletes ⚠️ May conflict with DEL revisions Exclude `deleted
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky