AgentStack
SKILL verified MIT Self-run

Ddd Best Practices

skill-luckys-agent-skills-ddd-best-practices · by luckys

Domain-Driven Design guidance for modeling complex domains. Use when designing Bounded Contexts or Subdomains, discovering Aggregate boundaries from invariants and transactions, defining Aggregate Roots, designing Domain Events, typed domain failures, or repository contracts, choosing exception vs Result/Either/Option semantics, choosing Repository vs DAO/query service/gateway, splitting oversize…

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-luckys-agent-skills-ddd-best-practices

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

Are you the author of Ddd Best Practices? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

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

  1. Start from the domain problem, not from technical constructs.
  2. Build a Ubiquitous Language before writing any code.
  3. Keep Aggregates small — consistency boundary, not convenience grouping.
  4. Prefer Value Objects when a domain concept has value semantics, not as a blanket wrapper for every primitive.
  5. Let Domain Events tell the story of what happened, not what to do next.
  6. Never let infrastructure concerns leak into the domain model.

Design Workflow

  1. 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?
  1. 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.).
  1. 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.
  1. 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.
  1. 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.md for Aggregate discovery, boundary signals, rule ownership, creation vs. reconstitution, concurrency, cross-Aggregate coordination, persistence, and review checklists.
  • Read references/repositories.md for repository semantics, contract ownership, Repository vs DAO/query service/gateway, absence, mapping, transactions, caching, pagination, testing, and legacy migration.
  • Read references/domain-events.md for event semantics, granularity, payload/envelope design, aggregate recording, creation vs reconstitution, Integration Event translation, subscribers, and delivery boundaries.
  • Read references/tactical-patterns.md for Entities, Value Objects, Aggregates, Domain Services, Domain Events, Repositories, Factories.
  • Read references/strategic-design.md for Subdomains (Core/Supporting/Generic), Bounded Contexts, and Ubiquitous Language.
  • Read references/context-mapping.md for Context Map patterns: Partnership, Shared Kernel, Customer-Supplier, Conformist, ACL, Open Host Service, Published Language.
  • Read references/cqrs-and-events.md for CQRS, Event Sourcing, Event Storming, and process managers.
  • Read references/hexagonal-architecture.md for Ports & Adapters: primary/driven ports, adapters, dependency direction, test strategy, Walking Skeleton implementation, and comparison with Clean/Onion Architecture.
  • Read references/ddd-in-practice.md for 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.md for 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.md for 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.md for 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.md for 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-practices for detailed Value Object construction, equality, immutability, optionality, persistence, and everyday object design within a Bounded Context.
  • Use design-patterns-best-practices for GoF and enterprise patterns inside the domain.
  • Use refactoring-best-practices when evolving an existing domain model safely.
  • Use tdd-best-practices for invariant-first Aggregate tests, deterministic fixtures, and concurrency integration tests.
  • Use infrastructure-design for transaction boundaries, optimistic locking, and reliable Outbox implementation.
  • Use rest-api-best-practices when 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.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.