← ClaudeAtlas

clean-architecturelisted

GM Clean Architecture patterns — modular (Failure + FailureHandlerMixin) vs non-modular (Result plus ErrorMapper) for Flutter
ghozimahdi/gm-aiagent-plugins · ★ 0 · AI & Automation · score 67
Install: claude install-skill ghozimahdi/gm-aiagent-plugins
Resolve `UFIL_ROOT` to the plugin root containing this skill. Claude Code may provide `CLAUDE_PLUGIN_ROOT`; Codex can resolve it from the installed skill path. ## Clean Architecture Patterns (GM Standard) ### Layer Rules - **Presentation → Domain → Data** flow only. Never access data layer from presentation. - Domain layer has NO dependencies on data or presentation. - Presentation uses UseCases, never imports from data layer directly. - **Pages MUST NOT call UseCases directly.** Only Blocs depend on UseCases — pages depend on Blocs. UseCases are injected into the Bloc via the constructor (`@injectable` Bloc + `@lazySingleton` UseCase). Pages dispatch events with `context.read<TBloc>().add(...)` and read state with `BlocBuilder`/`BlocConsumer`/`BlocSelector`/`BlocListener`. A page that imports a UseCase or calls `getIt<XUseCase>()` is ALWAYS wrong, even for one-shot ops like logout/refresh/delete — there is NO "too simple to need a bloc" exception. ### Model (Domain) — `@freezed` + `@Default`, NO nullable ```dart @freezed sealed class TenantModel with _$TenantModel { const factory TenantModel({ @Default('') String id, @Default('') String name, @Default('') String phone, }) = _TenantModel; } ``` ### DTO (Data) — `@freezed` + nullable + `@JsonKey`, NO `.toModel()` ```dart @freezed abstract class TenantDto with _$TenantDto { const factory TenantDto({ @JsonKey(name: 'id') String? id, @JsonKey(name: 'name') String? name, @JsonKey(name: 'phone_n