Skip to content

Latest commit

 

History

History
190 lines (135 loc) · 6.88 KB

File metadata and controls

190 lines (135 loc) · 6.88 KB

Flutter Dart License Platform

🏗️ Flutter Architecture Kit

A production-ready Flutter starter kit implementing Clean Architecture with Riverpod, GoRouter, Dio, and best-in-class patterns for scalable cross-platform development. Built for teams who need architecture that scales beyond a prototype, enforces type-safety, and makes testing a first-class citizen.


📐 Architecture Diagram

The project strictly follows the Dependency Rule: Source code dependencies must point inward. The Domain layer knows nothing of Flutter, Dio, or Riverpod.

graph TD
    UI[Presentation / UI] -->|Watches| Provider[Riverpod Provider]
    Provider -->|Calls| UseCase[Domain UseCase]
    UseCase -->|Calls| RepoInterface[Domain Repository Interface]
    RepoInterface -.->|Implemented by| RepoImpl[Data Repository Impl]
    RepoImpl -->|Calls| Datasource[Data Datasource]
    Datasource -->|Uses| ApiClient[Dio ApiClient]
    Datasource -->|Uses| Storage[SecureStorage/Cache]
Loading

##📁 Folder Structure

lib/
├── core/                   # Shared infrastructure & utilities
│   ├── config/             #   Environment & app configuration
│   ├── di/                 #   Dependency injection (Riverpod composition root)
│   ├── error/              #   Failure hierarchy & error mapping
│   ├── network/            #   Dio client, interceptors, API response models
│   ├── router/             #   GoRouter configuration & route guards
│   ├── storage/            #   Local & secure storage abstractions
│   ├── theme/              #   Material 3 theme, colors, typography, spacing
│   ├── utils/              #   Validators, loggers, extensions
│   └── widgets/            #   Reusable UI components (AppButton, AppLoader, etc.)
├── features/               # Feature-first modules
│   └── auth/               #   Authentication feature
│       ├── data/           #     DTOs, datasources, repository implementations
│       ├── domain/         #     Entities, repository interfaces, use cases
│       └── presentation/   #     Riverpod providers, pages, widgets
└── main.dart               # App entry point with flavor support

🚀 Getting Started

Prerequisites

  • Flutter 3.22+ / Dart 3.4+
  • Android Studio / VS Code

Installation

git clone https://github.com/amjadlabdev/flutter_architecture_kit.git
cd flutter_architecture_kit
flutter pub get
flutter pub run build_runner build --delete-conflicting-outputs  # Generate Freezed/Riverpod code
flutter run

Running per Environment

# Development (default)
flutter run --dart-define=APP_ENV=development

# Staging
flutter run --dart-define=APP_ENV=staging

# Production
flutter run --dart-define=APP_ENV=production

🧩 How to Add a New Feature

Follow this exact sequence to maintain the Dependency Rule:

  1. Domain Layer (features/{feature}/domain/):

    • Define entities/ (Pure Dart classes with Equatable).
    • Define repositories/{feature}_repository.dart (Abstract class with Either<Failure, T> returns).
    • Define usecases/ (Implement UseCase<Type, Params> interface).
  2. Data Layer (features/{feature}/data/):

    • Define models/ (Freezed DTOs with fromJson, toJson, and toEntity).
    • Define datasources/ (Remote: ApiClient calls, Local: Storage calls).
    • Define repositories/{feature}_repository_impl.dart (Implements Domain abstract class, maps Models to Entities).
  3. Presentation Layer (features/{feature}/presentation/):

    • Define providers/ (Riverpod AsyncNotifiers mapping UseCase results to State).
    • Define pages/ (Scaffold layouts).
    • Define widgets/ (Stateful/Stateless leaf components).
  4. DI (core/di/injection.dart):

    • Wire Datasources → Repository Implementation → Repository Interface.
  5. Routing (core/router/):

    • Add route constant to app_routes.dart.
    • Add GoRoute to app_router.dart.

##🧠 State Management: Why Riverpod?

Riverpod was chosen over BLoC and Provider for production apps because:

  • Compile-time safety: Providers are declared globally, preventing ProviderNotFoundException.
  • Testability: Providers can be overridden in ProviderContainer without masking.
  • AsyncNotifier: Native support for AsyncValue, eliminating loading/error boilerplate.
  • Code Generation: @riverpod removes the verbose NotifierProvider boilerplate.

Provider Hierarchy:

  • Provider: For dependency injection (Repositories, UseCases).
  • NotifierProvider / @riverpod: For complex synchronous state.
  • AsyncNotifierProvider / @riverpod: For async state (API calls) with built-in loading/error/copyWith.

🛡️ Error Handling: The Either Pattern

We use dartz's Either<Failure, T> instead of try/catch at the Domain layer.

Why? Exceptions are invisible in function signatures. You don't know a function can fail until it crashes at runtime. Either forces the caller to handle both Left (failure) and Right (success) at compile time.

Flow:

  1. ApiClient throws DioException.
  2. Repository catches it and maps it to Left(NetworkFailure()).
  3. UseCase passes the Either up.
  4. Provider folds the Either into AuthError or AuthAuthenticated state.
  5. UI handles AuthError with a SnackBar.

🧭 Navigation: GoRouter

Declarative routing tied to Riverpod state prevents manual Navigator.push bugs.

  • Auth Guard: Implemented via redirect callback reading authProvider.
  • Deep Links: Configured in GoRouter for universal links.
  • Named Routes: Enforced via AppRoutes constants to prevent string-typo crashes.

🧪 Testing Guide

Run tests:

flutter test

Mocking Strategy:

  • Domain: Mock Repositories to test UseCases independently.
  • Presentation: Override Providers in ProviderContainer to test state transitions.
  • Data: Mock ApiClient to test mapping logic without HTTP calls.

🤝 Contributing

  1. Fork the repository.
  2. Create a feature branch (git checkout -b feature/amazing-feature).
  3. Commit using Conventional Commits (feat: add user profile).
  4. Ensure flutter analyze passes with zero warnings.
  5. Open a Pull Request.

👨‍💻 Author

Amjad Ali — Senior Software Engineer & Solution Architect

Built with ❤️ and Clean Architecture principles.