domain-driven-design

Implements Domain-Driven Design patterns for TypeScript including aggregates, value objects, and bounded contexts.

Updated May 18, 2024
One-click install
npx skills add https://github.com/joshhornby/dotfiles --skill domain-driven-design-joshhornby
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: domain-driven-design
Source: https://github.com/joshhornby/dotfiles/tree/main/.claude/skills/domain-driven-design
Command: npx skills add https://github.com/joshhornby/dotfiles --skill domain-driven-design-joshhornby

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve? Applying Domain-Driven Design in TypeScript is error-prone: teams build anemic models, oversized aggregates, and leaky layers. This Skill provides concrete patterns and decision frameworks for modeling complex business domains correctly. ## Core Features & Use Cases - Building Blocks: Guidance for value objects, branded types, entities, aggregates, specifications, and domain services with immutable, always-valid TypeScript patterns. - Strategic Design: Bounded context discovery, context mapping (ACL, shared kernel), and glossary-driven ubiquitous language enforcement. - Tactical Decisions: Error modeling with discriminated unions, domain events with the Decider pattern, repository placement, and TDD integration by domain concept. - Use Case: When implementing a pledge feature in a gifting app, use this Skill to model the Occasion aggregate, enforce budget invariants through the root, and return explicit PledgeDecision results instead of throwing exceptions. ## Quick Start Ask the AI to apply the domain-driven-design skill to model a new aggregate with its invariants and domain events in your TypeScript project.

Frequently Asked Questions about domain-driven-design

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I design aggregates in TypeScript with DDD?

Design aggregates from invariants, not entity relationships. Include only the data needed to enforce consistency rules during state changes, reference other aggregates by ID, and modify one aggregate per transaction. Accept child IDs rather than child objects in root methods.

What is the difference between a domain service and a use case?

A domain service contains business logic operating on domain types, like pledgeContribution. A use case is application orchestration only: it loads aggregates via repositories, calls domain services, and saves results. You can tell them apart by their signatures.

When should I use domain events versus explicit return values?

Use explicit return values when side effects stay within one aggregate or transaction. Add domain events when side effects cross aggregate boundaries, other bounded contexts must react, or you need an audit trail. Start without events and add them when coordination demands it.

Should I use exceptions or result types for business errors in TypeScript?

Use discriminated union result types for expected business outcomes like rule violations, since the compiler enforces exhaustive handling. Reserve exceptions for programmer mistakes, invariant violations, and infrastructure failures that no business rule can handle.

When should I not use Domain-Driven Design?

Avoid DDD for simple CRUD applications with no business rules, technical or infrastructure-focused projects, and projects without access to a domain expert. Start with a glossary and value objects, adding aggregates and bounded contexts only when domain complexity demands them.