415 lines
16 KiB
Markdown
415 lines
16 KiB
Markdown
# 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](#-fonctionnalités)
|
||
2. [Architecture technique](#️-architecture-technique)
|
||
3. [Installation](#-installation-et-configuration)
|
||
4. [Modèles de données](#️-modèles-de-données)
|
||
5. [Architecture des composants](#-architecture-des-composants)
|
||
6. [Gestion des rôles](#-gestion-des-rôles)
|
||
7. [Interface utilisateur](#-interface-utilisateur)
|
||
8. [API et synchronisation](#-api-et-synchronisation)
|
||
9. [Gestion des erreurs](#-gestion-des-erreurs)
|
||
10. [Cartes et géolocalisation](#️-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
|
||
|
||
```mermaid
|
||
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](https://www.mapbox.com/)
|
||
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
|
||
|
||
```dart
|
||
// 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
|
||
|
||
```mermaid
|
||
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. 🚀
|