agentleFS
luckysluckys/agent-skills/skills/ddd-best-practices/SKILL.md

ddd-best-practices

Skill5 starsChanged 30 days agoMITView on GitHub

Use when modeling domain language, subdomains, bounded contexts, aggregates and invariants, value objects, domain events, typed domain failures, repository contracts, cross-aggregate consistency, context integration, CQRS, Event Sourcing, or hexagonal architecture. Focuses on domain ownership and consistency; use infrastructure guidance for delivery, storage, and transaction mechanisms.

The file

Show its rules and text

We split this skill into the rules it gives an agent

32 rules. About 0 are common, 11 are distinctive, and 21 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈11

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 21

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when the main question is how to model a domain, where to draw boundaries, or how to structure collaboration between …

    line 12
  2. Distinctive:

    Start from the domain problem, not from technical constructs.

    line 16
  3. Distinctive:

    Keep Aggregates small — consistency boundary, not convenience grouping.

    line 18
  4. Distinctive:

    Prefer Value Objects when a domain concept has value semantics, not as a blanket wrapper for every primitive.

    line 19
  5. Distinctive:

    Never let infrastructure concerns leak into the domain model.

    line 21
  6. Distinctive:

    Start from one business command and state the invariants it must preserve.

    line 36
  7. Distinctive:

    Check lifecycle, cardinality, contention, and concurrency.

    line 41
  8. Distinctive:

    Use Anti-Corruption Layers when consuming upstream models you don't control.

    line 53
  9. Distinctive:

    If a recognized business invariant requires two objects to commit or reject together, they likely belong in the same Aggregate.

    line 62
  10. Distinctive:

    If you track it over time or need to distinguish between two instances with the same data, it's an Entity.

    line 65
  11. Distinctive:

    If a significant domain operation doesn't naturally belong to any Entity or Value Object, it belongs in a Domain Service — but use …

    line 68
  12. Very specific:

    Prefer a specific semantic fact such as UserArchived over generic UserUpdated or StatusChanged.

    line 72
  13. Very specific:

    Read references/aggregates.md for Aggregate discovery, boundary signals, rule ownership, creation vs.

    line 98
  14. Very specific:

    Read references/repositories.md for repository semantics, contract ownership, Repository vs DAO/query service/gateway, absence, mapping, …

    line 99
  15. Very specific:

    Read references/domain-events.md for event semantics, granularity, payload/envelope design, aggregate recording, creation vs …

    line 100
  16. Very specific:

    Read references/model-evidence.md when resolving terminology, ownership, lifecycle states, or a consequential domain decision.

    line 101
  17. Very specific:

    Read references/tactical-patterns.md for Entities, Value Objects, Aggregates, Domain Services, Domain Events, Repositories, Factories.

    line 103
  18. Very specific:

    Read references/strategic-design.md for Subdomains (Core/Supporting/Generic), Bounded Contexts, and Ubiquitous Language.

    line 104
  19. Very specific:

    Read references/context-mapping.md for Context Map patterns: Partnership, Shared Kernel, Customer-Supplier, Conformist, ACL, Open Host …

    line 105
  20. Very specific:

    Read references/cqrs-and-events.md for CQRS, Event Sourcing, Event Storming, and process managers.

    line 106
  21. Very specific:

    Read references/hexagonal-architecture.md for Ports & Adapters: primary/driven ports, adapters, dependency direction, test strategy, …

    line 107
  22. Very specific:

    Read references/ddd-in-practice.md for practical DDD application: discovery process (Impact Mapping, Model Exploration Whirlpool), team …

    line 108
  23. Very specific:

    Read references/domain-errors.md for failure taxonomy and ownership, Option vs Result/Either vs exception decisions, stable codes, …

    line 109
  24. Very specific:

    Read references/read-models.md for aggregate-derived DTOs vs dedicated read models, CQRS query shapes, projection handlers, atomic …

    line 110
  25. Very specific:

    Read references/typescript-ddd-examples.md for the TypeScript DDD skeleton: folder structure by Bounded Context, explicit Value Objects, …

    line 111
  26. Very specific:

    Read references/go-ddd-examples.md for DDD in Go: folder structure by Bounded Context, Value Objects, Aggregate Root with unexported …

    line 112
  27. Very specific:

    Use oop-best-practices for detailed Value Object construction, equality, immutability, optionality, persistence, and everyday object design …

    line 116
  28. Very specific:

    Use design-patterns-best-practices for GoF and enterprise patterns inside the domain.

    line 117
  29. Very specific:

    Use refactoring-best-practices when evolving an existing domain model safely.

    line 118
  30. Very specific:

    Use tdd-best-practices for invariant-first Aggregate tests, deterministic fixtures, and concurrency integration tests.

    line 119
  31. Very specific:

    Use infrastructure-design for transaction boundaries, optimistic locking, and reliable Outbox implementation.

    line 120
  32. Very specific:

    Use rest-api-best-practices when exposing the domain through an HTTP API and translating domain errors to status codes.

    line 121

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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?
  2. 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.).
  3. 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.
    • Enforce invariants within the Aggregate boundary only.
    • Reference other Aggregates by identity, never by object reference, and make eventual consistency explicit.
    • Check lifecycle, cardinality, contention, and concurrency; table count does not define the consistency boundary.
  4. 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.
  5. 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/model-evidence.md when resolving terminology, ownership, lifecycle states, or a consequential domain decision.
  • 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)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.