Files
geo/app/TODO-APP.md
Pierre 206c76c7db feat: Livraison version 3.0.6
- Amélioration de la gestion des entités et des utilisateurs
- Mise à jour des modèles Amicale et Client avec champs supplémentaires
- Ajout du service de logging et amélioration du chargement UI
- Refactoring des formulaires utilisateur et amicale
- Intégration de file_picker et image_picker pour la gestion des fichiers
- Amélioration de la gestion des membres et de leur suppression
- Optimisation des performances de l'API
- Mise à jour de la documentation technique

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-08 20:33:54 +02:00

24 KiB

TODO-APP.md

📋 Liste des tâches à effectuer sur l'application GEOSECTOR

🔧 Migration du pattern de gestion des erreurs API

🎯 Objectif

Appliquer le nouveau pattern de gestion des erreurs pour que tous les messages spécifiques de l'API soient correctement affichés aux utilisateurs (au lieu du message générique "Erreur inattendue").


Repositories déjà migrés

  • MembreRepository (lib/core/repositories/membre_repository.dart)
    • Conversion DioException → ApiException
    • Simplification du code
    • Logs avec LoggerService

📝 Repositories à migrer

1. UserRepository (lib/core/repositories/user_repository.dart)

  • Vérifier/ajouter l'import ApiException
  • Simplifier updateUser() - supprimer les vérifications de statut après l'appel API
  • Simplifier syncUser() - supprimer les vérifications de statut après l'appel API
  • Simplifier syncAllUsers() - supprimer les vérifications de statut après l'appel API
  • Remplacer debugPrint par LoggerService
  • Améliorer la gestion des erreurs dans le bloc catch (ne pas logger DioException)

2. OperationRepository (lib/core/repositories/operation_repository.dart)

  • Vérifier/ajouter l'import ApiException
  • Simplifier createOperation() - supprimer les vérifications de statut après l'appel API
  • Simplifier updateOperation() - supprimer les vérifications de statut après l'appel API
  • Simplifier deleteOperation() - supprimer les vérifications de statut après l'appel API
  • Simplifier activateOperation() - supprimer les vérifications de statut après l'appel API
  • Remplacer debugPrint par LoggerService
  • Améliorer la gestion des erreurs dans le bloc catch (ne pas logger DioException)

3. PassageRepository (lib/core/repositories/passage_repository.dart)

  • Vérifier/ajouter l'import ApiException
  • Simplifier createPassage() - supprimer les vérifications de statut après l'appel API
  • Simplifier updatePassage() - supprimer les vérifications de statut après l'appel API
  • Simplifier updatePassageStatus() - supprimer les vérifications de statut après l'appel API
  • Simplifier syncPassages() - supprimer les vérifications de statut après l'appel API
  • Remplacer debugPrint par LoggerService
  • Améliorer la gestion des erreurs dans le bloc catch (ne pas logger DioException)

4. SectorRepository (lib/core/repositories/sector_repository.dart)

  • Vérifier/ajouter l'import ApiException
  • Simplifier createSector() - supprimer les vérifications de statut après l'appel API
  • Simplifier updateSector() - supprimer les vérifications de statut après l'appel API
  • Simplifier deleteSector() - supprimer les vérifications de statut après l'appel API
  • Simplifier assignUserToSector() - supprimer les vérifications de statut après l'appel API
  • Remplacer debugPrint par LoggerService
  • Améliorer la gestion des erreurs dans le bloc catch (ne pas logger DioException)

5. AmicaleRepository (lib/core/repositories/amicale_repository.dart)

  • Vérifier/ajouter l'import ApiException
  • Simplifier updateAmicale() - supprimer les vérifications de statut après l'appel API
  • Simplifier createAmicale() - supprimer les vérifications de statut après l'appel API
  • Simplifier syncAmicales() - supprimer les vérifications de statut après l'appel API
  • Remplacer debugPrint par LoggerService
  • Améliorer la gestion des erreurs dans le bloc catch (ne pas logger DioException)

🛠️ Pattern à appliquer

Code à supprimer (ancien pattern)

try {
  final response = await ApiService.instance.put('/endpoint', data: data);
  
  if (response.statusCode == 200) {
    // Traitement succès
    return true;
  }
  
  // ⚠️ Ce code ne sera JAMAIS exécuté
  if (response.data != null && response.data is Map<String, dynamic>) {
    final responseData = response.data as Map<String, dynamic>;
    if (responseData['status'] == 'error') {
      throw Exception(responseData['message']);
    }
  }
  return false;
} catch (e) {
  debugPrint('Erreur: $e');
  rethrow;
}

Nouveau pattern à utiliser

try {
  final response = await ApiService.instance.put('/endpoint', data: data);
  
  // Si on arrive ici, la requête a réussi (200/201)
  // Traitement succès
  return true;
  
} catch (e) {
  // Log propre sans détails techniques
  if (e is ApiException) {
    LoggerService.error('Erreur lors de l\'opération: ${e.message}');
  } else {
    LoggerService.error('Erreur lors de l\'opération');
  }
  rethrow; // Propager pour affichage UI
}

📦 Imports nécessaires

Ajouter ces imports dans chaque repository si manquants :

import 'package:geosector_app/core/services/logger_service.dart';
import 'package:geosector_app/core/utils/api_exception.dart';

🧪 Tests de validation

Pour chaque repository migré, tester :

  1. Test d'erreur 409 (Conflict) :

    • Créer/modifier avec un email déjà existant
    • Vérifier que le message "Cet email est déjà utilisé" s'affiche
  2. Test d'erreur 400 (Bad Request) :

    • Envoyer des données invalides
    • Vérifier que le message d'erreur spécifique s'affiche
  3. Test d'erreur réseau :

    • Couper la connexion
    • Vérifier que "Problème de connexion réseau" s'affiche
  4. Test de succès :

    • Opération normale
    • Vérifier que tout fonctionne comme avant

📊 Critères de succès

  • Tous les repositories utilisent le nouveau pattern
  • Plus aucun debugPrint dans les repositories (remplacé par LoggerService)
  • Les messages d'erreur spécifiques de l'API s'affichent correctement
  • Les logs en production sont désactivés (sauf erreurs)
  • Le code est plus simple et maintenable

🔍 Commandes utiles pour vérifier

# Rechercher les anciens patterns à remplacer
grep -r "response.statusCode ==" lib/core/repositories/
grep -r "responseData\['status'\] == 'error'" lib/core/repositories/
grep -r "debugPrint" lib/core/repositories/

# Vérifier les imports manquants
grep -L "LoggerService" lib/core/repositories/*.dart
grep -L "ApiException" lib/core/repositories/*.dart

📅 Priorité

  1. Haute : UserRepository (utilisé partout)
  2. Haute : OperationRepository (fonctionnalité critique)
  3. Moyenne : PassageRepository (utilisé fréquemment)
  4. Moyenne : AmicaleRepository (gestion administrative)
  5. Basse : SectorRepository (moins critique)

📝 Notes

  • Cette migration améliore l'UX en affichant des messages d'erreur clairs
  • Le LoggerService désactive automatiquement les logs en production
  • Le code devient plus maintenable et cohérent
  • Documenter dans README-APP.md une fois terminé

🧪 Tests unitaires Flutter à implémenter

📁 Structure des tests

Le dossier /test doit contenir des tests unitaires pour valider le comportement de l'application.

📝 Tests prioritaires à créer

1. Tests des Repositories (test/repositories/)

test/repositories/membre_repository_test.dart
  • Test de création d'un membre avec succès
  • Test de création avec email déjà existant (409)
  • Test de mise à jour d'un membre
  • Test de suppression d'un membre
  • Test de gestion des erreurs réseau
  • Test du cache Hive local
test/repositories/user_repository_test.dart
  • Test de connexion réussie
  • Test de connexion avec mauvais identifiants
  • Test de mise à jour du profil utilisateur
  • Test de synchronisation des données
  • Test de gestion de session
test/repositories/operation_repository_test.dart
  • Test de création d'opération
  • Test d'activation/désactivation
  • Test de récupération des opérations par amicale
  • Test de suppression avec transfert de passages

2. Tests des Services (test/services/)

test/services/api_service_test.dart
  • Test de détection d'environnement (DEV/REC/PROD)
  • Test de gestion des sessions
  • Test de conversion DioException vers ApiException
  • Test des différents codes d'erreur HTTP
  • Test du retry automatique
test/services/logger_service_test.dart
  • Test de désactivation des logs en PROD
  • Test des différents niveaux de log
  • Test du formatage des messages
test/services/hive_service_test.dart
  • Test d'initialisation des boîtes Hive
  • Test de sauvegarde et récupération
  • Test de suppression de données
  • Test de migration de schéma

3. Tests des Models (test/models/)

test/models/membre_model_test.dart
  • Test de sérialisation JSON
  • Test de désérialisation JSON
  • Test de conversion vers UserModel
  • Test des valeurs par défaut
test/models/amicale_model_test.dart
  • Test de sérialisation/désérialisation
  • Test des nouveaux champs booléens (chk_mdp_manuel, chk_username_manuel)
  • Test de validation des données

4. Tests des Widgets (test/widgets/)

test/widgets/user_form_test.dart
  • Test d'affichage conditionnel des champs (username/password)
  • Test de validation du mot de passe (regex)
  • Test de validation de l'username (pas d'espaces)
  • Test de génération automatique d'username
  • Test du mode création vs modification
test/widgets/membre_table_widget_test.dart
  • Test d'affichage responsive (mobile vs web)
  • Test de masquage des colonnes sur mobile
  • Test des icônes de statut
  • Test du tri et filtrage

5. Tests d'intégration (test/integration/)

test/integration/auth_flow_test.dart
  • Test du flow complet de connexion
  • Test de persistance de session
  • Test de déconnexion
  • Test de redirection après expiration
test/integration/membre_management_test.dart
  • Test de création complète d'un membre
  • Test de modification avec validation
  • Test de suppression avec transfert
  • Test de gestion des erreurs

🛠️ Configuration des tests

Fichier test/test_helpers.dart

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:dio/dio.dart';
import 'package:hive_flutter/hive_flutter.dart';

// Mocks nécessaires
class MockDio extends Mock implements Dio {}
class MockBox<T> extends Mock implements Box<T> {}
class MockApiService extends Mock implements ApiService {}

// Helper pour initialiser Hive en tests
Future<void> setupTestHive() async {
  await Hive.initFlutter();
  // Initialiser les boîtes de test
}

// Helper pour nettoyer après les tests
Future<void> tearDownTestHive() async {
  await Hive.deleteFromDisk();
}

// Helper pour créer des données de test
class TestDataFactory {
  static UserModel createTestUser() {
    return UserModel(
      id: 1,
      username: 'test_user',
      email: 'test@example.com',
      // ...
    );
  }
  
  static MembreModel createTestMembre() {
    return MembreModel(
      id: 1,
      fkEntite: 100,
      name: 'Test',
      firstName: 'User',
      // ...
    );
  }
}

📋 Commandes de test

# Lancer tous les tests
flutter test

# Lancer un test spécifique
flutter test test/repositories/membre_repository_test.dart

# Lancer avec coverage
flutter test --coverage

# Générer un rapport HTML de couverture
genhtml coverage/lcov.info -o coverage/html
open coverage/html/index.html

🎯 Objectifs de couverture

  • Repositories : 80% minimum
  • Services : 90% minimum
  • Models : 95% minimum
  • Widgets critiques : 70% minimum
  • Couverture globale : 75% minimum

📚 Dépendances de test à ajouter

Dans pubspec.yaml :

dev_dependencies:
  flutter_test:
    sdk: flutter
  mockito: ^5.4.4
  build_runner: ^2.4.8
  test: ^1.25.2
  flutter_lints: ^4.0.0
  coverage: ^1.7.2

🔄 Intégration CI/CD

Ajouter dans le pipeline CI :

test:
  stage: test
  script:
    - flutter test --coverage
    - genhtml coverage/lcov.info -o coverage/html
  artifacts:
    paths:
      - coverage/
  coverage: '/lines\.*: \d+\.\d+\%/'

📝 Bonnes pratiques

  1. Isolation : Chaque test doit être indépendant
  2. Mocking : Utiliser des mocks pour les dépendances externes
  3. Nommage : Utiliser des noms descriptifs (test_should_xxx_when_yyy)
  4. AAA : Suivre le pattern Arrange-Act-Assert
  5. Edge cases : Tester les cas limites et erreurs
  6. Performance : Les tests unitaires doivent être rapides (<100ms)

💬 Module Chat en ligne GEOSECTOR

📋 Vue d'ensemble

Le module chat est partiellement implémenté avec une architecture MQTT pour les notifications en temps réel. Il nécessite des développements supplémentaires pour être pleinement fonctionnel.

🏗️ Architecture existante

lib/chat/
├── models/                        # ✅ Modèles créés avec Hive
│   ├── conversation_model.dart    # Conversations (one-to-one, groupe, annonce)
│   ├── message_model.dart         # Messages avec pièces jointes
│   ├── participant_model.dart     # Participants aux conversations
│   └── audience_target_model.dart # Cibles pour les annonces
├── repositories/                  # ⚠️ À compléter
│   └── chat_repository.dart       # Logique métier du chat
├── services/                      # ⚠️ Partiellement implémenté
│   ├── chat_api_service.dart      # Communication avec l'API
│   ├── offline_queue_service.dart # File d'attente hors ligne
│   └── notifications/             # 🔧 MQTT configuré
│       ├── mqtt_notification_service.dart
│       └── mqtt_config.dart
├── widgets/                       # ⚠️ À implémenter
│   ├── chat_screen.dart          # Écran principal du chat
│   ├── conversations_list.dart   # Liste des conversations
│   ├── message_bubble.dart       # Bulles de messages
│   └── chat_input.dart           # Zone de saisie
└── pages/                        # ⚠️ À compléter
    └── chat_page.dart            # Page principale

📝 Tâches de développement Chat

1. Finalisation des modèles Hive

  • Compléter les adaptateurs Hive pour tous les modèles
  • Ajouter la gestion des pièces jointes (images, documents)
  • Implémenter le modèle AnonymousUserModel pour les utilisateurs temporaires
  • Ajouter les timestamps et statuts de lecture

2. Repository ChatRepository

  • Implémenter createConversation() avec participants
  • Implémenter sendMessage() avec queue hors ligne
  • Implémenter getConversations() avec pagination
  • Implémenter getMessages() avec lazy loading
  • Ajouter la gestion des participants (ajout/suppression)
  • Implémenter les annonces ciblées par groupe

3. Services

  • Compléter ChatApiService avec endpoints REST
  • Implémenter la synchronisation bidirectionnelle
  • Configurer OfflineQueueService pour messages en attente
  • Implémenter le retry automatique avec exponential backoff
  • Ajouter la compression des images avant envoi

4. Notifications MQTT

  • Installer et configurer Mosquitto dans le container Incus
  • Configurer SSL/TLS pour MQTT (port 8883)
  • Implémenter l'authentification par token JWT
  • Créer les topics par utilisateur/groupe/conversation
  • Implémenter le système de présence (online/offline/typing)
  • Ajouter les ACLs pour sécuriser les topics

5. Interface utilisateur

  • Créer ChatScreen avec liste de messages
  • Implémenter ConversationsList avec badges non-lus
  • Designer MessageBubble (texte, images, documents)
  • Créer ChatInput avec:
    • Saisie de texte avec emoji picker
    • Bouton d'envoi de fichiers
    • Indicateur "en train d'écrire"
    • Enregistrement vocal (optionnel)
  • Ajouter les animations (apparition messages, typing indicator)
  • Implémenter le swipe pour répondre
  • Ajouter la recherche dans les conversations

6. Fonctionnalités avancées

  • Notifications push locales via flutter_local_notifications
  • Chiffrement end-to-end des messages sensibles
  • Réactions aux messages (emojis)
  • Messages éphémères avec auto-suppression
  • Partage de localisation en temps réel
  • Appels audio/vidéo via WebRTC (phase 2)

🔧 Configuration backend requise

Base de données

-- Tables à créer (voir chat_tables.sql)
CREATE TABLE chat_conversations (
  id INT PRIMARY KEY AUTO_INCREMENT,
  type ENUM('one_to_one', 'group', 'announcement'),
  created_by INT,
  created_at TIMESTAMP,
  updated_at TIMESTAMP
);

CREATE TABLE chat_messages (
  id INT PRIMARY KEY AUTO_INCREMENT,
  conversation_id INT,
  sender_id INT,
  content TEXT,
  type ENUM('text', 'image', 'file', 'location'),
  status ENUM('sent', 'delivered', 'read'),
  created_at TIMESTAMP
);

CREATE TABLE chat_participants (
  conversation_id INT,
  user_id INT,
  role ENUM('admin', 'member'),
  joined_at TIMESTAMP,
  last_read_message_id INT
);

Configuration MQTT

# Installation Mosquitto
apt-get install mosquitto mosquitto-clients

# Configuration /etc/mosquitto/mosquitto.conf
listener 1883
listener 8883
cafile /etc/mosquitto/ca.crt
certfile /etc/mosquitto/server.crt
keyfile /etc/mosquitto/server.key
allow_anonymous false
password_file /etc/mosquitto/passwd

📦 Dépendances à ajouter

dependencies:
  # MQTT et notifications
  mqtt5_client: ^4.0.0
  flutter_local_notifications: ^17.0.0
  
  # UI et UX
  emoji_picker_flutter: ^2.0.0
  cached_network_image: ^3.3.1
  photo_view: ^0.14.0
  file_picker: ^6.1.1
  
  # Utilitaires
  path_provider: ^2.1.2
  image_picker: ^1.0.7
  image: ^4.1.7  # Pour compression
  intl: ^0.19.0  # Pour formatage dates

🧪 Tests à implémenter

  • Tests unitaires des repositories
  • Tests d'intégration MQTT
  • Tests de performance (1000+ messages)
  • Tests hors ligne/online
  • Tests de sécurité (injection, XSS)

💳 Module de paiement Stripe

📋 Vue d'ensemble

Intégration de Stripe pour permettre aux amicales ayant activé chk_stripe d'accepter les paiements par carte bancaire avec une commission de 1.4%.

🎯 Objectifs

  1. Permettre le paiement en ligne lors des passages
  2. Gérer les comptes Stripe des amicales
  3. Suivre les transactions et commissions
  4. Offrir une expérience de paiement fluide

📝 Tâches de développement Stripe

1. Configuration initiale Stripe

  • Créer un compte Stripe Connect Platform
  • Configurer les webhooks Stripe
  • Mettre en place l'environnement de test (sandbox)
  • Configurer les clés API (publishable/secret)
  • Implémenter la gestion sécurisée des clés

2. Onboarding des amicales

  • Créer un workflow d'inscription Stripe pour les amicales
  • Implémenter Stripe Connect Onboarding
  • Gérer le KYC (Know Your Customer) requis par Stripe
  • Stocker de manière sécurisée le stripe_account_id
  • Créer une page de statut du compte Stripe
  • Gérer les documents requis (RIB, statuts, etc.)

3. Modèles de données

  • Créer StripeAccountModel pour les comptes Connect
  • Créer PaymentIntentModel pour les intentions de paiement
  • Créer TransactionModel pour l'historique
  • Ajouter les champs Stripe dans PassageModel
  • Implémenter la table des commissions

4. Service StripeService

class StripeService {
  // Compte Connect
  Future<String> createConnectAccount(AmicaleModel amicale);
  Future<void> updateAccountStatus(String accountId);
  Future<String> createAccountLink(String accountId);
  
  // Paiements
  Future<PaymentIntent> createPaymentIntent({
    required double amount,
    required String currency,
    required String connectedAccountId,
  });
  
  Future<void> confirmPayment(String paymentIntentId);
  Future<void> refundPayment(String paymentIntentId);
  
  // Commissions
  double calculateApplicationFee(double amount); // 1.4%
}

5. Interface de paiement dans PassageForm

  • Détecter si l'amicale accepte Stripe (chk_stripe)
  • Ajouter l'option "Paiement par carte" dans le dropdown
  • Intégrer Stripe Elements pour la saisie de carte
  • Implémenter le flow de paiement 3D Secure
  • Gérer les erreurs de paiement
  • Afficher le reçu de paiement
  • Permettre l'envoi du reçu par email

6. Widget StripePaymentSheet

class StripePaymentSheet extends StatefulWidget {
  final double amount;
  final String currency;
  final AmicaleModel amicale;
  final Function(String) onSuccess;
  final Function(String) onError;
  
  // UI avec:
  // - Montant à payer
  // - Formulaire de carte (Stripe Elements)
  // - Bouton de validation
  // - Indicateur de traitement
  // - Gestion 3D Secure
}

7. Tableau de bord financier

  • Page de suivi des transactions Stripe
  • Graphiques des paiements par période
  • Export des transactions (CSV/Excel)
  • Calcul automatique des commissions
  • Rapprochement bancaire
  • Dashboard temps réel des paiements

8. Webhooks Stripe

// Backend PHP pour gérer les webhooks
class StripeWebhookHandler {
  // Events à gérer:
  - payment_intent.succeeded
  - payment_intent.failed
  - account.updated
  - payout.created
  - refund.created
}

9. Sécurité

  • Chiffrement des données sensibles
  • Validation PCI DSS
  • Audit trail des transactions
  • Détection de fraude
  • Rate limiting sur les API
  • Tokenisation des cartes

10. Tests et conformité

  • Tests avec cartes de test Stripe
  • Tests des cas d'erreur (carte refusée, etc.)
  • Tests 3D Secure
  • Tests de performance
  • Conformité RGPD pour les données de paiement
  • Documentation utilisateur

🔧 Configuration backend requise

Tables base de données

CREATE TABLE stripe_accounts (
  id INT PRIMARY KEY AUTO_INCREMENT,
  fk_entite INT NOT NULL,
  stripe_account_id VARCHAR(255) ENCRYPTED,
  status ENUM('pending', 'active', 'restricted'),
  charges_enabled BOOLEAN DEFAULT FALSE,
  payouts_enabled BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP,
  updated_at TIMESTAMP
);

CREATE TABLE stripe_transactions (
  id INT PRIMARY KEY AUTO_INCREMENT,
  fk_passage INT,
  stripe_payment_intent_id VARCHAR(255),
  amount DECIMAL(10,2),
  currency VARCHAR(3),
  status VARCHAR(50),
  application_fee DECIMAL(10,2),
  created_at TIMESTAMP
);

Variables d'environnement

STRIPE_PUBLISHABLE_KEY=pk_test_xxx
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
STRIPE_APPLICATION_FEE_PERCENT=1.4

📦 Dépendances Stripe

dependencies:
  # Stripe
  flutter_stripe: ^10.1.1
  
  # Sécurité
  flutter_secure_storage: ^9.0.0
  
  # UI
  shimmer: ^3.0.0  # Loading states
  lottie: ^3.1.0   # Animations succès/échec

🚀 Roadmap d'implémentation

Phase 1 (2 semaines)

  • Configuration Stripe Connect
  • Onboarding basique des amicales
  • Tests en sandbox

Phase 2 (3 semaines)

  • Intégration dans PassageForm
  • Gestion des paiements simples
  • Webhooks essentiels

Phase 3 (2 semaines)

  • Dashboard financier
  • Export et rapports
  • Tests complets

Phase 4 (1 semaine)

  • Mise en production
  • Monitoring
  • Documentation

💰 Estimation des coûts

  • Stripe Connect : 0.25€ par compte actif/mois
  • Transactions : 1.4% + 0.25€ par transaction
  • Commission application : 1.4% (reversée à GEOSECTOR)
  • Coût net pour l'amicale : ~2.8% + 0.25€ par transaction

Date de création : 2025-08-07 Auteur : Architecture Team Version : 1.2.0