ddd

┌─────────────────┐ ┌─────────────────┐ │ Order Context │────▶│ Payment Context │ │ (core domain) │ │ (supporting) │ └────────┬────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Inventory Context│ │ Notification Ctx │ │ (supporting) │ │ (generic) │ └─────────────────┘ └─────────────────┘

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "ddd" with this command: npx skills add claude-dev-suite/claude-dev-suite/claude-dev-suite-claude-dev-suite-ddd

Domain-Driven Design

Strategic DDD

┌─────────────────┐ ┌─────────────────┐ │ Order Context │────▶│ Payment Context │ │ (core domain) │ │ (supporting) │ └────────┬────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Inventory Context│ │ Notification Ctx │ │ (supporting) │ │ (generic) │ └─────────────────┘ └─────────────────┘

Tactical DDD (TypeScript)

Entity

class Order { private constructor( readonly id: OrderId, private items: OrderItem[], private status: OrderStatus, private readonly createdAt: Date, ) {}

static create(items: OrderItem[]): Order { if (items.length === 0) throw new DomainError('Order must have at least one item'); return new Order(OrderId.generate(), items, OrderStatus.PENDING, new Date()); }

get total(): Money { return this.items.reduce((sum, item) => sum.add(item.subtotal), Money.zero('USD')); }

confirm(): DomainEvent[] { if (this.status !== OrderStatus.PENDING) throw new DomainError('Can only confirm pending orders'); this.status = OrderStatus.CONFIRMED; return [new OrderConfirmed(this.id, this.total)]; } }

Value Object

class Money { private constructor(readonly amount: number, readonly currency: string) { if (amount < 0) throw new DomainError('Amount cannot be negative'); }

static of(amount: number, currency: string): Money { return new Money(Math.round(amount * 100) / 100, currency); }

static zero(currency: string): Money { return new Money(0, currency); }

add(other: Money): Money { if (this.currency !== other.currency) throw new DomainError('Currency mismatch'); return Money.of(this.amount + other.amount, this.currency); }

equals(other: Money): boolean { return this.amount === other.amount && this.currency === other.currency; } }

Domain Event

class OrderConfirmed implements DomainEvent { readonly occurredAt = new Date(); constructor(readonly orderId: OrderId, readonly total: Money) {} }

Repository (Port)

interface OrderRepository { findById(id: OrderId): Promise<Order | null>; save(order: Order): Promise<void>; nextId(): OrderId; }

Application Service

class ConfirmOrderUseCase { constructor( private orders: OrderRepository, private eventBus: EventBus, ) {}

async execute(orderId: string): Promise<void> { const order = await this.orders.findById(OrderId.from(orderId)); if (!order) throw new NotFoundError('Order', orderId);

const events = order.confirm();
await this.orders.save(order);
await this.eventBus.publishAll(events);

} }

DDD Building Blocks

Building Block Purpose Identity? Mutable?

Entity Domain object with identity Yes (ID) Yes

Value Object Immutable descriptor No (structural equality) No

Aggregate Consistency boundary Root entity has ID Yes (via root)

Domain Event Something that happened Event ID No

Repository Persistence abstraction N/A N/A

Domain Service Logic not belonging to entity N/A N/A

Anti-Patterns

Anti-Pattern Fix

Anemic domain model (logic in services) Put business logic in entities

Aggregate too large Keep aggregates small, reference by ID

Exposing entity internals Use methods that express domain intent

Cross-aggregate transactions Use domain events for eventual consistency

Repository returning DTOs Return domain objects, map in application layer

Production Checklist

  • Bounded contexts identified and documented

  • Ubiquitous language in code matches business terms

  • Aggregates enforce invariants

  • Value objects for all descriptors (Money, Email, Address)

  • Domain events for cross-context communication

  • Repository pattern for persistence abstraction

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

cron-scheduling

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

token-optimization

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

webrtc

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

react-19

No summary provided by upstream source.

Repository SourceNeeds Review