Flutter Quality Gate
When writing or modifying .dart files in mobile/lib/, apply these quality checks to all code you produce.
Naming Conventions
- •Files: Use
snake_case.dart(e.g.,task_tracking_screen.dart) - •Classes/Enums: Use
UpperCamelCase(e.g.,TaskTrackingScreen,TaskStatus) - •Variables/Functions: Use
lowerCamelCase(e.g.,userName,fetchTasks()) - •Constants: Use
lowerCamelCasefor Dart conventions (e.g.,maxTaskDistance) - •Private members: Prefix with
_(e.g.,_privateMethod()) - •Reusable widgets in
core/widgets/: Usesf_file prefix andSFclass prefix (e.g.,sf_button.dart→SFButton)
Widget Organization
- •Keep widgets small: If a widget's
build()method exceeds ~100 lines, extract sub-widgets - •Single responsibility: Each widget should do one thing well
- •Use
constconstructors: Always addconstto constructors when all fields are final and non-dynamic - •Use
conston literal widgets:const Text('...'),const SizedBox(height: 8),const Icon(Icons.add) - •Extract build helpers: If
build()has complex conditionals, extract to_buildSomething()methods — but prefer separate widget classes for reusability
No Business Logic in build()
Never put these in build() methods:
- •API calls or network requests
- •Heavy computation or data transformation
- •
async/awaitoperations - •Complex
setStatewith business logic
Instead:
- •Use Riverpod providers for async data
- •Pre-compute values in
initState()or provider - •Use
ref.watch()for reactive data inbuild()
Theme Token Usage
Always use design tokens from core/theme/ instead of hardcoded values:
| Instead of | Use |
|---|---|
Color(0xFF...) or Colors.blue | AppColors.primary, AppColors.gray600 |
EdgeInsets.all(16) | EdgeInsets.all(AppSpacing.paddingMD) |
BorderRadius.circular(12) | AppRadius.radiusMD or AppRadius.card |
BoxShadow(...) | AppShadows.small or AppShadows.medium |
Raw TextStyle(fontSize: 16) | Theme.of(context).textTheme.bodyLarge |
GoogleFonts.nunito(...) directly | Use theme's text styles |
Exception: Theme definition files in core/theme/ define these values and are excluded.
Performance Patterns
- •Lists: Use
ListView.builderfor dynamic lists, notListView(children: [...]) - •Sizing: Use
SizedBoxinstead ofContainerwhen only specifying width/height - •Opacity: Avoid
Opacity()widget — usecolor.withValues(alpha: 0.5)for simple cases - •Images: Use
CachedNetworkImagefor network images, notImage.network - •Const: Mark all possible widgets as
constto prevent unnecessary rebuilds
State Management (Riverpod)
- •Use
ref.watch()inbuild()for reactive updates - •Use
ref.read()in callbacks and event handlers - •Prefer
StateNotifierwith immutable state classes - •Use
copyWith()for state updates - •Keep providers in
core/providers/for shared state - •Feature-specific providers go in
features/*/providers/
File Structure
When creating new features, follow this structure:
code
features/
feature_name/
screens/ # Full-page widgets
widgets/ # Feature-specific reusable widgets
models/ # Data models
providers/ # Feature-specific providers (if any)