Claude-skill-registry acc-create-aggregate
Generates DDD Aggregates for PHP 8.5. Creates consistency boundaries with root entity, domain events, and invariant protection. Includes unit tests.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/acc-create-aggregate" ~/.claude/skills/majiayu000-claude-skill-registry-acc-create-aggregate && rm -rf "$T"
manifest:
skills/data/acc-create-aggregate/SKILL.mdsource content
Aggregate Generator
Generate DDD-compliant Aggregates with root, domain events, and tests.
Aggregate Characteristics
- Consistency boundary: All changes atomic
- Root entity: Single entry point
- Transactional consistency: Invariants always valid
- Domain events: Records what happened
- Encapsulation: Children accessed through root
- Identity: Referenced by root ID
Generation Process
Step 1: Generate Base AggregateRoot
Path:
src/Domain/Shared/Aggregate/
— Base class with event recordingAggregateRoot.php
Step 2: Generate Aggregate Root Entity
Path:
src/Domain/{BoundedContext}/Entity/
— Main aggregate root{Name}.php
Step 3: Generate Child Entities (if needed)
Path:
src/Domain/{BoundedContext}/Entity/
— Child entity inside aggregate{ChildName}.php
Step 4: Generate Domain Events
Path:
src/Domain/{BoundedContext}/Event/
{Name}CreatedEvent.php
for each behavior{Name}{Action}Event.php
Step 5: Generate Tests
Path:
tests/Unit/Domain/{BoundedContext}/Entity/
File Placement
| Component | Path |
|---|---|
| Base AggregateRoot | |
| Aggregate Entity | |
| Child Entities | |
| Domain Events | |
| Unit Tests | |
Naming Conventions
| Component | Pattern | Example |
|---|---|---|
| Aggregate Root | | |
| Child Entity | | |
| Created Event | | |
| State Event | | |
Quick Template Reference
Base AggregateRoot
abstract class AggregateRoot { private array $events = []; protected function recordEvent(DomainEvent $event): void { $this->events[] = $event; } public function releaseEvents(): array { $events = $this->events; $this->events = []; return $events; } }
Aggregate Root Entity
final class {Name} extends AggregateRoot { private {Name}Status $status; private function __construct( private readonly {Name}Id $id, {properties} ) { $this->status = {Name}Status::Draft; } public static function create({Name}Id $id, {params}): self { $aggregate = new self($id, {args}); $aggregate->recordEvent(new {Name}CreatedEvent(...)); return $aggregate; } public function {behavior}({params}): void { $this->ensureValidState(); // Apply change $this->recordEvent(new {Name}{Behavior}Event(...)); } }
Child Entity
final readonly class {ChildName} { public function __construct( public {PropertyType} $property1, public {PropertyType} $property2 ) {} public function total(): Money { return $this->unitPrice->multiply($this->quantity); } }
Design Rules
| Rule | Good | Bad |
|---|---|---|
| Transaction Boundary | One aggregate per transaction | Multiple aggregates |
| Reference | By ID only | Full entity reference |
| Size | Small, focused | Large with many collections |
| Invariants | Always valid | Can be in invalid state |
| Events | Record all state changes | No event recording |
Anti-patterns to Avoid
| Anti-pattern | Problem | Solution |
|---|---|---|
| Large Aggregate | Performance issues | Split into smaller aggregates |
| Entity References | Tight coupling | Use IDs only |
| Public Setters | No invariant protection | Use behavior methods |
| Missing Events | Can't track history | Record event for each change |
| No Root | Multiple entry points | Single root entity |
References
For complete PHP templates and examples, see:
— AggregateRoot, Entity, Child Entity, Test templatesreferences/templates.md
— Order aggregate with OrderLine, events, and testsreferences/examples.md