Roles¶
What the code inside a role's modules does: endpoints that hand their work on, no blocking calls in async def, abstract ports, adapters that declare their port, a single composition root, and ORM names. These rules judge code against choices a team makes, so they are opt-in; a template can turn one on for a role, and so do some presets.
| Code | Name | What it flags | On |
|---|---|---|---|
| INW012 | thin-endpoint |
An HTTP endpoint that does the work itself: too many statements, branches or loops, database or HTTP calls of its own, or no call into the layer delegate-to names |
opt-in |
| INW013 | async-blocking |
A synchronous database, cache or cloud call inside async def: a sync SQLAlchemy Session, redis.Redis, boto3 or a blocking driver |
opt-in |
| INW014 | ports-abstract |
A class in a port module that isn't an ABC or a Protocol, or a port method whose body does work | opt-in |
| INW015 | construct-only-in |
A module outside the composition root that imports an outbound adapter, or another guarded role, at runtime, or builds one of its classes | opt-in |
| INW016 | orm-naming |
A table name that isn't lower_case_snake and singular, or a datetime or date column without _at or _date; a whole-project run also wants a MetaData naming convention |
opt-in |
| INW020 | adapter-conformance |
A public class in an adapter module with no _: Port = Adapter(...) line under if TYPE_CHECKING:, such a line that runs at import, or one whose annotation names no port |
opt-in |
The rules index has the rules of every category in one list you can search, filter and sort.