nWave/skills/nw-legacy-refactoring-ddd/SKILL.md
DDD-guided legacy refactoring patterns -- strangler fig, bubble context, ACL migration, 14 tactical/strategic/infrastructure patterns, and incremental monolith-to-microservices methodology
npx skillsauth add nwave-ai/nwave nw-legacy-refactoring-dddInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Refactoring legacy systems using Domain-Driven Design as the strategic compass. DDD tells you WHERE and WHY to refactor; traditional techniques (progressive-refactoring, mikado-method) tell you HOW.
Principle: "Start simple, grow big" -- incremental steps tested at each stage.
Ask three questions before any DDD refactoring:
| Cynefin Domain | Refactoring Approach | |---------------|---------------------| | Clear | Apply established patterns directly; standard refactoring catalogs | | Complicated | Analyze with experts, then apply patterns; multiple valid solutions | | Complex | Probe with safe-to-fail experiments; EventStorming to discover patterns | | Chaotic | Act first to stabilize, then refactor; emergency patches acceptable | | Confusion | Gather information before deciding; avoid premature refactoring |
Build new DDD-modeled functionality alongside legacy. Route requests to new code as features complete. Legacy gradually shrinks until fully replaced. Changes are incremental, monitored, low risk of unexpected breakage.
Mikado integration: use Mikado exploration to discover dependencies between legacy components before extracting. Each Mikado leaf becomes an atomic refactoring step.
Create a small bounded context (the "bubble") where DDD principles apply. The bubble communicates with legacy through an Anti-Corruption Layer. Progressively expand the bubble to encompass more legacy functionality.
Steps:
Integration patterns change as refactoring progresses. Map current relationships, identify mismatches, propose new patterns. Typical evolution: Conformist -> Customer-Supplier with ACL -> Partnership.
When a context grows too large or serves conflicting purposes:
Validation: bounded context splits are driven by business evolution, not technical convenience. Validate with domain experts.
When separation causes more friction than value:
These patterns apply tactical DDD concepts (aggregates, value objects, domain events, domain services, CQRS) to refactoring. For foundational definitions and design rules, load domain-driven-design from solution-architect/.
| Pattern | What It Fixes | Key Step | |---------|--------------|----------| | Replace primitives with VOs | Primitive obsession | Create self-validating type, replace in aggregate, update mapping | | Enrich anemic model | Logic in services, data in entities | Move business rules from service "if" statements into owning entity | | Introduce domain events | Direct coupling between aggregates | Replace method calls with immutable past-tense events + handlers | | Extract domain service | Cross-aggregate operations in application layer | Create stateless domain-typed service; guard against overuse | | Introduce CQRS | Read/write contention on same model | Separate read DTOs from write aggregates; CQRS != event sourcing |
Most challenging aspect of DDD refactoring. Use expand/contract pattern for safe migration.
When contexts need data owned by another context:
Prepare for microservice extraction. Mediator is a stepping stone, not a destination.
Only when module is stable, independently deployable, and business-justified.
Measure refactoring progress with automated fitness functions in CI:
| Metric | What It Measures | Tool Examples | |--------|-----------------|---------------| | Afferent coupling | Incoming dependencies to module | NDepend, SonarQube, jdepend | | Efferent coupling | Outgoing dependencies from module | Same | | Dependency direction | Dependencies flow correctly (inward) | ArchUnit, NetArchTest | | Test coverage | Safety net for refactoring | Coverage tools | | Cohesion | Relatedness of components within module | LCOM metrics |
Define fitness function thresholds as acceptance criteria for refactoring stories.
| Test Type | When | Purpose | |-----------|------|---------| | Characterization tests | Before touching legacy code | Document current behavior as safety net | | Contract tests | When splitting contexts | Verify interservice communication | | Eventual consistency tests | After introducing events | Simulate network failures, verify convergence | | Schema integrity tests | During database refactoring | Verify constraints and data integrity |
Characterization tests (Feathers): run legacy code, observe output, write tests that assert current behavior -- even if behavior seems wrong. These tests protect against unintended changes during refactoring.
testing
Acceptance test creation methodology for the DISTILL wave. Domain knowledge for the acceptance designer agent: port-to-port principle, prior wave reading, wave-decision reconciliation, graceful degradation, and document back-propagation.
development
Cross-agent collaboration protocols, workflow handoff patterns, and commit message formats for TDD/Mikado/refactoring workflows
development
Creates a phased roadmap.json for a feature goal with acceptance criteria and TDD steps. Use when planning implementation steps before execution.
testing
Acceptance test creation methodology for the DISTILL wave. Domain knowledge for the acceptance designer agent: port-to-port principle, prior wave reading, wave-decision reconciliation, graceful degradation, and document back-propagation.