ionic-planb-logistic-app-fl.../PROJECT_STRUCTURE.md

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

  1. UI: HomePage requests routes in initState
  2. Provider: RouteProvider.loadRoutes() is called
  3. Service: RouteApiService.getDriverRoutes() fetches data
  4. API: Makes HTTP request to backend
  5. Response: Data flows back up through the layers
  6. 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

  1. Create feature directory structure

    lib/features/new_feature/
    ├── data/
    │   ├── models/
    │   └── repositories/
    ├── domain/
    │   ├── entities/
    │   └── repositories/
    └── presentation/
        ├── pages/
        ├── widgets/
        └── providers/
    
  2. Create models in data/models/

  3. Create services if needed in lib/services/

  4. Create provider in presentation/providers/

  5. Create UI in presentation/pages/ and presentation/widgets/

  6. 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 fromJson and toJson methods
  • Include copyWith method 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 const constructors where possible
  • Avoid rebuilding entire widget trees
  • Use ListView.builder for long lists
  • Optimize images and assets
  • Cache network responses
  • Use compute for heavy computations

Memory Management

  • Dispose controllers and streams
  • Cancel subscriptions
  • Clear caches when appropriate
  • Monitor memory usage

Future Enhancements

Planned Features

  1. Offline mode with local database
  2. Push notifications
  3. Real-time tracking
  4. Analytics and reporting
  5. Multi-language support
  6. Dark mode
  7. Driver authentication
  8. Chat with dispatcher

Technical Improvements

  1. Add unit tests
  2. Add integration tests
  3. Implement CI/CD
  4. Add error tracking (e.g., Sentry)
  5. Add analytics (e.g., Firebase Analytics)
  6. Implement proper logging
  7. Add code generation (e.g., freezed, json_serializable)