ai-superpower/.ai/instructions/skills/clean-architecture.instructions.md
moilanik a85c7dc0fb feat: add clean-code, clean-architecture and helm skills; fix .gitignore
New skill files:
- clean-code.instructions.md — naming, functions, classes, error handling,
  formatting, DRY/KISS/SOLID, Helm YAML conventions
- clean-architecture.instructions.md — dependency rule, layers, boundaries,
  SOLID foundation, Helm as outermost layer
- helm.instructions.md — resource ownership, values hygiene, required vs
  defaults, umbrella chart pattern, two-file values layering, KISS principle,
  hook ordering, config files pattern, dependency caching, template testing

Register all three in ai-root-instructions.md skills list and routing table.

Remove .ai from .gitignore — .ai/ is the product in this repo and must be
tracked; the apply.sh skip-by-marker mechanism prevents changes to other repos.
2026-03-04 09:54:07 +02:00

85 lines
4.4 KiB
Markdown

# 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