agentsclimarketplace

Ddd refactor

Skill radkomih/claude-code-ext/plugins/ddd-refactor/skills/ddd-refactor

Claude Code Plugins

Install
npx -y skills add radkomih/claude-code-ext --skill ddd-refactor

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Analyzes and refactors code using Domain-Driven Design principles. Use whenever the user mentions domain models, bounded contexts, aggregates, anemic models, ubiquitous language, or DDD — and also when you notice business logic leaking into services, missing domain events, or unclear ownership of business rules, even if the user doesn't explicitly ask for DDD.

SKILL.md

13.4 KB, ~2.9k tokens by cl100k_base, as published. Nobody here has run it

DDD Refactor Skill

Comprehensive Domain-Driven Design refactoring framework based on Eric Evans' DDD principles.

Prerequisites

Always read resources/ddd-principles.json (in this skill's directory) before starting.

This JSON contains 19+ principles with definitions, code smells, and refactoring guidance.

Refactoring Approach

Four-Phase Strategy

Phase 1: Discovery & Analysis (15-20 min)

Understand the Domain:

  1. Identify core domain vs supporting/generic subdomains
  2. Map existing bounded contexts (explicit or implicit)
  3. Document current ubiquitous language usage
  4. Analyze domain model structure

Scan for Code Smells:

  • Anemic domain models (all logic in services)
  • Missing ubiquitous language (technical jargon)
  • Blurred bounded context boundaries
  • Mutable value objects
  • Large aggregates without clear boundaries
  • Domain logic in application/infrastructure layers
  • Missing domain events
  • Repositories exposing internal entities
  • Bidirectional dependencies across contexts

Technical Exploration — search the codebase for:

  • Pattern class.*Entity in *.{js,ts,java,cs,py} files — find potential entities
  • Pattern class.*Service — find service classes that may contain misplaced domain logic
  • Pattern Repository — find existing repositories
  • Pattern Event — find domain events (or identify their absence)

Phase 2: Strategic Refactoring Plan (10-15 min)

Based on loaded DDD principles:

  1. Define Bounded Contexts

    • Map natural domain boundaries
    • Identify context relationships (Shared Kernel, Customer-Supplier, etc.)
    • Plan integration strategies
  2. Establish Ubiquitous Language

    • List terms needing renaming
    • Extract implicit concepts into explicit models
    • Create domain glossary
  3. Prioritize Refactoring

    • Critical: Core domain models, aggregate boundaries, data consistency
    • High: Entity/Value Object patterns, domain events, repositories
    • Medium: Services, factories, layering
    • Low: Supporting subdomains, infrastructure

Phase 3: Tactical Pattern Application (30-45 min)

Apply patterns systematically:

1. Entities - Identity-based objects

  • Extract objects with lifecycle and identity
  • Add identity equality (not value equality)
  • Encapsulate business rules within entities
  • Make state changes explicit through methods

2. Value Objects - Immutable descriptive objects

  • Convert primitive obsession to value objects
  • Make all value objects immutable
  • Implement value-based equality
  • Create self-validating value objects

3. Aggregates - Consistency boundaries

  • Group related entities under aggregate roots
  • Enforce invariants at aggregate boundaries
  • Make internal entities inaccessible from outside
  • Use aggregate roots for all external access

4. Domain Events - Significant occurrences

  • Identify state changes that matter to the domain
  • Publish events from aggregates after state changes
  • Use events to decouple bounded contexts
  • Record event history for audit/debugging

5. Repositories - Aggregate persistence

  • Create repositories only for aggregate roots
  • Return reconstituted aggregates (not raw data)
  • Abstract all storage concerns
  • Use specification pattern for complex queries

6. Domain Services - Stateless operations

  • Extract operations that don't belong to any entity
  • Keep services thin (orchestration, not logic)
  • Separate Domain/Application/Infrastructure services
  • Make service operations explicit domain concepts

7. Factories - Complex creation

  • Encapsulate complex aggregate construction
  • Hide creation details from clients
  • Ensure invariants are met at creation
  • Provide convenient creation methods

8. Layered Architecture

  • Move domain logic from controllers to domain layer
  • Isolate external systems with anti-corruption layers
  • Ensure dependencies point inward (domain is innermost)
  • Keep domain layer free of infrastructure concerns

Phase 4: Validation & Testing (10-15 min)

Verify Improvements:

  • Ubiquitous language is reflected in code
  • Business rules are explicit and testable
  • Bounded contexts have clear boundaries
  • Aggregates enforce their invariants
  • Domain events capture significant changes
  • Repositories work with aggregate roots
  • Domain layer is free of infrastructure
  • Integration points are explicit and controlled

Testing Strategy:

  • Unit test entity/value object logic
  • Test aggregate invariant enforcement
  • Test domain event publication
  • Integration test repositories
  • Test anti-corruption layers

Core DDD Principles Reference

Strategic Design

  1. Ubiquitous Language - Domain vocabulary in code
  2. Bounded Context - Explicit model boundaries
  3. Context Map - Relationships between contexts
  4. Continuous Integration - Prevent fragmentation

Tactical Patterns

  1. Entity - Identity-based objects with lifecycle
  2. Value Object - Immutable, attribute-based objects
  3. Aggregate - Consistency boundary and transaction scope
  4. Repository - Collection-like access to aggregates
  5. Factory - Complex object creation
  6. Domain Service - Stateless domain operations
  7. Domain Event - Record of domain occurrence

Architecture

  1. Layered Architecture - Separation of concerns
  2. Anti-Corruption Layer - Isolation from external systems

Context Mapping

  1. Shared Kernel - Explicit sharing between contexts
  2. Customer-Supplier - Upstream-downstream relationship
  3. Conformist - Adopt upstream model
  4. Open Host Service - Standardized API
  5. Published Language - Documented interchange format

Code Smell Detection Checklist

Strategic Anti-Patterns

  • No explicit bounded contexts
  • Technical names instead of domain language
  • Mixed business logic across contexts
  • No context integration strategy
  • Same entity meaning different things in different places

Tactical Anti-Patterns

  • Anemic domain model (getters/setters only)
  • Entities without clear identity
  • Mutable value objects
  • Large aggregates (>5-7 entities)
  • Repositories for non-root entities
  • Domain logic in services instead of entities
  • No domain events for state changes
  • Primitive obsession (no value objects)

Architecture Anti-Patterns

  • Domain logic in controllers/UI
  • Direct database access from domain
  • No anti-corruption layer for external systems
  • Infrastructure concerns in domain layer
  • Bidirectional dependencies between contexts

Output Format

1. Anti-Pattern Identified

File: src/orders/OrderService.java:45-78
Smell: Anemic domain model - Order entity has only getters/setters
Principle Violated: Entity Pattern
Impact: Business logic scattered in services, hard to test and maintain

2. DDD Principle to Apply

Principle: Entity (from ddd-principles.json)
Category: Tactical Pattern
Key Point: Entities should encapsulate business rules and behavior
When to Apply: Objects with identity that change over time

3. Refactoring Steps

Step 1: Move validation logic from OrderService to Order entity
Step 2: Add domain methods: order.cancel(), order.ship(), order.addItem()
Step 3: Enforce invariants within entity methods
Step 4: Raise domain events for significant state changes
Step 5: Update OrderService to orchestrate, not contain logic

4. Code Example

// BEFORE: Anemic Domain Model (Anti-pattern)
class Order {
  private id: string;
  private items: OrderItem[];
  private status: string;

  // Only getters and setters
  getId(): string { return this.id; }
  getStatus(): string { return this.status; }
  setStatus(status: string): void { this.status = status; }
}

class OrderService {
  cancelOrder(order: Order): void {
    // Business logic in service layer
    if (order.getStatus() === 'SHIPPED') {
      throw new Error('Cannot cancel shipped order');
    }
    order.setStatus('CANCELLED');
    this.emailService.sendCancellationEmail(order);
  }
}

// AFTER: Rich Domain Model (DDD Pattern)
class Order {
  private id: OrderId;
  private items: OrderItem[];
  private status: OrderStatus;
  private events: DomainEvent[] = [];

  constructor(id: OrderId, items: OrderItem[]) {
    this.id = id;
    this.items = items;
    this.status = OrderStatus.PENDING;
  }

  // Business logic in entity
  cancel(): void {
    if (!this.canBeCancelled()) {
      throw new OrderCannotBeCancelledException(
        'Cannot cancel order in status: ' + this.status
      );
    }
    this.status = OrderStatus.CANCELLED;
    this.recordEvent(new OrderCancelled(this.id, new Date()));
  }

  private canBeCancelled(): boolean {
    return this.status !== OrderStatus.SHIPPED
        && this.status !== OrderStatus.DELIVERED;
  }

  getDomainEvents(): DomainEvent[] {
    return [...this.events];
  }

  private recordEvent(event: DomainEvent): void {
    this.events.push(event);
  }
}

// Service becomes thin orchestrator
class OrderService {
  constructor(
    private orderRepository: OrderRepository,
    private eventBus: EventBus
  ) {}

  async cancelOrder(orderId: string): Promise<void> {
    const order = await this.orderRepository.findById(orderId);

    order.cancel(); // Domain logic stays in domain

    await this.orderRepository.save(order);

    // Publish events for other bounded contexts
    order.getDomainEvents().forEach(event => {
      this.eventBus.publish(event);
    });
  }
}

5. Impact Assessment

Benefits:

  • Business rules are explicit and self-documenting
  • Order enforces its own invariants
  • Easier to test (unit test the entity)
  • Domain events enable loose coupling
  • Service layer is thin and focused

Metrics:

  • Reduced cyclomatic complexity in services
  • Increased testability (pure domain logic)
  • Better domain language alignment
  • Clearer responsibility boundaries

Language-Specific Patterns

TypeScript/JavaScript

// Value Object with immutability
class Money {
  constructor(
    private readonly amount: number,
    private readonly currency: string
  ) {
    if (amount < 0) throw new Error('Amount cannot be negative');
  }

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

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

Java

// Aggregate with encapsulation
public class Order {
  private final OrderId id;
  private final List<OrderLine> lines;
  private OrderStatus status;

  // Package-private constructor (use factory)
  Order(OrderId id) {
    this.id = Objects.requireNonNull(id);
    this.lines = new ArrayList<>();
    this.status = OrderStatus.DRAFT;
  }

  public void addLine(Product product, Quantity quantity) {
    if (this.status != OrderStatus.DRAFT) {
      throw new OrderAlreadySubmittedException();
    }
    this.lines.add(new OrderLine(product, quantity));
  }

  // Factory method
  public static Order create(OrderId id) {
    return new Order(id);
  }
}

Python

from dataclasses import dataclass
from typing import List

# Value Object with frozen dataclass
@dataclass(frozen=True)
class EmailAddress:
    value: str

    def __post_init__(self):
        if '@' not in self.value:
            raise ValueError('Invalid email address')

# Entity with behavior
class Customer:
    def __init__(self, customer_id: str, email: EmailAddress):
        self._id = customer_id
        self._email = email
        self._events: List[DomainEvent] = []

    def change_email(self, new_email: EmailAddress) -> None:
        if self._email != new_email:
            old_email = self._email
            self._email = new_email
            self._events.append(
                EmailChanged(self._id, old_email, new_email)
            )

Best Practices

Do

  • Start with the domain model, not the database
  • Use domain language everywhere (code, tests, docs)
  • Make implicit concepts explicit
  • Favor immutability where possible
  • Test domain logic in isolation
  • Keep aggregates small (2-5 entities max)
  • Use domain events for inter-context communication
  • Apply anti-corruption layers for external systems

Don't

  • Don't let infrastructure drive the domain model
  • Don't skip domain events for significant changes
  • Don't make value objects mutable
  • Don't expose aggregate internals
  • Don't create repositories for non-aggregate roots
  • Don't put domain logic in services
  • Don't share entities across bounded contexts
  • Don't over-engineer - apply DDD where complexity justifies it

Resources

  • DDD Principles: See resources/ddd-principles.json for complete definitions
  • Checklist: See CHECKLIST.md for full anti-pattern list
  • Book: "Domain-Driven Design" by Eric Evans

Workflow Integration

This skill can be:

  • Invoked from /refactor command
  • Used by ddd-analyzer agent for autonomous analysis
  • Triggered by pre-commit hooks to check for anti-patterns
  • Called from other skills for domain model improvements

Gives 0 of the 12 instructions most refactoring skills give in ~2.9k tokens

Counted across 521 of the 525 authors here whose files we hold, read 2026-08-06

  • run tests after each changein 59 of 521, across 56 files
  • write tests before refactoringin 27 of 521, across 24 files
  • preserve external behaviorin 26 of 521, across 22 files
  • remove dead codein 25 of 521, across 24 files
  • make small incremental changesin 20 of 521, across 17 files
  • break the implementation into tiny commitsin 18 of 521, across 5 files
  • ask the user about alternative optionsin 17 of 521, across 4 files
  • create a GitHub issue with the planin 17 of 521, across 4 files
  • explore the repository to verify assertionsin 17 of 521, across 4 files
  • interview the user about the refactorin 16 of 521, across 3 files
  • check the codebase for test coveragein 16 of 521, across 3 files
  • refactor one thing at a timein 16 of 521, across 12 files

Said here and by no other author read

  • Read DDD principles before starting
  • Identify core domain versus subdomains
  • Map existing bounded contexts
  • Search codebase for domain patterns
  • List terms needing renaming for ubiquitous language
  • Prioritize core domain model refactoring

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.