---
name: clean-architecture
description: Analyze and improve application architecture using Clean Architecture principles
version: 1.0.0
author: wondelai (adapted)
platforms: [claude-code, cursor, windsurf]
license: MIT
source: https://github.com/wondelai/skills
based_on: "Clean Architecture by Robert C. Martin"
---

# Clean Architecture

Evaluate and improve application architecture for maintainability and testability.

## Scoring System
Rate architecture 0-10 on separation of concerns and dependency rules.
Show: current score → violations → refactored structure → benefits.

## The Dependency Rule
**Source code dependencies must point only inward toward higher-level policies.**

```
┌──────────────────────────────────────────┐
│  Frameworks & Drivers (outermost)        │
│  ┌────────────────────────────────────┐  │
│  │  Interface Adapters               │  │
│  │  ┌──────────────────────────────┐ │  │
│  │  │  Application Business Rules │ │  │
│  │  │  ┌────────────────────────┐ │ │  │
│  │  │  │  Enterprise Business  │ │ │  │
│  │  │  │  Rules (Entities)     │ │ │  │
│  │  │  └────────────────────────┘ │ │  │
│  │  └──────────────────────────────┘ │  │
│  └────────────────────────────────────┘  │
└──────────────────────────────────────────┘
```

## The 4 Layers

### 1. Entities (Domain)
Pure business objects with no framework dependencies:
```python
@dataclass
class Invoice:
    id: str
    amount: Decimal
    due_date: date

    def is_overdue(self) -> bool:
        return date.today() > self.due_date
```

### 2. Use Cases (Application)
Orchestrates entities to fulfill business requirements:
```python
class ProcessPaymentUseCase:
    def __init__(self, invoice_repo: IInvoiceRepository, payment_gateway: IPaymentGateway):
        self.invoice_repo = invoice_repo
        self.payment_gateway = payment_gateway

    def execute(self, invoice_id: str, card_token: str) -> PaymentResult:
        invoice = self.invoice_repo.get(invoice_id)
        result = self.payment_gateway.charge(card_token, invoice.amount)
        invoice.mark_paid()
        self.invoice_repo.save(invoice)
        return result
```

### 3. Interface Adapters
Converts data between use cases and external formats:
```python
class InvoiceController:  # converts HTTP request → use case input
    def pay(self, request: HttpRequest) -> HttpResponse:
        result = ProcessPaymentUseCase(...).execute(
            invoice_id=request.path_params["id"],
            card_token=request.body["card_token"]
        )
        return HttpResponse(status=200, body=result.to_dict())
```

### 4. Frameworks & Drivers
Django, FastAPI, SQLAlchemy, etc. Nothing in the inner layers knows these exist.

## Violation Checklist
- [ ] Does domain/entities import from frameworks (Django ORM, requests, etc.)?
- [ ] Does application layer know about HTTP, JSON, or database details?
- [ ] Are there circular imports between layers?
- [ ] Are repository interfaces defined in domain but implemented in infra?
- [ ] Does testing require a database or web server to run?

## Ports & Adapters Pattern
```python
# Port (inner layer defines the interface)
class IEmailService(Protocol):
    def send(self, to: str, subject: str, body: str) -> None: ...

# Adapter (outer layer implements it)
class SendGridEmailService:
    def send(self, to: str, subject: str, body: str) -> None:
        sendgrid_client.send(...)
```