$npx -y skills add krzysztofsurdy/code-virtuoso --skill clean-architectureClean Architecture, Hexagonal Architecture (Ports and Adapters), and Domain-Driven Design fundamentals. Use when the user asks to design system architecture, define layer boundaries, apply DDD tactical patterns (entities, value objects, aggregates, repositories), structure a hexa
| 1 | # Clean Architecture & DDD |
| 2 | |
| 3 | Architectural patterns and tactical design techniques for building systems where business logic is isolated, testable, and independent of frameworks, databases, and delivery mechanisms. Rooted in the work of Robert C. Martin, Alistair Cockburn, and Eric Evans. |
| 4 | |
| 5 | ## When to Use |
| 6 | |
| 7 | - The domain has meaningful business rules that deserve explicit modeling |
| 8 | - The system must survive framework upgrades, database migrations, or delivery mechanism changes |
| 9 | - Multiple entry points (API, CLI, message consumer, scheduled jobs) share the same business logic |
| 10 | - Long-lived product where maintenance cost outweighs initial development speed |
| 11 | - Team size or turnover demands clear boundaries and enforceable conventions |
| 12 | - Testability is a priority — business rules must be verifiable without infrastructure |
| 13 | |
| 14 | ## When NOT to Use |
| 15 | |
| 16 | Not every system benefits from this level of architectural rigor. Avoid over-engineering when: |
| 17 | |
| 18 | - The application is a simple CRUD wrapper with no meaningful business logic |
| 19 | - The project is a short-lived prototype or proof of concept |
| 20 | - The team is very small and the domain is well understood with few rules |
| 21 | - The overhead of layer separation exceeds the complexity of the problem |
| 22 | - A simple framework-centric approach (e.g., MVC with active records) adequately serves the need |
| 23 | |
| 24 | The key question: **Does the domain have enough complexity to justify the investment?** If the answer is no, a simpler architecture is the right choice. You can always introduce boundaries later as complexity grows. |
| 25 | |
| 26 | ## Architecture Styles |
| 27 | |
| 28 | Three well-known styles share the same core principle: **dependencies point inward**, and the domain sits at the center. |
| 29 | |
| 30 | | Style | Origin | Key Metaphor | Distinguishing Idea | |
| 31 | |---|---|---|---| |
| 32 | | **Clean Architecture** | Robert C. Martin (2012) | Concentric circles | Explicit layer names: Entity, Use Case, Interface Adapter, Framework | |
| 33 | | **Hexagonal (Ports & Adapters)** | Alistair Cockburn (2005) | Hexagon with ports | Symmetry between driving (primary) and driven (secondary) adapters | |
| 34 | | **Onion Architecture** | Jeffrey Palermo (2008) | Onion layers | Emphasis on domain model at the core, infrastructure at the outer ring | |
| 35 | |
| 36 | **What they share:** |
| 37 | |
| 38 | - Domain logic at the center, free of external dependencies |
| 39 | - The **Dependency Rule**: source code dependencies always point inward |
| 40 | - Infrastructure and delivery concerns live in outer layers |
| 41 | - Communication crosses boundaries through abstractions (interfaces/ports) |
| 42 | |
| 43 | For practical purposes, the differences are naming conventions. The principles below apply to all three. |
| 44 | |
| 45 | ### Ports & Adapters Concept |
| 46 | |
| 47 | The Hexagonal Architecture introduces a useful vocabulary that applies across all three styles: |
| 48 | |
| 49 | - **Ports** are interfaces defined by the application. They describe what the application needs from the outside world (driven/secondary ports) or what the outside world can ask of the application (driving/primary ports). |
| 50 | - **Adapters** are implementations that connect a port to a specific technology. A database adapter implements a repository port. An HTTP controller is an adapter for a driving port. |
| 51 | - **Driving (primary) adapters** initiate interaction with the application: HTTP controllers, CLI commands, message consumers, scheduled jobs. |
| 52 | - **Driven (secondary) adapters** are called by the application: database repositories, email senders, payment gateways, file storage. |
| 53 | |
| 54 | This symmetry is powerful: the application does not know whether it is being driven by a REST API or a CLI command, and it does not know whether it is persisting to a relational database or an in-memory store. |
| 55 | |
| 56 | ## The Dependency Rule |
| 57 | |
| 58 | > Source code dependencies must point inward. Nothing in an inner layer can know anything about an outer layer — no names, types, interfaces, or concepts. |
| 59 | |
| 60 | This is the single most important rule. Every other guideline flows from it. |
| 61 | |
| 62 | **What "inward" means:** |
| 63 | |
| 64 | - Inner layers define interfaces (ports); outer layers implement them |
| 65 | - Data crosses boundaries as simple structures (DTOs, primitives), never as framework objects |
| 66 | - The domain layer never imports from infrastructure, presentation, or application layers |
| 67 | - The application layer never imports from infrastructure or presentation layers |
| 68 | |
| 69 | **Why it matters:** |
| 70 | |
| 71 | - The domain can be tested without a database, HTTP server, or message broker |
| 72 | - Frameworks become replaceable implementation details |
| 73 | - Business rules are readable w |