- 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>
25 KiB
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
- Vue d'ensemble
- Flow normal de démarrage
- Flow avec nettoyage du cache
- Gestion des Hive Box
- Vérifications et redirections
- Points critiques
🎯 Vue d'ensemble
L'application GEOSECTOR utilise une architecture de démarrage en 3 étapes principales :
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
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)
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
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)
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
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)
@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 :
areBoxesInitialized(): Vérifieusers,membres,settingshive_initialized: Flag dans settings confirmant init complète- Redirection automatique : Si échec → retour SplashPage avec params
🧹 Flow avec nettoyage du cache
Déclenchement manuel (Web uniquement)
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)
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
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
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()
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_requestssi elle contient des données - Recrée des boxes vierges
2. areBoxesInitialized() - Vérification rapide
Appelée par : LoginPage.initState()
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 pourgetCurrentUser() - ✅
membres: Nécessaire pour pré-remplissage username - ✅
settings: Contienthive_initializedetapp_version
3. cleanDataOnLogout() - Nettoyage logout
Appelée par : LoginPage (bouton "Nettoyer le cache")
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
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èteapp_version(String) : Version actuelle pour détection changements- Autres paramètres utilisateur
⚠️ Importance :
- Si
settingsest supprimée sans sauvegarde → perte de la version - Si
hive_initializedest absent → boucle de réinitialisation
✅ Solution actuelle :
- Nettoyage du cache : sauvegarde
app_versionen 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 :
// 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 :
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 :
// 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 :
// 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