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
- Fonctionnalités
- Architecture technique
- Installation
- Modèles de données
- Architecture des composants
- Gestion des rôles
- Interface utilisateur
- API et synchronisation
- Gestion des erreurs
- 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)
- Créer un compte sur Mapbox
- Générer un token d'accès
- Ajouter le token dans
.env
Configuration MQTT (Chat)
- Configurer votre broker MQTT
- Créer les credentials
- 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. 🚀