acc-create-command
1
总安装量
1
周安装量
#51842
全站排名
安装命令
npx skills add https://github.com/dykyi-roman/awesome-claude-code --skill acc-create-command
Agent 安装分布
opencode
1
claude-code
1
Skill 文档
Command Generator
Generate CQRS-compliant Commands and Command Handlers with tests.
Command Characteristics
- Immutable:
final readonly class - Imperative naming: Verb + noun (CreateOrder, ConfirmPayment)
- Self-validating: Validates invariants in constructor
- Intent-revealing: Name describes what should happen
- Returns void or ID: Never returns data
Generation Process
Step 1: Generate Command
Path: src/Application/{BoundedContext}/Command/
{Name}Command.phpâ Immutable command DTO
Step 2: Generate Handler
Path: src/Application/{BoundedContext}/Handler/
{Name}Handler.phpâ Command processor
Step 3: Generate Tests
Path: tests/Unit/Application/{BoundedContext}/
File Placement
| Component | Path |
|---|---|
| Command | src/Application/{BoundedContext}/Command/ |
| Handler | src/Application/{BoundedContext}/Handler/ |
| Unit Tests | tests/Unit/Application/{BoundedContext}/ |
Command Naming Conventions
| Action | Command Name | Returns |
|---|---|---|
| Create new | CreateOrderCommand |
ID |
| Confirm/Approve | ConfirmOrderCommand |
void |
| Cancel/Reject | CancelOrderCommand |
void |
| Update property | UpdateShippingAddressCommand |
void |
| Add child | AddOrderLineCommand |
void |
| Remove child | RemoveOrderLineCommand |
void |
Quick Template Reference
Command
final readonly class {Name}Command
{
public function __construct(
public {ValueObject} $id,
public string $data
) {
if (empty($data)) {
throw new \InvalidArgumentException('Data is required');
}
}
public static function fromArray(array $data): self
{
return new self(
id: new {ValueObject}($data['id']),
data: $data['data']
);
}
}
Handler (Update Flow)
final readonly class {Name}Handler
{
public function __construct(
private {Repository}Interface $repository,
private EventDispatcherInterface $events
) {}
public function __invoke({Name}Command $command): void
{
$aggregate = $this->repository->findById($command->id);
if ($aggregate === null) {
throw new NotFoundException($command->id);
}
$aggregate->doSomething($command->data);
$this->repository->save($aggregate);
foreach ($aggregate->releaseEvents() as $event) {
$this->events->dispatch($event);
}
}
}
Handler (Create Flow)
public function __invoke(CreateCommand $command): AggregateId
{
$aggregate = Aggregate::create(
id: $this->repository->nextIdentity(),
...
);
$this->repository->save($aggregate);
foreach ($aggregate->releaseEvents() as $event) {
$this->events->dispatch($event);
}
return $aggregate->id();
}
Anti-patterns to Avoid
| Anti-pattern | Problem | Solution |
|---|---|---|
| Returning Data | Query through command | Use Query for reads |
| No Validation | Invalid commands | Validate in constructor |
| Business Logic | Handler has decisions | Delegate to aggregate |
| Missing Events | Events not dispatched | Always dispatch after save |
| Direct Persistence | Bypassing aggregate | Always use aggregate methods |
References
For complete PHP templates and examples, see:
references/templates.mdâ Command, Handler, Test templates with patternsreferences/examples.mdâ CreateOrder, ConfirmOrder, CancelOrder examples and tests