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.md
source 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/

  1. {Name}Query.php
    — Immutable query DTO with parameters

Step 2: Generate Handler

Path:

src/Application/{BoundedContext}/Handler/

  1. {Name}Handler.php
    — Read model consumer

Step 3: Generate DTOs

Path:

src/Application/{BoundedContext}/DTO/

  1. {Name}DTO.php
    — Result data structure
  2. PaginatedResultDTO.php
    — For list queries (optional)

Step 4: Generate Read Model Interface

Path:

src/Application/{BoundedContext}/ReadModel/

  1. {Name}ReadModelInterface.php
    — Query methods contract

Step 5: Generate Tests

Path:

tests/Unit/Application/{BoundedContext}/


File Placement

ComponentPath
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}/

Query Naming Conventions

PurposeQuery NameReturns
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

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-patternProblemSolution
Side EffectsHandler modifies stateKeep read-only
Returning EntitiesLeaking domainReturn DTOs only
No ValidationInvalid parametersValidate in constructor
Unbounded ListsPerformance issuesAlways paginate
Missing Read ModelQuerying write modelUse dedicated read model

References

For complete PHP templates and examples, see:

  • references/templates.md
    — Query, Handler, DTO, PaginatedResult, ReadModel templates
  • references/examples.md
    — GetOrderDetails, ListOrders, OrderDTO examples and tests