CQRS architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Command Query Responsibility Segregation audits.
From accnpx claudepluginhub dykyi-roman/awesome-claude-code --plugin accThis skill uses the workspace's default tool permissions.
references/antipatterns.mdreferences/bus-patterns.mdreferences/command-patterns.mdreferences/handler-patterns.mdreferences/query-patterns.mdQuick reference for CQRS architecture patterns and PHP implementation guidelines.
┌─────────────────────────────────────────────────────────────┐
│ APPLICATION │
├─────────────────────────────────────────────────────────────┤
│ WRITE SIDE (Commands) │ READ SIDE (Queries) │
├─────────────────────────────┼───────────────────────────────┤
│ Command → Handler → Domain │ Query → Handler → ReadModel │
│ Changes state │ Returns data, no side effects│
│ Uses Domain Model │ Can bypass Domain Model │
│ Single aggregate per cmd │ Can join multiple sources │
└─────────────────────────────┴───────────────────────────────┘
Rule: Commands WRITE, Queries READ. Never mix.
| Component | Purpose | Returns | Side Effects |
|---|---|---|---|
| Command | Request to change state | void or ID | Yes |
| CommandHandler | Executes command logic | void or ID | Yes |
| Query | Request for data | Data DTO | No |
| QueryHandler | Fetches and transforms data | Data DTO | No |
| CommandBus | Routes commands to handlers | Depends | N/A |
| QueryBus | Routes queries to handlers | Query result | N/A |
execute() or __invoke() method| Violation | Where to Look | Severity |
|---|---|---|
| Query with side effects | QueryHandler calling save() | Critical |
| Command returning data | CommandHandler returning entity | Critical |
| Mixed read/write in handler | Handler with both get and save | Critical |
| Business logic in handler | if/switch on domain state | Warning |
| Missing command validation | Command without invariants | Warning |
| Query using write DB | QueryHandler using EntityManager | Info |
final readonly class CreateOrderCommand
{
public function __construct(
public CustomerId $customerId,
/** @var array<OrderLineData> */
public array $lines,
public ?string $notes = null
) {
if (empty($lines)) {
throw new InvalidArgumentException('Order must have at least one line');
}
}
}
final readonly class CreateOrderHandler
{
public function __construct(
private OrderRepositoryInterface $orders,
private EventDispatcherInterface $events
) {}
public function __invoke(CreateOrderCommand $command): OrderId
{
$order = Order::create(
id: OrderId::generate(),
customerId: $command->customerId,
lines: $command->lines
);
$this->orders->save($order);
foreach ($order->releaseEvents() as $event) {
$this->events->dispatch($event);
}
return $order->id();
}
}
final readonly class GetOrderDetailsQuery
{
public function __construct(
public OrderId $orderId
) {}
}
final readonly class GetOrderDetailsHandler
{
public function __construct(
private OrderReadModelInterface $readModel
) {}
public function __invoke(GetOrderDetailsQuery $query): ?OrderDetailsDTO
{
return $this->readModel->findById($query->orderId);
}
}
For detailed information, load these reference files:
references/command-patterns.md — Command structure, naming, validationreferences/query-patterns.md — Query structure, read modelsreferences/handler-patterns.md — Handler patterns, async/syncreferences/bus-patterns.md — Command/Query bus implementationsreferences/antipatterns.md — Common violations with detection patternsProvides 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.