acc-create-read-model

Generates Read Model/Projection for PHP 8.5. Creates optimized query models for CQRS read side with projections and denormalization. Includes unit tests.

181 stars

Best use case

acc-create-read-model is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Generates Read Model/Projection for PHP 8.5. Creates optimized query models for CQRS read side with projections and denormalization. Includes unit tests.

Teams using acc-create-read-model should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/acc-create-read-model/SKILL.md --create-dirs "https://raw.githubusercontent.com/majiayu000/claude-skill-registry/main/skills/data/acc-create-read-model/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/acc-create-read-model/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How acc-create-read-model Compares

Feature / Agentacc-create-read-modelStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Generates Read Model/Projection for PHP 8.5. Creates optimized query models for CQRS read side with projections and denormalization. Includes unit tests.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# 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/`

1. `{Name}ReadModel.php` — Immutable read model with fromArray/toArray
2. `{Name}ReadModelRepositoryInterface.php` — Query-focused repository interface

### Step 2: Generate Application Projection

**Path:** `src/Application/{BoundedContext}/Projection/`

1. `{Name}ProjectionInterface.php` — Projection contract
2. `{Name}Projection.php` — Event handlers building read model

### Step 3: Generate Infrastructure

**Path:** `src/Infrastructure/{BoundedContext}/`

1. `Projection/{Name}Store.php` — Store for insert/update/upsert
2. `ReadModel/Doctrine{Name}Repository.php` — Repository implementation

### Step 4: Generate Tests

1. `{Name}ReadModelTest.php` — Read model serialization tests
2. `{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

```php
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

```php
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

```php
// Query read model
$orders = $orderSummaryRepository->findByCustomerId($customerId);

// Project event
$projection->project($orderCreatedEvent);

// Reset projection for rebuild
$projection->reset();
```

---

## Database Schema

```sql
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 templates
- `references/examples.md` — OrderSummary example and tests

Related Skills

adding-models

181
from majiayu000/claude-skill-registry

Guide for adding new LLM models to Letta Code. Use when the user wants to add support for a new model, needs to know valid model handles, or wants to update the model configuration. Covers models.json configuration, CI test matrix, and handle validation.

add-openrouter-model

181
from majiayu000/claude-skill-registry

Fetch OpenRouter model details and provide guidance for adding models to acai-ts provider configuration.

add-opencode-model

181
from majiayu000/claude-skill-registry

Fetch OpenCode Zen model details and provide guidance for adding models to acai-ts provider configuration.

add-odoo-model

181
from majiayu000/claude-skill-registry

Add integration for an additional Odoo Studio model to an existing Odoo PWA project. Use when user wants to add support for another model, mentions "add new model", "integrate another Odoo model", or similar.

Add Model Property

181
from majiayu000/claude-skill-registry

Add a new property to an existing data model and propagate changes through model generation to client and server. Use when adding fields to entities, extending models, or modifying data structures. Handles source model editing, regeneration, ViewModel updates, and server-side changes.

adapting-transfer-learning-models

181
from majiayu000/claude-skill-registry

Build this skill automates the adaptation of pre-trained machine learning models using transfer learning techniques. it is triggered when the user requests assistance with fine-tuning a model, adapting a pre-trained model to a new dataset, or performing... Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.

bio-read-qc-adapter-trimming

181
from majiayu000/claude-skill-registry

Remove sequencing adapters from FASTQ files using Cutadapt and Trimmomatic. Supports single-end and paired-end reads, Illumina TruSeq, Nextera, and custom adapter sequences. Use when FastQC shows adapter contamination or before alignment of short reads.

accessibility-readability

181
from majiayu000/claude-skill-registry

Ensure textbook content is accessible, readable, and understandable for learners of all skill levels. Use when reviewing content for clarity, adding explanations for beginners, or improving content accessibility.

accessibility-object-model-integration

181
from majiayu000/claude-skill-registry

Programmatic manipulation of the accessibility tree to support complex custom controls in React.

acc-readme-template

181
from majiayu000/claude-skill-registry

Generates README.md files for PHP projects. Creates structured documentation with badges, installation, usage, and examples.

acc-create-value-object

181
from majiayu000/claude-skill-registry

Generates DDD Value Objects for PHP 8.5. Creates immutable, self-validating objects with equality comparison. Includes unit tests.

acc-create-use-case

181
from majiayu000/claude-skill-registry

Generates Application Use Cases for PHP 8.5. Creates orchestration services that coordinate domain objects, handle transactions, and dispatch events. Includes unit tests.