What this prompt does
This prompt makes the AI implement event sourcing for [domain_context] on Laravel [laravel_version] using [es_package], scoped to [aggregate_count] aggregates and [event_volume] events daily. It sets up the event store with [event_store_driver], base classes, and the [namespace_structure], then builds the [primary_aggregate] with [state_properties] and [command_count] command methods that validate rules and record events. Declaring the domain and volume keeps the design grounded rather than an academic CQRS exercise.
The structure works because event sourcing is a chain of deliberate pieces. [event_count] immutable events with fromArray()/toArray() and a [schema_version_strategy] model the domain; [projector_count] projectors maintain read models like [read_model_table] with idempotency by event UUID; [reactor_count] reactors fire side effects only on live events, not during replay; and a replay command reprocesses events in batches of [replay_batch_size]. The given/when/then testing helpers make the aggregate logic safe to change. Declaring [event_volume] and [event_store_driver] keeps the design grounded in your actual throughput, and the [example_flow] you supply walks the AI through the full command lifecycle so the aggregate's state transitions are demonstrated end to end. The [schema_version_strategy] handles event evolution through upcasting, which matters because stored events are immutable and old payloads must keep deserializing as the domain changes over months and years.
When to use it
- You have a domain where the audit trail genuinely matters
- You need to reconstruct state by replaying events from a date or aggregate UUID
- You want read models kept in sync via idempotent projectors
- You need side effects (notifications, external calls) that skip during replay
- You want fluent given/when/then tests for aggregate business rules
- You need event schema evolution via upcasting as the domain changes
Example output
The AI returns event-sourcing infrastructure: configured [es_package], a customized StoredEvent model, abstract AggregateRoot and Projector base classes, the [primary_aggregate] with [command_count] command methods showing the [example_flow] lifecycle, [event_count] immutable event classes with factories and versioning, [projector_count] projectors maintaining [read_model_table] with UUID idempotency, [reactor_count] reactors guarded against replay, a replay Artisan command batching [replay_batch_size] events, and given/when/then testing helpers.
Pro tips
- Only reach for this when the audit trail truly matters; event sourcing adds real complexity over plain CRUD
- Make every event immutable with typed properties so historical events never change meaning
- Guard reactors with the live-event check so replays do not re-send notifications or re-call external APIs
- Enforce idempotency in projectors by tracking the event UUID, or a replay will double-apply
- Plan
[schema_version_strategy]upcasting early; events live forever and old payloads must keep deserializing - Tune
[replay_batch_size]to balance replay speed against memory when rebuilding[read_model_table] - Keep aggregate command methods focused on validating rules and recording events, with state changes applied only through those events
- Scope
[aggregate_count]tightly; more aggregates means more projectors and reactors to keep idempotent and replay-safe