Files
geo/app/docs/FLOW-BOOT-APP.md
pierre 570a1fa1f0 feat: Version 3.3.4 - Nouvelle architecture pages, optimisations widgets Flutter et API
- Mise à jour VERSION vers 3.3.4
- Optimisations et révisions architecture API (deploy-api.sh, scripts de migration)
- Ajout documentation Stripe Tap to Pay complète
- Migration vers polices Inter Variable pour Flutter
- Optimisations build Android et nettoyage fichiers temporaires
- Amélioration système de déploiement avec gestion backups
- Ajout scripts CRON et migrations base de données

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-05 20:11:15 +02:00

900 lines
25 KiB
Markdown

# FLOW DE DÉMARRAGE DE L'APPLICATION GEOSECTOR
**Version** : 3.2.4
**Date** : 04 octobre 2025
**Objectif** : Cartographie complète du démarrage de l'application jusqu'à `login_page.dart`
---
## 📋 Table des matières
1. [Vue d'ensemble](#-vue-densemble)
2. [Flow normal de démarrage](#-flow-normal-de-démarrage)
3. [Flow avec nettoyage du cache](#-flow-avec-nettoyage-du-cache)
4. [Gestion des Hive Box](#-gestion-des-hive-box)
5. [Vérifications et redirections](#-vérifications-et-redirections)
6. [Points critiques](#-points-critiques)
---
## 🎯 Vue d'ensemble
L'application GEOSECTOR utilise une architecture de démarrage en **3 étapes principales** :
```mermaid
graph LR
A[main.dart] --> B[SplashPage]
B --> C[LoginPage]
C --> D[UserPage / AdminPage]
style A fill:#e1f5ff
style B fill:#fff4e1
style C fill:#e8f5e9
style D fill:#f3e5f5
```
**Responsabilités** :
- **main.dart** : Initialisation minimale des services et Hive
- **SplashPage** : Initialisation complète Hive + vérification permissions GPS
- **LoginPage** : Validation Hive + formulaire de connexion
---
## 🚀 Flow normal de démarrage
### **1. Point d'entrée : `main.dart`**
```mermaid
sequenceDiagram
participant M as main()
participant AS as ApiService
participant H as Hive
participant App as GeosectorApp
M->>M: usePathUrlStrategy()
M->>M: WidgetsFlutterBinding.ensureInitialized()
M->>AS: ApiService.initialize()
Note over AS: Détection environnement<br/>(DEV/REC/PROD)
AS-->>M: ✅ ApiService prêt
M->>H: Hive.initFlutter()
Note over H: Initialisation minimale<br/>PAS d'adaptateurs<br/>PAS de Box
H-->>M: ✅ Hive base initialisé
M->>App: runApp(GeosectorApp())
App->>App: Build MaterialApp.router
App->>App: Route initiale: '/' (SplashPage)
```
#### **Code : main.dart (lignes 10-32)**
```dart
void main() async {
usePathUrlStrategy(); // URLs sans #
WidgetsFlutterBinding.ensureInitialized();
await _initializeServices(); // ApiService + autres
await _initializeHive(); // Hive.initFlutter() seulement
runApp(const GeosectorApp()); // Lancer l'app
}
```
**🔑 Points clés :**
-**Initialisation minimale** : Pas d'adaptateurs, pas de Box
-**Services singleton** : ApiService, CurrentUserService, etc.
-**Hive base** : Juste `Hive.initFlutter()`, le reste dans SplashPage
---
### **2. Étape d'initialisation : `SplashPage`**
```mermaid
sequenceDiagram
participant SP as SplashPage
participant HS as HiveService
participant LS as LocationService
participant GPS as Permissions GPS
SP->>SP: initState()
SP->>SP: _getAppVersion()
SP->>SP: _startInitialization()
Note over SP: Progress: 0%
alt Sur Mobile (non-Web)
SP->>LS: checkAndRequestPermission()
LS->>GPS: Demande permissions
alt Permissions OK
GPS-->>LS: Granted
LS-->>SP: true
Note over SP: Progress: 10%
else Permissions refusées
GPS-->>LS: Denied
LS-->>SP: false
SP->>SP: _showLocationError = true
Note over SP: ❌ ARRÊT de l'initialisation
end
end
SP->>HS: initializeAndResetHive()
Note over SP: Progress: 15-60%
HS->>HS: _registerAdapters()
Note over HS: Enregistrement 14 adaptateurs
HS->>HS: _destroyAllData()
Note over HS: Fermeture boxes<br/>Suppression fichiers
HS->>HS: _createAllBoxes()
Note over HS: Ouverture 14 boxes typées
HS-->>SP: ✅ Hive initialisé
SP->>HS: ensureBoxesAreOpen()
Note over SP: Progress: 60-80%
HS-->>SP: ✅ Toutes les boxes ouvertes
SP->>SP: _checkVersionAndCleanIfNeeded()
Note over SP: Vérification app_version<br/>Nettoyage si nouvelle version
SP->>SP: Ouvrir pending_requests box
Note over SP: Progress: 80%
SP->>HS: areAllBoxesOpen()
HS-->>SP: true
Note over SP: Progress: 95%
SP->>SP: Sauvegarder hive_initialized = true
Note over SP: Progress: 100%
alt Paramètres URL fournis
SP->>SP: _handleAutoRedirect()
Note over SP: Redirection auto vers<br/>/login/user ou /login/admin
else Pas de paramètres
SP->>SP: Afficher boutons de choix
Note over SP: User / Admin / Register
end
```
#### **Code : SplashPage._startInitialization() (lignes 325-501)**
```dart
void _startInitialization() async {
// Étape 1: Permissions GPS (Mobile uniquement) - 0 à 10%
if (!kIsWeb) {
final hasPermission = await LocationService.checkAndRequestPermission();
if (!hasPermission) {
setState(() {
_showLocationError = true;
_isInitializing = false;
});
return; // ❌ ARRÊT si permissions refusées
}
}
// Étape 2: Initialisation Hive complète - 15 à 60%
await HiveService.instance.initializeAndResetHive();
// Étape 3: Ouverture des Box - 60 à 80%
await HiveService.instance.ensureBoxesAreOpen();
// Étape 4: Vérification version + nettoyage auto - 80%
await _checkVersionAndCleanIfNeeded();
// Étape 5: Box pending_requests - 80%
await Hive.openBox(AppKeys.pendingRequestsBoxName);
// Étape 6: Vérification finale - 80 à 95%
final allBoxesOpen = HiveService.instance.areAllBoxesOpen();
// Étape 7: Marquer initialisation terminée - 95 à 100%
final settingsBox = Hive.box(AppKeys.settingsBoxName);
await settingsBox.put('hive_initialized', true);
await settingsBox.put('app_version', _appVersion);
// Redirection ou affichage boutons
if (widget.action != null) {
await _handleAutoRedirect();
} else {
setState(() => _showButtons = true);
}
}
```
**🔑 Boxes créées (14 au total) :**
| Box Name | Type | Usage |
|----------|------|-------|
| `users` | UserModel | Utilisateur connecté |
| `amicales` | AmicaleModel | Organisations |
| `clients` | ClientModel | Clients distributions |
| `operations` | OperationModel | Campagnes |
| `sectors` | SectorModel | Secteurs géographiques |
| `passages` | PassageModel | Distributions |
| `membres` | MembreModel | Équipes membres |
| `user_sector` | UserSectorModel | Affectations secteurs |
| `chat_rooms` | Room | Salles de chat |
| `chat_messages` | Message | Messages chat |
| `pending_requests` | PendingRequest | File requêtes offline |
| `temp_entities` | dynamic | Entités temporaires |
| `settings` | dynamic | **Paramètres app** ⚠️ |
| `regions` | dynamic | Régions |
**⚠️ Box critique : `settings`**
- Contient `hive_initialized` (flag d'initialisation complète)
- Contient `app_version` (détection changement de version)
---
### **3. Page de connexion : `LoginPage`**
```mermaid
sequenceDiagram
participant LP as LoginPage
participant HS as HiveService
participant S as Settings Box
participant UR as UserRepository
LP->>LP: initState()
LP->>HS: areBoxesInitialized()
HS->>HS: Vérifier boxes critiques:<br/>users, membres, settings
alt Boxes non initialisées
HS-->>LP: false
LP->>LP: Redirection: '/?action=login&type=admin'
Note over LP: ❌ Retour SplashPage<br/>pour réinitialisation
else Boxes initialisées
HS-->>LP: true
LP->>S: get('hive_initialized')
alt hive_initialized != true
S-->>LP: false
LP->>LP: Redirection: '/?action=login&type=admin'
Note over LP: ❌ Retour SplashPage<br/>pour réinitialisation complète
else hive_initialized == true
S-->>LP: true
LP->>LP: Continuer initialisation
LP->>LP: Détecter loginType (user/admin)
LP->>UR: getAllUsers()
LP->>LP: Pré-remplir username si rôle correspond
LP->>LP: Afficher formulaire de connexion
end
end
```
#### **Code : LoginPage.initState() (lignes 100-162)**
```dart
@override
void initState() {
super.initState();
// VÉRIFICATION 1 : Boxes critiques ouvertes ?
if (!HiveService.instance.areBoxesInitialized()) {
debugPrint('⚠️ Boxes Hive non initialisées, redirection vers SplashPage');
final loginType = widget.loginType ?? 'admin';
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
context.go('/?action=login&type=$loginType');
}
});
_loginType = '';
return; // ❌ ARRÊT de initState
}
// VÉRIFICATION 2 : Flag hive_initialized défini ?
try {
if (Hive.isBoxOpen(AppKeys.settingsBoxName)) {
final settingsBox = Hive.box(AppKeys.settingsBoxName);
final isInitialized = settingsBox.get('hive_initialized', defaultValue: false);
if (isInitialized != true) {
debugPrint('⚠️ Réinitialisation Hive requise');
final loginType = widget.loginType ?? 'admin';
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
context.go('/?action=login&type=$loginType');
}
});
_loginType = '';
return; // ❌ ARRÊT de initState
}
debugPrint('✅ Hive correctement initialisé');
}
} catch (e) {
// En cas d'erreur, forcer réinitialisation
final loginType = widget.loginType ?? 'admin';
context.go('/?action=login&type=$loginType');
return;
}
// ✅ Tout est OK : continuer initialisation normale
_loginType = widget.loginType!;
// ... pré-remplissage username, etc.
}
```
**🔑 Vérifications critiques :**
1. **`areBoxesInitialized()`** : Vérifie `users`, `membres`, `settings`
2. **`hive_initialized`** : Flag dans settings confirmant init complète
3. **Redirection automatique** : Si échec → retour SplashPage avec params
---
## 🧹 Flow avec nettoyage du cache
### **Déclenchement manuel (Web uniquement)**
```mermaid
sequenceDiagram
participant U as Utilisateur
participant SP as SplashPage
participant Clean as _performSelectiveCleanup()
participant SW as Service Worker (Web)
participant H as Hive
participant PR as pending_requests
participant Settings as settings box
U->>SP: Clic "Nettoyer le cache"
SP->>U: Dialog confirmation
U->>SP: Confirme "Nettoyer"
SP->>Clean: _performSelectiveCleanup(manual: true)
Note over Clean: Progress: 10%
alt Sur Web (kIsWeb)
Clean->>SW: Désenregistrer Service Workers
Clean->>SW: Supprimer caches navigateur
SW-->>Clean: ✅ Caches web nettoyés
end
Note over Clean: Progress: 30%
Clean->>PR: Sauvegarder en mémoire
PR-->>Clean: List<dynamic> pendingRequests
Clean->>Settings: Sauvegarder app_version en mémoire
Settings-->>Clean: String savedAppVersion
Clean->>PR: Fermer box
Clean->>Settings: Fermer box
Note over Clean: Progress: 50%
Clean->>H: Fermer toutes les boxes
loop Pour chaque box (11 boxes)
Clean->>H: close() + deleteBoxFromDisk()
end
Note over Clean: ⚠️ Boxes supprimées:<br/>users, operations, passages,<br/>sectors, membres, amicale,<br/>clients, user_sector,<br/>chatRooms, chatMessages,<br/>settings
Note over Clean: ✅ Boxes préservées:<br/>pending_requests
Note over Clean: Progress: 70%
Clean->>H: Hive.close()
Clean->>H: Future.delayed(500ms)
Clean->>H: Hive.initFlutter()
Note over Clean: Progress: 80%
Clean->>PR: Restaurer pending_requests
loop Pour chaque requête
Clean->>PR: add(request)
end
Clean->>Settings: Restaurer app_version
Clean->>Settings: put('app_version', savedAppVersion)
Note over Clean: Progress: 100%
Clean-->>SP: ✅ Nettoyage terminé
SP->>SP: _startInitialization()
Note over SP: Redémarrage complet<br/>de l'application
```
#### **Code : SplashPage._performSelectiveCleanup() (lignes 84-243)**
```dart
Future<void> _performSelectiveCleanup({bool manual = false}) async {
debugPrint('🧹 === DÉBUT DU NETTOYAGE DU CACHE === 🧹');
try {
// Étape 1: Service Worker (Web uniquement) - 10%
if (kIsWeb) {
final registrations = await html.window.navigator.serviceWorker?.getRegistrations();
for (final registration in registrations) {
await registration.unregister();
}
final cacheNames = await html.window.caches!.keys();
for (final cacheName in cacheNames) {
await html.window.caches!.delete(cacheName);
}
}
// Étape 2: Sauvegarder pending_requests + app_version - 30%
List<dynamic>? pendingRequests;
String? savedAppVersion;
if (Hive.isBoxOpen(AppKeys.pendingRequestsBoxName)) {
final pendingBox = Hive.box(AppKeys.pendingRequestsBoxName);
pendingRequests = pendingBox.values.toList();
await pendingBox.close();
}
if (Hive.isBoxOpen(AppKeys.settingsBoxName)) {
final settingsBox = Hive.box(AppKeys.settingsBoxName);
savedAppVersion = settingsBox.get('app_version') as String?;
}
// Étape 3: Lister boxes à nettoyer - 50%
final boxesToClean = [
AppKeys.userBoxName,
AppKeys.operationsBoxName,
AppKeys.passagesBoxName,
AppKeys.sectorsBoxName,
AppKeys.membresBoxName,
AppKeys.amicaleBoxName,
AppKeys.clientsBoxName,
AppKeys.userSectorBoxName,
AppKeys.settingsBoxName, // ⚠️ Supprimée (mais version sauvegardée)
AppKeys.chatRoomsBoxName,
AppKeys.chatMessagesBoxName,
];
// Étape 4: Supprimer les boxes - 50%
for (final boxName in boxesToClean) {
if (Hive.isBoxOpen(boxName)) {
await Hive.box(boxName).close();
}
await Hive.deleteBoxFromDisk(boxName);
}
// Étape 5: Réinitialiser Hive - 70%
await Hive.close();
await Future.delayed(const Duration(milliseconds: 500));
await Hive.initFlutter();
// Étape 6: Restaurer données critiques - 80-100%
if (pendingRequests != null && pendingRequests.isNotEmpty) {
final pendingBox = await Hive.openBox(AppKeys.pendingRequestsBoxName);
for (final request in pendingRequests) {
await pendingBox.add(request);
}
}
if (savedAppVersion != null) {
final settingsBox = await Hive.openBox(AppKeys.settingsBoxName);
await settingsBox.put('app_version', savedAppVersion);
}
debugPrint('🎉 === NETTOYAGE TERMINÉ AVEC SUCCÈS === 🎉');
} catch (e) {
debugPrint('❌ ERREUR CRITIQUE lors du nettoyage: $e');
}
}
```
### **Nettoyage automatique sur changement de version**
```mermaid
sequenceDiagram
participant SP as SplashPage
participant S as Settings Box
participant Check as _checkVersionAndCleanIfNeeded()
participant Clean as _performSelectiveCleanup()
SP->>SP: _startInitialization()
SP->>S: Boxes ouvertes
SP->>Check: _checkVersionAndCleanIfNeeded()
Check->>S: get('app_version')
S-->>Check: lastVersion = "3.2.3"
Check->>Check: currentVersion = "3.2.4"
alt Version changée
Check->>Check: lastVersion != currentVersion
Note over Check: 🆕 NOUVELLE VERSION DÉTECTÉE
Check->>Clean: _performSelectiveCleanup(manual: false)
Clean-->>Check: ✅ Nettoyage auto terminé
Check->>S: put('app_version', '3.2.4')
S-->>Check: ✅ Version mise à jour
else Même version
Check->>Check: lastVersion == currentVersion
Note over Check: ✅ Pas de nettoyage nécessaire
end
Check-->>SP: Terminé
```
**🔑 Cas d'usage :**
- **Déploiement nouvelle version web** : Cache automatiquement nettoyé
- **Update version mobile** : Détection et nettoyage auto
- **Préserve** : `pending_requests` (requêtes offline) + `app_version`
---
## 📦 Gestion des Hive Box
### **HiveService : Architecture complète**
```mermaid
graph TD
A[HiveService Singleton] --> B[Initialisation]
A --> C[Nettoyage]
A --> D[Utilitaires]
B --> B1[initializeAndResetHive]
B --> B2[ensureBoxesAreOpen]
B1 --> B1a[_registerAdapters]
B1 --> B1b[_destroyAllData]
B1 --> B1c[_createAllBoxes]
B1b --> B1b1[_destroyDataWeb]
B1b --> B1b2[_destroyDataIOS]
B1b --> B1b3[_destroyDataAndroid]
B1b --> B1b4[_destroyDataDesktop]
C --> C1[cleanDataOnLogout]
C --> C2[_clearSingleBox]
D --> D1[areBoxesInitialized]
D --> D2[areAllBoxesOpen]
D --> D3[getDiagnostic]
style A fill:#e1f5ff
style B fill:#fff4e1
style C fill:#ffe1e1
style D fill:#e8f5e9
```
### **Méthodes critiques**
#### **1. `initializeAndResetHive()` - Initialisation complète**
**Appelée par** : `SplashPage._startInitialization()`
```dart
Future<void> initializeAndResetHive() async {
// 1. Initialisation de base
await Hive.initFlutter();
// 2. Enregistrement adaptateurs (14 types)
_registerAdapters();
// 3. Destruction complète des anciennes données
await _destroyAllData();
// 4. Création de toutes les Box vides et propres
await _createAllBoxes();
_isInitialized = true;
}
```
**⚠️ Comportement destructif** :
- Supprime TOUTES les boxes existantes
- Préserve `pending_requests` si elle contient des données
- Recrée des boxes vierges
---
#### **2. `areBoxesInitialized()` - Vérification rapide**
**Appelée par** : `LoginPage.initState()`
```dart
bool areBoxesInitialized() {
// Vérifier seulement les boxes critiques
final criticalBoxes = [
AppKeys.userBoxName, // getCurrentUser
AppKeys.membresBoxName, // Pré-remplissage
AppKeys.settingsBoxName, // Préférences
];
for (final boxName in criticalBoxes) {
if (!Hive.isBoxOpen(boxName)) {
return false;
}
}
if (!_isInitialized) {
return false;
}
return true;
}
```
**🔑 Boxes critiques vérifiées** :
-`users` : Nécessaire pour `getCurrentUser()`
-`membres` : Nécessaire pour pré-remplissage username
-`settings` : Contient `hive_initialized` et `app_version`
---
#### **3. `cleanDataOnLogout()` - Nettoyage logout**
**Appelée par** : `LoginPage` (bouton "Nettoyer le cache")
```dart
Future<void> cleanDataOnLogout() async {
// Nettoyer toutes les Box SAUF users
for (final config in _boxConfigs) {
if (config.name != AppKeys.userBoxName) {
await _clearSingleBox(config.name);
}
}
}
```
**⚠️ Préserve** : Box `users` (pour pré-remplissage username au prochain login)
---
## 🔍 Vérifications et redirections
### **Système de redirections automatiques**
```mermaid
graph TD
Start[Application démarre] --> Main[main.dart]
Main --> Splash[SplashPage]
Splash --> GPS{Permissions GPS?<br/>Mobile uniquement}
GPS -->|Refusées| ShowError[Afficher erreur GPS<br/>+ Boutons Réessayer/Paramètres]
ShowError --> End1[❌ Arrêt initialisation]
GPS -->|OK ou Web| InitHive[Initialisation Hive complète]
InitHive --> CheckVersion{Changement version?<br/>Web uniquement}
CheckVersion -->|Oui| CleanCache[Nettoyage auto du cache]
CleanCache --> OpenBoxes[Ouverture boxes]
CheckVersion -->|Non| OpenBoxes
OpenBoxes --> AllOpen{Toutes boxes<br/>ouvertes?}
AllOpen -->|Non| ErrorInit[❌ Erreur initialisation]
ErrorInit --> End2[Afficher message d'erreur]
AllOpen -->|Oui| SaveFlag[settings.put<br/>'hive_initialized' = true]
SaveFlag --> URLParams{Paramètres URL<br/>fournis?}
URLParams -->|Oui| AutoRedirect[Redirection auto<br/>/login/user ou /login/admin]
URLParams -->|Non| ShowButtons[Afficher boutons choix]
AutoRedirect --> Login[LoginPage]
ShowButtons --> UserClick{Utilisateur clique}
UserClick --> Login
Login --> CheckBoxes{Boxes initialisées?}
CheckBoxes -->|Non| BackSplash[Redirection<br/>'/?action=login&type=X']
BackSplash --> Splash
CheckBoxes -->|Oui| CheckFlag{hive_initialized<br/>== true?}
CheckFlag -->|Non| BackSplash
CheckFlag -->|Oui| ShowForm[✅ Afficher formulaire]
ShowForm --> UserLogin[Utilisateur se connecte]
UserLogin --> Dashboard[UserPage / AdminPage]
style Start fill:#e1f5ff
style Splash fill:#fff4e1
style Login fill:#e8f5e9
style Dashboard fill:#f3e5f5
style ShowError fill:#ffe1e1
style ErrorInit fill:#ffe1e1
```
### **Tableau des redirections**
| Condition | Action | Paramètres URL |
|-----------|--------|----------------|
| **Boxes non initialisées** | Redirect → SplashPage | `/?action=login&type=admin` |
| **`hive_initialized` != true** | Redirect → SplashPage | `/?action=login&type=user` |
| **Permissions GPS refusées** | Afficher erreur | Aucune redirection |
| **Changement version (Web)** | Nettoyage auto | Transparent |
| **Nettoyage manuel** | Réinitialisation complète | Vers `/` après nettoyage |
---
## ⚠️ Points critiques
### **1. Box `settings` - Données essentielles**
**Contenu** :
- `hive_initialized` (bool) : Flag confirmant initialisation complète
- `app_version` (String) : Version actuelle pour détection changements
- Autres paramètres utilisateur
**⚠️ Importance** :
- Si `settings` est supprimée sans sauvegarde → perte de la version
- Si `hive_initialized` est absent → boucle de réinitialisation
**✅ Solution actuelle** :
- Nettoyage du cache : sauvegarde `app_version` en mémoire avant suppression
- Restauration automatique après réinitialisation Hive
---
### **2. Box `pending_requests` - Requêtes offline**
**Contenu** :
- File d'attente des requêtes API en mode hors ligne
- Modèle : `PendingRequest`
**⚠️ Protection** :
- JAMAIS supprimée pendant nettoyage si elle contient des données
- Sauvegardée en mémoire pendant `_performSelectiveCleanup()`
- Restaurée après réinitialisation
**Code protection** :
```dart
// Dans _performSelectiveCleanup()
if (Hive.isBoxOpen(AppKeys.pendingRequestsBoxName)) {
final pendingBox = Hive.box(AppKeys.pendingRequestsBoxName);
pendingRequests = pendingBox.values.toList(); // Sauvegarde
await pendingBox.close();
}
// ... nettoyage des autres boxes ...
// Restauration
if (pendingRequests != null && pendingRequests.isNotEmpty) {
final pendingBox = await Hive.openBox(AppKeys.pendingRequestsBoxName);
for (final request in pendingRequests) {
await pendingBox.add(request);
}
}
```
---
### **3. Permissions GPS (Mobile uniquement)**
**Vérification obligatoire** :
- Sur mobile : `LocationService.checkAndRequestPermission()`
- Si refusées : affichage erreur + arrêt initialisation
- Sur web : vérification ignorée
**Messages contextuels** :
```dart
final errorMessage = await LocationService.getLocationErrorMessage();
// Exemples de messages :
// - "Permissions refusées temporairement"
// - "Permissions refusées définitivement - ouvrir Paramètres"
// - "Service de localisation désactivé"
```
---
### **4. Bouton "Nettoyer le cache" (Web uniquement)**
**Restriction plateforme** :
```dart
// Dans splash_page.dart (ligne 932)
if (kIsWeb)
AnimatedOpacity(
child: TextButton.icon(
label: Text('Nettoyer le cache'),
// ...
),
),
```
**Fonctionnalités Web spécifiques** :
- Désenregistrement Service Workers
- Suppression caches navigateur (`window.caches`)
- Nettoyage localStorage (via Service Worker)
**⚠️ Sur mobile** : Utilise `HiveService.cleanDataOnLogout()` (dans LoginPage)
---
### **5. Détection automatique d'environnement**
**ApiService** :
```dart
// Détection basée sur l'URL
if (currentUrl.contains('dapp.geosector.fr')) DEV
if (currentUrl.contains('rapp.geosector.fr')) REC
Sinon PROD
```
**Impact sur le nettoyage** :
- Web DEV/REC : nettoyage auto sur changement version
- Web PROD : nettoyage auto sur changement version
- Mobile : pas de nettoyage auto (version gérée par stores)
---
## 📊 Récapitulatif des états
### **États de l'application**
| État | Description | Boxes Hive | Flag `hive_initialized` |
|------|-------------|-----------|------------------------|
| **Démarrage initial** | Premier lancement | Vides | ❌ Absent |
| **Initialisé** | SplashPage terminé | Ouvertes et vides | ✅ `true` |
| **Connecté** | Utilisateur loggé | Remplies avec données API | ✅ `true` |
| **Après nettoyage** | Cache vidé | Réinitialisées | ✅ `true` (restauré) |
| **Erreur init** | Échec initialisation | Partielles ou fermées | ❌ Absent ou `false` |
### **Chemins possibles**
```
main.dart
SplashPage (initialisation)
[Web] Vérification version → Nettoyage auto si besoin
[Mobile] Vérification GPS → Erreur si refusé
Ouverture 14 boxes Hive
settings.put('hive_initialized', true)
LoginPage
Vérification boxes + hive_initialized
[OK] Afficher formulaire
[KO] Redirection SplashPage
```
---
## 🎯 Conclusion
Le système de démarrage GEOSECTOR v3.2.4 implémente une architecture robuste en **3 étapes** avec des **vérifications multiples** et une **gestion intelligente du cache**.
**Points forts** :
- ✅ Initialisation progressive avec feedback visuel (barre de progression)
- ✅ Protection des données critiques (`pending_requests`, `app_version`)
- ✅ Détection automatique des problèmes (boxes non ouvertes, version changée)
- ✅ Redirections automatiques pour forcer réinitialisation si nécessaire
- ✅ Nettoyage sélectif du cache (Web uniquement)
**Sécurités** :
- ⚠️ Vérification permissions GPS (mobile obligatoire)
- ⚠️ Double vérification Hive (boxes + flag `hive_initialized`)
- ⚠️ Sauvegarde mémoire avant nettoyage (`pending_requests`, `app_version`)
- ⚠️ Restriction plateforme (bouton cache Web uniquement)
---
**Document généré le** : 04 octobre 2025
**Version application** : v3.2.4
**Auteur** : Documentation technique GEOSECTOR