Install
$ agentstack add skill-luckys-agent-skills-ddd-best-practices ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
DDD Best Practices
Use this skill when the main question is how to model a domain, where to draw boundaries, or how to structure collaboration between subdomains.
Working Style
- Start from the domain problem, not from technical constructs.
- Build a Ubiquitous Language before writing any code.
- Keep Aggregates small — consistency boundary, not convenience grouping.
- Prefer Value Objects when a domain concept has value semantics, not as a blanket wrapper for every primitive.
- Let Domain Events tell the story of what happened, not what to do next.
- Never let infrastructure concerns leak into the domain model.
Design Workflow
- Discover the domain.
- Who are the domain experts? What language do they use?
- What are the core subdomains (Core, Supporting, Generic)?
- Where does the most complex business logic live?
- Draw Bounded Contexts.
- One model per context — resist the urge to share models across contexts.
- Name each context after a team or capability, not a technical layer.
- Define context relationships explicitly (Partnership, Customer-Supplier, Anti-Corruption Layer, etc.).
- Design Aggregates.
- Start from one business command and state the invariants it must preserve.
- Include only state that must commit or reject atomically.
- Each Aggregate has one root Entity that controls access.
- Reference other Aggregates by identity and make eventual consistency explicit.
- Check lifecycle, cardinality, contention, and concurrency; table count does not define the boundary.
- Model with tactical patterns.
- Entity: has identity that persists over time.
- Value Object: defined by its attributes; value equality; immutable by default; no identity.
- Domain Service: stateless logic that doesn't belong to any single Entity.
- Domain Event: records that something significant happened.
- Repository: collection-like access to Aggregates.
- Factory: encapsulates complex construction.
- Integrate contexts.
- Translate at boundaries — never let one context's model pollute another.
- Use Anti-Corruption Layers when consuming upstream models you don't control.
- Translate internal Domain Events into stable Integration Events before crossing a context boundary.
Heuristics
Bounded Context
Draw the boundary where the Ubiquitous Language changes — the same word meaning different things is a signal for a boundary.
Aggregate
If a recognized business invariant requires two objects to commit or reject together, they likely belong in the same Aggregate. Do not confuse a convenient synchronous workflow with an invariant. If temporary inconsistency has an acceptable recovery path, prefer separate Aggregates.
Entity vs Value Object
If you track it over time or need to distinguish between two instances with the same data, it's an Entity. If all that matters is its value, it's a Value Object.
Domain Service
If a significant domain operation doesn't naturally belong to any Entity or Value Object, it belongs in a Domain Service — but use sparingly.
Domain Event
Name events in the past tense: OrderPlaced, PaymentFailed, UserRegistered. They record facts — they don't issue commands. Prefer a specific semantic fact such as UserArchived over generic UserUpdated or StatusChanged; let the Aggregate record it and the application deliver it.
Repository
One Repository per Aggregate Root. Never expose a Repository for child entities within an Aggregate. Return complete Aggregates for invariant-bearing work; use dedicated query models for reports and partial projections, and gateways for external capabilities.
Warning Signs
- Anemic Domain Model: Entities have only getters/setters; all logic is in services.
- God Aggregate: one Aggregate contains everything related to a concept.
- Shared database between Bounded Contexts — contexts are coupled through the schema.
- Ubiquitous Language drift: code uses different terms from the domain experts.
- Application Service doing domain logic instead of orchestrating domain objects.
- Repository returning arbitrary queries instead of meaningful collection operations.
- Repository exposing ORM/query-builder types, interpolated SQL, or transaction control.
- Generic CRUD events carry full Aggregate snapshots without a consumer or compatibility reason.
- A use case invents Domain Events after the transition, or an Aggregate publishes through an Event Bus.
- Raw internal Domain Events cross a Bounded Context instead of being translated to versioned Integration Events.
- One transaction routinely modifies multiple Aggregate Roots without a documented invariant.
- Public setters or mutable child collections let callers bypass the Aggregate Root.
- Repository access exists for a child Entity inside an Aggregate.
- Aggregate boundaries mirror ORM relationships, UI screens, or table layouts.
- A global uniqueness rule is checked only in memory, without a concurrent persistence constraint.
References
- Read
references/aggregates.mdfor Aggregate discovery, boundary signals, rule ownership, creation vs. reconstitution, concurrency, cross-Aggregate coordination, persistence, and review checklists. - Read
references/repositories.mdfor repository semantics, contract ownership, Repository vs DAO/query service/gateway, absence, mapping, transactions, caching, pagination, testing, and legacy migration. - Read
references/domain-events.mdfor event semantics, granularity, payload/envelope design, aggregate recording, creation vs reconstitution, Integration Event translation, subscribers, and delivery boundaries. - Read
references/tactical-patterns.mdfor Entities, Value Objects, Aggregates, Domain Services, Domain Events, Repositories, Factories. - Read
references/strategic-design.mdfor Subdomains (Core/Supporting/Generic), Bounded Contexts, and Ubiquitous Language. - Read
references/context-mapping.mdfor Context Map patterns: Partnership, Shared Kernel, Customer-Supplier, Conformist, ACL, Open Host Service, Published Language. - Read
references/cqrs-and-events.mdfor CQRS, Event Sourcing, Event Storming, and process managers. - Read
references/hexagonal-architecture.mdfor Ports & Adapters: primary/driven ports, adapters, dependency direction, test strategy, Walking Skeleton implementation, and comparison with Clean/Onion Architecture. - Read
references/ddd-in-practice.mdfor practical DDD application: discovery process (Impact Mapping, Model Exploration Whirlpool), team topology, DDD adoption anti-patterns, and PHP implementation examples (Value Objects, Entities, Aggregate Root, Application Service, Specification). - Read
references/domain-errors.mdfor failure taxonomy and ownership, Option vs Result/Either vs exception decisions, stable codes, exhaustive composition, state atomicity, and safe boundary translation. - Read
references/read-models.mdfor aggregate-derived DTOs vs dedicated read models, CQRS query shapes, projection handlers, atomic idempotency, missing event data, incremental updates, and shadow rebuilds. - Read
references/typescript-ddd-examples.mdfor the TypeScript DDD skeleton: folder structure by Bounded Context, explicit Value Objects, AggregateRoot/DomainEvent examples, creation vs reconstitution strategies, use case structure, CommandBus/QueryBus, Object Mother, and Criteria pattern. - Read
references/go-ddd-examples.mdfor DDD in Go: folder structure by Bounded Context, Value Objects, Aggregate Root with unexported fields, Domain Events, Repository interface (port) vs implementation (adapter), Use Case, ACL, CQRS query side, Domain Service.
Related Skills
- Use
oop-best-practicesfor detailed Value Object construction, equality, immutability, optionality, persistence, and everyday object design within a Bounded Context. - Use
design-patterns-best-practicesfor GoF and enterprise patterns inside the domain. - Use
refactoring-best-practiceswhen evolving an existing domain model safely. - Use
tdd-best-practicesfor invariant-first Aggregate tests, deterministic fixtures, and concurrency integration tests. - Use
infrastructure-designfor transaction boundaries, optimistic locking, and reliable Outbox implementation. - Use
rest-api-best-practiceswhen exposing the domain through an HTTP API and translating domain errors to status codes.
Source Influences
This skill is synthesized from:
- Domain-Driven Design by Eric Evans (the blue book)
- Implementing Domain-Driven Design by Vaughn Vernon
- Domain-Driven Design Distilled by Vaughn Vernon
- Learning Domain-Driven Design by Vladik Khononov
- Patterns, Principles, and Practices of Domain-Driven Design by Scott Millett & Nick Tune
- Hexagonal Architecture Explained by Alistair Cockburn & Juan Manuel Garrido de Paz
- DDD in PHP (community resource)
- CodelyTV Aggregates course
- CodelyTV Repository Pattern course (including production counterexamples)
- CodelyTV Domain Events course (including modeling and delivery counterexamples)
- CodelyTV Domain Modeling Errors course (including Optional, Result, Effect, exhaustivity, and boundary counterexamples)
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: luckys
- Source: luckys/agent-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.