clean-architecture
Clean architecture: controller → service → repository
Usage
Invoke bare (/clean-architecture) for the full pattern. Invoke with an app name (/clean-architecture <app>) for clean-architecture-reviewer to audit that app against it.
This skill is the detailed reference behind the short policy in root CLAUDE.md under "Clean architecture (controller → service → repository)". Read that section first if you haven't — this document expands on it.
For what each layer logs, how errors propagate with their stack intact, and how a requestId threads through all three layers (and across a call to another of this repo's own apps), see the companion structured-logging skill — the two are meant to be read together when building a new controller/service/repository.
Language and strictness requirement
Every controller, service, repository, and consumer built under this pattern is TypeScript with strict: true — no exceptions, even though this repo generally allows plain JS+JSDoc (common/vanilla/*) and most existing tsconfig.json files here (common/compiled/node) run with strict: false. This architecture is stricter than the repo default on purpose: a repository/service boundary is exactly where a silent any or an unchecked null does the most damage, since it's the layer everything else is mocked against.
Give the app its own tsconfig.json — this is the one actually used (and verified against real strict-mode output, not just written and assumed to work) in apps/sample-common and apps/sample-queue-consumer: