Files
geo/app/README2-APP.md
2025-06-12 16:39:44 +02:00

22 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 Membres (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

Membre (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

👥 Gestion des membres (Admin Amicale)

🎯 Vue d'ensemble

La gestion des membres est une fonctionnalité clé pour les Admins Amicale (Rôle 2) qui permet une administration complète des équipes au sein de leur amicale. Cette interface centralise toutes les opérations liées aux membres avec une approche sécurisée et intuitive.

📱 Interface AdminAmicalePage

L'interface principale admin_amicale_page.dart offre une vue d'ensemble complète :

  • Informations de l'amicale : Affichage des détails de l'amicale courante
  • Liste des membres : Tableau interactif avec actions contextuelles
  • Ajout de membres : Bouton d'action pour créer de nouveaux comptes
  • Opération courante : Indication de l'opération active en cours

Fonctionnalités principales

🆕 Création de nouveaux membres

// Workflow de création
1. Clic sur "Ajouter un membre"
2. Ouverture du UserFormDialog
3. Formulaire vierge avec valeurs par défaut
4. Sélection du rôle (Membre/Administrateur)
5. Configuration du statut actif
6. Validation et création via API
7. Attribution automatique à l'amicale courante

Champs obligatoires :

  • Email (unique dans le système)
  • Au moins un nom (nom de famille OU nom de tournée)
  • Rôle dans l'amicale

Champs optionnels :

  • Nom d'utilisateur (éditable pour les admins)
  • Prénom, téléphones, dates
  • Nom de tournée (pour identification terrain)

✏️ Modification des membres existants

// Actions disponibles
- Clic sur une ligne  Ouverture du formulaire d'édition
- Modification de tous les champs personnels
- Changement de rôle (Membre  Administrateur)
- Activation/Désactivation du compte
- Gestion du nom de tournée

Workflow de modification :

  1. Sélection du membre dans le tableau
  2. Ouverture automatique du UserFormDialog
  3. Formulaire pré-rempli avec données existantes
  4. Modification des champs souhaités
  5. Validation et mise à jour via API
  6. Synchronisation automatique avec Hive

🗑️ Suppression intelligente des membres

La suppression des membres intègre une logique métier avancée pour préserver l'intégrité des données :

🔍 Vérification des passages
// Algorithme de vérification
1. Récupération de l'opération courante
2. Analyse des passages du membre pour cette opération
3. Classification : passages réalisés vs passages à finaliser
4. Comptage total des passages actifs
📊 Scénarios de suppression

Cas 1 : Aucun passage (suppression simple)

DELETE /users/{id}
  • Confirmation simple
  • Suppression directe
  • Aucun transfert nécessaire

Cas 2 : Passages existants (suppression avec transfert)

DELETE /users/{id}?transfer_to={destinataire}&operation_id={operation}
  • Dialog d'avertissement avec détails
  • Sélection obligatoire d'un membre destinataire
  • Transfert automatique de tous les passages
  • Préservation de l'historique

Cas 3 : Alternative recommandée (désactivation)

// Mise à jour du statut
membre.copyWith(isActive: false)
  • Préservation complète des données
  • Blocage de la connexion
  • Maintien de l'historique
  • Réactivation possible ultérieurement

🔐 Sécurité et permissions

Contrôles d'accès

  • Isolation par amicale : Admins limités à leur amicale
  • Vérification des rôles : Validation côté client et serveur
  • Opération courante : Filtrage par contexte d'opération
  • Validation API : Contrôles d'unicité et cohérence

Gestion des erreurs

graph TD
    A[Action utilisateur] --> B[Validation locale]
    B --> C[Appel API]
    C --> D{Succès ?}
    D -->|Oui| E[Mise à jour Hive]
    D -->|Non| F[Affichage erreur]
    E --> G[Notification succès]
    F --> H[Dialog reste ouvert]

🎨 Interface utilisateur

Tableaux interactifs

MembreTableWidget - Composant principal :

  • Colonnes : ID, Prénom, Nom, Email, Rôle, Statut
  • Actions : Modification, Suppression
  • Alternance de couleurs pour lisibilité
  • Tri et navigation intuitifs

MembreRowWidget - Ligne individuelle :

  • Clic pour édition rapide
  • Boutons d'action contextuels
  • Indicateurs visuels de statut
  • Tooltip informatifs

Formulaires adaptatifs

UserFormDialog - Modale réutilisable :

  • Layout responsive (>900px vs mobile)
  • Validation en temps réel
  • Gestion des erreurs inline
  • Sauvegarde avec feedback

📡 Synchronisation et réactivité

Architecture ValueListenableBuilder

// Écoute automatique des changements
ValueListenableBuilder<Box<MembreModel>>(
  valueListenable: membreRepository.getMembresBox().listenable(),
  builder: (context, membresBox, child) {
    // Interface mise à jour automatiquement
    final membres = membresBox.values
        .where((m) => m.fkEntite == currentUser.fkEntite)
        .toList();

    return MembreTableWidget(membres: membres);
  },
)

Principe "API First"

  1. Validation API : Tentative sur serveur en priorité
  2. Succès → Sauvegarde locale + mise à jour interface
  3. Erreur → Affichage message + maintien état local
  4. Cohérence : Données locales toujours synchronisées

🔄 Workflow complet

sequenceDiagram
    participant A as Admin
    participant UI as Interface
    participant R as Repository
    participant API as Serveur
    participant H as Hive

    A->>UI: Action membre
    UI->>R: Appel repository
    R->>API: Requête HTTP
    API-->>R: Réponse

    alt Succès
        R->>H: Sauvegarde locale
        H-->>UI: Notification changement
        UI-->>A: Interface mise à jour
    else Erreur
        R-->>UI: Exception
        UI-->>A: Message d'erreur
    end

🎯 Bonnes pratiques

Pour les administrateurs

  1. Vérification avant suppression : Toujours examiner les passages
  2. Préférer la désactivation : Éviter la perte de données
  3. Noms de tournée : Utiliser des identifiants terrain clairs
  4. Rôles appropriés : Limiter les administrateurs aux besoins

Gestion des erreurs courantes

Erreur Cause Solution
Email déjà utilisé Duplication Choisir un autre email
Membre avec passages Données liées Transférer ou désactiver
Aucune opération active Configuration Vérifier les opérations
Accès refusé Permissions Vérifier le rôle admin

Cette architecture garantit une gestion des membres robuste, sécurisée et intuitive, optimisant l'efficacité administrative tout en préservant l'intégrité des données opérationnelles. 👥

🗺️ 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. 🚀