Modular, test‑driven Flutter app using a Clean Architecture split into local packages:
packages/domain— pure Dart entities and repository interfacespackages/data— repository implementations (in‑memory, Firebase/Auth, Firestore/Tasks)packages/application— state/controllers using Riverpodlib— UI, app bootstrap, provider wiring
The default runtime uses in‑memory repositories for both Auth and Tasks so you can run immediately without Firebase.
This repo includes a reusable design system package focused on Android Material 3.
- Tokens: colors, spacing, radii, elevations, durations, opacities
- Theme:
DSThemeBuilder.light()/dark()andfromScheme(...)for dynamic color - Components:
DSButton,DSInput,DSCardwith cohesive component themes
Quick start:
import 'package:design_system/design_system.dart';
MaterialApp(
theme: DSThemeBuilder.light(),
darkTheme: DSThemeBuilder.dark(),
themeMode: ThemeMode.system,
);
Dynamic color (Android 12+), using fromScheme:
final light = ColorScheme.fromSeed(seedColor: DSColors.light.brand);
final dark = ColorScheme.fromSeed(seedColor: DSColors.dark.brand, brightness: Brightness.dark);
MaterialApp(
theme: DSThemeBuilder.fromScheme(light),
darkTheme: DSThemeBuilder.fromScheme(dark, dark: true),
themeMode: ThemeMode.system,
);
See full docs and examples: packages/design_system/README.md
-
Requirements
- Flutter 3.32+ / Dart 3.8+
- Firebase optional (only needed if you switch to Firebase/Firestore repos)
-
Install dependencies
flutter pub get
-
Run the app
flutter run -d chrome(or any device)
-
Run tests
- Domain:
cd packages/domain && dart pub get && dart test - Data:
cd packages/data && flutter pub get && flutter test - Application:
cd packages/application && flutter pub get && flutter test - App widgets:
flutter test
- Domain:
-
Domain
- Entities:
AppUser,Task - Interfaces:
AuthRepository,TasksRepository
- Entities:
-
Data (implementations)
- Auth:
InMemoryAuthRepository,FirebaseAuthRepository - Tasks:
InMemoryTasksRepository,FirestoreTasksRepository
- Auth:
-
Application (Riverpod controllers)
AuthControllerviaauthControllerProviderTasksControllerviatasksControllerProvider
-
UI
lib/app/app.dart— Material/Cupertino applib/features/home/home_page.dart— sign‑in/out and a simple task list
Runtime provider overrides live in lib/main.dart:
- Defaults to in‑memory for both Auth and Tasks.
- You can switch at runtime using
--dart-defineflags (no code edits):- Firebase Auth:
--dart-define=USE_FIREBASE_AUTH=true - Firestore Tasks:
--dart-define=USE_FIRESTORE_TASKS=true - Example:
flutter run -d chrome \ --dart-define=USE_FIREBASE_AUTH=true \ --dart-define=USE_FIRESTORE_TASKS=true
- Firebase Auth:
Under the hood, lib/config/runtime.dart reads the flags and lib/main.dart sets provider overrides accordingly.
Only needed if using FirebaseAuthRepository and/or FirestoreTasksRepository.
-
Configure with FlutterFire
dart pub global activate flutterfire_cliflutterfire configure- Ensure
lib/firebase_options.dartexists with your web/ios/android config
-
Notes for Web
- Construct Firebase‑backed repos lazily (done via provider override) to avoid init timing issues.
- If you see init errors, verify
firebase_options.dartand browser extensions aren’t blocking Firebase.
- Web:
flutter build web --release→ outputs tobuild/web
- CI generates coverage for app and all packages, merges them into
coverage/combined.info, and uploads artifacts. - Optional Codecov upload (using the merged report) is enabled when
CODECOV_TOKENis set as a repo secret.- Create a Codecov account and add this repo.
- Add GitHub secret
CODECOV_TOKEN(from Codecov) to enable uploads.
The repo was grown test‑first. Key tests include:
- Domain: entity equality and
copyWithsemantics - Data: in‑memory repos + Firestore and Firebase Auth repos (mocked)
- Application: controllers/providers behavior
- UI: widget tests for sign‑in/out and task list interaction
packages/domain/lib/—src/auth/*,src/tasks/*,domain.dartpackages/data/lib/—src/auth/*,src/tasks/*,data.dartpackages/application/lib/—src/auth/*,src/tasks/*,application.dartlib/—app/*,features/home/home_page.dart,bootstrap.dart,main.dart
- Analyzer warnings about mocking sealed Firestore classes appear in tests; they don’t affect builds. We can switch to wrappers/fakes later to silence them.
- Feel free to open issues or PRs for improvements, e.g., full Firestore UI, deletion of tasks, or CI workflows.