create-read-model
Read Model / Projection Generator
Creates Read Model infrastructure for CQRS read side with optimized query models.
When to Use
| Scenario | Example |
|---|---|
| CQRS read side | Separate query models |
| Denormalized views | Dashboard aggregates |
| Complex queries | Multi-entity joins |
| Event-driven updates | Event projections |
Component Characteristics
Read Model
- Optimized for queries
- Denormalized data
- Eventually consistent
- No business logic
Projection
- Builds read models from events
- Handles event streams
- Maintains synchronization
- Idempotent processing
Repository
- Query-focused methods
- Returns read models
- No write operations
Generation Process
Step 1: Generate Domain Read Model
Path: src/Domain/{BoundedContext}/ReadModel/
{Name}ReadModel.php— Immutable read model with fromArray/toArray{Name}ReadModelRepositoryInterface.php— Query-focused repository interface
Step 2: Generate Application Projection
Path: src/Application/{BoundedContext}/Projection/
{Name}ProjectionInterface.php— Projection contract{Name}Projection.php— Event handlers building read model
Step 3: Generate Infrastructure
Path: src/Infrastructure/{BoundedContext}/
Projection/{Name}Store.php— Store for insert/update/upsertReadModel/Doctrine{Name}Repository.php— Repository implementation
Step 4: Generate Tests
{Name}ReadModelTest.php— Read model serialization tests{Name}ProjectionTest.php— Projection event handling tests
File Placement
| Component | Path |
|---|---|
| Read Model | src/Domain/{BoundedContext}/ReadModel/ |
| Repository Interface | src/Domain/{BoundedContext}/ReadModel/ |
| Projection Interface | src/Application/{BoundedContext}/Projection/ |
| Projection | src/Application/{BoundedContext}/Projection/ |
| Store | src/Infrastructure/{BoundedContext}/Projection/ |
| Repository Impl | src/Infrastructure/{BoundedContext}/ReadModel/ |
| Unit Tests | tests/Unit/ |
Naming Conventions
| Component | Pattern | Example |
|---|---|---|
| Read Model | {Name}ReadModel |
OrderSummaryReadModel |
| Repository Interface | {Name}ReadModelRepositoryInterface |
OrderSummaryReadModelRepositoryInterface |
| Projection Interface | {Name}ProjectionInterface |
OrderSummaryProjectionInterface |
| Projection | {Name}Projection |
OrderSummaryProjection |
| Store | {Name}Store |
OrderSummaryStore |
| Test | {ClassName}Test |
OrderSummaryProjectionTest |
Quick Template Reference
Read Model
final readonly class {Name}ReadModel
{
public function __construct(
public string $id,
// ... denormalized properties
public \DateTimeImmutable $createdAt,
public \DateTimeImmutable $updatedAt
) {}
public static function fromArray(array $data): self;
public function toArray(): array;
}
Projection
final class {Name}Projection implements {Name}ProjectionInterface
{
public function project(DomainEventInterface $event): void
{
match ($event::class) {
OrderCreated::class => $this->whenOrderCreated($event),
OrderShipped::class => $this->whenOrderShipped($event),
default => null,
};
}
public function reset(): void;
public function subscribedEvents(): array;
}
Usage Example
// Query read model
$orders = $orderSummaryRepository->findByCustomerId($customerId);
// Project event
$projection->project($orderCreatedEvent);
// Reset projection for rebuild
$projection->reset();
Database Schema
CREATE TABLE order_summaries (
id VARCHAR(36) PRIMARY KEY,
order_number VARCHAR(50) NOT NULL UNIQUE,
customer_id VARCHAR(36) NOT NULL,
customer_name VARCHAR(255) NOT NULL,
status VARCHAR(50) NOT NULL,
total_cents BIGINT NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
INDEX idx_customer (customer_id),
INDEX idx_status (status)
);
Anti-patterns to Avoid
| Anti-pattern | Problem | Solution |
|---|---|---|
| Business Logic | Read model has behavior | Keep data-only |
| Write Operations | Modifying read models | Use projections only |
| Non-idempotent | Re-projection breaks data | Idempotent event handling |
| Missing Reset | Can't rebuild | Add reset() method |
| Tight Coupling | Projection depends on domain | Use events only |
References
For complete PHP templates and examples, see:
references/templates.md— Read model, projection, store templatesreferences/examples.md— OrderSummary example and testsreferences/event-sourcing-projections.md— Event replay projections, versioning, checkpoint tracking, async workers
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