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

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

  1. Vue d'ensemble
  2. Flow normal de démarrage
  3. Flow avec nettoyage du cache
  4. Gestion des Hive Box
  5. Vérifications et redirections
  6. 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 :

  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)

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_requests si 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 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")

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è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 :

// 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