ruvnet / ddd-aggregate
Scaffold an aggregate root with entity, value objects, repository interface, domain events, and test stubs. Use when adding a new aggregate to an existing bounded context, modeling a new business concept that owns invariants, or generating the boilerplate for an entity + repo + events triplet.
Scaffold a complete aggregate root inside a bounded context.
Parse $ARGUMENTS as <context-name> <aggregate-name> (both kebab-case). The context must already exist under src/.
Steps
- Validate: Confirm
src/<context>/domain/exists. If not, suggest running/ddd-context <context>first. - Pre-task hook:
npx @claude-flow/cli@latest hooks pre-task --description "DDD aggregate: <aggregate-name> in <context>" Create aggregate root entity:
- File:
src/<context>/domain/entities/<aggregate-name>.entity.ts - Include: unique ID field, constructor with invariant validation, domain methods that enforce business rules,
equals()based on identity - Export a TypeScript class extending or implementing a base
AggregateRootinterface
- File:
Create value objects:
- File:
src/<context>/domain/value-objects/<aggregate-name>-id.value-object.ts - Include: immutable ID value object with factory method and validation
- Add additional value objects as properties of the aggregate suggest them
- File:
Create repository interface:
- File:
src/<context>/domain/repositories/<aggregate-name>.repository.ts - Include:
findById,save,deletemethods - Use the aggregate root and its ID value object as types
- This is an interface only -- no implementation (infrastructure concern)
- File:
Create domain events:
- File:
src/<context>/domain/events/<aggregate-name>-created.event.ts - File:
src/<context>/domain/events/<aggregate-name>-updated.event.ts - Include: event name (past tense), timestamp, aggregate ID, payload
- File:
Create unit test stubs:
- File:
src/<context>/domain/entities/<aggregate-name>.entity.test.ts - Include: test cases for construction invariants, domain methods, equality
- Use
describe/itwithshould [behavior] when [condition]names
- File:
- Update barrel exports: Add new files to the relevant
index.tsbarrel files. Store in domain model graph:
`
mcppluginruflo-corerufloagentdb_hierarchical-store({ key: "domain/context-<context>/aggregate-<aggregate-name>", value: "Aggregate <aggregate-name> (parent: context-<context>)", tier: "semantic" })
mcppluginruflo-corerufloagentdb_causal-edge({ sourceId: "entity:context-<context>", targetId: "entity:aggregate-<aggregate-name>", relation: "contains" })
mcppluginruflo-coreruflomemorystore({ key: "ddd-aggregate-<context>-<aggregate-name>", value: "AGGREGATESUMMARY", namespace: "tasks" })`- Post-task hook:
npx @claude-flow/cli@latest hooks post-task --task-id "ddd-aggregate-<aggregate-name>" --success true