Awesome-claude-code create-query
Generates CQRS Queries and Handlers for PHP 8.4. Creates read-only query DTOs with handlers that return data without side effects. Includes unit tests.
install
source · Clone the upstream repo
git clone https://github.com/dykyi-roman/awesome-claude-code
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/dykyi-roman/awesome-claude-code "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/create-query" ~/.claude/skills/dykyi-roman-awesome-claude-code-create-query && rm -rf "$T"
manifest:
skills/create-query/SKILL.mdsource content
Query Generator
Generate CQRS-compliant Queries and Query Handlers with tests.
Query Characteristics
- Immutable:
final readonly class - Interrogative naming: Get/Find/List + noun
- No side effects: Handler never modifies state
- Returns DTOs: Never returns domain entities
- Read-optimized: Can use dedicated read models
Generation Process
Step 1: Generate Query
Path:
src/Application/{BoundedContext}/Query/
— Immutable query DTO with parameters{Name}Query.php
Step 2: Generate Handler
Path:
src/Application/{BoundedContext}/Handler/
— Read model consumer{Name}Handler.php
Step 3: Generate DTOs
Path:
src/Application/{BoundedContext}/DTO/
— Result data structure{Name}DTO.php
— For list queries (optional)PaginatedResultDTO.php
Step 4: Generate Read Model Interface
Path:
src/Application/{BoundedContext}/ReadModel/
— Query methods contract{Name}ReadModelInterface.php
Step 5: Generate Tests
Path:
tests/Unit/Application/{BoundedContext}/
File Placement
| Component | Path |
|---|---|
| Query | |
| Handler | |
| DTO | |
| Read Model Interface | |
| Unit Tests | |
Query Naming Conventions
| Purpose | Query Name | Returns |
|---|---|---|
| Single by ID | | DTO or throws |
| Single by field | | DTO or null |
| List/Collection | | PaginatedResult |
| Search | | array of DTOs |
| Count | | int |
| Check existence | | bool |
Quick Template Reference
Query
final readonly class {Name}Query { public function __construct( public {IdType} $id ) {} }
Query with Pagination
final readonly class List{Name}Query { public function __construct( public ?{FilterType} $filter = null, public int $limit = 20, public int $offset = 0, public string $sortBy = 'created_at', public string $sortDirection = 'desc' ) { if ($limit < 1 || $limit > 100) { throw new \InvalidArgumentException('Limit must be between 1 and 100'); } } }
Handler
final readonly class {Name}Handler { public function __construct( private {ReadModelInterface} $readModel ) {} public function __invoke({Name}Query $query): {ResultDTO} { $result = $this->readModel->findById($query->id->value); if ($result === null) { throw new {NotFoundException}($query->id); } return $result; } }
Anti-patterns to Avoid
| Anti-pattern | Problem | Solution |
|---|---|---|
| Side Effects | Handler modifies state | Keep read-only |
| Returning Entities | Leaking domain | Return DTOs only |
| No Validation | Invalid parameters | Validate in constructor |
| Unbounded Lists | Performance issues | Always paginate |
| Missing Read Model | Querying write model | Use dedicated read model |
References
For complete PHP templates and examples, see:
— Query, Handler, DTO, PaginatedResult, ReadModel templatesreferences/templates.md
— GetOrderDetails, ListOrders, OrderDTO examples and testsreferences/examples.md