Files
geo/app/docs/README-APP.md
pierre 2f5946a184 feat: Version 3.5.2 - Configuration Stripe et gestion des immeubles
- Configuration complète Stripe pour les 3 environnements (DEV/REC/PROD)
  * DEV: Clés TEST Pierre (mode test)
  * REC: Clés TEST Client (mode test)
  * PROD: Clés LIVE Client (mode live)
- Ajout de la gestion des bases de données immeubles/bâtiments
  * Configuration buildings_database pour DEV/REC/PROD
  * Service BuildingService pour enrichissement des adresses
- Optimisations pages et améliorations ergonomie
- Mises à jour des dépendances Composer
- Nettoyage des fichiers obsolètes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:26:27 +01:00

80 KiB
Executable File
Raw Blame History

GEOSECTOR v3.2.4

🚒 Application de gestion des distributions de calendriers par secteurs géographiques pour les amicales de pompiers


🎯 Vue d'ensemble

GEOSECTOR est une solution complète développée en Flutter qui révolutionne la gestion des campagnes de distribution de calendriers pour les amicales de pompiers. L'application combine géolocalisation, gestion multi-rôles et synchronisation en temps réel pour optimiser les tournées et maximiser l'efficacité des équipes.

🏆 Points forts de la v3.2.4

  • Architecture moderne sans Provider, basée sur l'injection de dépendances
  • Réactivité native avec ValueListenableBuilder et Hive
  • Interface adaptative selon les rôles utilisateur et la taille d'écran
  • Performance optimisée avec un ApiService singleton et cache Hive
  • Gestion avancée des permissions multi-niveaux
  • Gestion d'erreurs centralisée avec ApiException
  • Interface utilisateur épurée avec suppression des titres superflus
  • Chat responsive avec layout adaptatif mobile/desktop
  • Système de filtrage centralisé dans PassagesListWidget
  • Intégration Stripe Connect pour les paiements des amicales

📋 Table des matières

  1. Fonctionnalités
  2. Architecture technique
  3. Installation
  4. Modèles de données
  5. Architecture des composants
  6. Gestion des rôles
  7. Interface utilisateur
  8. API et synchronisation
  9. Gestion des erreurs
  10. Gestion des membres
  11. Intégration Stripe
  12. Cartes et géolocalisation

🚀 Fonctionnalités

🎯 Fonctionnalités métier

Pour les Membres (Rôle 1)

  • Visualisation des secteurs assignés sur carte interactive
  • Suivi GPS en temps réel des tournées
  • Enregistrement des passages avec géolocalisation
  • Gestion des stocks de calendriers
  • Historique des distributions
  • Chat intégré avec l'équipe

Pour les Admins Amicale (Rôle 2)

  • Gestion de leur amicale (informations, coordonnées)
  • Gestion des membres de l'amicale (création, modification, suppression)
  • Attribution des rôles aux membres (Membre/Administrateur)
  • Gestion du statut actif des comptes membres
  • Consultation des statistiques de l'amicale
  • Attribution des secteurs aux membres
  • Suivi des performances équipe

Pour les Super Admins (Rôle 3+)

  • Gestion globale multi-amicales
  • Administration des utilisateurs et permissions
  • Configuration des paramètres système
  • Analytics avancées et reporting
  • Gestion des secteurs géographiques

💳 Fonctionnalités de paiement Stripe

Stripe Connect V1 (Opérationnel depuis 01/09/2024)

  • Configuration amicale : Onboarding Stripe Connect pour chaque amicale
  • Comptes séparés : Chaque amicale reçoit directement ses paiements (0% commission plateforme)
  • Interface web : Configuration uniquement via interface web (rôle admin minimum)
  • Statuts dynamiques : Vérification temps réel du statut des comptes Stripe
  • Messages français : Interface entièrement traduite avec statuts explicites
  • Sécurité PCI : Conformité automatique via Stripe Connect

Tap to Pay V2 🔄 (En développement - Livraison prévue Q4 2025)

  • 🔄 Paiement sans contact : NFC iPhone pour accepter cartes bancaires
  • 🔄 Compatibilité iOS : iPhone XS+ avec iOS 16.4+ minimum
  • 🔄 Mode offline : File d'attente avec synchronisation automatique
  • 🔄 Montants flexibles : Prédéfinis (10€, 20€, 30€, 50€) ou personnalisés
  • 🔄 Reçus numériques : Envoi automatique par email/SMS
  • 🔄 Dashboard vendeur : Statistiques temps réel des ventes
  • 🔄 Support Android : Prévu en V2.2 avec appareils certifiés

🔧 Fonctionnalités techniques

  • 🗺️ Cartographie avancée : Flutter Map avec tuiles Mapbox
  • 📍 Géolocalisation précise : Suivi GPS des équipes
  • 💾 Stockage hybride : Cache local Hive + synchronisation cloud avec optimisation des performances
  • 💬 Communication : Chat MQTT en temps réel
  • 🔐 Sécurité : Authentification JWT + gestion fine des permissions
  • 📱 Multi-plateforme : iOS, Android, Web
  • 🌐 Mode hors-ligne : Fonctionnement dégradé sans connexion
  • Gestion d'erreurs robuste : Extraction automatique des messages API
  • 🎨 Interface responsive : Adaptation automatique selon la taille d'écran
  • 💳 Paiements Stripe : Stripe Connect V1 + Tap to Pay V2 (iOS 16.4+)
  • 🏪 E-commerce intégré : Encaissement direct des dons via carte bancaire

🏗️ Architecture technique

Stack technologique

Composant Technologie Version Usage
Framework Flutter 3.32+ Interface multi-plateforme
Langage Dart 3.0+ Logique applicative
Navigation GoRouter 12.1.3 Routing déclaratif
Stockage local Hive 2.2.3 Base de données NoSQL locale
Réactivité ValueListenableBuilder Native Écoute des changements Hive
HTTP Dio 5.4.0 Client HTTP avec intercepteurs
Cartes Flutter Map 6.1.0 Rendu cartographique
Géolocalisation Geolocator 10.1.0 Services de localisation
Chat MQTT5 Client 4.2.0 Messagerie temps réel
UI Material Design 3 Native Composants d'interface
Logging LoggerService Custom Logs conditionnels par env
Paiements Stripe Flutter 12.0.0 SDK Stripe pour paiements web
Terminal mek_stripe_terminal 3.2.0 SDK Tap to Pay (iOS)
Device Info device_info_plus 10.1.0 Détection compatibilité

🏛️ Architecture en couches

L'application utilise une architecture en trois couches :

  • UI Layer : Widgets avec ValueListenableBuilder
  • Repository Layer : Logique métier (UserRepository, AmicaleRepository, MembreRepository)
  • Data Layer : Hive Boxes + API Service Singleton + ApiException Handler

💳 Architecture Stripe Connect & Terminal

L'architecture Stripe se divise en deux parties :

  • Web Admin : Interface Web Admin → AmicaleRepository → StripeConnectService → API PHP Stripe → Stripe Connect API → Base de données
  • Mobile : App Flutter → StripeTapToPayService → mek_stripe_terminal SDK → Stripe Terminal API → Hive Local Storage
  • Services : DeviceInfoService, CurrentUserService, PaymentRepository

📁 Structure du projet

Le projet est organisé en plusieurs dossiers principaux :

lib/ - Code source principal

  • core/ - Couche centrale

    • constants/ - Constantes globales (app_keys.dart, api_endpoints.dart)
    • data/models/ - Modèles Hive (user_model, amicale_model, membre_model)
    • repositories/ - Logique métier (user_repository, amicale_repository, membre_repository)
    • services/ - Services externes (api_service, chat_service, location_service, stripe_connect_service, stripe_tap_to_pay_service, device_info_service)
    • utils/ - Utilitaires (validators, formatters)
  • presentation/ - Interface utilisateur

    • admin/ - Pages administrateur
    • user/ - Pages utilisateur
    • widgets/ - Composants réutilisables (tables, forms, common)
    • theme/ - Thème de l'application

Autres dossiers

  • assets/ - Ressources statiques (images, icons, fonts)
  • test/ - Tests unitaires
  • integration_test/ - Tests d'intégration
  • docs/ - Documentation


🚀 Installation et configuration

Prérequis système

  • Flutter SDK : 3.32 ou supérieur
  • Dart SDK : 3.0 ou supérieur
  • IDE : Android Studio, VS Code, ou IntelliJ
  • Environnement :
    • Android : SDK 21+ (Android 5.0+)
    • iOS : iOS 12.0+
    • Web : Navigateurs modernes

🔐 Configuration des clés API

Mapbox (Cartographie)

  1. Créer un compte sur Mapbox
  2. Générer un token d'accès
  3. Ajouter le token dans .env

Configuration MQTT (Chat)

  1. Configurer votre broker MQTT
  2. Créer les credentials
  3. Tester la connexion

🗄️ Modèles de données

Registres Hive des adaptateurs

Modèles principaux :

  • UserModelAdapter : typeId 0
  • OperationModelAdapter : typeId 1
  • SectorModelAdapter : typeId 3
  • PassageModelAdapter : typeId 4
  • MembreModelAdapter : typeId 5
  • UserSectorModelAdapter : typeId 6
  • RegionModelAdapter : typeId 7
  • ClientModelAdapter : typeId 10
  • AmicaleModelAdapter : typeId 11

Modèles de chat :

  • ConversationModelAdapter : typeId 20
  • MessageModelAdapter : typeId 21
  • ParticipantModelAdapter : typeId 22
  • AnonymousUserModelAdapter : typeId 23
  • AudienceTargetModelAdapter : typeId 24
  • NotificationSettingsAdapter : typeId 25

Clarification importante : UserModel vs MembreModel vs UserSectorModel

⚠️ ATTENTION : Il existe une distinction cruciale entre ces trois modèles :

UserModel (Box: users)

  • Représente uniquement l'utilisateur courant connecté (current user)
  • Stocké dans la box Hive users qui ne contient qu'un seul enregistrement
  • Utilisé pour l'authentification et la session de l'utilisateur actuel
  • Ne pas confondre avec les membres de l'amicale

MembreModel (Box: membres)

  • Représente tous les membres d'une amicale
  • Stocké dans la box Hive membres qui contient plusieurs enregistrements
  • Utilisé pour la gestion des équipes et l'attribution aux secteurs
  • Chaque membre a son propre ID unique

UserSectorModel (Box: user_sector)

  • Représente l'association entre un membre et un secteur
  • ⚠️ IMPORTANT : Le champ id dans UserSectorModel correspond à l'ID du membre (MembreModel.id), PAS à l'ID de l'utilisateur (UserModel.id)
  • Permet de savoir quels membres sont affectés à quels secteurs
  • Nom trompeur : devrait s'appeler "MemberSectorModel" pour éviter la confusion

Compatibilité entre modèles

  • UserModel ↔ MembreModel : Conversion bidirectionnelle via toUserModel() et fromUserModel()
  • Synchronisation : Maintien de la cohérence entre les deux représentations
  • Champs spécialisés : Préservation des données spécifiques à chaque modèle

🎨 Interface utilisateur

📱 Améliorations v3.x - Interface épurée et responsive

🎯 Simplification des titres de pages

La v3.1.0 a apporté une refonte majeure de l'interface pour maximiser l'espace utile et améliorer l'expérience utilisateur sur tous les écrans :

Pages avec titres supprimés :

  • user_history_page.dart : Historique des passages
  • user_statistics_page.dart : Statistiques
  • user_map_page.dart : Carte des passages
  • admin_history_page.dart : Historique admin
  • admin_statistics_page.dart : Statistiques admin
  • chat_communication_page.dart : Interface de chat

Pages avec titres conservés mais optimisés :

  • user_dashboard_home_page.dart : Titre responsive (taille réduite de 28 à 20)
  • admin_dashboard_home_page.dart : Titre réduit (de headlineSmall à titleLarge) + suppression icône refresh

💬 Chat responsive adaptatif

Le module de chat (rooms_page_embedded.dart) s'adapte automatiquement à la taille d'écran :

Desktop (>900px) :

  • Layout horizontal : Rooms à gauche (300px), Messages à droite
  • Navigation fluide entre les conversations

Mobile (<900px) :

  • Layout vertical : Rooms en haut (30% hauteur), Messages en bas
  • Hauteur adaptative avec contraintes (200-350px)
  • Optimisation pour les écrans tactiles

🗺️ Carte avec filtres intégrés

La carte des passages (user_map_page.dart) a été repensée :

  • Carte plein écran : Utilisation maximale de l'espace disponible
  • Filtres en overlay : 6 pastilles colorées en bas à gauche
  • Design minimaliste :
    • Pastille vive = filtre actif
    • Pastille semi-transparente (alpha 0.3) = filtre inactif
    • Sans labels pour économiser l'espace
    • Container blanc arrondi avec ombre pour regrouper les pastilles

Architecture des composants

UserFormDialog - Modale unifiée Réutilisabilité : Même widget pour "Mon Compte" et "Gestion des Membres" Personnalisation contextuelle : Sélecteur de rôle (Membre/Administrateur) Checkbox statut actif/inactif Édition du nom d'utilisateur selon le contexte Gestion du nom de tournée (sectName) Interface responsive : Adaptation automatique selon la largeur d'écran UserForm - Formulaire intelligent Layout adaptatif :

900px : Champs groupés en lignes (username+email, prénom+nom, téléphones, dates) ≤ 900px : Champs empilés verticalement Validation conditionnelle : Au moins nom OU nom de tournée requis Champs dynamiques : Affichage selon les permissions et le contexte Indicateurs visuels : Points rouges sur les champs obligatoires Tableaux interactifs AmicaleTableWidget : Gestion des amicales avec édition inline MembreTableWidget : Gestion des membres avec actions contextuelles Alternance de couleurs : Amélioration de la lisibilité Clic sur ligne : Ouverture directe du formulaire d'édition

🔗 API et synchronisation

Principe "API First"

Flow de mise à jour

Validation API : Tentative de mise à jour sur le serveur Succès → Sauvegarde locale avec isSynced: true Erreur → Aucune modification locale + affichage de l'erreur

Avantages

Cohérence des données : Local toujours synchronisé avec le serveur Gestion d'erreurs propre : Pas de conflits entre données locales et distantes UX claire : Feedback immédiat sur les erreurs de validation

ApiService Singleton

  • Thread-safe : Initialisation sécurisée avec verrous
  • Auto-configuration : Détection automatique de l'environnement (DEV/REC/PROD)
  • Gestion de session : Headers d'authentification automatiques
  • Retry logic : Nouvelles tentatives pour les erreurs réseau

⚠️ Gestion des erreurs

🎯 Système ApiException intelligent

GEOSECTOR v3.x utilise un système centralisé de gestion des messages qui s'adapte automatiquement au contexte d'affichage pour garantir une visibilité optimale des notifications utilisateur.

🧠 Détection automatique de contexte

L'ApiException détecte intelligemment si elle est appelée depuis une Dialog et adapte l'affichage :

  • 📱 Contexte normal : SnackBar standard en bas d'écran
  • 💬 Contexte Dialog : Overlay SnackBar positionné au-dessus de la Dialog estompée
  • 🌐 Mobile/Web : Adaptation automatique selon la plateforme
  • 🎨 Cohérence visuelle : Couleurs, icônes et comportements unifiés

Gestion des validations :

  • En cas d'erreur dans une Dialog : affichage de l'erreur, Dialog reste ouverte
  • En cas de succès : fermeture de la Dialog puis affichage de la confirmation

Avantages de l'approche unifiée

Aspect Avant Avec ApiException
Visibilité SnackBar masqué par Dialog Overlay visible au-dessus
Consistance Messages dispersés API unifiée dans toute l'app
Maintenance Code répétitif Système centralisé
UX Frustrant (messages cachés) Fluide et prévisible

Architecture centralisée

Flux de gestion des erreurs :

  1. Succès API :

    • UI appelle Repository → API Service → Serveur
    • Réponse 200 OK → Mise à jour des données
    • Affichage message de succès
  2. Erreur API (ex: email déjà utilisé) :

    • Serveur retourne 409 Conflict
    • Conversion automatique en ApiException avec extraction du message
    • Propagation de l'exception UI ← Repository ← API Service
    • Affichage message d'erreur spécifique, Dialog reste ouverte
  3. Erreur réseau :

    • Timeout ou erreur de connexion
    • Conversion en ApiException avec message générique
    • Affichage message "Problème de connexion réseau"

Composants de gestion d'erreurs

ApiException

Extraction intelligente : Messages spécifiques depuis la réponse API Codes HTTP standardisés : Mapping automatique des erreurs communes Types d'erreurs : Classification (validation, authentification, réseau, conflit) Méthodes d'affichage : showError() et showSuccess() intégrées

Responsabilités par couche

ApiService : Conversion des erreurs Dio en ApiException Repository : Propagation transparente des erreurs Interface : Affichage utilisateur via ApiException.showError()

Messages d'erreurs contextuels

409 Conflict : "Cet email est déjà utilisé par un autre utilisateur" 400 Bad Request : "Données invalides" 401 Unauthorized : "Non autorisé : veuillez vous reconnecter" 500 Server Error : "Erreur serveur interne" Network Errors : "Problème de connexion réseau" Timeout : "Délai d'attente dépassé"

🔧 Pattern de gestion des erreurs API dans les Repositories

🎯 Problème à résoudre

Les messages d'erreur spécifiques de l'API (comme "Cet email est déjà utilisé") n'étaient pas affichés à l'utilisateur. À la place, un message générique "Erreur inattendue" apparaissait.

📝 Modifications requises

1. ApiService - Conversion automatique des DioException

Toutes les méthodes HTTP génériques doivent convertir les DioException en ApiException :

Pattern à suivre :

  • Intercepter les DioException dans un bloc try/catch
  • Convertir avec ApiException.fromDioException(e) pour extraire automatiquement le message
  • Propager les ApiException existantes avec rethrow
  • Créer une nouvelle ApiException pour les erreurs inattendues

Ce pattern s'applique à toutes les méthodes : post(), get(), put(), delete().

2. Repository - Simplification de la gestion des erreurs

Pattern incorrect :

  • Vérifications manuelles du statusCode
  • Vérifications des données de réponse qui ne seront jamais atteintes
  • Dio lance automatiquement une exception pour les codes d'erreur

Pattern correct :

  • Appel de l'API via ApiService
  • Si l'appel réussit (pas d'exception), sauvegarder dans Hive et retourner true
  • En cas d'erreur, propager l'exception avec rethrow (elle contient déjà le message extrait)

3. Amélioration des logs (avec LoggerService)

Bonnes pratiques de logging :

  • Ne pas logger les détails techniques de DioException
  • Pour ApiException : logger uniquement le message d'erreur utilisateur
  • Pour les autres exceptions : logger un message générique
  • Toujours propager l'exception avec rethrow

Import nécessaire : api_exception.dart

🔄 Flux d'erreur corrigé

Scénario 1 : Code d'erreur (409, 400, etc.)

  • UI → Repository → ApiService → Dio → API
  • API retourne erreur avec JSON body contenant le message
  • Dio lance DioException
  • ApiService convertit en ApiException via fromDioException()
  • Extraction du message depuis response.data
  • Propagation ApiException → Repository → UI
  • Affichage du message spécifique à l'utilisateur

Scénario 2 : Succès (200, 201)

  • UI → Repository → ApiService → Dio → API
  • API retourne succès
  • Repository sauvegarde dans Hive
  • Repository retourne true à l'UI

Checklist de migration

Pour chaque repository :

  • Vérifier que l'ApiService convertit les DioException en ApiException
  • Simplifier le code : supprimer les vérifications de statut après l'appel API
  • Propager les exceptions avec rethrow
  • Améliorer les logs pour ne pas afficher les détails techniques
  • Importer ApiException si nécessaire
  • Tester avec une erreur 409 pour vérifier l'affichage du message

📊 Résultat attendu

Avant Après
"Erreur inattendue" "Cet email est déjà utilisé par un autre utilisateur"
Logs avec stack trace Dio Message d'erreur simple et clair
Code complexe avec vérifications inutiles Code simplifié et maintenable

Cette approche garantit que tous les messages d'erreur de l'API sont correctement affichés à l'utilisateur, améliorant ainsi l'expérience utilisateur et facilitant le débogage.

📝 Service de Logging Intelligent

🎯 Vue d'ensemble

GEOSECTOR v3.x implémente un LoggerService centralisé qui désactive automatiquement les logs de debug en production, optimisant ainsi les performances et la sécurité tout en facilitant le développement.

🔍 Détection automatique de l'environnement

Le LoggerService détecte automatiquement l'environnement d'exécution :

Pour le web :

  • URL contient 'dapp.geosector.fr' → Environnement DEV
  • URL contient 'rapp.geosector.fr' → Environnement REC
  • Autre URL → Environnement PROD

Pour mobile/desktop :

  • Utilise kReleaseMode de Flutter

Comportement par environnement :

Environnement Logs Debug Logs Erreur Stack Traces
DEV Activés Activés Complètes
REC Activés Activés Complètes
PROD Désactivés Activés Masquées

🛠️ API du LoggerService

Méthodes principales

Logs basiques :

  • LoggerService.log() - Message simple, remplacement direct de debugPrint
  • LoggerService.info() - Information avec emoji
  • LoggerService.success() - Opération réussie avec emoji
  • LoggerService.warning() - Attention avec emoji ⚠️
  • LoggerService.error() - Erreur avec emoji (toujours affiché, même en PROD)
  • LoggerService.debug() - Debug avec emoji personnalisable

Logs spécialisés :

  • LoggerService.api() - Requêtes API avec emoji 🔗
  • LoggerService.database() - Opérations base de données avec emoji 💾
  • LoggerService.navigation() - Navigation avec emoji 🧭
  • LoggerService.performance() - Performance avec emoji ⏱️

Fonctionnalités avancées

Logs groupés :

  • LoggerService.group() - Affiche une liste de messages avec hiérarchie visuelle
  • Format : ┌─ titre / ├─ items / └─ dernier item

Log JSON formaté :

  • LoggerService.json() - Affiche un objet JSON de manière lisible
  • Format : 📋 titre : / propriété: valeur (indentées)

Log conditionnel :

  • LoggerService.conditional() - Affiche un message uniquement si une condition est vraie

🔄 Migration depuis debugPrint

Avant (debugPrint partout) :

  • Utilisation manuelle des emojis
  • Pas de catégorisation
  • Logs toujours actifs en production

Après (LoggerService) :

  • Emojis automatiques selon le type de log
  • Catégorisation claire (info, api, error)
  • Désactivation automatique en production (sauf erreurs)

📋 Utilisation avec les extensions

Pour une syntaxe encore plus concise, utilisez les extensions String :

Import nécessaire : logger_service.dart

Méthodes disponibles :

  • 'message'.logSuccess() - Log de succès
  • 'message'.logError(exception) - Log d'erreur avec exception
  • 'message'.logApi() - Log d'API
  • 'message'.logDatabase() - Log de base de données

🎯 Bonnes pratiques

1. Catégorisation des logs

Bonne pratique :

  • Utiliser les méthodes spécialisées (api, database, etc.)
  • Messages clairs et descriptifs avec contexte

Mauvaise pratique :

  • Utiliser debugPrint avec messages génériques
  • Pas de catégorisation ni de contexte

2. Gestion des erreurs

Pattern recommandé :

  • Log de succès après opération réussie
  • Log d'erreur avec exception et stackTrace en cas d'échec
  • Les erreurs sont TOUJOURS loggées, même en PROD

3. Logs de performance

Pattern recommandé :

  • Démarrer un Stopwatch avant l'opération
  • Arrêter le Stopwatch après l'opération
  • Logger le temps écoulé avec LoggerService.performance()

🔒 Sécurité et performances

Avantages en production

  1. Sécurité : Aucune information sensible exposée dans la console
  2. Performance : Pas d'appels inutiles à debugPrint
  3. Taille : Bundle JavaScript plus léger (tree shaking)
  4. Professionnalisme : Console propre pour les utilisateurs finaux

Conservation des logs d'erreur

Les erreurs restent visibles en production pour faciliter le support :

  • LoggerService.error() toujours affiché, même en PROD
  • Stack trace complète masquée en production pour ne pas révéler les détails d'implémentation
  • Message d'erreur utilisateur conservé

📊 Impact sur le codebase

Métrique Avant Après
Logs en PROD Tous visibles Erreurs uniquement
Performance web debugPrint actifs Désactivés automatiquement
Maintenance debugPrint dispersés Service centralisé
Lisibilité Emojis manuels Catégorisation automatique

🚀 Configuration et initialisation

Le LoggerService fonctionne automatiquement sans configuration :

  • Aucune initialisation requise dans main.dart
  • Détection automatique de l'environnement via ApiService.getCurrentEnvironment()
  • Utilisation immédiate dans n'importe quel fichier après import

Cette architecture garantit un système de logging professionnel, sécurisé et performant, adapté aux besoins de développement tout en protégeant la production. 📝

🔐 Gestion des identifiants - Normes NIST SP 800-63B

🎯 Vue d'ensemble

GEOSECTOR v3.x implémente les normes NIST SP 800-63B pour la gestion des identifiants (usernames et passwords), offrant une sécurité renforcée tout en améliorant l'expérience utilisateur avec des règles plus flexibles et modernes.

📋 Conformité NIST SP 800-63B

Exigence NIST Implémentation Statut
Longueur minimale : 8 caractères MIN = 8 caractères CONFORME
Longueur maximale : 64 caractères minimum MAX = 64 caractères CONFORME
Accepter TOUS les caractères ASCII imprimables Aucune restriction sur les caractères CONFORME
Accepter les espaces Espaces acceptés (début, milieu, fin) CONFORME
Accepter Unicode (émojis, accents, etc.) Support UTF-8 complet CONFORME
Vérifier contre les mots de passe compromis API Have I Been Pwned avec k-anonymity CONFORME
Pas d'obligation de composition Pas d'erreur si manque majuscules/chiffres/spéciaux CONFORME
Pas de changement périodique forcé Aucune expiration automatique CONFORME
Permettre les phrases de passe "Mon chat Félix a 3 ans!" accepté CONFORME

🔑 Règles pour les identifiants

Username (Nom d'utilisateur)

  • Longueur : 8 à 64 caractères
  • Caractères acceptés : TOUS (lettres, chiffres, espaces, accents, symboles, emojis)
  • Exemples valides :
    • jean dupont 75
    • Marie-Claire.2024
    • Pompier Paris 🚒
    • utilisateur@amicale

Password (Mot de passe)

  • Longueur : 8 à 64 caractères
  • Aucune règle de composition obligatoire (plus besoin de majuscules/minuscules/chiffres/spéciaux)
  • Phrases de passe recommandées pour une meilleure mémorisation
  • Exemples valides :
    • Mon chat Félix a 3 ans!
    • J'aime les pizzas du vendredi soir
    • Le camion rouge part à 8h30
    • ☀️ Soleil brillant sur Paris ☀️

🎲 Générateurs intelligents

Générateur de username

Crée des noms d'utilisateur uniques basés sur :

  • Nom/prénom de la personne
  • Code postal et ville de l'amicale
  • Numéro aléatoire pour l'unicité
  • Peut inclure des espaces et séparateurs (., -, _)

Générateur de phrases de passe

Génère des phrases de passe mémorables en français :

  • Phrases naturelles et faciles à retenir
  • Combinaisons variées (sujets, verbes, compléments)
  • Ajout optionnel de caractères spéciaux ou emojis
  • Exemples générés :
    • Le chien Max danse dans le jardin!
    • Mon vélo rouge vole 42 fois en été
    • Luna a 7 ans!☀️

⚠️ Points importants

  1. Pas de trim() : Les espaces en début/fin sont préservés et font partie de l'identifiant
  2. Pas de vérification password == username : Sur demande du client, cette règle a été retirée
  3. Validation côté API : L'API vérifie les mots de passe contre la base Have I Been Pwned
  4. Rétrocompatibilité : Les anciens identifiants restent valides

🔄 Impact sur l'expérience utilisateur

Aspect Avant Après NIST
Complexité Règles strictes difficiles à mémoriser Liberté totale, phrases naturelles
Longueur password 12-16 caractères obligatoires 8-64 caractères flexibles
Caractères spéciaux Obligatoires Optionnels
Mémorisation Mots de passe complexes oubliés Phrases personnelles mémorables
Sécurité Règles arbitraires Vérification contre bases de données compromises

🎯 Gestion des rôles

Hiérarchie des permissions

Membre (Rôle 1) : Consultation et distribution dans ses secteurs Admin Amicale (Rôle 2) : Gestion complète de son amicale et ses membres Super Admin (Rôle 3+) : Administration globale multi-amicales

Fonctionnalités par rôle

Admin Amicale - Gestion des membres Création : Nouveaux membres avec attribution de rôle Modification : Informations personnelles, rôle, statut actif Suppression : Avec confirmation obligatoire Validation : Contrôle d'unicité email/username par l'API

Interface adaptative

Sélecteur de rôle : Visible uniquement pour les admins Checkbox statut actif : Contrôle d'accès aux comptes Édition contextuelle : Champs modifiables selon les permissions Actions conditionnelles : Boutons disponibles selon le niveau d'autorisation

👥 Gestion des membres (Admin Amicale)

🎯 Vue d'ensemble

La gestion des membres est une fonctionnalité clé pour les Admins Amicale (Rôle 2) qui permet une administration complète des équipes au sein de leur amicale. Cette interface centralise toutes les opérations liées aux membres avec une approche sécurisée et intuitive.

📱 Interface AdminAmicalePage

L'interface principale admin_amicale_page.dart offre une vue d'ensemble complète :

  • Informations de l'amicale : Affichage des détails de l'amicale courante
  • Liste des membres : Tableau interactif avec actions contextuelles
  • Ajout de membres : Bouton d'action pour créer de nouveaux comptes
  • Opération courante : Indication de l'opération active en cours

Fonctionnalités principales

🆕 Création de nouveaux membres

Workflow de création :

  1. Clic sur "Ajouter un membre"
  2. Ouverture du UserFormDialog
  3. Formulaire vierge avec valeurs par défaut
  4. Sélection du rôle (Membre/Administrateur)
  5. Configuration du statut actif
  6. Validation et création via API
  7. Attribution automatique à l'amicale courante

Champs obligatoires :

  • Email (unique dans le système)
  • Au moins un nom (nom de famille OU nom de tournée)
  • Rôle dans l'amicale

Champs optionnels :

  • Nom d'utilisateur (éditable pour les admins)
  • Prénom, téléphones, dates
  • Nom de tournée (pour identification terrain)

✏️ Modification des membres existants

Actions disponibles :

  • Clic sur une ligne → Ouverture du formulaire d'édition
  • Modification de tous les champs personnels
  • Changement de rôle (Membre ↔ Administrateur)
  • Activation/Désactivation du compte
  • Gestion du nom de tournée

Workflow de modification :

  1. Sélection du membre dans le tableau
  2. Ouverture automatique du UserFormDialog
  3. Formulaire pré-rempli avec données existantes
  4. Modification des champs souhaités
  5. Validation et mise à jour via API
  6. Synchronisation automatique avec Hive

🗑️ Suppression intelligente des membres

La suppression des membres intègre une logique métier avancée pour préserver l'intégrité des données :

🔍 Vérification des passages

Algorithme de vérification :

  1. Récupération de opération courante
  2. Analyse des passages du membre pour cette opération
  3. Classification : passages réalisés vs passages à finaliser
  4. Comptage total des passages actifs
📊 Scénarios de suppression

Cas 1 : Aucun passage (suppression simple)

  • Endpoint : DELETE /users/{id}
  • Confirmation simple
  • Suppression directe
  • Aucun transfert nécessaire

Cas 2 : Passages existants (suppression avec transfert)

  • Endpoint : DELETE /users/{id}?transfer_to={destinataire}&operation_id={operation}
  • Dialog d'avertissement avec détails
  • Sélection obligatoire d'un membre destinataire
  • Transfert automatique de tous les passages
  • Préservation de l'historique

Cas 3 : Alternative recommandée (désactivation)

  • Méthode : membre.copyWith(isActive: false)
  • Préservation complète des données
  • Blocage de la connexion
  • Maintien de l'historique
  • Réactivation possible ultérieurement

🔐 Sécurité et permissions

Contrôles d'accès

  • Isolation par amicale : Admins limités à leur amicale
  • Vérification des rôles : Validation côté client et serveur
  • Opération courante : Filtrage par contexte d'opération
  • Validation API : Contrôles d'unicité et cohérence

Gestion des erreurs

Flux de traitement :

  • Action utilisateur → Validation locale → Appel API
  • En cas de succès : Mise à jour Hive → Notification succès
  • En cas d'erreur : Affichage erreur → Dialog reste ouverte

🎨 Interface utilisateur

Tableaux interactifs

MembreTableWidget - Composant principal :

  • Colonnes : ID, Prénom, Nom, Email, Rôle, Statut
  • Actions : Modification, Suppression
  • Alternance de couleurs pour lisibilité
  • Tri et navigation intuitifs

MembreRowWidget - Ligne individuelle :

  • Clic pour édition rapide
  • Boutons d'action contextuels
  • Indicateurs visuels de statut
  • Tooltip informatifs

Formulaires adaptatifs

UserFormDialog - Modale réutilisable :

  • Layout responsive (>900px vs mobile)
  • Validation en temps réel
  • Gestion des erreurs inline
  • Sauvegarde avec feedback

📡 Synchronisation et réactivité

Architecture ValueListenableBuilder

Pattern d'écoute automatique :

  • ValueListenableBuilder écoute la Box Hive des membres
  • À chaque modification de la Box, le builder est appelé automatiquement
  • Filtrage des membres par amicale (fkEntite)
  • Affichage dans le tableau via MembreTableWidget
  • Mise à jour de l'interface en temps réel

Principe "API First"

  1. Validation API : Tentative sur serveur en priorité
  2. Succès → Sauvegarde locale + mise à jour interface
  3. Erreur → Affichage message + maintien état local
  4. Cohérence : Données locales toujours synchronisées

🔄 Workflow complet

Flux de traitement standard :

En cas de succès :

  • Admin effectue une action → Interface → Repository → API
  • API retourne succès → Repository sauvegarde dans Hive
  • Hive notifie changement → Interface mise à jour automatiquement

En cas d'erreur :

  • Admin effectue une action → Interface → Repository → API
  • API retourne erreur → Repository propage exception
  • Interface affiche message d'erreur

🎯 Bonnes pratiques

Pour les administrateurs

  1. Vérification avant suppression : Toujours examiner les passages
  2. Préférer la désactivation : Éviter la perte de données
  3. Noms de tournée : Utiliser des identifiants terrain clairs
  4. Rôles appropriés : Limiter les administrateurs aux besoins

Gestion des erreurs courantes

Erreur Cause Solution
Email déjà utilisé Duplication Choisir un autre email
Membre avec passages Données liées Transférer ou désactiver
Aucune opération active Configuration Vérifier les opérations
Accès refusé Permissions Vérifier le rôle admin

Cette architecture garantit une gestion des membres robuste, sécurisée et intuitive, optimisant l'efficacité administrative tout en préservant l'intégrité des données opérationnelles. 👥

💳 Intégration Stripe - Système de paiement

🎯 Vue d'ensemble

GEOSECTOR v3.x intègre un système de paiement complet basé sur Stripe, permettant aux amicales de pompiers d'encaisser directement les dons pour leurs calendriers via deux solutions complémentaires :

  • Stripe Connect V1 : Configuration des comptes Stripe (opérationnel)
  • Tap to Pay V2 🔄 : Paiements sans contact iPhone (en développement)

🏗️ Architecture Stripe Connect

Principe de fonctionnement

Chaque amicale dispose de son propre compte Stripe Connect :

  • 0% commission plateforme : L'amicale reçoit 100% des paiements
  • Comptes isolés : Fonds totalement séparés entre amicales
  • Conformité PCI : Sécurité automatique via Stripe
  • Onboarding guidé : Configuration assistée en français

Flow de configuration V1

Étapes de configuration :

  1. Admin active "Accepte CB" et clique "Configurer Stripe"
  2. Interface Web → API PHP : POST /stripe/create-account
  3. API PHP → Stripe : Création compte Express
  4. Stripe retourne account_id
  5. API PHP demande génération lien onboarding à Stripe
  6. Stripe retourne onboarding_url
  7. Redirection admin vers Stripe pour saisie infos entreprise/bancaires
  8. Retour vers application après onboarding
  9. Vérification statut compte
  10. Affichage " Compte actif"

🔑 Configuration des clés API Stripe par environnement

GEOSECTOR utilise des clés Stripe différentes selon l'environnement pour séparer les données de test et de production.

Fichier de configuration

/home/pierre/dev/geosector/api/src/Config/AppConfig.php

Répartition des clés par environnement

Environnement URL Plateforme Stripe Clés utilisées Mode Usage
DEV dapp.geosector.fr Test Pierre pk_test_51QwoVN...
sk_test_51QwoVN...
test Développement
REC rapp.geosector.fr Test Client CLIENT_PK_TEST_A_REMPLACER
CLIENT_SK_TEST_A_REMPLACER
test Recette
PROD app3.geosector.fr Live Client CLIENT_PK_LIVE_A_REMPLACER
CLIENT_SK_LIVE_A_REMPLACER
live Production

Types de clés Stripe

Clés obligatoires (2) :

Clé Format Où la trouver Utilisation
Publishable key pk_test_51XXXXX... ou pk_live_XXXXX... Dashboard → Developers → API Keys Client-side (Flutter app)
Secret key sk_test_51XXXXX... ou sk_live_XXXXX... Dashboard → Developers → API Keys (révéler) Server-side (API PHP)

Clé optionnelle :

Clé Format Où la trouver Utilisation
Webhook secret whsec_test_XXXXX... ou whsec_live_XXXXX... Dashboard → Webhooks → Endpoint → Signing secret Validation webhooks (non utilisé actuellement)

Récupération des clés client

Pour configurer REC et PROD, le client doit fournir ses clés depuis son Dashboard Stripe :

Pour REC (clés TEST) :

  1. Se connecter sur https://dashboard.stripe.com/test/apikeys
  2. Copier la Publishable keyCLIENT_PK_TEST_A_REMPLACER
  3. Révéler et copier la Secret keyCLIENT_SK_TEST_A_REMPLACER

Pour PROD (clés LIVE) :

  1. Se connecter sur https://dashboard.stripe.com/apikeys (mode live)
  2. Copier la Publishable keyCLIENT_PK_LIVE_A_REMPLACER
  3. Révéler et copier la Secret keyCLIENT_SK_LIVE_A_REMPLACER

Configuration dans AppConfig.php

Structure du fichier :

// Configuration DÉVELOPPEMENT (dapp.geosector.fr)
'stripe' => [
  'public_key_test' => 'pk_test_51QwoVN...', // Clés Pierre (opérationnel)
  'secret_key_test' => 'sk_test_51QwoVN...',
  'mode' => 'test',
],

// Configuration RECETTE (rapp.geosector.fr)
'stripe' => [
  'public_key_test' => 'CLIENT_PK_TEST_A_REMPLACER', // À remplacer
  'secret_key_test' => 'CLIENT_SK_TEST_A_REMPLACER', // À remplacer
  'mode' => 'test',
],

// Configuration PRODUCTION (app3.geosector.fr)
'stripe' => [
  'public_key_live' => 'CLIENT_PK_LIVE_A_REMPLACER', // À remplacer
  'secret_key_live' => 'CLIENT_SK_LIVE_A_REMPLACER', // À remplacer
  'mode' => 'live',
],

Points importants

⚠️ Isolation des environnements :

  • DEV utilise la plateforme de test de Pierre (développement isolé)
  • REC utilise la plateforme de test du client (tests en conditions réelles)
  • PROD utilise la plateforme live du client (vraies transactions)

⚠️ Sécurité :

  • Ne JAMAIS commiter les vraies clés dans Git
  • Vérifier que AppConfig.php est dans .gitignore
  • Les clés secrètes ne doivent jamais être exposées côté client

⚠️ Mode de fonctionnement :

  • L'API détecte automatiquement l'environnement via l'URL
  • Le mode (test ou live) détermine quelle paire de clés utiliser
  • En mode test : utilise public_key_test et secret_key_test
  • En mode live : utilise public_key_live et secret_key_live

Déploiement après modification

Après avoir remplacé les placeholders par les vraies clés :

cd /home/pierre/dev/geosector/api
./deploy-api.sh

L'API sera redéployée sur l'environnement correspondant avec les nouvelles clés.

📱 Tap to Pay V2 - Paiement sans contact

Fonctionnalités prévues

🎯 Interface de paiement
  • Sélection montant : Prédéfinis (10€, 20€, 30€, 50€) ou personnalisé
  • Terminal NFC : Animation "Approchez la carte du dos de l'iPhone"
  • Confirmation visuelle : Succès/échec avec feedback utilisateur
  • Reçus automatiques : Envoi par email/SMS
📊 Dashboard vendeur
  • Statistiques temps réel : Ventes du jour/semaine/mois
  • Historique complet : Liste des transactions avec détails
  • Mode offline : File d'attente avec synchronisation auto
  • Export données : Reporting pour comptabilité

Flow Tap to Pay

Étapes du processus de paiement :

  1. Validation du formulaire de passage dans l'app
  2. App → API : POST /passages pour sauvegarder le passage
  3. API retourne passage_id
  4. App → API : POST /stripe/create-intent
  5. API → Stripe : Création PaymentIntent
  6. Stripe retourne pi_xxx + client_secret
  7. App active NFC avec message "Approchez carte"
  8. App → Stripe : Collecte données carte via NFC
  9. Stripe traite le paiement
  10. Stripe confirme paiement à l'app
  11. App → API : POST /stripe/confirm
  12. App → API : PUT /passages/{id} avec stripe_payment_id
  13. API confirme mise à jour du passage

🔐 Sécurité et conformité

Standards respectés

  • PCI DSS Level 1 : Plus haut niveau de sécurité
  • 3D Secure 2 : Authentification forte européenne
  • Chiffrement E2E : Données carte jamais en clair
  • Tokenisation : Pas de stockage de données sensibles
  • RGPD : Conformité données personnelles

Contrôles d'accès

Vérifications avant paiement :

  • Web admin uniquement pour configuration : !kIsWeb && role < 2
  • Stripe activé sur l'amicale : amicale.chkStripe
  • Appareil compatible : canUseTapToPay()

📱 Compatibilité appareils

iPhone - Tap to Pay

Modèles compatibles :

  • iPhone XS, XS Max, XR (2018+)
  • iPhone 11, 11 Pro, 11 Pro Max
  • iPhone 12, 12 mini, 12 Pro, 12 Pro Max
  • iPhone 13, 13 mini, 13 Pro, 13 Pro Max
  • iPhone 14, 14 Plus, 14 Pro, 14 Pro Max
  • iPhone 15, 15 Plus, 15 Pro, 15 Pro Max
  • iPhone 16 (tous modèles)

Prérequis :

  • iOS 16.4+ minimum
  • NFC activé
  • Connexion internet (initialisation)

Android - Tap to Pay 🔄 (V2.2)

  • Android 9.0+ (API 28+)
  • Appareils certifiés (liste dynamique via API)
  • Google Pay compatible

🛠️ Services Stripe implémentés

StripeConnectService

Méthodes disponibles :

  • createStripeAccount(AmicaleModel) - Création compte Stripe Express
  • getAccountStatus(String accountId) - Vérification statut en temps réel
  • createOnboardingLink(String accountId) - Génération lien onboarding
  • createLocation(String accountId) - Création location Terminal

StripeTapToPayService 🔄 (En développement)

Méthodes prévues :

  • initialize() - Initialisation SDK Terminal
  • canUseTapToPay() - Vérification compatibilité appareil
  • createPaymentIntent(amount, passageId) - Création PaymentIntent
  • collectPayment(clientSecret) - Collecte NFC carte
  • queueOfflinePayment(payment) - File d'attente mode offline
  • syncOfflineQueue() - Synchronisation file d'attente

🔄 DeviceInfoService - Détection compatibilité

Le service DeviceInfoService détecte automatiquement la compatibilité Tap to Pay :

Informations collectées :

  • Modèle exact de l'appareil
  • Version du système d'exploitation
  • Compatibilité Tap to Pay (booléen)
  • Niveau de batterie
  • Adresse IP réseau
  • Type de connexion (WiFi/Cellulaire)

Vérification compatibilité :

  • Plateforme : iOS uniquement
  • Modèles compatibles : iPhone 11 à iPhone 16 (tous modèles)
  • Version iOS supportée requise
  • Retour booléen true/false

Envoi automatique post-login :

  • Collecte des informations après authentification
  • Envoi vers API via POST /users/device-info
  • Sauvegarde locale dans Hive pour cache

📊 États et statuts Stripe

États compte Stripe Connect

État Interface Description Actions
Non configuré 🟠 + Bouton "Configurer" CB non activé Cocher case CB
En cours 🟡 + "Configuration en cours" Onboarding incomplet Terminer sur Stripe
Actif 🟢 + "Compte configuré" Prêt paiements Aucune
Problème 🔴 + ⚠️ "Action requise" Document manquant Vérifier Stripe

Messages utilisateur

  • 💳 Initial : "Activez les paiements par carte bancaire pour vos membres"
  • En cours : "Configuration Stripe en cours. Veuillez compléter le processus d'onboarding."
  • Actif : "Compte Stripe configuré - 100% des paiements pour votre amicale"

📈 Métriques et monitoring

KPIs techniques

  • Taux de succès paiements : > 95%
  • Temps moyen transaction : < 15 secondes
  • Taux completion onboarding : > 85%
  • Synchronisation offline : > 99%

KPIs business

  • Adoption Tap to Pay : > 50% en 3 mois
  • Augmentation dons : +30%
  • Satisfaction utilisateur : > 4.5/5
  • Réduction paiements espèces : -60%

Cette intégration Stripe transforme GEOSECTOR en solution e-commerce complète pour les amicales de pompiers, combinant facilité d'usage, sécurité maximale et conformité réglementaire. 💳

🗺️ Cartes et géolocalisation

🎯 Architecture cartographique

Flutter Map : Rendu cartographique haute performance Providers de tuiles : Solution hybride Mapbox/OpenStreetMap Géolocalisation temps réel : Suivi GPS des équipes Secteurs géographiques : Visualisation et attribution dynamique Passages géolocalisés : Enregistrement précis des distributions

🌍 Configuration des tuiles de carte

GEOSECTOR v3.x utilise une stratégie différenciée pour l'affichage des tuiles de carte selon la plateforme :

Configuration actuelle

Plateforme Provider URL Template Raison
Web Mapbox https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/ Token compatible avec l'API styles
Mobile OpenStreetMap https://tile.openstreetmap.org/{z}/{x}/{y}.png Gratuit, sans restriction de token

Pourquoi cette approche ?

  1. Problème de permissions Mapbox : Les tokens Mapbox actuels (DEV/REC/PROD) n'ont pas les permissions pour l'API styles/v1 qui retourne une erreur 403 sur mobile
  2. Solution pragmatique : OpenStreetMap fonctionne parfaitement sans token et offre une qualité de carte équivalente
  3. Facilité de maintenance : Pas besoin de gérer des tokens différents selon les environnements

💾 Système de cache des tuiles

Le cache fonctionne pour les deux providers (Mapbox et OpenStreetMap) :

Configuration du cache

Paramètres du cache :

  • Provider : CachedTileProvider avec FileCacheStore
  • Durée de validité : 30 jours (maxStale)
  • Localisation : cachePath spécifique par provider

Caches séparés par provider

  • Web (Mapbox) : Cache dans MapboxTileCache/
  • Mobile (OSM) : Cache dans OSMTileCache/

Avantages du cache

Mode hors ligne : Les zones visitées restent disponibles sans connexion Performance : Chargement instantané des tuiles en cache Économie de données : Pas de re-téléchargement inutile Fiabilité : Fonctionne même avec une connexion instable

🔧 Widget MapboxMap centralisé

Le widget MapboxMap (lib/presentation/widgets/mapbox_map.dart) centralise toute la logique cartographique :

Paramètres principaux

Configuration du widget MapboxMap :

  • initialPosition : Position initiale (ex: Rennes - LatLng(48.1173, -1.6778))
  • initialZoom : Niveau de zoom initial (ex: 13.0)
  • markers : Liste de marqueurs (passages, etc.)
  • polygons : Liste de polygones (secteurs géographiques)
  • useOpenStreetMap : Choix du provider (!kIsWeb = OSM mobile, Mapbox web)
  • showControls : Affichage boutons zoom/localisation

Utilisation dans l'application

  • admin_map_page.dart : Carte d'administration avec édition de secteurs
  • user_map_page.dart : Carte utilisateur avec visualisation des passages
  • user_field_mode_page.dart : Mode terrain avec GPS et boussole

🎯 Architecture "API First" - Pas de filtrage client

⚠️ IMPORTANT : Les données cartographiques (secteurs et passages) sont déjà filtrées par l'API selon le rôle de l'utilisateur. Aucun filtrage supplémentaire ne doit être effectué côté client lors du chargement dans map_page.dart.

Principe de fonctionnement

En mode utilisateur (Rôle 1) :

  • L'API retourne uniquement les secteurs assignés à l'utilisateur
  • L'API retourne uniquement les passages de ces secteurs
  • Ne pas filtrer avec UserSectorModel côté client
  • Charger directement depuis les Hive boxes

En mode admin (Rôle 2+) :

  • L'API retourne tous les secteurs de l'amicale et de l'opération
  • L'API retourne tous les passages de l'amicale et de l'opération
  • Ne pas filtrer par rôle côté client
  • Charger directement depuis les Hive boxes

Implémentation dans map_page.dart

Pattern correct (v3.2.4+) :

void _loadSectors() {
  // L'API retourne déjà les secteurs filtrés selon le rôle (admin ou user)
  try {
    final sectorsBox = Hive.box<SectorModel>(AppKeys.sectorsBoxName);
    final sectors = sectorsBox.values.toList();
    // ... traitement direct sans filtrage
  }
}

void _loadPassages() {
  // L'API retourne déjà les passages filtrés selon le rôle (admin ou user)
  try {
    final passagesBox = Hive.box<PassageModel>(AppKeys.passagesBoxName);
    // ... traitement direct sans filtrage par secteur utilisateur
  }
}

Pattern incorrect (éviter) :

void _loadSectors() {
  // ❌ MAUVAIS : Filtrage inutile, l'API l'a déjà fait
  if (!isAdmin) {
    final userSectorIds = userSectorBox.values
        .where((us) => us.id == currentUserId)
        .map((us) => us.fkSector)
        .toSet();
    // ... filtrage des secteurs
  }
}

Avantages de cette approche

Aspect Filtrage client API First
Performance Double filtrage inutile Filtrage unique côté serveur
Cohérence Risque d'erreur de logique Logique centralisée dans l'API
Maintenance Code dupliqué Code simplifié
Sécurité Vérifications redondantes Sécurité garantie par l'API

🔄 Migration future vers Mapbox complet

Si vous obtenez un token Mapbox avec les permissions appropriées :

  1. Retirer le paramètre useOpenStreetMap: !kIsWeb dans les pages
  2. Le widget détectera automatiquement et utilisera Mapbox partout
  3. Le cache continuera de fonctionner avec le nouveau provider

📱 Mode terrain (Field Mode)

Le mode terrain offre des fonctionnalités avancées pour les équipes sur le terrain :

  • Indicateurs GPS : Qualité du signal (GPS/Réseau) avec actualisation 5s
  • Mode boussole : Orientation de la carte selon le magnétomètre
  • Markers optimisés : Affichage simplifié (première lettre de rueBis)
  • Liste triée : Passages organisés par distance
  • Cercles de distance : Visualisation des zones de proximité

🔄 Synchronisation et réactivité

Hive + ValueListenableBuilder

Réactivité native : Mise à jour automatique de l'interface Performance optimisée : Pas de Provider, injection directe Écoute sélective : Réactivité fine par Box Hive Cohérence des données : Synchronisation bidirectionnelle User/Membre

Services Singleton

CurrentUserService : Gestion de l'utilisateur connecté CurrentAmicaleService : Amicale de l'utilisateur actuel ApiService : Communication centralisée avec l'API DataLoadingService : Orchestration du chargement des données

🚀 Optimisation des performances Hive

📈 Gestion des Box Hive avec cache

GEOSECTOR v3.x implémente une stratégie de cache avancée pour les Box Hive afin d'éliminer les goulots d'étranglement de performance lors d'opérations haute fréquence.

🎯 Problème résolu

Avant l'optimisation, l'application effectuait jusqu'à 848 vérifications Hive.isBoxOpen() par chargement de page, causant des ralentissements significatifs lors du rendu des listes et du filtrage des données.

💡 Solution : Cache lazy des Box

Pattern implémenté dans tous les repositories :

Variables de cache :

  • _cachedBox : Référence nullable à la Box

Getter lazy :

  • Vérification si cache null
  • Si null : vérification Box ouverte + récupération + mise en cache + log
  • Retour de la Box cachée

Méthode reset :

  • _resetCache() : Réinitialise la variable cache à null

🔄 Gestion du cache et réactivité

Point critique : Le cache doit être réinitialisé après toute modification pour garantir le bon fonctionnement de ValueListenableBuilder :

Après sauvegarde :

  • Appel _modelBox.put()
  • Appel _resetCache() - OBLIGATOIRE
  • Appel notifyListeners()

Après suppression :

  • Appel _modelBox.delete()
  • Appel _resetCache() - OBLIGATOIRE
  • Appel notifyListeners()

Après vidage ou traitement API :

  • Appel _modelBox.clear()
  • Traitement des données
  • Appel _resetCache() - OBLIGATOIRE
  • Appel notifyListeners()

📊 Impact performance

Métrique Avant optimisation Après optimisation
Vérifications box 848 par page 1 par session
Temps de rendu 200-500ms <50ms
Filtrage liste Lent (check répétés) Instantané
Mémoire Overhead minimal Impact négligeable

🏗️ Repositories optimisés

L'optimisation est implémentée dans tous les repositories critiques :

  • SectorRepository : Gestion des secteurs géographiques
  • PassageRepository : Suivi des distributions
  • MembreRepository : Gestion des équipes
  • OperationRepository : Campagnes et opérations
  • AmicaleRepository : Organisations

🎯 Règles d'implémentation

  1. Cache systématique : Tous les repositories fréquemment utilisés
  2. Reset obligatoire : Après toute opération de modification
  3. Getter lazy : Accès différé à la box uniquement si nécessaire
  4. Debug logging : Traçabilité du cache en développement
  5. Cohérence : Pattern appliqué uniformément

Cette architecture garantit une application performante, maintenable et évolutive avec une excellente expérience utilisateur. 🚀

🎨 Architecture des Dialogs Auto-Gérées

🎯 Principe de conception

GEOSECTOR v3.x implémente une architecture simplifiée des dialogs qui élimine la complexité des callbacks asynchrones et garantit une gestion robuste des formulaires modaux.

🏗️ Pattern "Dialog Auto-Gérée"

Architecture du pattern :

  • Page Parente injecte Repository dans Dialog Auto-Gérée
  • Dialog appelle directement Repository
  • Repository effectue API Call vers Serveur
  • Serveur retourne réponse
  • Repository sauvegarde dans Hive Local
  • Dialog se ferme automatiquement en cas de succès
  • Dialog exécute callback simple vers Page Parente
  • ValueListenableBuilder met à jour Page Parente automatiquement

📱 Widgets de passages et navigation

🎯 PassagesListWidget

Le widget PassagesListWidget est le composant central pour l'affichage et la gestion des passages dans toute l'application. Il offre une expérience utilisateur cohérente avec des fonctionnalités adaptatives selon le contexte.

Fonctionnalités principales

  • Affichage adaptatif : Liste complète ou tableau de bord avec fond transparent
  • Flux conditionnel de clic : Comportement intelligent selon le type de passage
  • Bouton de création intégré : Bouton "+" vert dans l'en-tête pour ajouter des passages
  • Système de filtrage centralisé : Tous les filtres intégrés et configurables
  • Actions contextuelles : Modification, suppression, génération de reçus

🔧 Système de filtrage centralisé (v3.2.2)

Depuis la v3.2.2, PassagesListWidget intègre tous les filtres de manière configurable :

Paramètres de données :

  • passages : Liste des passages formatés

Configuration des filtres (booléens) :

  • showFilters : Active le système de filtrage global
  • showSearch : Barre de recherche textuelle
  • showTypeFilter : Filtre par type de passage
  • showPaymentFilter : Filtre par mode de paiement
  • showSectorFilter : Filtre par secteur géographique
  • showUserFilter : Filtre par membre (admin uniquement)
  • showPeriodFilter : Filtre par période temporelle

Données pour les filtres :

  • sectors : Liste des secteurs disponibles
  • members : Liste des membres (pour pages admin)

Valeurs initiales :

  • initialSectorId : Secteur sélectionné par défaut
  • initialUserId : Membre sélectionné par défaut
  • initialPeriod : Période par défaut
  • dateRange : Plage de dates personnalisée

Callback de synchronisation :

  • onFiltersChanged(filters) : Notifie la page parente des changements de filtres

Avantages de la centralisation :

  • Code unique : Plus de duplication entre les pages
  • Configuration flexible : Chaque page active uniquement les filtres pertinents
  • Interface cohérente : Même expérience utilisateur partout
  • Maintenance simplifiée : Modifications centralisées
  • Responsive automatique : Adaptation desktop/mobile gérée par le widget

🔄 Flux conditionnel des clics sur passages

Le widget implémente un comportement intelligent lors du clic sur un passage :

Logique de gestion :

  • Récupération du type de passage
  • Si type 2 (À finaliser) : Ouverture directe du formulaire d'édition pour finalisation rapide
  • Sinon : Affichage des détails avec option "Modifier"

Comportements par type de passage :

  • Type 1 (Réalisé) : Affiche les détails complets avec option "Modifier"
  • Type 2 (À finaliser) : Ouvre directement le formulaire d'édition pour finalisation rapide
  • Type 3 (Absent) : Affiche les détails avec options limitées
  • Type 4 (Refusé) : Affiche les détails en lecture seule

🎨 Dialog de détails amélioré

La boîte de dialogue des détails a été repensée pour une meilleure lisibilité :

  • Organisation par sections : Client, Passage, Lieu avec icônes distinctives
  • Badges colorés : Visualisation rapide du type et statut
  • Formatage intelligent : Dates, montants et informations structurées
  • Actions contextuelles : Boutons adaptés selon les permissions

Bouton de création contextuel

Le widget intègre un bouton "+" vert flottant dans l'en-tête pour créer de nouveaux passages :

Paramètres :

  • showAddButton: true : Active le bouton "+"
  • onAddPassage : Callback exécuté lors du clic (affiche PassageFormDialog)

Pages avec bouton de création activé :

  • user_field_mode_page.dart : Mode terrain pour création rapide
  • user_history_page.dart : Historique avec ajout possible
  • admin_history_page.dart : Gestion administrative complète

🎯 DashboardAppBar - Évolution de l'interface

Suppression du bouton "Nouveau passage"

Le bouton global "Nouveau passage" a été définitivement retiré de la barre d'application (DashboardAppBar) pour privilégier une approche contextuelle :

Avant :

  • Bouton toujours visible dans l'AppBar
  • Création de passage possible depuis n'importe quelle page
  • Confusion possible sur le contexte de création

Après :

  • Boutons "+" contextuels dans les pages appropriées
  • Création limitée aux contextes pertinents
  • Interface épurée et plus intuitive

🎨 Architecture simplifiée

La suppression du bouton global a permis de :

  • Nettoyer les dépendances (passage_form_dialog.dart, app_keys.dart)
  • Simplifier les paramètres de DashboardLayout
  • Réduire la complexité de navigation
  • Améliorer la cohérence UX

🎯 Mode tableau de bord

Pour les pages de tableau de bord, le PassagesListWidget s'adapte automatiquement :

🏠 Page d'accueil utilisateur

Dans user_dashboard_home_page.dart, l'affichage est optimisé :

Configuration spécifique dashboard :

  • Container : SizedBox avec hauteur 450 pour éviter overflow
  • passages : recentPassages (20 derniers)
  • showFilters: false : Pas de filtres sur le dashboard
  • showSearch: false : Pas de recherche
  • maxPassages: 20 : Limite aux 20 plus récents
  • transparentBackground: true : Fond transparent pour intégration harmonieuse

Améliorations du dashboard :

  • Suppression de la Card wrapper pour un design épuré
  • Fond transparent pour intégration harmonieuse
  • En-tête coloré maintenu pour la lisibilité
  • Limite augmentée à 20 passages récents (au lieu de 10)

Composants de l'architecture

1. Page Parente (ex: AdminOperationsPage)

Pattern d'ouverture simplifié :

  • Appel showDialog avec context
  • Builder retournant OperationFormDialog
  • Injection directe du repository en paramètre
  • Callback onSuccess avec simple rafraîchissement setState()

2. Dialog Auto-Gérée (ex: OperationFormDialog)

Gestion complète dans la dialog :

En cas de succès :

  • Appel direct repository.saveOperationFromModel()
  • Délai 200ms pour synchronisation Hive
  • Auto-fermeture avec Navigator.pop()
  • Appel callback onSuccess()
  • Affichage message succès

En cas d'erreur :

  • Interception exception dans catch
  • Affichage erreur via ApiException.showError()
  • Dialog reste ouverte pour correction

🎯 Avantages de cette approche

Aspect Avant (Complexe) Après (Simplifié)
Callbacks Asynchrones complexes Simple onSuccess: () => setState()
Fermeture Gérée par le parent Auto-fermeture dans la dialog
Gestion d'erreurs Dispersée Centralisée dans la dialog
Synchronisation Problématique Délai de 200ms pour Hive
Maintenance Code dispersé Logique unifiée

🔧 Responsabilités claires

Page Parente

  • Ouverture des dialogs avec injection de dépendances
  • Rafraîchissement de l'interface via setState()
  • Gestion des tableaux et listes intégrés

Dialog Auto-Gérée

  • Validation et soumission du formulaire
  • Appel direct des repositories
  • Auto-fermeture en cas de succès
  • Gestion des erreurs sans fermeture

Repository

  • Logique métier (création vs modification)
  • Appels API appropriés
  • Sauvegarde locale dans Hive
  • Propagation des exceptions

🚀 Exemple d'implémentation

1. Page parente - Code minimal :

  • Méthode _showCreateDialog()
  • showDialog avec builder retournant OperationFormDialog
  • Injection repository et callback onSuccess

2. Dialog - Auto-gestion complète :

  • Classe OperationFormDialog extends StatefulWidget
  • Propriétés : operationRepository, onSuccess
  • Gestion interne : validation, API, fermeture, erreurs

3. Repository - Logique métier pure :

  • Méthode saveOperationFromModel(OperationModel)
  • Si operation.id == 0 : createOperation() avec POST
  • Sinon : updateOperation() avec PUT

Résultats obtenus

  • 🎯 Simplicité : Code plus lisible et maintenable
  • 🔒 Robustesse : Gestion d'erreurs centralisée
  • Performance : Synchronisation optimisée avec Hive
  • 🎨 UX : Fermeture automatique et messages appropriés
  • 🔧 Maintenance : Architecture cohérente et prévisible

Cette approche "Dialog Auto-Gérée" constitue un pattern architectural clé de GEOSECTOR v3.x, garantissant une expérience utilisateur fluide et un code maintenable. 🎉

Fonction de création d'une opération

Fonction de création d'une opération

🔄 Traitement des données complexes

Lors de la création d'une opération via OperationRepository.createOperation(), l'API retourne en réponse 201 Created ou 200 OK un payload complexe contenant 4 groupes de données essentiels :

Structure de la réponse :

  • operations : 3 dernières opérations dont la nouvelle active
  • secteurs : Secteurs de la nouvelle opération active
  • passages : Passages de la nouvelle opération active
  • users_sectors : Associations user-secteurs de la nouvelle opération

📦 Groupes de données attendus

Groupe operations :

  • Contient les 3 dernières opérations de l'amicale
  • Inclut celle qui vient d'être créée (devient automatiquement active)

Groupe secteurs :

  • Contient tous les secteurs géographiques
  • Associés à la dernière opération créée et active

Groupe passages :

  • Contient l'ensemble des passages
  • Générés pour cette dernière opération créée et active

Groupe users_sectors :

  • Contient les associations utilisateur-secteurs
  • Définit les attributions pour cette dernière opération créée et active

⚙️ Traitement automatique des données

Ces 4 groupes sont traités de manière identique au processus de connexion utilisateur, en utilisant le DataLoadingService :

Étapes de traitement :

  1. Vidage des Box Hive concernées :

    • Récupération des 4 Box typées (operations, secteurs, passages, users_sectors)
    • Appel clear() sur chaque Box
  2. Traitement des 4 groupes via DataLoadingService :

    • Si clé 'operations' présente : processOperationsFromApi()
    • Si clé 'secteurs' présente : processSectorsFromApi()
    • Si clé 'passages' présente : processPassagesFromApi()
    • Si clé 'users_sectors' présente : processUserSectorsFromApi()

🔄 Flux de synchronisation

Étapes du flux :

  1. Création initiale :

    • Interface → OperationRepository : createOperation()
    • OperationRepository → API : POST /operations
    • API retourne 201 Created avec les 4 groupes de données
  2. Traitement des données :

    • OperationRepository → HiveService : clear() sur 4 Box
    • OperationRepository → DataLoadingService : processOperationsFromApi()
    • OperationRepository → DataLoadingService : processSectorsFromApi()
    • OperationRepository → DataLoadingService : processPassagesFromApi()
    • OperationRepository → DataLoadingService : processUserSectorsFromApi()
  3. Sauvegarde et notification :

    • DataLoadingService → HiveService : put() dans Box typées
    • HiveService → ValueListenableBuilder : Notifications de changement
    • ValueListenableBuilder → Interface : Mise à jour automatique

Avantages de cette approche

  • Cohérence totale : Données locales parfaitement synchronisées avec le serveur
  • Performance optimisée : Un seul appel API pour toutes les données nécessaires
  • Réactivité immédiate : Interface mise à jour automatiquement via ValueListenableBuilder
  • Logique centralisée : Réutilisation du DataLoadingService existant
  • Gestion d'erreurs : Rollback automatique en cas d'échec du traitement

Cette architecture garantit une synchronisation robuste et performante lors de la création d'opérations, en maintenant la cohérence des données tout en optimisant l'expérience utilisateur. 🚀


📝 Changelog

🔄 v4.0.0 (Q4 2025 - En développement)

Tap to Pay V2 - Paiements sans contact 🔄

  • 📱 Interface Tap to Pay
    • Écran de sélection montant avec chips prédéfinis (10€, 20€, 30€, 50€)
    • Terminal NFC avec animation "Approchez la carte"
    • Confirmation visuelle et sonore des paiements
    • Gestion complète des erreurs avec retry intelligent
  • 🛠️ Services Tap to Pay
    • Service StripeTapToPayService avec SDK mek_stripe_terminal
    • Service DeviceInfoService pour détection compatibilité
    • Service OfflineQueueService pour mode hors ligne
    • Integration avec PaymentRepository existant
  • 📱 Compatibilité appareils
    • iPhone XS+ avec iOS 16.4+ (V2.1)
    • Android 9.0+ avec appareils certifiés (V2.2)
    • Détection automatique et messages explicites
  • 📊 Dashboard vendeur
    • Statistiques temps réel (jour/semaine/mois/total)
    • Historique des transactions avec détails
    • Export CSV pour comptabilité
    • Mode offline avec synchronisation automatique
  • 🔄 Flow de paiement
    • Création passage → PaymentIntent → Collecte NFC → Confirmation
    • Double validation : API + Stripe pour traçabilité complète
    • Metadata bidirectionnelle (passage_id ↔ stripe_payment_id)
    • Gestion d'erreurs robuste avec retry et timeout

v3.3.3 (04 Octobre 2025)

Optimisation majeure des widgets de statistiques

  • Simplification de l'architecture de calcul

    • Suppression des doubles calculs redondants dans PassageSummaryCard et PaymentSummaryCard
    • Une seule source de vérité : méthode unique de calcul par widget
    • Total calculé automatiquement par somme des valeurs par type
    • Garantie de cohérence entre total affiché et décompte détaillé
  • 🎯 PassageSummaryCard - Architecture optimisée

    • Suppression de _calculateUserPassagesCount() (redondante)
    • Méthode unique _calculatePassagesCounts() retourne Map<int, int> par type
    • Total = somme des valeurs de la Map
    • Filtre excludePassageTypes appliqué uniformément
  • 💳 PaymentSummaryCard - Architecture optimisée

    • Suppression de _calculatePaymentStats() (redondante)
    • Méthode unique _calculatePaymentAmounts() retourne Map<int, double> par type
    • Total = somme des montants de la Map
    • Filtre fkUser appliqué uniformément en mode utilisateur
  • 🧹 HomePage - Nettoyage complet

    • Suppression de _loadDashboardData() et toutes variables d'état obsolètes
    • Widgets calculent leurs propres données via ValueListenableBuilder
    • Suppression des méthodes inutilisées : _getUserSectorPassages(), _preparePaymentData(), _convertPaymentDataToMap()
    • Paramètre customTotalDisplay utilise directement le paramètre calculé
  • Bénéfices de l'optimisation

    • DRY : Une seule méthode de calcul par widget
    • Cohérence garantie : Impossibilité d'avoir des totaux incohérents
    • Performance : Réduction des calculs redondants
    • Maintenabilité : Architecture simplifiée et prévisible
    • Réactivité : Mise à jour automatique via ValueListenableBuilder

v3.2.7 (25 Septembre 2025)

Gestion conditionnelle du type Lot et améliorations des formulaires

  • 🎯 Affichage conditionnel du type "Lot" (type 5)

    • Masquage automatique du type "Lot" dans toute l'interface lorsque chkLotActif = false dans l'amicale
    • Implémentation dans : PassageFormDialog, PassagePieChart, MembersBoardPassages, PassagesListWidget
    • Filtrage intelligent des types de passages selon la configuration de l'amicale
  • 📝 Améliorations du formulaire utilisateur (UserFormDialog)

    • Boutons radio du rôle (Administrateur/Membre) alignés sur la même ligne sans bordure
    • Suppression des descriptions (helpers) sous les boutons radio pour une interface épurée
    • Email rendu optionnel avec validation uniquement si rempli
    • Ajout du helper text "Identifiant de connexion" sous le champ username
    • Suppression du bouton de génération automatique de mot de passe
  • 🔐 Amélioration de la gestion du username

    • Modification du username possible en création ET en édition (si permissions accordées)
    • Vérification automatique de la disponibilité du username lors de la soumission
    • Appel API /users/check-username pour détecter les conflits
    • Affichage des suggestions si le username est déjà pris
    • Blocage de la soumission si username non disponible
  • 🧹 Nettoyage de l'interface admin

    • Suppression du tag membre sélectionné dans l'en-tête de admin_history_page
    • Suppression des méthodes inutilisées : _getMemberNameWithSector(), _clearMemberFilter(), _formatUserName()
    • Interface plus claire et épurée pour l'administration

v3.2.4 (04 Septembre 2025)

Optimisations et corrections

  • 🐛 Correction du PassagesListWidget dans user_dashboard_home_page
    • Suppression de la hauteur fixe pour éviter le rectangle gris
    • Affichage des 20 derniers passages sans scrolling interne
    • Utilisation du scrolling de la page principale uniquement
  • 🧹 Nettoyage du code
    • Suppression des méthodes non utilisées (_formatDate, _buildSimplePassageCard, _showPassageDetails)
    • Amélioration de la structure des blocs if/else selon les bonnes pratiques
    • Suppression des imports inutiles (intl)
  • Qualité du code
    • Flutter analyze : 0 erreur, 0 warning sur tous les fichiers modifiés
    • Réduction globale de 65% des issues (de 493 à 171)

v3.2.3 (03 Septembre 2025)

Mise à jour des interfaces mobiles

  • 📱 Améliorations de l'interface utilisateur
    • Optimisation des layouts pour mobiles et tablettes
    • Amélioration de la réactivité des composants
  • 🔧 Corrections de bugs mineurs
    • Résolution des problèmes d'affichage sur certains appareils
    • Amélioration des performances de rendu

v3.2.2 (02 Septembre 2025)

Centralisation des filtres dans PassagesListWidget

  • 🎯 Refactoring majeur du système de filtrage
    • Tous les filtres déplacés dans PassagesListWidget (recherche, type, paiement, secteur, membre, période)
    • Configuration flexible via paramètres booléens (showTypeFilter, showPaymentFilter, showSectorFilter, etc.)
    • Suppression du code de filtrage dupliqué dans les pages parentes
  • 🔧 Nouveaux filtres avancés
    • Filtre par secteur avec liste déroulante
    • Filtre par membre pour les pages admin
    • Filtre par période avec options prédéfinies (24h, 48h, 7 jours, 15 jours, mois)
    • Support des plages de dates personnalisées avec DateRangePicker
  • 📱 Interface responsive des filtres
    • Desktop : Filtres compacts sur 2 lignes maximum
    • Mobile : Filtres empilés verticalement pour une meilleure ergonomie
    • Recherche toujours en premier pour une accessibilité optimale
  • 🔄 Synchronisation des filtres
    • Callback onFiltersChanged pour synchroniser l'état avec les pages parentes
    • Notification automatique des changements de filtres
    • Persistance des sélections entre les navigations
  • 📊 Pages simplifiées
    • admin_history_page.dart : Suppression de 400+ lignes de code de filtrage dupliqué
    • user_history_page.dart : Simplification avec activation sélective des filtres pertinents
    • Maintenance facilitée avec une logique unique centralisée
  • 🔧 Correction des layouts
    • admin_history_page.dart : Utilisation d'Expanded au lieu de hauteur fixe (85%)
    • Liste des passages s'étend maintenant jusqu'en bas de l'écran sur mobile
  • 📝 Amélioration des labels de filtres
    • "Tous les types" au lieu de "Tous"
    • "Tous les règlements" au lieu de "Tous"
    • "Toutes les périodes" au lieu de "Tous"
    • Meilleure clarté pour l'utilisateur

v3.2.1 (31 Août 2025)

Build et déploiement

  • 🚀 Publication sur Google Play Store
    • Build AAB (Android App Bundle) pour distribution optimisée
    • Configuration des signatures et keystores
    • Optimisation de la taille de l'application
  • 🔧 Corrections de bugs critiques
    • Fix des problèmes de compilation
    • Résolution des dépendances obsolètes
    • Amélioration de la stabilité générale

v3.2.0 (30 Août 2025)

Intégration Stripe Connect V1

  • 💳 Système de paiement pour les amicales
    • Configuration Stripe Connect Express pour chaque amicale
    • Interface web de gestion des comptes (admin uniquement)
    • Onboarding guidé en français avec statuts temps réel
    • Comptes séparés : 0% commission plateforme, 100% pour l'amicale
  • 🏗️ Architecture de paiement V1
    • Service StripeConnectService avec 4 endpoints API
    • Intégration complète avec widget amicale_form.dart
    • Gestion des états : Non configuré → En cours → Actif
    • Messages utilisateur contextuels et visuels
  • 🔐 Sécurité et conformité
    • Conformité PCI DSS automatique via Stripe
    • Aucune donnée sensible stockée localement
    • Communication HTTPS obligatoire
    • Validation côté serveur et client

v3.1.0 (Juillet 2025)

Interface utilisateur

  • 🎨 Suppression des titres de pages pour maximiser l'espace utile
    • Pages utilisateur : historique, statistiques, carte
    • Pages admin : historique, statistiques
    • Module de chat
  • 📱 Chat responsive avec layout adaptatif
    • Desktop : disposition horizontale rooms/messages
    • Mobile : disposition verticale avec hauteur adaptative
  • 🗺️ Carte optimisée
    • Mode plein écran
    • Filtres en pastilles colorées overlay (bas gauche)
    • Design minimaliste sans labels
  • 📏 Titres responsive sur dashboards
    • Tailles adaptées aux petits écrans
    • Suppression des éléments superflus (icône refresh)

v3.0.0 (Juin 2025)

Refonte architecturale majeure

  • 🏗️ Architecture moderne sans Provider
    • Migration vers l'injection de dépendances
    • Repositories singleton avec instances globales
    • Suppression complète de Provider/Bloc
  • 💾 Optimisation cache Hive
    • Stratégie de cache pour éliminer les vérifications répétées
    • Performance améliorée de 99% sur les opérations de liste
    • Gestion intelligente du cache avec reset après modifications
  • 🔐 Normes NIST SP 800-63B pour les identifiants
    • Support des phrases de passe
    • Acceptation de tous les caractères Unicode
    • Vérification contre les bases de mots de passe compromis
  • 📊 Système de logging intelligent
    • LoggerService centralisé avec détection d'environnement
    • Logs désactivés automatiquement en production
    • Catégorisation avec emojis automatiques
  • 🎯 Pattern Dialog Auto-Gérée
    • Dialogs responsables de leur propre cycle de vie
    • Auto-fermeture sur succès
    • Gestion d'erreurs centralisée dans la dialog

v2.x (2024 - Début 2025)

Versions de développement initial

  • Base de l'architecture Flutter
  • Mise en place des modèles Hive
  • Intégration des cartes Mapbox/OpenStreetMap
  • Système de chat MQTT
  • Gestion des rôles et permissions