mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 20:49:57 +01:00
5.4 KiB
5.4 KiB
| name | description | argument-hint | allowed-tools | |
|---|---|---|---|---|
| ddd-model | Interactive Domain-Driven Design modeling workflow. Use when you need to: design a new domain, identify Aggregates and Entities, choose architecture, define invariants. Generates Go code following Uber Style Guide. |
|
Read, Write, Edit, Glob, AskUserQuestion |
DDD Domain Modeling Skill
This skill guides you through a complete DDD modeling cycle for Go projects.
Overview
The workflow consists of 6 phases:
- Domain Discovery - Understand the domain and subdomain type
- Bounded Contexts - Define context boundaries and ubiquitous language
- Tactical Modeling - Identify Entities, Value Objects, Aggregates
- Invariants - Define business rules that must always hold
- Code Generation - Generate Go code with Clean Architecture
- Validation - Check DDD rules compliance
Quick Start
When user invokes /ddd-model [domain-name]:
- Read
workflow.mdfor detailed phase instructions - Use
AskUserQuestionto gather information at each phase - Read templates from
templates/for code generation - Apply rules from
rules/for validation - Reference
examples/banking.mdfor real-world example
Phase 1: Domain Discovery
Start by understanding the domain:
AskUserQuestion:
- "Describe the domain/subdomain you want to model"
- "What type of subdomain is this?" → Core / Supporting / Generic
- "What are the main business processes?"
Based on subdomain type, determine DDD investment level:
- Core → Full DDD (Aggregates, Domain Events, CQRS if needed)
- Supporting → Simplified DDD (Aggregates, basic patterns)
- Generic → CRUD/Transaction Script (minimal DDD)
Phase 2: Bounded Contexts
Identify and define bounded contexts:
- List key domain concepts through questions
- Propose BC boundaries (with ASCII diagram)
- Define Ubiquitous Language for each BC
- Map relationships between BCs (Context Map)
Example Context Map:
┌─────────────┐ ┌─────────────┐
│ Accounts │────>│ Transfers │
│ (Core) │ │ (Core) │
└─────────────┘ └─────────────┘
│ │
v v
┌─────────────┐ ┌─────────────┐
│ Fees │ │ Loyalty │
│ (Supporting)│ │ (Core) │
└─────────────┘ └─────────────┘
Phase 3: Tactical Modeling
For each Bounded Context, identify building blocks:
AskUserQuestion for each concept:
- "What has a unique identity?" → Entity
- "What is defined only by its values?" → Value Object
- "What entities always change together?" → Aggregate
- "What is the entry point to the aggregate?" → Aggregate Root
Decision Tree for Entity vs Value Object:
Does it have identity?
├── YES: Does identity matter for equality?
│ ├── YES → Entity
│ └── NO → Value Object with ID field
└── NO: Is it immutable?
├── YES → Value Object
└── NO → Consider making it immutable
Phase 4: Invariants
For each Aggregate, define invariants:
AskUserQuestion:
- "What business rules MUST always be true?"
- "What cannot be violated during changes?"
- "What conditions trigger errors?"
Format invariants as:
// Invariant: Account balance cannot be negative
// Invariant: Transfer amount must be positive
// Invariant: Account must have at least one owner
Phase 5: Code Generation
Generate Go code following Clean Architecture:
- Read
rules/clean-arch.mdfor folder structure - Use templates from
templates/:aggregate.go.md- Aggregate Root templateentity.go.md- Entity templatevalue-object.go.md- Value Object templaterepository.go.md- Repository interface template
- Generate files in:
internal/domain/<bc>/- Domain layerinternal/application/<bc>/- Application layerinternal/infrastructure/<bc>/- Infrastructure layer
Phase 6: Validation
Output validation checklist:
## DDD Validation Checklist
### Aggregate Rules
- [ ] Aggregate Root is the only entry point
- [ ] All changes go through Aggregate Root methods
- [ ] Invariants are checked in constructor and methods
- [ ] No direct references to other Aggregates (only IDs)
- [ ] One Aggregate = one transaction boundary
### Entity Rules
- [ ] ID is immutable after creation
- [ ] Equals/HashCode based on ID only
### Value Object Rules
- [ ] Fully immutable (no setters)
- [ ] Equals compares all fields
- [ ] Validation in constructor
Uber Go Style Guide Conventions
Apply these conventions in generated code:
- Value receivers for Value Objects (immutable)
- Pointer receivers for Aggregates/Entities (mutable)
- Compile-time interface checks:
var _ Repository = (*PostgresRepo)(nil) - Domain-specific error types:
type InsufficientFundsError struct{} - Package names = bounded context names (lowercase)
- Constructor functions:
NewAccount(),MustMoney()for tests
File References
- Detailed workflow:
workflow.md - DDD rules checklist:
rules/ddd-rules.md - Clean Architecture guide:
rules/clean-arch.md - Invariants guide:
rules/invariants.md - Code templates:
templates/*.go.md - Example domain:
examples/banking.md