ai-superpower/.ai/skills/clean-architecture/SKILL.md

4.6 KiB

name description category impact
clean-architecture Enforce clean architecture principles and Hexagonal/Onion patterns. Use when designing system architecture, domains, or defining module boundaries. code medium

Clean Architecture

Based on Robert C. Martin's Clean Architecture. Apply these principles when designing systems, services, and infrastructure — including Helm chart structure and Kubernetes deployments.


The Dependency Rule

Source code dependencies point only inward. Inner layers define interfaces; outer layers implement them.

[ Frameworks & Drivers ]   ← outermost: UI, DB, APIs, Helm, K8s
    [ Interface Adapters ]  ← controllers, presenters, gateways
        [ Use Cases ]        ← application business rules
            [ Entities ]     ← enterprise business rules (innermost)
  • Inner layers know nothing about outer layers
  • Data crossing a boundary is always in the form the inner layer prefers — never a raw DB row or HTTP request object
  • If an outer layer changes (swap MySQL for Postgres, REST for gRPC), the inner layers are untouched

Layers

Entities — Core Business Rules

  • Enterprise-wide business objects with their validation and invariants
  • Pure domain models: no framework imports, no DB annotations, no HTTP concepts
  • Stable — change only if fundamental business rules change

Use Cases — Application Business Rules

  • Orchestrate entities to fulfil one actor's goal: TransferMoneyUseCase, ProvisionClusterUseCase
  • Define input/output via interfaces owned by this layer — no knowledge of controllers or DB implementations
  • One use case = one reason to exist

Interface Adapters

  • Convert data between use cases and the outside world
  • Controllers translate HTTP/CLI input → use case input models
  • Gateways implement repository interfaces defined by use cases
  • Presenters format use case output → UI/API response format

Frameworks & Drivers

  • The outermost ring: web frameworks, ORMs, message brokers, Kubernetes, Helm
  • These are details — they plug into the system via the adapters; the core doesn't know they exist

SOLID as the Foundation

  • SRP — one module, one actor, one reason to change
  • OCP — extend behaviour through new implementations, not modification of existing code
  • LSP — subtypes must honour the contracts of their interfaces
  • ISP — prefer narrow, focused interfaces over fat ones
  • DIP — high-level policy depends on abstractions; low-level detail implements them

Boundaries

  • Boundaries are where the power lives — they isolate components so that one side can change without affecting the other
  • Define boundaries at the most volatile points: DB, UI, external services
  • Cross a boundary only via an interface; never pass a concrete type across

What This Means in Practice

  • Business rules have no imports from frameworks, ORMs, or infrastructure libraries
  • Tests of use cases and entities need no running database, no HTTP server, no cluster
  • Swapping the database or the delivery mechanism (REST → gRPC, monolith → microservices) touches only the outer rings
  • "Screaming architecture" — the top-level structure should reflect the use cases, not the framework: invoice/, user/, payment/ not controllers/, models/, views/

In Helm and Kubernetes

Clean Architecture applies to how infrastructure is organised, not just application code.

Helm charts are the outermost layer — they are the delivery mechanism, not the system.

  • A chart should deploy exactly one service or one cohesive unit — not a bundle of unrelated things
  • Business rules belong in application config (values.yaml keys mapped to env vars); they must not be hardcoded in templates
  • Separate concerns across charts: one chart for the app, separate charts (or dependencies) for databases, queues, and shared infrastructure
  • A chart change (resource limits, replica count, ingress rules) must never require touching application business logic
  • Use _helpers.tpl as the adapter layer — it translates chart-level abstractions into Kubernetes primitives; templates themselves stay thin
  • Environments (values-dev.yaml, values-prod.yaml) are driver-layer configuration — they override defaults without touching templates
  • Test charts with helm template + schema validation; business logic is tested independently of the chart

Dependency Rule for Helm:

  • App charts depend on library charts, not the reverse
  • Library charts define interfaces (helpers, common labels); app charts implement them
  • Avoid circular chart dependencies — they indicate a missing layer or a misplaced responsibility