8.1 KiB
Project Structure Documentation
Architecture Overview
This project follows a Feature-First Clean Architecture approach, organizing code by features rather than layers. This makes the codebase more maintainable and scalable.
Directory Structure
/lib/core/
Contains shared resources used across the entire application.
/core/constants/
- app_constants.dart: Application-wide constants
- API endpoints
- Configuration values
- App metadata
- Default settings
/core/theme/
- app_theme.dart: Application theme configuration
- Color schemes
- Text styles
- Component themes
- Helper methods for dynamic theming
/core/utils/
Utility functions and helper classes (to be added as needed)
- Date formatting helpers
- Validation functions
- Common calculations
/core/widgets/
Reusable widgets used throughout the app
- status_badge.dart: Badge widget for displaying status
/lib/features/
Feature-based modules following clean architecture principles.
/features/routes/
Main feature for route management.
/features/routes/data/
Data layer - handles data sources and models.
/data/models/
- location_model.dart: Location data with latitude/longitude
- stop_model.dart: Stop information (pickup/dropoff)
- route_model.dart: Route details with stops and metadata
/data/repositories/
Implementation of repository interfaces (to be added as needed)
/features/routes/domain/
Domain layer - business logic and entities.
/domain/entities/
Pure business objects (if needed, separate from models)
/domain/repositories/
Repository interfaces/contracts
/features/routes/presentation/
Presentation layer - UI and state management.
/presentation/pages/
- home_page.dart: Main dashboard showing all routes
- route_details_page.dart: Detailed view of a single route
- map_view_page.dart: Map view showing all stops
/presentation/widgets/
Feature-specific widgets:
- route_card.dart: Card displaying route summary
- stop_card.dart: Card displaying stop information
/presentation/providers/
State management using Provider:
- route_provider.dart: Manages route state and business logic
/features/navigation/
Navigation-related features (to be expanded)
/lib/services/
Application-wide services.
/services/location/
- location_service.dart: Handles device location
- Get current position
- Track location changes
- Handle permissions
- Calculate distances
/services/maps/
- navigation_service.dart: Google Maps navigation
- Open Google Maps navigation
- Open Apple Maps (fallback)
- Handle navigation URLs
/services/api/
- route_api_service.dart: Backend API communication
- Fetch routes
- Update route status
- Update stop status
- Report issues
/lib/main.dart
Application entry point:
- Initializes services
- Sets up providers
- Configures app theme
- Defines root widget
Data Flow
UI (Pages/Widgets)
↓
Providers (State Management)
↓
Services/Repositories
↓
API/Data Sources
Example: Loading Routes
- UI:
HomePagerequests routes ininitState - Provider:
RouteProvider.loadRoutes()is called - Service:
RouteApiService.getDriverRoutes()fetches data - API: Makes HTTP request to backend
- Response: Data flows back up through the layers
- UI: Provider notifies listeners, UI rebuilds with data
State Management
Using Provider package for state management:
- ChangeNotifier: Used in providers to notify UI of changes
- Consumer: Used in widgets to listen to provider changes
- Provider.of / context.read/watch: Access provider data
Example Usage
// In widget
Consumer<RouteProvider>(
builder: (context, routeProvider, child) {
return Text(routeProvider.currentRoute?.id ?? 'No route');
},
)
// Or
final routeProvider = context.watch<RouteProvider>();
// For actions (no rebuild)
context.read<RouteProvider>().loadRoutes(driverId);
Models
Location Model
LocationModel {
double latitude
double longitude
String? address
}
Stop Model
StopModel {
String id
String customerId
String customerName
String? customerPhone
LocationModel location
StopType type // pickup | dropoff
StopStatus status // pending | inProgress | completed | failed
DateTime scheduledTime
DateTime? completedTime
String? notes
List<String> items
int orderNumber
String? signature
String? photo
}
Route Model
RouteModel {
String id
String driverId
String driverName
DateTime date
RouteStatus status // notStarted | inProgress | completed | cancelled
List<StopModel> stops
double totalDistance
int estimatedDuration
DateTime? startTime
DateTime? endTime
String? vehicleId
String? notes
}
Key Dependencies
Core Dependencies
- flutter: UI framework
- provider: State management
- google_maps_flutter: Map integration
- geolocator: Location services
- permission_handler: Handle permissions
Network & Data
- dio: HTTP client
- url_launcher: Open external apps
Utilities
- intl: Internationalization and date formatting
- uuid: Generate unique identifiers
Adding New Features
Steps to Add a New Feature
-
Create feature directory structure
lib/features/new_feature/ ├── data/ │ ├── models/ │ └── repositories/ ├── domain/ │ ├── entities/ │ └── repositories/ └── presentation/ ├── pages/ ├── widgets/ └── providers/ -
Create models in
data/models/ -
Create services if needed in
lib/services/ -
Create provider in
presentation/providers/ -
Create UI in
presentation/pages/andpresentation/widgets/ -
Register provider in
main.dart:MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => RouteProvider()), ChangeNotifierProvider(create: (_) => NewFeatureProvider()), ], // ... )
Best Practices
Code Organization
- Keep files small and focused
- One class per file
- Use meaningful names
- Group related functionality
State Management
- Use Provider for global state
- Use StatefulWidget for local state
- Keep business logic in providers
- Keep UI logic in widgets
Models
- Include
fromJsonandtoJsonmethods - Include
copyWithmethod for immutability - Add computed properties when useful
- Use enums for fixed values
Services
- Make services singleton where appropriate
- Handle errors gracefully
- Log important operations
- Use async/await for asynchronous operations
UI
- Extract reusable widgets
- Use const constructors when possible
- Follow Material Design guidelines
- Handle loading and error states
Testing Strategy
Unit Tests
- Test models (fromJson, toJson, copyWith)
- Test business logic in providers
- Test utility functions
Widget Tests
- Test individual widgets
- Test widget interactions
- Test state changes
Integration Tests
- Test complete user flows
- Test API integration
- Test navigation
Performance Considerations
Optimization Tips
- Use
constconstructors where possible - Avoid rebuilding entire widget trees
- Use
ListView.builderfor long lists - Optimize images and assets
- Cache network responses
- Use
computefor heavy computations
Memory Management
- Dispose controllers and streams
- Cancel subscriptions
- Clear caches when appropriate
- Monitor memory usage
Future Enhancements
Planned Features
- Offline mode with local database
- Push notifications
- Real-time tracking
- Analytics and reporting
- Multi-language support
- Dark mode
- Driver authentication
- Chat with dispatcher
Technical Improvements
- Add unit tests
- Add integration tests
- Implement CI/CD
- Add error tracking (e.g., Sentry)
- Add analytics (e.g., Firebase Analytics)
- Implement proper logging
- Add code generation (e.g., freezed, json_serializable)