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.
From accnpx claudepluginhub dykyi-roman/awesome-claude-code --plugin accThis skill uses the workspace's default tool permissions.
references/examples.mdreferences/templates.mdGenerate CQRS-compliant Queries and Query Handlers with tests.
final readonly classPath: src/Application/{BoundedContext}/Query/
{Name}Query.php — Immutable query DTO with parametersPath: src/Application/{BoundedContext}/Handler/
{Name}Handler.php — Read model consumerPath: src/Application/{BoundedContext}/DTO/
{Name}DTO.php — Result data structurePaginatedResultDTO.php — For list queries (optional)Path: src/Application/{BoundedContext}/ReadModel/
{Name}ReadModelInterface.php — Query methods contractPath: tests/Unit/Application/{BoundedContext}/
| Component | Path |
|---|---|
| Query | src/Application/{BoundedContext}/Query/ |
| Handler | src/Application/{BoundedContext}/Handler/ |
| DTO | src/Application/{BoundedContext}/DTO/ |
| Read Model Interface | src/Application/{BoundedContext}/ReadModel/ |
| Unit Tests | tests/Unit/Application/{BoundedContext}/ |
| Purpose | Query Name | Returns |
|---|---|---|
| Single by ID | GetOrderDetailsQuery | DTO or throws |
| Single by field | FindUserByEmailQuery | DTO or null |
| List/Collection | ListOrdersQuery | PaginatedResult |
| Search | SearchProductsQuery | array of DTOs |
| Count | CountPendingOrdersQuery | int |
| Check existence | CheckEmailExistsQuery | bool |
final readonly class {Name}Query
{
public function __construct(
public {IdType} $id
) {}
}
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');
}
}
}
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-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 |
For complete PHP templates and examples, see:
references/templates.md — Query, Handler, DTO, PaginatedResult, ReadModel templatesreferences/examples.md — GetOrderDetails, ListOrders, OrderDTO examples and testsProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.