# Flutter Development Guidelines
## Core Principles
- Follow SOLID principles
- Document all public APIs
- Maximum 300 lines per file
- Use barrel files for public exports
- Prefer composition over inheritance
- Use dependency injection (GetIt) for loose coupling
- Use VeryGoodCLI for scaffolding
## Project Structure
```
lib/
├── core/
│ ├── di/
│ │ └── injection.dart # GetIt configuration
│ └── errors/
│ └── app_errors.dart # Custom error definitions
├── app/
│ ├── app.dart
│ └── bloc_observer.dart
├── features/
│ └── feature_name/
│ ├── bloc/
│ │ ├── feature_bloc.dart
│ │ ├── feature_event.dart
│ │ └── feature_state.dart
│ ├── models/
│ │ └── model_1.dart
│ │ └── model_2.dart
│ │ └── models.dart
│ ├── view/
│ │ ├── feature_page.dart
│ │ └── view.dart
│ └── widgets/
│ │ └── feature_list.dart
│ │ └── feature_item.dart
│ └── widgets.dart
└── development_main.dart
└── staging_main.dart
└── production_main.dart
packages/
│── package_name/
│ ├── lib/
│ │ └── src/
│ │ └── package_name.dart
```
## Data Layer
### Package Organization
- Create local packages in /packages directory
- Wrap static methods in wrapper classes (exclude from coverage)
- Use VeryGoodCLI for package scaffolding
### Repository Pattern
- Implement interface for each repository
- Provide default factory constructor in interface
- Don't expose third-party dependencies
- Use custom errors with documentation
- Handle caching and error handling
- Keep repositories independent of bloc
## Domain Layer
- Transform data from data layer to domain models
- Use DTOs where appropriate
- Create use-cases for common logic
- Handle complex transformations
- Orchestrate multiple repositories/use-cases
## State Management
### BLoC Organization
- Event Handlers
- Async methods prefixed with _on
- Track analytics at start
- Use try/catch for error handling
- Emit states within try block
- Call addError() with stack trace
- Keep single responsibility
- States
- Use sealed classes
- Never use freezed
- Keep immutable
- Implement Equatable
- Events
- Use sealed classes
- Never use freezed
- Include required data
- Keep events focused
### Error Handling
- Catch exceptions in bloc
- Add errors to state
- Define clear error states
- Use sealed classes for error types
- Implement retry mechanisms
- Log appropriately
## Presentation Layer
### Page/View Pattern
- Pages (@RoutePage)
- Wrap with BlocProvider
- Inject bloc using appRegistry.get<T>
- Keep minimal - only provider setup
- Views
- Implement core UI structure
- Use BlocBuilder for state updates
- No direct bloc injection
- Widgets
- Break UI into focused components
- Keep under 100 lines
- Handle specific UI responsibilities
- Use const constructors
### Performance
- Prefer stateless widgets
- Use const constructors
- Optimize list views
- Implement proper keys
- Avoid unnecessary rebuilds
- Lazy load images and data
## Testing
### Layer Testing
- Unit test business logic
- Widget test UI components
- Integration test critical flows
- Test each layer independently
- Mock dependencies appropriately
### BLoC Testing
- Use blocTest
- Test initial state
- Verify state transitions
- Mock repositories
- Follow Given-When-Then pattern
## Development Process
1. Define domain models
2. Implement repositories
3. Create bloc (states/events)
4. Build UI components
5. Test each layer
6. Refactor as needed
7. Update documentation
## Code Quality
- Profile regularly
- Handle state disposal
- Maintain clean separation
- Keep documentation updated
- Follow VGV analysis options
## Localization
- Use l10n for all user-facing strings
- Keep translations in arb files
- No hardcoded strings in widgets
- Use flutter gen-l10n to generate l10n
analytics
c
c++
cmake
dart
golang
html
kotlin
+4 more
First Time Repository
C++
Languages:
C: 0.7KB
C++: 16.4KB
CMake: 8.0KB
Dart: 7.4KB
HTML: 1.2KB
Kotlin: 0.1KB
Objective-C: 0.0KB
Swift: 1.7KB
Created: 12/28/2024
Updated: 12/31/2024