60 lines
2.8 KiB
Markdown
60 lines
2.8 KiB
Markdown
# Clean Architecture layer contract
|
|
|
|
The import direction is `domain <- application <- presentation`; concrete
|
|
adapters implement application-owned ports and are assembled only in
|
|
`src/bootstrap`.
|
|
|
|
| Layer | Owns | May depend on |
|
|
| --- | --- | --- |
|
|
| `domain` | framework-neutral models and pure policies | domain siblings |
|
|
| `application` | use cases, ports, orchestration, view-models | domain and application siblings |
|
|
| `presentation` | routes, components, user interaction and view state | application public API and shared UI |
|
|
| `adapters` | browser and third-party implementations of application ports | application ports and limited domain values |
|
|
| `features/<id>` | removable vertical domain/application/contracts/adapters/presentation slice | the same inward rule plus platform public boundaries |
|
|
| `bootstrap` | runtime configuration, adapter construction and React mount | all selected runtime modules |
|
|
|
|
The following edges are forbidden:
|
|
|
|
- domain to application, presentation, adapters, bootstrap, React, or browser globals
|
|
- application to presentation, concrete adapters, bootstrap, React, or browser globals
|
|
- presentation to concrete adapters, raw DTO schemas, or storage implementations
|
|
- an adapter to presentation, bootstrap internals, or another concrete adapter
|
|
- feature domain/application to its presentation or outbound adapter, and
|
|
feature presentation to its outbound adapter
|
|
|
|
`bootstrap` contains composition only. Business rules and page-specific
|
|
orchestration belong to domain/application.
|
|
|
|
The [ports, adapters, and feature-boundary contract](./frontend-ports-adapters-and-boundaries.md)
|
|
explains how `presentation` acts as the inbound adapter and how feature
|
|
application APIs augment the generic typed input registry. Concrete output
|
|
ports are composed in bootstrap and stay hidden behind the application facade.
|
|
Project-selected capabilities still implement the same output boundaries.
|
|
|
|
`check:architecture` keeps dependency-cruiser's report and adds the
|
|
authoritative TypeScript-aware graph below it:
|
|
|
|
```json
|
|
{
|
|
"staticImportGraph": {
|
|
"analyzer": "babel-parser-node-resolver",
|
|
"modules": [],
|
|
"dependencies": [],
|
|
"unresolved": [],
|
|
"parseFailures": [],
|
|
"cycles": [],
|
|
"violations": [],
|
|
"summary": { "errors": 0 },
|
|
"fixtureChecks": { "passed": true, "checks": [], "failures": [] }
|
|
}
|
|
}
|
|
```
|
|
|
|
The graph scans TypeScript and TSX, including static, dynamic, type, CommonJS
|
|
and JSDoc import references. It applies the path rules from
|
|
`.dependency-cruiser.json`, requires explicit TypeScript extensions for local
|
|
source imports, and fails closed on JavaScript-family source/specifiers,
|
|
unsupported rule shapes, unresolved imports, parse failures, error-severity
|
|
layer violations, or cycles. Regression fixtures prove the allowed resolver
|
|
path and each rejection class.
|