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 History Bundle Laravel Package

bobv/entity-history-bundle

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Doctrine-Centric Design: The bundle is optimized for Symfony’s Doctrine ORM, making it a strong fit for Laravel applications using DoctrineBridge (e.g., fruitcake/laravel-doctrine). For pure Eloquent apps, this is not a direct fit and would require significant adaptation or alternative solutions (e.g., spatie/laravel-activitylog).
  • Audit Trail Use Cases: Ideal for regulatory compliance (GDPR, SOX), data integrity tracking, or user-facing version history. However, it lacks event-sourcing capabilities (e.g., no support for branching history or immutable state).
  • Separation of Concerns: Uses Doctrine lifecycle events (preUpdate, prePersist, etc.), ensuring minimal intrusion into business logic. However, this also means it cannot track changes made outside the ORM (e.g., raw SQL queries).
  • Query Limitations: Provides basic history retrieval via Doctrine queries, but no built-in support for diff views, real-time subscriptions, or aggregated analytics. Extending this would require custom development.

Integration Feasibility

  • Laravel Compatibility:
    • DoctrineBridge Required: Without fruitcake/laravel-doctrine, integration is non-trivial and may involve rewriting event listeners or using a facade layer.
    • Event Dispatcher: Laravel’s event system is not directly compatible with Symfony’s EventDispatcher. A custom bridge would be needed to route Doctrine events to Laravel’s ecosystem.
  • Database Schema:
    • Adds a history table per entity with foreign keys to the original table. Schema migrations must:
      • Support indexing on entity_id, changed_at, and revision for performance.
      • Account for storage growth (history tables are append-only and unbounded).
    • Soft Deletes: If using Gedmo/SoftDeleteable, ensure history records are not deleted when entities are soft-deleted.
  • Testing Complexity:
    • Mocking Doctrine events in Laravel’s testing stack (Pest/PHPUnit) requires custom test doubles or partial mocks of the EntityManager.
    • Edge Cases: Testing history recording for nested entities, collections, or complex relationships may expose gaps in the bundle’s design.

Technical Risk

  • Vendor Lock-in:
    • Doctrine ORM Dependency: Tight coupling to Doctrine limits flexibility if migrating to Eloquent or a non-Doctrine stack. Alternatives like laravel-audit-log would be easier to swap in later.
    • Symfony Event System: Laravel’s event system is not interchangeable, requiring a custom abstraction layer.
  • Performance Overhead:
    • Synchronous Writes: History records are written immediately during entity operations, which could bottleneck high-write systems.
    • Query Performance: Poorly indexed history tables or unoptimized queries (e.g., SELECT *) could degrade read performance.
  • Concurrency Issues:
    • Last-Write-Wins: No built-in conflict resolution for concurrent updates. Critical for high-contention systems (e.g., financial transactions).
    • Transaction Safety: History writes must fail atomically with the original operation to avoid partial records.
  • Legacy System Conflicts:
    • May conflict with existing audit triggers, custom Doctrine listeners, or database-level auditing (e.g., PostgreSQL pg_audit).
    • Backfilling Challenges: Retroactively recording history for existing data requires custom scripts and may not preserve original timestamps.

Key Questions

  1. Why Doctrine Over Eloquent?
    • Is the team committed to Doctrine ORM, or is this a temporary choice? If Eloquent is the primary ORM, evaluate alternatives like spatie/laravel-activitylog or owen-it/laravel-audit-trails.
  2. Scale and Performance
    • What is the expected write volume for tracked entities? Plan for history table bloat (e.g., 1M+ rows/year per entity).
    • Are there real-time requirements (e.g., WebSocket updates for history changes)? The bundle does not support this out of the box.
  3. Query and UI Needs
    • Will users need diff views (e.g., "Show changes between v1 and v2") or aggregated reports? The bundle’s query API may need extension.
    • Is there a need for user-facing history UIs (e.g., admin panels)? This may require additional frontend integration.
  4. Deployment and Backfilling
    • Can history be backfilled for existing data, or is it forward-only? Retroactive tracking requires custom scripts.
    • How will schema migrations (e.g., adding new fields) affect history records? Will they be forward-compatible?
  5. Alternatives and Tradeoffs
    • Compared to Laravel’s built-in logging, custom triggers, or event sourcing, what unique advantages does this bundle offer?
    • Is the MIT license acceptable, or are there enterprise support needs (e.g., SLAs, security audits)?

Integration Approach

Stack Fit

  • Core Stack:
    • Doctrine ORM Required: This bundle is not compatible with Eloquent. If using Eloquent, consider:
      • spatie/laravel-activitylog (Eloquent-compatible).
      • owen-it/laravel-audit-trails (supports both Eloquent and Doctrine).
      • A custom solution using Eloquent observers or model events.
    • Symfony Interop: Laravel’s service container and event system are not directly compatible with Symfony’s EventDispatcher. A custom bridge is needed to:
      • Route Doctrine events to Laravel’s event system.
      • Handle event priorities and listener registration.
  • Database:
    • Requires PostgreSQL/MySQL with foreign key support and indexing.
    • Schema Design: History tables should include:
      • entity_id (foreign key to original table).
      • revision (auto-incremented or UUID-based).
      • changed_at (timestamp).
      • action (e.g., CREATE, UPDATE, DELETE).
      • Optional: user_id, ip_address, or other metadata.

Migration Path

  1. Pilot Phase
    • Start with 1–2 critical entities (e.g., User, Order) to validate:
      • Performance impact of history recording.
      • Query patterns (e.g., fetching past versions).
    • Use Doctrine’s SchemaTool to generate history tables without downtime.
  2. Incremental Rollout
    • Add @History annotations or YAML/XML config to entities gradually.
    • Monitor:
      • Database growth (set alerts for history table size).
      • Query latency (optimize indexes as needed).
  3. Backfill Strategy
    • For existing data, use a console command or seeder to replay changes:
      // Example: Backfill history for existing users
      $users = $entityManager->getRepository(User::class)->findAll();
      foreach ($users as $user) {
          $history = $entityManager->getRepository(History::class);
          $history->recordChange($user, 'initial state', 'backfill');
      }
      
    • Consider batch processing to avoid timeouts.

Compatibility

  • Doctrine Version:
    • Tested with Doctrine ORM 2.10+. Ensure Laravel’s fruitcake/laravel-doctrine is compatible.
    • Check for deprecated APIs (e.g., Extension class references in older versions).
  • PHP Version:
    • Requires PHP 8.1+ (aligns with Laravel 10+). Downgrading may break type safety.
  • Conflict with Existing Logic:
    • Doctrine Listeners: Check for existing preUpdate, prePersist, or postRemove listeners that might interfere with history recording.
    • Transactions: Ensure history writes are atomic with the original operation. Use Doctrine’s flush() in a transaction.
    • Soft Deletes: If using Gedmo/SoftDeleteable, configure the bundle to preserve history during soft deletes.

Sequencing

  1. Setup
    • Install the bundle via Composer:
      composer require bobv/entity-history-bundle
      
    • Configure Doctrine event listeners in config/packages/doctrine.yaml:
      doctrine:
          orm:
              event_listeners:
                  App\Doctrine\HistoryListener: ~
      
    • Register a custom listener to bridge Symfony events to Laravel’s ecosystem:
      // src/Doctrine/HistoryListener.php
      use Doctrine\Common\EventSubscriber;
      use Doctrine\ORM\Event\LifecycleEventArgs;
      
      class HistoryListener implements EventSubscriber
      {
          public function getSubs
      
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui