create-event-store
Event Store Generator
Creates Event Store infrastructure for event sourcing with aggregate history and event replay.
When to Use
| Scenario | Example |
|---|---|
| Event sourcing | Aggregate state from events |
| Audit trail | Complete change history |
| Event replay | Rebuild projections from events |
| Temporal queries | Query state at any point in time |
Component Characteristics
StoredEvent
- Immutable event wrapper
- Contains aggregate metadata (id, type, version)
- Serialized payload
- Creation timestamp
EventStream
- Ordered collection of stored events
- Implements IteratorAggregate
- Tracks current version
- Supports appending new events
EventStoreInterface
- Append events with optimistic locking
- Load full event stream for aggregate
- Load events from specific version
- Stream-based reading for large aggregates
Generation Process
Step 1: Generate Domain Components
Path: src/Domain/{BoundedContext}/EventStore/
StoredEvent.php— Immutable stored event value objectEventStreamInterface.php— Event stream contractEventStream.php— Event stream implementationEventStoreInterface.php— Event store contract
Step 2: Generate Infrastructure
Path: src/Infrastructure/{BoundedContext}/EventStore/
DoctrineEventStore.php— Doctrine DBAL implementation with optimistic locking- Database migration SQL
Step 3: Generate Tests
StoredEventTest.php— Stored event immutability testsEventStreamTest.php— Stream operations testsDoctrineEventStoreTest.php— Integration tests
File Placement
| Component | Path |
|---|---|
| StoredEvent | src/Domain/{BoundedContext}/EventStore/ |
| EventStream | src/Domain/{BoundedContext}/EventStore/ |
| EventStoreInterface | src/Domain/{BoundedContext}/EventStore/ |
| DoctrineEventStore | src/Infrastructure/{BoundedContext}/EventStore/ |
| Unit Tests | tests/Unit/Domain/{BoundedContext}/EventStore/ |
| Integration Tests | tests/Integration/Infrastructure/{BoundedContext}/EventStore/ |
Naming Conventions
| Component | Pattern | Example |
|---|---|---|
| Stored Event | StoredEvent |
StoredEvent |
| Stream Interface | EventStreamInterface |
EventStreamInterface |
| Stream | EventStream |
EventStream |
| Store Interface | EventStoreInterface |
EventStoreInterface |
| Store Impl | Doctrine{Name}EventStore |
DoctrineEventStore |
| Exception | ConcurrencyException |
ConcurrencyException |
| Test | {ClassName}Test |
StoredEventTest |
Quick Template Reference
StoredEvent
final readonly class StoredEvent
{
public function __construct(
public string $aggregateId,
public string $aggregateType,
public string $eventType,
public string $payload,
public int $version,
public \DateTimeImmutable $createdAt
) {}
public static function fromDomainEvent(string $aggregateId, string $aggregateType, int $version, object $event): self;
public function toArray(): array;
public static function fromArray(array $data): self;
}
EventStoreInterface
interface EventStoreInterface
{
public function append(string $aggregateId, EventStream $events, int $expectedVersion): void;
public function load(string $aggregateId): EventStream;
public function loadFromVersion(string $aggregateId, int $fromVersion): EventStream;
}
EventStream
final class EventStream implements \IteratorAggregate, \Countable
{
public static function empty(): self;
public static function fromEvents(array $events): self;
public function append(StoredEvent $event): self;
public function getVersion(): int;
public function isEmpty(): bool;
public function getIterator(): \ArrayIterator;
public function count(): int;
}
Usage Example
// Append events
$events = EventStream::fromEvents([
StoredEvent::fromDomainEvent($orderId, 'Order', 1, $orderCreated),
StoredEvent::fromDomainEvent($orderId, 'Order', 2, $itemAdded),
]);
$eventStore->append($orderId, $events, expectedVersion: 0);
// Load and replay
$stream = $eventStore->load($orderId);
foreach ($stream as $event) {
$aggregate->apply($event);
}
Database Schema
CREATE TABLE event_store (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
aggregate_id VARCHAR(36) NOT NULL,
aggregate_type VARCHAR(255) NOT NULL,
event_type VARCHAR(255) NOT NULL,
payload JSON NOT NULL,
version INT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE INDEX idx_aggregate_version (aggregate_id, version),
INDEX idx_aggregate_type (aggregate_type),
INDEX idx_event_type (event_type),
INDEX idx_created_at (created_at)
);
Anti-patterns to Avoid
| Anti-pattern | Problem | Solution |
|---|---|---|
| Mutable Events | History changes | Immutable StoredEvent |
| Missing Version | No optimistic locking | Version per aggregate |
| No Idempotency | Duplicate appends | Unique aggregate_id + version |
| Large Payloads | Slow reads | Serialize only essential data |
| No Snapshots | Slow rebuilds for long streams | Use create-snapshot |
| Global Stream Only | Can't load per-aggregate | Per-aggregate stream support |
References
For complete PHP templates and examples, see:
references/templates.md— StoredEvent, EventStream, EventStoreInterface, DoctrineEventStore templatesreferences/examples.md— Order event store usage and tests
More from dykyi-roman/awesome-claude-code
psr-overview-knowledge
PHP Standards Recommendations (PSR) overview knowledge base. Provides comprehensive reference for all accepted PSRs including PSR-1,3,4,6,7,11,12,13,14,15,16,17,18,20. Use for PSR selection decisions and compliance audits.
22detect-code-smells
Detects code smells in PHP codebases. Identifies God Class, Feature Envy, Data Clumps, Long Parameter List, Long Method, Primitive Obsession, Message Chains, Inappropriate Intimacy. Generates actionable reports with refactoring recommendations.
15clean-arch-knowledge
Clean Architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Clean Architecture and Hexagonal Architecture audits.
15ddd-knowledge
DDD architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Domain-Driven Design audits.
14testing-knowledge
Testing knowledge base for PHP 8.4 projects. Provides testing pyramid, AAA pattern, naming conventions, isolation principles, DDD testing guidelines, and PHPUnit patterns.
12bug-root-cause-finder
Root cause analysis methods for PHP bugs. Provides 5 Whys technique, fault tree analysis, git bisect guidance, and stack trace parsing.
12