--- trigger: model_decision description: When working on a Flutter or React Native mobile application, setting up mobile project structure --- ## Flutter/Mobile Layout Use this structure for Flutter or React Native mobile applications. The vertical slice principle applies — features are self-contained modules. ``` apps/ mobile/ # Mobile application source code (Flutter) lib/ core/ # Foundational concerns (the "Framework") network/ # HTTP client setup, interceptors api_client.dart # Dio/http client with base config api_interceptor.dart # Auth token, logging interceptors storage/ # Local storage abstractions local_storage.dart # SharedPreferences / Hive wrapper theme/ # App theming app_theme.dart # ThemeData, color schemes app_typography.dart # TextStyles, font families router/ # Navigation / routing app_router.dart # GoRouter config (@riverpod function) app_router.g.dart # Generated provider code constants/ # App-wide constants features/ # Business Features (Vertical Slices) task/ # Task management feature # --- Presentation --- screens/ task_list_screen.dart # Full screen (route target, ConsumerWidget) task_detail_screen.dart widgets/ # Feature-specific widgets task_card.dart task_form.dart # --- State Management (Riverpod 3) --- state/ task_notifier.dart # @riverpod class (Notifier/AsyncNotifier) task_notifier.g.dart # Generated provider code (build_runner) task_state.dart # State classes (generated via freezed) # --- Domain (Business Logic) --- models/ task.dart # Domain model (freezed) task.g.dart # Generated code (json_serializable) task.freezed.dart # Generated code (freezed) logic/ task_logic.dart # Pure business rules # --- Data (I/O Abstraction) --- repository/ task_repository.dart # Abstract repository interface task_repository_impl.dart # Implementation (API + cache) task_repository_mock.dart # Mock for testing api/ task_api.dart # REST API calls (Dio) auth/ # Authentication feature ... settings/ # Settings feature ... shared/ # Shared across features widgets/ # Reusable UI components (NO domain logic) app_button.dart app_text_field.dart loading_indicator.dart utils/ # Pure utility functions date_formatter.dart validators.dart models/ # Shared data models api_response.dart pagination.dart test/ # Test directory (mirrors lib/ layout) features/ task/ state/ task_notifier_test.dart # Unit tests for state logic logic/ task_logic_test.dart # Unit tests for pure business rules widgets/ task_card_test.dart # Widget tests api/ task_api_test.dart # API integration tests integration_test/ # Integration / E2E tests task_flow_test.dart pubspec.yaml # Dependencies analysis_options.yaml # Lint rules (includes riverpod_lint) ``` **Key differences from web frontend:** - `screens/` replaces `views/` — mobile uses screen-based navigation - `widgets/` replaces `components/` — Flutter's terminology - `state/` replaces `store/` — Riverpod 3 `@riverpod` class (Notifier/AsyncNotifier) instead of Pinia/Redux - `*.g.dart` files in `state/` — generated provider code from `riverpod_generator` + `build_runner` - `repository/` replaces `api/` — mobile often caches data locally - No separate `di/` directory — Riverpod 3 uses `ProviderScope` at the app root for dependency injection; no manual service locator needed **Codegen artifacts (gitignore-able):** - `*.g.dart` — generated by `riverpod_generator` and `json_serializable` - `*.freezed.dart` — generated by `freezed` - Run `dart run build_runner build --delete-conflicting-outputs` after changes **Test location:** Tests live in the `test/` directory, mirroring the `lib/` layout. This is Flutter's default convention — `flutter test` discovers tests here automatically with no extra configuration. - **Naming:** `*_test.dart` (unit), `*_integration_test.dart` (integration) - **Discovery:** `flutter test` (runs all tests in `test/`) - **Structure:** Mirror the feature directory structure from `lib/` ### Related Principles - Project Structure @project-structure.md (core philosophy) - Flutter Idioms and Patterns @flutter-idioms-and-patterns.md (Riverpod 3 patterns, widget idioms)