Layering Rules
Summary
The dependency direction is fixed. Violating it is a design defect.
Allowed imports
Forbidden imports
Why
- A pure domain is testable without a server, a database, or an event loop.
- Adapters can be swapped (in-memory fake, real database) without touching business logic.
- The HTTP edge stays thin and replaceable.
The port/adapter contract
A port is an abstract class or protocol declared in domain/<x>/ports/.
An adapter implements it in infra/adapters/. The composition root binds
the two.
Enforcement
- Keep every domain module importable with only the standard library and
Pydantic. If a domain import pulls in
fastapi, the layering is broken. - Reviewers (and CI) reject
import fastapiinsidedomain/orinfra/.