--- description: "Clean Architecture conventions for {{PROJECT_NAME}}" alwaysApply: true --- # Clean Architecture — {{PROJECT_NAME}} ## Layer structure ``` lib/features/[feature]/ ├── domain/ │ ├── entities/ ← Pure Dart, no framework imports │ ├── repositories/ ← Abstract interfaces only │ └── usecases/ ← Single-responsibility business operations ├── data/ │ ├── datasources/ ← Remote (API) + Local (cache) implementations │ ├── models/ ← DTOs with fromJson/toJson (can use Freezed) │ └── repositories/ ← Implements domain/repositories interfaces └── presentation/ ├── bloc/ or notifiers/ ├── pages/ └── widgets/ ``` ## Import rules (STRICTLY ENFORCED by arch-guard hook) {{ARCH_IMPORT_RULES}} ## UseCase pattern ```dart // One UseCase = one operation = one method class GetProductsUseCase { final ProductRepository _repository; const GetProductsUseCase(this._repository); Future>> call(ProductFilter filter) => _repository.getProducts(filter); } ``` ## Entity rules - Entities are pure Dart — zero Flutter or framework imports - Entities are immutable — use `final` fields + factory constructors - Entities NEVER have `fromJson`/`toJson` — that belongs in the data layer model ## Repository rules - Domain defines the **interface** (abstract class) - Data layer **implements** it - Use `Either` or `Result` return types — never throw in domain ## Dependency injection - Use `injectable` + `get_it` if `codegen` includes `injectable` - All UseCases injected into BLoC/Notifier via constructor - `DataSource → Repository → UseCase → Bloc` dependency direction