- What Laravel versions does stupid-event-sourcing support?
- The package requires Laravel 9+ and PHP 8.1+. It leverages modern Laravel features like enums and attributes, so older versions (e.g., Laravel 8 or PHP 7.x) won’t work without significant modifications. Always check the package’s GitLab repo for the latest compatibility notes before upgrading.
- How do I store events for a Laravel Eloquent model?
- You manually dispatch events using `Event::dispatch(new YourEvent($data))` in your model’s methods (e.g., `created()`, `updated()`). The package doesn’t auto-magically tie to Eloquent lifecycle hooks—you’ll need to replace traditional `saved()` listeners with explicit event dispatches. Example: `OrderCreated::dispatch($order->id, $order->amount)`.
- Can I use this for financial transactions where replayability is critical?
- Yes, but with caveats. The package excels at audit trails and replaying events to rebuild state, which is perfect for financial systems. However, you’ll need to implement snapshotting manually for large aggregates (e.g., 1M+ events) to avoid performance issues during replay. Test thoroughly for edge cases like schema migrations or out-of-order events.
- How do I rebuild an aggregate’s state from stored events?
- You’ll need to write a projection job (e.g., `php artisan make:job RebuildOrderAggregate`). In the job, fetch events for the aggregate (e.g., `Event::where('aggregate_id', $id)->get()`), then apply them sequentially to rebuild the state. Use Laravel Queues to offload this work asynchronously for better performance.
- Does this package handle event versioning or schema migrations?
- No, it doesn’t include built-in versioning or migration tools. If you add fields to an event class later, older events won’t have those fields, breaking replayability. Design your events to be backward-compatible (e.g., add optional fields with null defaults) or implement custom logic to handle schema changes during replay.
- What happens if an event fails to store in the database?
- The package doesn’t include retry logic or dead-letter queues. If the database fails during `Event::dispatch()`, the event is lost unless you wrap the dispatch in a transaction and handle rollbacks. For production, consider using Laravel Queues with a dead-letter queue (e.g., `failed_jobs` table) to catch and reprocess failed events.
- Is this package suitable for high-throughput systems (e.g., 10K+ events/sec)?
- No, it’s not optimized for high throughput. The write path is fast for single events, but storing 10K+ events per second may bottleneck without batching or async processing. Use Laravel Queues to offload event storage and consider batching events (e.g., store 100 events at once) to improve performance. Monitor database writes under load.
- How do I test event replay and state reconstruction?
- Use Laravel’s `Event::fake()` for unit tests to mock events. For integration tests, replay events from your database and assert the final state. Example: `Event::assertDispatched(OrderCreated::class);` for unit tests, or write a test that queries the events table and rebuilds the aggregate to verify state. Mock projections if needed.
- Are there alternatives to this package for Laravel event sourcing?
- Yes, if you need more features like snapshotting or distributed consensus, consider `spatie/laravel-event-sourcing` (more robust but heavier) or `axiomlabs/laravel-event-sourcing` (focused on CQRS). For microservices, look at `eventuous/eventuous` (PHP-based but not Laravel-specific). This package is ideal if you want simplicity and don’t need advanced ES features.
- How do I handle out-of-order events (e.g., due to network delays or retries)?
- The package doesn’t enforce event ordering, so you’ll need to implement idempotency checks in your projections. For example, store the last processed event ID in your aggregate’s state and skip duplicates or out-of-order events during replay. Use Laravel’s `unique()` constraint on the events table to prevent duplicates if needed.