Enforces Clean Architecture patterns for Flutter apps with Firebase integration, MVVM state management, and comprehensive development guidelines. Based on a TMB calculator project developed with AI assistance.
This skill enforces Clean Architecture principles and development patterns for Flutter applications with Firebase backend, based on a production TMB (Basal Metabolic Rate) calculator project.
You are working on a **Flutter** application built with **Clean Architecture** principles and **Firebase** integration. The project follows MVVM pattern, uses ChangeNotifier for state management, and implements a comprehensive design system.
```dart
class UserProfile {
final String id;
final String name;
final double weight;
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'weight': weight,
};
}
static UserProfile fromMap(Map<String, dynamic> map) {
return UserProfile(
id: map['id'] as String,
name: map['name'] as String,
weight: (map['weight'] as num).toDouble(),
);
}
}
```
Always use the Result pattern from `lib/core/utils/result.dart`:
```dart
Future<Result<UserProfile>> getUserProfile() async {
try {
final profile = await _firebaseService.getUserProfile();
return Result.success(profile);
} catch (e) {
return Result.failure(DatabaseException('Erro ao buscar perfil: $e'));
}
}
// In UI
final result = await _getUserProfile();
result.when(
success: (profile) => _updateUI(profile),
failure: (error) => _showError(error.message),
);
```
Follow this consistent widget structure:
```dart
class ExampleScreen extends StatefulWidget {
const ExampleScreen({super.key});
@override
State<ExampleScreen> createState() => _ExampleScreenState();
}
class _ExampleScreenState extends State<ExampleScreen> {
// State variables
@override
void initState() {
super.initState();
// Initialization
}
@override
Widget build(BuildContext context) {
return Scaffold(
// UI implementation
);
}
// Private methods at the end
void _privateMethod() { }
}
```
Always use components from `lib/core/theme/app_theme.dart` and `lib/core/widgets/ui_components.dart`:
**Theme Properties:**
**Reusable Components:**
```dart
GradientCard()
MenuCard()
StatCard()
PrimaryButton()
SecondaryButton()
CustomTextField()
UserAvatar()
LoadingOverlay()
SectionHeader()
```
```javascript
match /users/{userId} {
allow read, write: if request.auth != null
&& request.auth.uid == userId;
allow read: if request.auth != null;
}
```
Always validate:
```dart
// 1. Flutter SDK
import 'package:flutter/material.dart';
// 2. Third-party packages
import 'package:firebase_auth/firebase_auth.dart';
import 'package:provider/provider.dart';
// 3. Relative imports
import '../models/user_profile.dart';
import '../../core/utils/result.dart';
```
Implement consistent validators:
```dart
String? validateEmail(String? value) {
if (value == null || value.isEmpty) return 'Email é obrigatório';
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) {
return 'Email inválido';
}
return null;
}
String? validatePassword(String? value) {
if (value == null || value.isEmpty) return 'Senha é obrigatória';
if (value.length < 6) return 'Senha deve ter no mínimo 6 caracteres';
return null;
}
```
1. **Use ChangeNotifier** for providers
2. **Use StreamBuilder** for real-time Firebase data
3. **Use StatefulWidget** only when necessary
4. **Always dispose** controllers and subscriptions
```dart
class _ScreenState extends State<Screen> with TickerProviderStateMixin {
late AnimationController _controller;
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
```
1. Use `const` constructors whenever possible
2. Implement `ListView.builder` for large lists
3. Use `FutureBuilder`/`StreamBuilder` appropriately
4. Implement proper loading states and caching
```dart
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ItemWidget(item: items[index]);
},
)
```
```dart
void main() {
group('UserProfile', () {
test('deve calcular TMB corretamente', () {
// Arrange
final profile = UserProfile(
weight: 70,
height: 175,
age: 30,
gender: 'male',
);
// Act
final tmb = profile.calculateTmb();
// Assert
expect(tmb, equals(expectedValue));
});
});
}
```
```dart
/// Calcula a Taxa Metabólica Basal (TMB) usando a fórmula de Harris-Benedict.
///
/// Returns: Valor da TMB em kcal/dia
double calculateTmb() {
// Implementation
}
```
```
lib/
├── core/ # Application core
│ ├── constants/ # Global constants
│ ├── di/ # Dependency injection
│ ├── exceptions/ # Custom exceptions
│ ├── interfaces/ # Contracts/Interfaces
│ ├── theme/ # Design system (AppTheme)
│ ├── utils/ # Utilities (Result pattern)
│ └── widgets/ # Reusable components
├── models/ # Entities/Models
├── modules/ # Features by module
│ ├── auth/ # Authentication
│ └── home/ # Main functionalities
├── providers/ # State management
├── repositories/ # Data layer
├── services/ # External services
├── use_cases/ # Business logic
└── main.dart
```
When implementing new features:
1. **Define the model** in `lib/models/` with `toMap()`/`fromMap()`
2. **Create use case** in `lib/use_cases/` with business logic
3. **Define repository interface** in `lib/repositories/`
4. **Implement service** in `lib/services/` for Firebase operations
5. **Create provider** in `lib/providers/` for state management
6. **Build UI** in `lib/modules/` using design system components
7. **Add Firebase rules** if needed
8. **Write tests** for business logic
9. **Document** the feature
This project was developed with **Claude Sonnet + Cursor** as a demonstration of AI-assisted development. Maintain:
**Goal:** Keep the project as a quality reference for Flutter development with AI assistance.
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/flutter-clean-architecture-basal-fit-pattern/raw