Help us improve
Share bugs, ideas, or general feedback.
From tsal
Guides domain modeling with Rich Hickey's data-oriented and Scott Wlaschin's type-driven design principles. Contextualizes models, identifies inconsistencies, builds ubiquitous language, generates Mermaid/Graphviz/ASCII diagrams for types and business domains.
npx claudepluginhub bfollington/terma --plugin tsalHow this skill is triggered — by the user, by Claude, or both
Slash command
/tsal:domain-driven-designThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill provides guidance for domain modeling based on Rich Hickey's data-oriented design principles and Scott Wlaschin's type-driven design approach. Focus on building systems that make illegal states unrepresentable, prioritize data and transformations over objects and methods, and establish a ubiquitous language that bridges technical implementation and business domain.
Apply DDD principles to model business domains, design aggregates, and establish clear language across teams. Use when modeling complex business logic or integrating domain experts.
Guides Domain-Driven Design for complex business logic: aggregates, bounded contexts, ubiquitous language, value objects, entities, and TypeScript implementations with invariants.
Models software around business domains using bounded contexts, aggregates, and ubiquitous language. Guides splitting monoliths into services and aligning code with business processes.
Share bugs, ideas, or general feedback.
This skill provides guidance for domain modeling based on Rich Hickey's data-oriented design principles and Scott Wlaschin's type-driven design approach. Focus on building systems that make illegal states unrepresentable, prioritize data and transformations over objects and methods, and establish a ubiquitous language that bridges technical implementation and business domain.
Simplicity over Ease
Data is King
Value of Values
Decomplecting
Make Illegal States Unrepresentable
Domain Modeling Made Functional
Railway-Oriented Programming
Types as Documentation
Entities are defined by identity, not attributes:
Value Objects are defined entirely by attributes:
Decision Guide:
Aggregate: A cluster of entities and value objects treated as a single unit for data changes.
Aggregate Root: The single entity through which all external access to the aggregate must pass.
Purpose:
Rules:
When NOT to create an aggregate:
Definition: An explicit boundary within which a domain model applies.
Purpose:
Key Insight: Ubiquitous language is only ubiquitous within a context. "Customer" in Sales context may be different from "Customer" in Shipping context.
When modeling:
Definition: Something important that happened in the domain.
Characteristics:
Uses:
Purpose: Provide illusion of an in-memory collection of aggregates, abstracting persistence.
Characteristics:
Pattern: Application layer uses repository to get/save aggregates; domain layer remains pure.
Start by identifying the domain concepts, using terminology from domain experts:
Action Items:
Output Format: Create a glossary section documenting each term:
**Term** (Type: Entity/ValueObject/Event/Command)
- Definition: [Clear, domain-expert-approved definition]
- Examples: [Concrete examples]
- Invariants: [Rules that must always hold]
Before making changes, understand the current state:
Exploration Steps:
Questions to Answer:
Common problems to surface:
Naming Inconsistencies
Structural Problems
status: "approved" | "rejected" with separate approved_at and rejected_at fields that can both be set)Complected Concerns
Missing Concepts
Apply type-driven and data-driven principles:
Data Modeling:
Type Design:
type PaymentStatus =
| Pending
| Approved { approvedAt: Timestamp, approvedBy: UserId }
| Rejected { rejectedAt: Timestamp, reason: string }
type EmailAddress = EmailAddress of string // with validation
type Money = { amount: Decimal, currency: Currency }
Workflow Modeling:
ValidateInput → ExecuteBusinessLogic → HandleResult → Persist → Notify
Consistency Rules:
Code Conventions:
Documentation:
Use diagrams to communicate domain structure and relationships:
Mermaid for Relationships:
classDiagram
Order --> Customer
Order --> OrderLine
OrderLine --> Product
Order --> PaymentStatus
class Order {
+OrderId id
+CustomerId customerId
+List~OrderLine~ lines
+PaymentStatus status
}
class PaymentStatus {
<<enumeration>>
Pending
Approved
Rejected
}
Mermaid for Workflows:
graph LR
A[Receive Order] --> B{Valid?}
B -->|Yes| C[Calculate Total]
B -->|No| D[Return Validation Error]
C --> E[Process Payment]
E --> F{Payment Success?}
F -->|Yes| G[Fulfill Order]
F -->|No| H[Cancel Order]
Mermaid for State Transitions:
stateDiagram-v2
[*] --> Draft
Draft --> Submitted: submit()
Submitted --> Approved: approve()
Submitted --> Rejected: reject()
Approved --> Fulfilled: fulfill()
Fulfilled --> [*]
Rejected --> [*]
Graphviz/DOT for Complex Relationships:
digraph domain {
rankdir=LR;
node [shape=box];
Customer -> Order [label="places"];
Order -> OrderLine [label="contains"];
OrderLine -> Product [label="references"];
Order -> Payment [label="requires"];
Payment -> PaymentMethod [label="uses"];
}
ASCII for Quick Sketches:
Customer
└─> Order (1:N)
├─> OrderLine (1:N)
│ └─> Product
└─> Payment (1:1)
└─> PaymentMethod
When to Use Each:
Anemic Domain Model
Entity Services Anti-Pattern
UserService, OrderManager, ProductFactoryapproveOrder, cancelSubscription, calculateDiscountPrimitive Obsession
Accidental Complexity
Hidden Temporal Coupling
Boolean Blindness
When adding to or changing an existing domain model:
Key Questions:
Before completing domain modeling work:
Language & Communication:
Type Design:
Domain Logic:
Aggregates & Boundaries:
Consistency & Integration:
Documentation:
This skill includes reference documentation for deeper exploration:
ddd_foundations_and_patterns.md: Eric Evans' foundational DDD concepts (entities, value objects, aggregates, bounded contexts, repositories, domain events), Martin Fowler's Ubiquitous Language guidance, and practical Clojure/functional patterns. Essential reading for understanding DDD building blocks and how to apply them.
rich_hickey_principles.md: Core concepts from Rich Hickey's talks including Simple Made Easy, Value of Values, and The Language of the System. Focus on data-oriented design, simplicity, decomplecting, and the power of immutable values.
wlaschin_patterns.md: Scott Wlaschin's type-driven design patterns, domain modeling recipes, functional architecture guidance, and railway-oriented programming. Emphasis on making illegal states unrepresentable and designing with types.
visualization_examples.md: Comprehensive examples of Mermaid, Graphviz, and ASCII diagram patterns for domain modeling. Includes entity relationships, workflows, state machines, aggregate boundaries, and bounded context maps.
Load these references when deeper context is needed on specific principles or patterns.