Files
geo/app/README2-APP.md
2025-06-11 09:27:25 +02:00

16 KiB

GEOSECTOR v2.0

🚒 Application de gestion des distributions de calendriers par secteurs géographiques pour les amicales de pompiers


🎯 Vue d'ensemble

GEOSECTOR est une solution complète développée en Flutter qui révolutionne la gestion des campagnes de distribution de calendriers pour les amicales de pompiers. L'application combine géolocalisation, gestion multi-rôles et synchronisation en temps réel pour optimiser les tournées et maximiser l'efficacité des équipes.

🏆 Points forts de la v2.0

  • Architecture moderne sans Provider, basée sur l'injection de dépendances
  • Réactivité native avec ValueListenableBuilder et Hive
  • Interface adaptative selon les rôles utilisateur
  • Performance optimisée avec un ApiService singleton
  • Gestion avancée des permissions multi-niveaux
  • Gestion d'erreurs centralisée avec ApiException
  • Interface utilisateur unifiée avec UserFormDialog réutilisable

📋 Table des matières

  1. Fonctionnalités
  2. Architecture technique
  3. Installation
  4. Modèles de données
  5. Architecture des composants
  6. Gestion des rôles
  7. Interface utilisateur
  8. API et synchronisation
  9. Gestion des erreurs
  10. Cartes et géolocalisation

🚀 Fonctionnalités

🎯 Fonctionnalités métier

Pour les Distributeurs (Rôle 1)

  • Visualisation des secteurs assignés sur carte interactive
  • Suivi GPS en temps réel des tournées
  • Enregistrement des passages avec géolocalisation
  • Gestion des stocks de calendriers
  • Historique des distributions
  • Chat intégré avec l'équipe

Pour les Admins Amicale (Rôle 2)

  • Gestion de leur amicale (informations, coordonnées)
  • Gestion des membres de l'amicale (création, modification, suppression)
  • Attribution des rôles aux membres (Membre/Administrateur)
  • Gestion du statut actif des comptes membres
  • Consultation des statistiques de l'amicale
  • Attribution des secteurs aux membres
  • Suivi des performances équipe

Pour les Super Admins (Rôle 3+)

  • Gestion globale multi-amicales
  • Administration des utilisateurs et permissions
  • Configuration des paramètres système
  • Analytics avancées et reporting
  • Gestion des secteurs géographiques

🔧 Fonctionnalités techniques

  • 🗺️ Cartographie avancée : Flutter Map avec tuiles Mapbox
  • 📍 Géolocalisation précise : Suivi GPS des équipes
  • 💾 Stockage hybride : Cache local Hive + synchronisation cloud
  • 💬 Communication : Chat MQTT en temps réel
  • 🔐 Sécurité : Authentification JWT + gestion fine des permissions
  • 📱 Multi-plateforme : iOS, Android, Web
  • 🌐 Mode hors-ligne : Fonctionnement dégradé sans connexion
  • Gestion d'erreurs robuste : Extraction automatique des messages API
  • 🎨 Interface responsive : Adaptation automatique selon la taille d'écran

🏗️ Architecture technique

Stack technologique

Composant Technologie Version Usage
Framework Flutter 3.32+ Interface multi-plateforme
Langage Dart 3.0+ Logique applicative
Navigation GoRouter 12.1.3 Routing déclaratif
Stockage local Hive 2.2.3 Base de données NoSQL locale
Réactivité ValueListenableBuilder Native Écoute des changements Hive
HTTP Dio 5.4.0 Client HTTP avec intercepteurs
Cartes Flutter Map 6.1.0 Rendu cartographique
Géolocalisation Geolocator 10.1.0 Services de localisation
Chat MQTT5 Client 4.2.0 Messagerie temps réel
UI Material Design 3 Native Composants d'interface

🏛️ Architecture en couches

graph TD
    A[UI Layer - Widgets] --> B[Repository Layer - Business Logic]
    B --> C[Data Layer - Hive + API]

    A1[ValueListenableBuilder] --> A
    A2[Custom Widgets] --> A
    A3[UserFormDialog] --> A

    B1[UserRepository] --> B
    B2[AmicaleRepository] --> B
    B3[MembreRepository] --> B

    C1[Hive Boxes] --> C
    C2[API Service Singleton] --> C
    C3[ApiException Handler] --> C

📁 Structure du projet

app/
├── lib/
│   ├── core/                          # Couche centrale
│   │   ├── constants/                 # Constantes globales
│   │   │   ├── app_keys.dart         # Clés des Box Hive
│   │   │   └── api_endpoints.dart    # Endpoints API
│   │   ├── data/
│   │   │   └── models/               # Modèles Hive
│   │   │       ├── user_model.dart   # @HiveType(typeId: 3)
│   │   │       ├── amicale_model.dart # @HiveType(typeId: 4)
│   │   │       └── membre_model.dart  # @HiveType(typeId: 5)
│   │   ├── repositories/             # Logique métier
│   │   │   ├── user_repository.dart
│   │   │   ├── amicale_repository.dart
│   │   │   └── membre_repository.dart
│   │   ├── services/                 # Services externes
│   │   │   ├── api_service.dart      # HTTP Singleton
│   │   │   ├── chat_service.dart     # MQTT
│   │   │   └── location_service.dart # GPS
│   │   └── utils/                    # Utilitaires
│   │       ├── validators.dart
│   │       └── formatters.dart
│   ├── presentation/                  # Interface utilisateur
│   │   ├── admin/                    # Pages administrateur
│   │   │   ├── admin_dashboard_page.dart
│   │   │   ├── admin_amicale_page.dart
│   │   │   └── admin_statistics_page.dart
│   │   ├── user/                     # Pages utilisateur
│   │   │   ├── user_dashboard_page.dart
│   │   │   ├── map_page.dart
│   │   │   └── distribution_page.dart
│   │   ├── widgets/                  # Composants réutilisables
│   │   │   ├── tables/
│   │   │   │   ├── amicale_table_widget.dart
│   │   │   │   ├── amicale_row_widget.dart
│   │   │   │   ├── membre_table_widget.dart
│   │   │   │   └── membre_row_widget.dart
│   │   │   ├── forms/
│   │   │   │   ├── amicale_form.dart
│   │   │   │   └── custom_text_field.dart
│   │   │   └── common/
│   │   │       ├── dashboard_layout.dart
│   │   │       └── loading_widget.dart
│   │   └── theme/
│   │       └── app_theme.dart
│   ├── app.dart                      # Configuration app
│   └── main.dart                     # Point d'entrée
├── assets/                           # Ressources statiques
│   ├── images/
│   ├── icons/
│   └── fonts/
├── test/                            # Tests unitaires
├── integration_test/                # Tests d'intégration
└── docs/                           # Documentation


🚀 Installation et configuration

Prérequis système

  • Flutter SDK : 3.32 ou supérieur
  • Dart SDK : 3.0 ou supérieur
  • IDE : Android Studio, VS Code, ou IntelliJ
  • Environnement :
    • Android : SDK 21+ (Android 5.0+)
    • iOS : iOS 12.0+
    • Web : Navigateurs modernes

🔐 Configuration des clés API

Mapbox (Cartographie)

  1. Créer un compte sur Mapbox
  2. Générer un token d'accès
  3. Ajouter le token dans .env

Configuration MQTT (Chat)

  1. Configurer votre broker MQTT
  2. Créer les credentials
  3. Tester la connexion

🗄️ Modèles de données

Registres Hive des adaptateurs

// Modèles principaux
UserModelAdapter()           // typeId: 0
OperationModelAdapter()      // typeId: 1
SectorModelAdapter()         // typeId: 3
PassageModelAdapter()        // typeId: 4
MembreModelAdapter()         // typeId: 5
UserSectorModelAdapter()     // typeId: 6
RegionModelAdapter()         // typeId: 7
ClientModelAdapter()         // typeId: 10
AmicaleModelAdapter()        // typeId: 11

// Modèles de chat
ConversationModelAdapter()   // typeId: 20
MessageModelAdapter()        // typeId: 21
ParticipantModelAdapter()    // typeId: 22
AnonymousUserModelAdapter() // typeId: 23
AudienceTargetModelAdapter() // typeId: 24
NotificationSettingsAdapter() // typeId: 25

Compatibilité entre modèles UserModel ↔ MembreModel : Conversion bidirectionnelle via toUserModel() et fromUserModel() Synchronisation : Maintien de la cohérence entre les deux représentations Champs spécialisés : Préservation des données spécifiques à chaque modèle 🎨 Interface utilisateur Architecture des composants UserFormDialog - Modale unifiée Réutilisabilité : Même widget pour "Mon Compte" et "Gestion des Membres" Personnalisation contextuelle : Sélecteur de rôle (Membre/Administrateur) Checkbox statut actif/inactif Édition du nom d'utilisateur selon le contexte Gestion du nom de tournée (sectName) Interface responsive : Adaptation automatique selon la largeur d'écran UserForm - Formulaire intelligent Layout adaptatif :

900px : Champs groupés en lignes (username+email, prénom+nom, téléphones, dates) ≤ 900px : Champs empilés verticalement Validation conditionnelle : Au moins nom OU nom de tournée requis Champs dynamiques : Affichage selon les permissions et le contexte Indicateurs visuels : Points rouges sur les champs obligatoires Tableaux interactifs AmicaleTableWidget : Gestion des amicales avec édition inline MembreTableWidget : Gestion des membres avec actions contextuelles Alternance de couleurs : Amélioration de la lisibilité Clic sur ligne : Ouverture directe du formulaire d'édition

🔗 API et synchronisation

Principe "API First"

Flow de mise à jour

Validation API : Tentative de mise à jour sur le serveur Succès → Sauvegarde locale avec isSynced: true Erreur → Aucune modification locale + affichage de l'erreur

Avantages

Cohérence des données : Local toujours synchronisé avec le serveur Gestion d'erreurs propre : Pas de conflits entre données locales et distantes UX claire : Feedback immédiat sur les erreurs de validation

ApiService Singleton

  • Thread-safe : Initialisation sécurisée avec verrous
  • Auto-configuration : Détection automatique de l'environnement (DEV/REC/PROD)
  • Gestion de session : Headers d'authentification automatiques
  • Retry logic : Nouvelles tentatives pour les erreurs réseau

⚠️ Gestion des erreurs

Architecture centralisée

sequenceDiagram
    participant UI as dashboard_app_bar.dart
    participant UR as user_repository.dart
    participant AS as api_service.dart
    participant API as API Server
    participant AE as ApiException
    participant EU as ErrorUtils

    Note over UI: Utilisateur clique "Enregistrer"
    UI->>UR: updateUser(updatedUser)

    Note over UR: Tente la mise à jour
    UR->>AS: updateUser(user)

    Note over AS: Appel HTTP PUT
    AS->>API: PUT /users/123 {email: "test@test.com"}

    alt Succès API
        API-->>AS: 200 OK {user data}
        AS-->>UR: UserModel (mis à jour)
        UR-->>UI: UserModel (succès)
        UI->>EU: showSuccessSnackBar()
        Note over UI: ✅ "Profil mis à jour"

    else Erreur API (ex: email déjà utilisé)
        API-->>AS: 409 Conflict {"message": "Cet email est déjà utilisé"}

        Note over AS: Conversion en ApiException
        AS->>AE: ApiException.fromDioException(dioError)
        AE-->>AS: ApiException("Cet email est déjà utilisé")
        AS-->>UR: throw ApiException
        UR-->>UI: throw ApiException

        Note over UI: Gestion de l'erreur
        UI->>EU: showErrorSnackBar(context, exception)
        EU->>AE: extractErrorMessage(exception)
        AE-->>EU: "Cet email est déjà utilisé"
        Note over UI: ❌ "Erreur: Cet email est déjà utilisé"
        Note over UI: Dialog reste ouvert

    else Erreur réseau
        API-->>AS: Network Error / Timeout
        AS->>AE: ApiException.fromDioException(networkError)
        AE-->>AS: ApiException("Problème de connexion réseau")
        AS-->>UR: throw ApiException
        UR-->>UI: throw ApiException
        UI->>EU: showErrorSnackBar(context, exception)
        Note over UI: ❌ "Problème de connexion réseau"
    end

Composants de gestion d'erreurs

ApiException

Extraction intelligente : Messages spécifiques depuis la réponse API Codes HTTP standardisés : Mapping automatique des erreurs communes Types d'erreurs : Classification (validation, authentification, réseau, conflit) Méthodes d'affichage : showError() et showSuccess() intégrées

Responsabilités par couche

ApiService : Conversion des erreurs Dio en ApiException Repository : Propagation transparente des erreurs Interface : Affichage utilisateur via ApiException.showError()

Messages d'erreurs contextuels

409 Conflict : "Cet email est déjà utilisé par un autre utilisateur" 400 Bad Request : "Données invalides" 401 Unauthorized : "Non autorisé : veuillez vous reconnecter" 500 Server Error : "Erreur serveur interne" Network Errors : "Problème de connexion réseau" Timeout : "Délai d'attente dépassé"

🎯 Gestion des rôles

Hiérarchie des permissions

Distributeur (Rôle 1) : Consultation et distribution dans ses secteurs Admin Amicale (Rôle 2) : Gestion complète de son amicale et ses membres Super Admin (Rôle 3+) : Administration globale multi-amicales

Fonctionnalités par rôle

Admin Amicale - Gestion des membres Création : Nouveaux membres avec attribution de rôle Modification : Informations personnelles, rôle, statut actif Suppression : Avec confirmation obligatoire Validation : Contrôle d'unicité email/username par l'API

Interface adaptative

Sélecteur de rôle : Visible uniquement pour les admins Checkbox statut actif : Contrôle d'accès aux comptes Édition contextuelle : Champs modifiables selon les permissions Actions conditionnelles : Boutons disponibles selon le niveau d'autorisation

🗺️ Cartes et géolocalisation

Flutter Map : Rendu cartographique haute performance Tuiles Mapbox : Cartographie détaillée et personnalisable Géolocalisation temps réel : Suivi GPS des équipes Secteurs géographiques : Visualisation et attribution dynamique Passages géolocalisés : Enregistrement précis des distributions

🔄 Synchronisation et réactivité

Hive + ValueListenableBuilder

Réactivité native : Mise à jour automatique de l'interface Performance optimisée : Pas de Provider, injection directe Écoute sélective : Réactivité fine par Box Hive Cohérence des données : Synchronisation bidirectionnelle User/Membre

Services Singleton

CurrentUserService : Gestion de l'utilisateur connecté CurrentAmicaleService : Amicale de l'utilisateur actuel ApiService : Communication centralisée avec l'API DataLoadingService : Orchestration du chargement des données

Cette architecture garantit une application performante, maintenable et évolutive avec une excellente expérience utilisateur. 🚀