# 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
(DEV/REC/PROD) AS-->>M: ✅ ApiService prêt M->>H: Hive.initFlutter() Note over H: Initialisation minimale
PAS d'adaptateurs
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
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
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
/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:
users, membres, settings alt Boxes non initialisées HS-->>LP: false LP->>LP: Redirection: '/?action=login&type=admin' Note over LP: ❌ Retour SplashPage
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
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 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:
users, operations, passages,
sectors, membres, amicale,
clients, user_sector,
chatRooms, chatMessages,
settings Note over Clean: ✅ Boxes préservées:
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
de l'application ``` #### **Code : SplashPage._performSelectiveCleanup() (lignes 84-243)** ```dart Future _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? 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 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 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?
Mobile uniquement} GPS -->|Refusées| ShowError[Afficher erreur GPS
+ Boutons Réessayer/Paramètres] ShowError --> End1[❌ Arrêt initialisation] GPS -->|OK ou Web| InitHive[Initialisation Hive complète] InitHive --> CheckVersion{Changement version?
Web uniquement} CheckVersion -->|Oui| CleanCache[Nettoyage auto du cache] CleanCache --> OpenBoxes[Ouverture boxes] CheckVersion -->|Non| OpenBoxes OpenBoxes --> AllOpen{Toutes boxes
ouvertes?} AllOpen -->|Non| ErrorInit[❌ Erreur initialisation] ErrorInit --> End2[Afficher message d'erreur] AllOpen -->|Oui| SaveFlag[settings.put
'hive_initialized' = true] SaveFlag --> URLParams{Paramètres URL
fournis?} URLParams -->|Oui| AutoRedirect[Redirection auto
/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
'/?action=login&type=X'] BackSplash --> Splash CheckBoxes -->|Oui| CheckFlag{hive_initialized
== 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