# Tâches restantes — Analyse source (unionflow-mobile-apps)

Document généré à partir de la **lecture intégrale** de chaque fichier `.dart` sous `lib/` (de la première à la dernière ligne, sans lecture par plages).  
Chaque entrée indique le fichier, les numéros de ligne et la tâche à faire (strictement déduite du code).  
Fichiers exclus : `.md`. Fichiers `.g.dart` : lus mais tâches métier ciblant le code source non généré.

**Principe** : Chaque tâche est rédigée comme une **décision unique** / **action prioritaire** selon les bonnes pratiques : pas de « soit… soit… », pas d’« ou » entre alternatives, pas d’optionnel non assumé — on choisit une approche et on la suit.

---

## 1. App

### 1.1 `lib/app/app.dart`
- **L.39-40** — Thème sombre et themeMode sont commentés : `// darkTheme: AppThemeSophisticated.darkTheme,` et `// themeMode: ThemeMode.system`. **Tâche** : Activer le thème sombre et le mode système (bonne pratique UX) ; si désactivation volontaire, ajouter un commentaire explicite dans le code (ex. « Désactivé car… »).

---

## 2. Core

### 2.1 `lib/core/utils/logger.dart`
- **L.232-240** — `_sendToMonitoring` : stub non implémenté. **Tâche** : Implémenter l’envoi des erreurs vers le service de monitoring retenu (ex. Sentry ou Firebase Crashlytics) lors de l’intégration.
- **L.244-250** — `_sendToAnalytics` : stub non implémenté. **Tâche** : Implémenter l’envoi des événements vers le service d’analytics retenu (ex. Firebase Analytics ou Mixpanel) lors de l’intégration.

### 2.2 `lib/core/storage/dashboard_cache_manager.dart`
- **L.36-37** — `catch (_) {}` dans `get<T>` (décodage JSON disque). **Tâche** : Logger l’erreur avec `AppLogger` et remonter une erreur typée (ou retourner une valeur par défaut documentée) ; ne pas laisser de catch vide.
- **L.48-49** — `catch (_) {}` dans `set<T>` (écriture disque). **Tâche** : Logger l’erreur et propager l’échec (rethrow) pour que l’appelant sache que l’écriture a échoué.

### 2.3 `lib/core/network/api_client.dart`
- **L.99-108** — `_forceLogout` et `_refreshToken` : les `catch` utilisent uniquement `debugPrint`. **Tâche** : Centraliser la gestion d’erreur : appeler `ErrorHandler.getErrorMessage`, logger, et notifier via un callback critique pour que les échecs de déconnexion/refresh soient tracés et gérés.

### 2.4 `lib/core/navigation/adaptive_navigation.dart`
- **L.86-122, 136-178, 190-229, etc.** — `AdaptiveNavigationDrawer` référence des routes (`/moderation`, `/communication`, `/analytics`, etc.) qui ne sont pas définies dans `AppRouter` (seuls `/`, `/login`, `/dashboard` existent). **Tâche** : Enregistrer chaque route utilisée par le drawer dans le même routeur que `MainNavigationLayout`, et faire pointer les `onTap` vers la navigation réelle ; ne pas laisser de routes orphelines.

---

## 3. Features — About

### 3.1 `lib/features/about/presentation/pages/about_page.dart`
- **L.44-45** — `IconButton` « Partager » avec `onPressed: () {}`. **Tâche** : Implémenter le partage avec le package `share_plus` pour partager les infos de l’app (titre, lien, description).
- **L.378-408** — `_showRatingDialog()` est définie mais jamais appelée depuis l’UI. **Tâche** : Exposer un bouton « Évaluer l’app » (ex. dans la page À propos) qui appelle `_showRatingDialog()` pour réutiliser le code existant.
- **L.392** — Dans `_showRatingDialog`, le bouton « Évaluer maintenant » appelle `_showErrorSnackBar('Fonctionnalité bientôt disponible')`. **Tâche** : Implémenter l’ouverture du store avec `url_launcher` (lien Play Store / App Store) pour que l’utilisateur puisse noter l’app.

---

## 4. Features — Adhesions

### 4.0 `lib/features/adhesions/data/repositories/adhesion_repository.dart`
- **L.40-46, 117-123, 133-138, 148-153, 164-169** — `getAll`, `getByMembre`, `getByOrganisation`, `getByStatut`, `getEnAttente` supposent que `response.data` est une liste. Si le backend renvoie un format paginé (ex. `{ "content": [...] }`), le cast échouera. **Tâche** : Vérifier le contrat API et gérer les deux formats (liste directe et objet paginé avec `content`) comme dans `evenement_repository_impl.dart`.

### 4.1 `lib/features/adhesions/bloc/adhesions_bloc.dart`
- **L.129-134** — `_onLoadAdhesionsStats` : `catch (_) {}` sans émission d’état ni message. **Tâche** : Dans le catch, logger l’erreur avec `AppLogger` et émettre un état d’erreur (ex. `AdhesionsStatsLoadFailed(message: ErrorHandler.getErrorMessage(e))`) pour que l’UI puisse afficher un message.

### 4.2 `lib/features/adhesions/presentation/widgets/create_adhesion_dialog.dart`
- **L.49-55** — `_loadInitialData` : `catch (_)` sans message utilisateur. **Tâche** : Logger l’erreur, émettre un état d’erreur et afficher un SnackBar pour indiquer l’échec du chargement du profil ou des organisations.

### 4.3 `lib/features/adhesions/presentation/widgets/rejet_adhesion_dialog.dart`
- **L.40-45** — Après `context.read<AdhesionsBloc>().add(RejeterAdhesion(widget.adhesionId, motif))`, le dialogue appelle immédiatement `widget.onRejected()` et `Navigator.of(context).pop()` sans attendre le résultat du BLoC. En cas d’erreur API (réseau, validation), l’utilisateur a déjà fermé le dialogue et peut ne pas voir le message d’erreur. **Tâche** : Envelopper le contenu dans un `BlocListener<AdhesionsBloc, AdhesionsState>` (ou équivalent) pour fermer le dialogue et appeler `onRejected` uniquement lorsque le rejet a réussi ; en cas d’état `AdhesionsStatus.error`, afficher un SnackBar avec `state.message` et remettre `_loading` à false sans fermer.

---

## 5. Features — Admin

### 5.1 `lib/features/admin/presentation/pages/user_management_detail_page.dart`
- **L.197** — Dans `_openAssocierOrganisationDialog`, `catch (_) {}` après `orgService.getOrganizations`. **Tâche** : Logger l’erreur avec `AppLogger` et afficher un SnackBar à l’utilisateur (« Impossible de charger les organisations ») pour que le dialogue ne reste pas vide sans explication.

---

## 6. Features — Authentication

### 6.1 `lib/features/authentication/presentation/pages/login_page.dart`
- **L.101-116** — `TextButton` « Oublié ? » avec `onPressed: () {}`. **Tâche** : Implémenter le flux « Mot de passe oublié » : ouvrir l’URL Keycloak de réinitialisation dans un WebView pour que l’utilisateur puisse réinitialiser son mot de passe.

### 6.2 `lib/features/authentication/data/datasources/keycloak_auth_service.dart`
- **L.54-57, 110-112, 147-149** — Plusieurs `catch` qui ne font que `debugPrint`. **Tâche** : Logger avec `AppLogger` et retourner un résultat typé (ex. `Result<User, AuthFailure>`) pour que les échecs d’auth soient tracés et gérés en prod.

### 6.3 `lib/features/authentication/data/datasources/permission_engine.dart`
- **L.243-247** — `_checkContextualPermissions` : commentaire « Logique contextuelle future (intégration avec le serveur). Pour l’instant, retourne false ». **Tâche** : Implémenter l’appel au backend (endpoint de vérification contextuelle) et remplacer le `return false` par le résultat de l’API ; si l’endpoint n’existe pas encore, ajouter un commentaire explicite « Vérification contextuelle désactivée — endpoint non disponible » et conserver `return false`.

---

## 7. Features — Backup

### 7.0 `lib/features/backup/data/repositories/backup_repository.dart`
- **L.29-36** — `getAll()` suppose que `response.data` est une liste. Si le backend renvoie un format paginé (ex. `{ "content": [...], "totalElements": ... }`), le cast échouera. **Tâche** : Vérifier le contrat API et gérer les deux formats (liste directe et objet paginé avec `content`) comme dans `evenement_repository_impl.dart`.

### 7.1 `lib/features/backup/presentation/pages/backup_page.dart`
- **L.168-176** — Cartes « Dernière sauvegarde », « Taille totale », « Statut » avec valeurs en dur (`'2h'`, `'2.3 GB'`, `'OK'`). **Tâche** : Remplacer par des données issues du BLoC / API (ex. `BackupConfigLoaded`, dernier backup).
- **L.437-439** — `_handleBackupAction` pour l’action `'download'` : seul `_showSuccessSnackBar('Action "$action" exécutée')` est appelé. **Tâche** : Implémenter le téléchargement réel : récupérer le lien depuis l’API, télécharger le fichier, le sauvegarder en local et proposer le partage à l’utilisateur.
- **L.609-610** — `_restoreFromFile()` et `_selectiveRestore()` ne font qu’appeler `_showSuccessSnackBar` avec un message fixe. **Tâche** : Implémenter la sélection de fichier (file_picker) et la restauration depuis fichier, ainsi que le mode « restauration sélective ».

---

## 8. Features — Contributions

### 8.1 `lib/features/contributions/presentation/widgets/payment_dialog.dart`
- **L.364-385** — Pour les méthodes autres que Wave, `widget.cotisation.copyWith(...)` est appelé mais le résultat n’est pas utilisé. **Tâche** : Utiliser le modèle retourné par l’API après enregistrement du paiement pour mettre à jour l’UI ; si le BLoC rafraîchit déjà la liste, supprimer l’appel à `copyWith` inutile.
- **L.319** — `_getMethodeLabel` : le cas `PaymentMethod.freeMoney` n’est pas géré dans le switch. **Tâche** : Ajouter le cas `freeMoney` dans le switch avec le libellé approprié pour éviter un crash.

### 8.2 `lib/features/contributions/data/repositories/contribution_repository.dart`
- **L.335** — Un `catch (_)` est présent. **Tâche** : Logger l’erreur avec `AppLogger` et la remonter (rethrow) pour que l’appelant puisse afficher un message et ne pas masquer l’échec.

### 8.3 `lib/features/contributions/presentation/pages/mes_statistiques_cotisations_page.dart`
- **L.534** — `catch (_) {}` dans une méthode. **Tâche** : Logger l’erreur avec `AppLogger` et afficher un SnackBar pour informer l’utilisateur de l’échec.

### 8.4 `lib/features/contributions/presentation/widgets/create_contribution_dialog.dart`
- **L.48-54** — `_loadMe` : `catch (e)` sans message utilisateur, seul `_isInitLoading = false` est mis à jour. **Tâche** : Logger l’erreur et afficher un SnackBar lorsque le chargement du profil échoue.

---

## 9. Features — Dashboard

### 9.1 `lib/features/dashboard/presentation/pages/connected_dashboard_page.dart`
- **L.284-302** — `UnionActionGrid` : les quatre boutons (Cotiser, Envoyer, Retirer, Créer) ont `onTap: () {}`. **Tâche** : Brancher chaque bouton sur la navigation vers l’écran métier correspondant (cotisations, envoi, retrait, création).
- **L.317-318** — `UnionTransactionCard` : `onSeeAll: () {}`. **Tâche** : Implémenter la navigation vers la page « Toutes les activités » (liste détaillée).
- **L.321-332** — Liste `transactions` en dur (noms et montants fictifs). **Tâche** : Remplacer par les données du dashboard (`state.dashboardData.recentActivities`).
- **L.364-377** — `UnionLineChart` : `spots` en dur (valeurs fixes). **Tâche** : Utiliser les données réelles du backend (évolution de la caisse par période).
- **L.384-406** — `UnionPieChart` : `sections` en dur (40% Cotisations, 30% Épargne, etc.). **Tâche** : Alimenter avec les données réelles (répartition par catégorie).
- **L.419-435** — Métriques « Entrées », « Sorties », « Bénéfice », « Taux » en dur (`'1.8M FCFA'`, `'450K FCFA'`, etc.). **Tâche** : Remplacer par les stats du backend.
- **L.564-566** — `_handleExport` : simulation avec `Future.delayed(2 secondes)`. **Tâche** : Appeler le service d’export (DashboardExportService), récupérer le fichier généré et proposer le téléchargement.

### 9.2 `lib/features/dashboard/presentation/pages/role_dashboards/visitor_dashboard.dart`
- **L.201-203** — Bouton « Créer un Compte » : `onPressed` avec commentaire « Navigation vers inscription ». **Tâche** : Implémenter la navigation vers l’écran d’inscription (flux d’enregistrement).
- **L.220-224** — `TextButton` « Déjà membre ? Se connecter » : `onPressed` avec commentaire « Navigation vers connexion ». **Tâche** : Implémenter la navigation vers l’écran de connexion (ex. route `/login`).

### 9.3 `lib/features/dashboard/presentation/pages/role_dashboards/simple_member_dashboard.dart`
- Aucune tâche restante identifiée dans ce fichier (actions rapides et navigation déjà branchées).

### 9.4 `lib/features/dashboard/presentation/pages/role_dashboards/active_member_dashboard.dart`
- Aucune tâche restante identifiée dans ce fichier (navigation des boutons déjà implémentée).

### 9.5 `lib/features/dashboard/presentation/pages/role_dashboards/moderator_dashboard.dart`
- **L.328-339, 417-418, 480-533** — Plusieurs `UnionActionButton` avec `onTap: () {}` : Approuver, Vérifier, Signaler, Membres, Contenus, Historique. **Tâche** : Implémenter la navigation vers les écrans de modération correspondants.

### 9.6 `lib/features/dashboard/presentation/pages/role_dashboards/consultant_dashboard.dart`
- **L.215-268** — Six `UnionActionButton` avec `onTap: () {}` (Rapports, Analytics, Exports, etc.). **Tâche** : Brancher chaque bouton sur la page correspondante.

### 9.7 `lib/features/dashboard/presentation/pages/role_dashboards/hr_manager_dashboard.dart`
- **L.286-339** — Six boutons d’action avec `onTap: () {}`. **Tâche** : Implémenter les actions (Membres, Recrutement, Contrats, etc.).
- **L.417** — Un `onPressed: () {}` (bouton dans l’AppBar ou similaire). **Tâche** : Donner une action réelle (ex. filtre, recherche, paramètres).

### 9.8 `lib/features/dashboard/presentation/pages/role_dashboards/super_admin_dashboard.dart`
- **L.82** — Valeur affichée en dur avec `value: stats != null ? '1' : '0'` (commentaire « TODO: Ajouter au backend »). **Tâche** : Ajouter côté backend la métrique manquante, puis l’afficher à la place de la valeur fixe.

### 9.9 `lib/features/dashboard/presentation/pages/role_dashboards/org_admin_dashboard.dart`
- **L.430** — Bouton non branché (commentaire « TODO: brancher sur une page Historique / Activité »). **Tâche** : Créer la page Historique / Activité puis brancher la navigation depuis ce bouton vers cette page.
- **L.500** — Bouton export non branché (commentaire « TODO: brancher export dashboard »). **Tâche** : Brancher le bouton sur `DashboardExportService` pour générer le rapport et proposer le téléchargement.

### 9.10 `lib/features/dashboard/presentation/widgets/search/dashboard_search_widget.dart`
- **L.276-304** — Cinq éléments avec `onTap: () {}` (résultats de recherche / suggestions). **Tâche** : Au tap sur un résultat, ouvrir la page de détail correspondante ; au tap sur une suggestion, appliquer le filtre et mettre à jour les critères de recherche.

### 9.11 `lib/features/dashboard/data/datasources/dashboard_remote_datasource.dart`
- **L.80** — `catch (_)` dans une méthode. **Tâche** : Logger l’erreur et la propager (rethrow) pour ne pas masquer les échecs réseau/serveur.

### 9.12 `lib/features/dashboard/data/repositories/finance_repository.dart`
- **L.28** — `epargneBalance: 0.0` en dur (commentaire « TODO: appeler endpoint épargne »). **Tâche** : Appeler l’endpoint épargne dans le repository et remplacer la valeur 0.0 par le solde retourné.
- **L.71** — `catch (_)`. **Tâche** : Logger l’erreur avec `AppLogger` et remonter l’erreur (rethrow) pour que l’appelant soit notifié.

### 9.13 `lib/features/dashboard/presentation/bloc/finance_bloc.dart`
- **L.29** — Stub d’appel paiement (commentaire « TODO: Logique d'appel vers le service Wave ou Orange Money »). **Tâche** : Implémenter l’appel au service de paiement retenu (Wave ou Orange Money) selon le design métier.

### 9.14 `lib/features/dashboard/presentation/pages/advanced_dashboard_page.dart`
- **L.199** — Bouton paramètres non connecté (commentaire « Navigation vers paramètres non encore connectée »). **Tâche** : Connecter le bouton à la page des paramètres (navigation vers l’écran paramètres).

### 9.15 `lib/features/dashboard/data/services/dashboard_offline_service.dart`
- **L.9** — Import `'../cache/dashboard_cache_manager.dart'` : le dossier `lib/features/dashboard/data/cache/` n’existe pas. Le cache est dans `lib/core/storage/dashboard_cache_manager.dart`. **Tâche** : Remplacer l’import par le chemin vers le cache central : `'../../../../core/storage/dashboard_cache_manager.dart'`.
- **L.316** — Méthode `forcSync` (typo). **Tâche** : Renommer en `forceSync` pour cohérence.
- **L.253** — `_syncEventJoin` appelle `POST /api/evenements/$eventId/inscription` avec body `{membreId}` ; le backend peut attendre `POST .../inscrire` sans body. **Tâche** : Vérifier le contrat API (route et corps) et aligner.

### 9.16 `lib/features/dashboard/data/services/dashboard_performance_monitor.dart`
- **L.155** — `Socket.connect('localhost', 8080)` : hôte et port en dur pour la latence réseau. **Tâche** : Utiliser l’URL/port de l’API depuis la config (ex. `AppConfig.apiBaseUrl`).
- **L.124-132, 137-146, etc.** — `MethodChannel('dashboard_performance')` et méthodes natives (`getMemoryUsage`, `getCpuUsage`, `getFrameRate`, `getBatteryLevel`, `getDiskUsage`, `getNetworkUsage`) : si non implémentées côté plateforme (Android/iOS), les appels lanceront. **Tâche** : Implémenter le `MethodChannel` côté Android et iOS pour les métriques (mémoire, CPU, batterie, etc.) ; dans le code Dart, envelopper les appels dans un try/catch et renvoyer des valeurs par défaut avec un commentaire « fallback si canal natif absent ».
- **L.378** — `alertsGenerated: 0` avec commentaire « À implémenter si nécessaire ». **Tâche** : Incrémenter un compteur dans `_checkAlerts` à chaque alerte émise et alimenter `PerformanceStats.alertsGenerated` pour que les stats de monitoring soient correctes.

### 9.17 `lib/features/dashboard/presentation/widgets/dashboard_drawer.dart`
- **L.15-18** — Imports corrigés en `'../../../profile/...'`, `'../../../notifications/...'`, etc. (trois niveaux pour remonter à `lib/features/`). Aucune tâche restante sur les imports.

### 9.18 `lib/features/dashboard/presentation/widgets/shortcuts/dashboard_shortcuts_widget.dart`
- **L.148-157** — Raccourci « Envoyer Message » affiche uniquement un SnackBar « Messagerie – à venir ». **Tâche** : Implémenter la navigation vers l’écran de messagerie ; tant que l’écran n’existe pas, retirer le raccourci du dashboard pour éviter un lien mort.

### 9.19 `lib/features/dashboard/presentation/widgets/connected/connected_recent_activities.dart`
- **L.106-163** — `_buildActivityItem` affiche une ligne d’activité mais `_navigateForActivity` (L.165-184) n’est jamais appelée : les items ne sont pas cliquables. **Tâche** : Envelopper chaque item dans un `InkWell` et appeler `_navigateForActivity(context, activity)` au tap ; si `activity.hasAction` est vrai, effectuer la navigation, sinon ouvrir un détail par défaut.

### 9.20 `lib/features/dashboard/presentation/widgets/navigation/dashboard_navigation.dart`
- **L.211-216, 223-228, 231-236, 239-244** — Tous les `_buildSettingsTile` (Thème, Langue, Notifications push, Emails, Synchronisation, Cache) ont `onTap: () {}`. **Tâche** : Brancher chaque entrée sur la page de paramètres correspondante (thème, langue, notifications, sync, vidage cache).
- **L.341-344** — `_buildQuickActionItem` : `onTap` ne fait que `Navigator.pop(context)`. Les six actions (Nouveau Membre, Créer Événement, etc.) n’effectuent aucune navigation. **Tâche** : Brancher chaque raccourci sur la navigation vers la page cible (même logique que dans `DashboardShortcutsWidget`).

### 9.21 `lib/features/dashboard/presentation/widgets/notifications/dashboard_notifications_widget.dart`
- **L.288, 302, 327, 333** — Les notifications générées ont `onAction: () {}` pour les libellés « Voir » et « Améliorer ». **Tâche** : Brancher ces callbacks sur la navigation (page demandes, événements, activités, paramètres engagement).

### 9.22 `lib/features/dashboard/presentation/pages/role_dashboards/org_admin_dashboard_loader.dart`
- **L.86** — `firstOrgId = orgs.first.id ?? ''` : si `orgs.first.id` est null, une chaîne vide est envoyée à `LoadDashboardData`. **Tâche** : Filtrer la liste pour ne garder que les organisations avec `id` non null ; si aucune n’a d’id valide, afficher un message à l’utilisateur et ne pas appeler `LoadDashboardData`.

### 9.23 `lib/features/dashboard/presentation/widgets/settings/theme_selector_widget.dart`
- **Imports / symboles** — Le fichier n’importe que `dashboard_theme_manager.dart` mais utilise `CoreCard`, `AppColors`, `AppTypography` et `DashboardTheme.spacing16`, `DashboardTheme.borderRadius` (classe inexistante). **Tâche** : Ajouter les imports `unionflow_design_system.dart` et `core_card.dart` ; remplacer `DashboardTheme.spacing16` par `SpacingTokens.xl`, `DashboardTheme.spacing12` par `SpacingTokens.lg`, `DashboardTheme.borderRadius` par `SpacingTokens.radiusLg` (ou `RadiusTokens.lg`) en s’appuyant sur les tokens existants.

---

## 10. Features — Epargne

### 10.1 `lib/features/epargne/presentation/pages/epargne_detail_page.dart`
- **L.50** — `catch (_) {}` dans une méthode. **Tâche** : Logger l’erreur avec `AppLogger` et afficher un SnackBar pour informer l’utilisateur.

### 10.2 `lib/features/epargne/data/repositories/transaction_epargne_repository.dart`
- **L.16-24, 28-35** — `CompteEpargneRepository.getMesComptes()` et `getByMembre()` : en cas d’échec ou de `data` non liste, le code retourne `[]` sans logger. **Tâche** : Logger l’échec avec `AppLogger` et propager une exception (ou retour `Left`) pour que l’appelant affiche « Impossible de charger les comptes » au lieu d’une liste vide silencieuse.

---

## 11. Features — Help

### 11.1 `lib/features/help/presentation/pages/help_support_page.dart`
- **L.504** — Message « Le chat en direct sera bientôt disponible ! ». **Tâche** : Implémenter l’intégration au chat en direct (service de chat / WebSocket) ; tant que la fonctionnalité n’existe pas, retirer l’entrée et le libellé pour ne pas afficher de promesse non livrée.
- **L.602** — Message indiquant qu’un guide sera bientôt disponible. **Tâche** : Implémenter l’ouverture du guide (page dédiée) ; à défaut, retirer le libellé pour ne pas afficher de promesse non livrée.
- **L.633** — Message « La visite guidée interactive sera bientôt disponible ! ». **Tâche** : Implémenter la visite guidée avec un package dédié (type tutorial) ; à défaut, retirer le libellé.
- **L.644** — `_showSuccessSnackBar('Visite guidée ajoutée à votre liste de tâches !')`. **Tâche** : Brancher l’action sur une liste de tâches réelle (persistance locale type SharedPreferences) ; à défaut, retirer le bouton et le message pour éviter un feedback trompeur.

---

## 12. Features — Members

### 12.0 `lib/features/members/presentation/pages/advanced_search_page.dart`
- **L.21** — `GetIt.instance<MembreSearchService>()` : `MembreSearchService` n’est pas enregistré dans `injection.config.dart`. **Tâche** : Ajouter `@injectable` sur `MembreSearchService`, puis exécuter `dart run build_runner build` pour régénérer `injection.config.dart` et permettre la résolution GetIt.
- **L.39-40** — `_selectedOrganisations` et `_selectedRoles` sont utilisés dans `_buildSearchCriteria()` mais jamais alimentés par l’UI. **Tâche** : Ajouter dans le formulaire de recherche avancée des champs de sélection (dropdown multi-select) pour organisations et rôles, alimentés depuis l’API organisations et la liste des rôles, et les lier à `_selectedOrganisations` et `_selectedRoles`.

### 12.1 `lib/features/members/data/services/membre_search_service.dart`
- **L.33, 61, 65, 67, 249, 255** — Utilisation de `print()` pour le diagnostic. **Tâche** : Remplacer par un logger (ex. `AppLogger` de `core/utils/logger.dart`) pour un logging cohérent et désactivable en prod.

### 12.2 `lib/features/members/presentation/pages/members_page_wrapper.dart`
- **L.216-217** — Dans `_convertMembreToMap`, champs en dur : `'permissions': 15`, `'contributionScore': 0`, `'projectsInvolved': 0`. **Tâche** : Faire exposer par l’API membre les champs `permissions`, `contributionScore`, `projectsInvolved` et les mapper ici ; en attendant, ajouter un commentaire dans le code indiquant « Valeurs par défaut tant que l’API ne les fournit pas » pour traçabilité.

### 12.3 `lib/features/members/presentation/pages/members_page.dart`
- **L.1134** — SnackBar avec texte « Fonctionnalité d'ajout de membre à implémenter ». **Tâche** : Implémenter l’ajout de membre (formulaire + appel API).
- **L.1149** — SnackBar « Actions groupées à implémenter ». **Tâche** : Implémenter les actions groupées sur les membres sélectionnés.
- **L.1199** — SnackBar « Fonctionnalité de modification à implémenter ». **Tâche** : Implémenter la modification d’un membre (écran détail / édition).
- **L.1218** — SnackBar « Message à ${member['name']} à implémenter ». **Tâche** : Implémenter l’envoi de message au membre (notification, email, etc.).

---

## 13. Features — Notifications

### 13.0 `lib/features/notifications/presentation/bloc/notifications_bloc.dart`
- **L.71-73** — Dans `_onMarkAsRead`, `catch (e) { … }` : aucune émission d’état ni log. **Tâche** : Logger l’erreur avec `AppLogger` et émettre un état d’erreur (ou conserver l’état précédent) ; afficher un SnackBar « Impossible de marquer comme lu » pour informer l’utilisateur.

### 13.1 `lib/features/notifications/presentation/pages/notifications_page.dart`
- **L.704, 707, 710** — `_showSuccessSnackBar` pour « Navigation vers la gestion des membres », « vers les événements », « vers les organisations » : la navigation réelle n’est pas faite. **Tâche** : Remplacer par une navigation effective vers les écrans concernés.
- **L.725, 731, 763, 824, 876, 892** — Plusieurs actions n’affichent qu’un SnackBar de succès (marquer lu/non lu, supprimer, etc.). **Tâche** : Pour chaque action, dispatcher l’événement BLoC correspondant (qui appelle l’API), puis réécouter le BLoC pour que l’UI reflète le résultat ; ne pas se contenter du SnackBar sans effet côté données.

### 13.2 `lib/features/notifications/presentation/pages/notifications_page_wrapper.dart`
- **L.28** — `catch (_) {}`. **Tâche** : Logger l’erreur avec `AppLogger` et afficher un SnackBar à l’utilisateur pour signaler l’échec.

### 13.3 `lib/features/notifications/presentation/bloc/notification_bloc.dart`
- **L.46** — `catch (_)`. **Tâche** : Logger l’erreur avec `AppLogger` et émettre un état d’erreur (ex. `NotificationsError`) pour que l’UI puisse afficher un message au lieu d’ignorer silencieusement.

### 13.4 `lib/presentation/notifications/notification_page.dart`
- **L.74** — Navigation au tap non implémentée (commentaire « TODO: Navigation selon category »). **Tâche** : Implémenter la navigation en fonction du type/catégorie de la notification (ex. ouvrir l’écran détail adhésion, événement, contribution, etc.).

---

## 14. Features — Organizations

### 14.1 `lib/features/organizations/presentation/pages/organizations_page.dart`
- **L.771** — Clic sur une organisation sans navigation (commentaire « TODO: Implémenter la page de détails »). **Tâche** : Implémenter la navigation vers `OrganizationDetailPage` avec l’organisation sélectionnée (ex. `OrganizationDetailPage(organizationId: ...)`).

### 14.2 `lib/features/organizations/presentation/pages/organization_detail_page.dart`
- **L.368** — Statistique « Événements » avec `value: '0'` et commentaire « Nécessite endpoint stats par organisation ». **Tâche** : Appeler l’endpoint de stats par organisation (ou inclure le nombre d’événements dans le DTO organisation) et afficher la valeur réelle à la place de `'0'`.
- **L.434-437** — `_showEditDialog()` affiche uniquement un SnackBar « Édition - À implémenter ». **Tâche** : Implémenter l’édition : ouvrir `EditOrganizationPage` avec l’organisation courante et le BLoC `UpdateOrganization`.

---

## 15. Features — Profile

### 15.1 `lib/features/profile/presentation/pages/profile_page.dart`
- **L.1316** — SnackBar « Cette fonctionnalité sera bientôt disponible ! ». **Tâche** : Implémenter la fonctionnalité concernée ; à défaut, retirer l’entrée de menu pour ne pas afficher de promesse non livrée.
- **L.1568** — `_showErrorSnackBar('Fonctionnalité désactivée pour la démo')`. **Tâche** : Activer la fonctionnalité en production ; en mode démo, garder le message mais documenter le flag qui désactive l’option.
- **L.88, 597, 603, 609, 684, 696, 796, 802, 1342, 1397, 1431, 1462, 1493, 1583, 1588, 1593** — Nombreux `_showSuccessSnackBar` : vérifier que chaque action (mise à jour profil, préférences, 2FA, export, sessions, cache, etc.) est bien réalisée côté API/BLoC et pas seulement en SnackBar. **Tâche** : S’assurer que les actions sont persistées et que l’UI reflète l’état réel.

---

## 16. Features — Reports

### 16.0 `lib/features/reports/data/repositories/reports_repository.dart`
- **L.58-59, 76-78, 90-91, etc.** — Toutes les méthodes en cas de `DioException` retournent `{}` ou `[]` sans logger. **Tâche** : Dans chaque bloc catch, appeler `AppLogger` (ou `ErrorHandler.getErrorMessage`) pour tracer l’échec et faciliter le diagnostic lorsque les rapports sont vides.

### 16.0b DI — Reports non enregistrés
- **`lib/features/reports/presentation/pages/reports_page_wrapper.dart`** (L.16) appelle `GetIt.instance<ReportsBloc>()`, mais **`ReportsBloc`** et **`ReportsRepository`** ne sont pas enregistrés dans `injection.config.dart` (généré par injectable). À l’ouverture de la page Rapports, l’app peut lever une exception GetIt. **Tâche** : Ajouter `@injectable` sur `ReportsBloc` et `@LazySingleton(as: ReportsRepository)` sur `ReportsRepositoryImpl`, puis exécuter `dart run build_runner build` pour régénérer `injection.config.dart`.

### 16.1 `lib/features/reports/presentation/pages/reports_page.dart`
- **L.745** — SnackBar « Export lancé - Vous recevrez un email ». **Tâche** : Vérifier que l’export est bien déclenché côté backend et que l’email est envoyé.
- **L.755-756** — `_scheduleReport()` et `_generateReport(type)` ne font qu’afficher un SnackBar. **Tâche** : Implémenter l’appel API de programmation et de génération de rapport.

---

## 17. Features — Settings

### 17.1 `lib/features/settings/presentation/pages/system_settings_page.dart`
- **L.426, 520, 529, 633, 642, 651, 750, 1336, 1455, 1507, 1542, 1554** — Nombreux `_showSuccessSnackBar` pour options (debug, SSL, logs, monitoring, etc.). **Tâche** : Persister chaque réglage (API pour les réglages serveur, SharedPreferences pour les réglages locaux) et appliquer la valeur côté app.
- **L.1563-1593** — Méthodes `_optimizeDatabase`, `_resetSessions`, `_generateAuditReport`, etc. qui ne font qu’afficher un SnackBar. **Tâche** : Implémenter les appels backend (ou services réels) pour chaque action.

### 17.2 `lib/features/settings/presentation/pages/feedback_page.dart`
- **L.57** — `catch (_)`. **Tâche** : Logger l’erreur et afficher un message à l’utilisateur en cas d’échec d’envoi du feedback.

---

## 18. Features — Solidarity

### 18.0 `lib/features/solidarity/presentation/pages/demande_aide_detail_page.dart`
- **L.206** — Bouton « REJETER » envoie `RejeterDemandeAide(demande.id!)` sans motif. Le backend exige souvent un motif de rejet (audit, traçabilité). **Tâche** : Vérifier le contrat API (`PUT .../rejeter` avec body/query) ; si un motif est requis, ouvrir un dialogue de saisie du motif avant d’émettre `RejeterDemandeAide` (ou étendre l’événement avec un paramètre `motif`).

### 18.1 `lib/features/solidarity/presentation/widgets/create_demande_aide_dialog.dart`
- **L.64** — `catch (_)`. **Tâche** : Logger l’erreur et afficher un SnackBar en cas d’échec du chargement des données initiales.

---

## 19. Presentation (hors features)

### 19.0 `lib/presentation/widgets/shared/profile_drawer.dart`
- **L.31-32, 40, 46-50** — Données utilisateur en dur : « Utilisateur UnionFlow », « @Membre123 », « 12 Cotisations », « 4 Événements attendus ». **Tâche** : Alimenter depuis le contexte (AuthBloc / profil utilisateur) pour afficher le nom, l’identifiant et les statistiques réels.
- **L.64-67** — Cinq `_buildDrawerItem` avec `onTap: () {}` (Mon Profil, Historique, Solidarité, Paramètres, Aide & Support). **Tâche** : Brancher chaque élément sur la navigation vers la page correspondante (utiliser le même routeur que le reste de l’app).

### 19.1 `lib/presentation/dashboard/finance_page.dart`
- **L.6** — Import corrigé en `'../widgets/shared/mini_metric_widget.dart'` (le widget est dans `lib/presentation/widgets/shared/mini_metric_widget.dart`). Aucune tâche restante sur l’import.

### 19.2 `lib/presentation/feed/unified_feed_page.dart`
- **L.189** — Bouton dans l’AppBar avec `onPressed: () {}`. **Tâche** : Implémenter l’action du bouton selon le design du feed (filtre, création de post, rafraîchissement).

### 19.3 `lib/presentation/widgets/shared/mini_header_bar.dart`
- **L.36** — Commentaire « TODO: Ouvrir le Drawer ou le Profil complet via GoRouter ». **Tâche** : Implémenter l’action au tap sur l’icône du header : appeler `ScaffoldState.openDrawer()` pour ouvrir le Drawer latéral. L’accès au profil reste dans le Drawer et la barre de navigation.

---

## 20. Shared

### 20.0 `lib/shared/widgets/confirmation_dialog.dart`
- **L.106-122** — Les boutons du dialogue appellent `Navigator.pop(context)` sans valeur, puis `onCancel?.call()` / `onConfirm?.call()`. Les helpers (L.206-279) passent `onConfirm: () {}` et `onCancel: () {}`, donc `showDialog<bool>` reçoit toujours `null` et `return result ?? false` renvoie systématiquement `false`. **Tâche** : Dans `ConfirmationDialog`, faire `Navigator.pop(context, true)` sur confirmation et `Navigator.pop(context, false)` sur annulation (au lieu de `Navigator.pop(context)`), puis appeler les callbacks ; ainsi les helpers retourneront le bon booléen à l’appelant.

### 20.1 `lib/shared/design_system/components/uf_page_header.dart`
- **L.15** — Exemple en commentaire avec `onPressed: () {}`. **Tâche** : Remplacer par un exemple avec une action réelle (ex. `onPressed: () => Navigator.pop(context)`) pour que la doc soit exploitable comme référence.

---

## 21. Features — Events

### 21.1 `lib/features/events/presentation/pages/event_detail_page.dart`
- **L.284** — `const isInscrit = false; // Nécessite endpoint d'inscription par utilisateur`. **Tâche** : Récupérer l’état d’inscription via l’API (exposé dans le BLoC) et remplacer le booléen en dur pour afficher « S’inscrire » ou « Se désinscrire » correctement.

### 21.2 `lib/features/events/presentation/pages/events_page_wrapper.dart`
- **L.184-291** — Méthodes `_convertEvenementsToMapList`, `_convertEvenementToMap`, `_mapTypeToString`, `_mapStatutToString`, `_mapPrioriteToString` sont définies mais jamais appelées. **Tâche** : Supprimer ces méthodes (code mort). En cas de besoin d’export ou de conversion plus tard, réintroduire la logique dans un module dédié et l’appeler explicitement.

### 21.3 `lib/features/events/data/repositories/evenement_repository_impl.dart`
- **L.234-252, 255-272, 275-292** — `getEvenementsAVenir`, `getEvenementsEnCours`, `getEvenementsPasses` appellent `EvenementSearchResult.fromJson(response.data)` en supposant que la réponse est un objet (Map). Si le backend renvoie une liste directe (comme dans `getEvenements` L.126-137), un crash survient. **Tâche** : Gérer le cas où `response.data is List` comme dans `getEvenements` (construire un `EvenementSearchResult` à partir de la liste) pour rester compatible avec les deux formats API.

### 21.4 `lib/features/events/presentation/widgets/create_event_dialog.dart`
- **L.376-388** — Après `context.read<EvenementsBloc>().add(CreateEvenement(evenement))`, le dialogue se ferme immédiatement et un SnackBar « Événement créé avec succès » s’affiche, sans attendre le résultat du BLoC. En cas d’erreur (validation, réseau), l’utilisateur voit quand même le succès. **Tâche** : Écouter le BLoC (BlocListener) pour fermer et afficher le SnackBar uniquement sur `EvenementCreated`, et afficher une erreur sur `EvenementsError` / `EvenementsValidationError`.

### 21.5 `lib/features/events/presentation/widgets/edit_event_dialog.dart`
- **L.352-363** — Même schéma : après `UpdateEvenement`, fermeture et SnackBar succès sans vérifier le résultat du BLoC. **Tâche** : Utiliser un BlocListener pour réagir à `EvenementUpdated` vs états d’erreur avant de fermer et d’afficher le message.

### 21.6 `lib/features/events/presentation/widgets/inscription_event_dialog.dart`
- **L.289-314** — Après `InscrireEvenement` / `DesinscrireEvenement`, le dialogue se ferme et un SnackBar de succès s’affiche sans attendre la fin du traitement BLoC. **Tâche** : Écouter le BLoC (BlocListener) pour ne fermer et afficher le succès que sur `EvenementInscrit` / `EvenementDesinscrit`, et afficher une erreur sinon.

---

## 22. Features — Logs

### 22.0 `lib/features/logs/data/repositories/logs_monitoring_repository.dart`
- **L.47-51, 68-72** — `searchLogs` et `getAlerts` supposent que `response.data` est une liste. Si l’API renvoie un objet paginé (ex. `{ "content": [...] }`), le cast lèvera. **Tâche** : Vérifier le contrat API et gérer les deux formats (liste directe et pagination avec `content`).

### 22.1 `lib/features/logs/presentation/pages/logs_page.dart`
- **L.44-53** — `_systemMetrics` : valeurs initiales en dur (cpu, memory, disk, network, activeConnections, errorRate, responseTime, uptime). **Tâche** : Alimenter à partir du BLoC/API (MetricsLoaded) dès le chargement ; la méthode `_updateSystemMetricsFromState` existe mais les valeurs par défaut restent fictives.
- **L.56-73** — `_activeAlerts` : liste d’alertes en dur (2 exemples). **Tâche** : Remplacer par les données du BLoC (LoadAlerts → AlertsLoaded) et afficher les alertes réelles.
- **L.341-356** — `CheckboxListTile` dans `_showExportDialog` : `onChanged: (value) {}` (aucune mise à jour d’état). **Tâche** : Gérer l’état des cases à cocher (logs, métriques, alertes) et les passer à `_exportLogs`.
- **L.377-379** — `_exportLogs()` ne fait qu’appeler `_showSuccessSnackBar('Export des données lancé - Vous recevrez un email')`. **Tâche** : Implémenter l’export réel : appel API qui retourne le fichier (ou génération côté client), puis notification utilisateur.
- **L.364-377** — Statistiques « Logs totaux », « Erreurs », « Warnings », « Temps réponse » dans `_buildQuickStats` : valeurs en dur ('15,247', '23', '156', '127ms'). **Tâche** : Remplacer par des données du BLoC/API.
- **L.398-401** — Statut des services (API Server, Database, Keycloak, CDN) en dur (`true`/`false`). **Tâche** : Récupérer le statut réel des services depuis l’API de monitoring.
- **L.696-734** — `_getFilteredLogs()` retourne une liste de logs en dur (6 entrées fictives). **Tâche** : Brancher sur le BLoC (SearchLogs → LogsLoaded) et afficher les logs réels dans l’onglet Logs.
- **L.731-738** — Configuration des alertes (UFSwitchTile) : `onChanged` ne fait qu’un SnackBar, pas de persistance. **Tâche** : Persister les préférences d’alertes (API si disponible, sinon SharedPreferences) et refléter l’état réel.
- **L.657-678** — Configuration des logs (niveau, rétention, format, etc.) : `onChanged` uniquement SnackBar. **Tâche** : Persister les paramètres (API pour les réglages serveur, SharedPreferences pour le local) et les appliquer.
- **L.747-753** — `_acknowledgeAlert` ne met à jour que l’état local (`_activeAlerts`). **Tâche** : Appeler le BLoC (AcknowledgeAlert) puis rafraîchir les alertes depuis l’API.

---

## 23. Features — Feed / Presentation

### 23.1 `lib/presentation/feed/unified_feed_page.dart`
- **L.127-132** — `DynamicFAB` : `onPressed` avec commentaire « Action primaire (Nouveau Post/Demande) via une BottomSheet par exemple », corps vide. **Tâche** : Implémenter l’ouverture d’une bottom sheet pour créer un post ou une demande.
- **L.177-188** — `IconButton` « more_vert » : `onPressed: () {}`. **Tâche** : Implémenter le menu contextuel (options du post : modifier, supprimer, signaler, etc.).
- **L.204-207** — `ActionRow` : `onComment: () {}`, `onShare: () {}`, `onCustomAction: item.customActionLabel != null ? () {} : null`. **Tâche** : Brancher les commentaires (navigation vers la page de détail du post), le partage (package `share_plus`) et l’action personnalisée (navigation selon `actionUrlTarget` ou le type d’item).

### 23.2 `lib/features/feed/data/repositories/feed_repository.dart`
- **L.16-18** — Commentaire « NOTE: L'URL exacte dépendra des routes Quarkus disponibles » et appel à `'/feed'`. **Tâche** : Vérifier l’endpoint backend (ex. `/api/feed` ou `/posts`) et adapter l’URL et le mapping JSON si la structure API diffère.

### 23.3 `lib/features/feed/presentation/bloc/unified_feed_bloc.dart`
- **L.52-54** — Dans `_onLoadMoreRequested`, le `catch` ne fait que réinitialiser `isFetchingMore` sans état d’erreur. **Tâche** : Logger l’erreur, émettre un état d’erreur (ex. `FeedLoadMoreFailed`) et afficher un SnackBar « Impossible de charger plus » pour que l’utilisateur soit informé.

---

## 24. Features — Explore

### 24.0 `lib/features/explore/presentation/bloc/network_bloc.dart`
- **L.20-23** — `_onLoadNetworkRequested` n’appelle pas le repository : il émet directement `NetworkLoaded(items: [], currentQuery: '')`. **Tâche** : Appeler le repository au chargement (ex. `_repository.search('')` ou endpoint liste initiale selon l’API) et émettre `NetworkLoaded` avec les données retournées pour que l’écran affiche des données cohérentes dès l’ouverture.

### 24.1 `lib/features/explore/data/repositories/network_repository.dart`
- **L.23-24, 39-40** — `searchMembers` et `searchOrganizations` supposent que `response.data` est une liste. Si l’API renvoie un objet paginé (ex. `{ "content": [...] }`), le cast échouera. **Tâche** : Gérer les deux formats (liste directe et objet paginé avec `response.data['content']`) comme dans `demande_aide_repository.dart`.

### 24.2 `lib/presentation/explore/network_page.dart`
- **L.154-159** — Badge « Suivre » / « Connecté » : pas d’`onTap` sur le badge. **Tâche** : Implémenter l’action au tap : appel API suivre / ne plus suivre, puis mise à jour du BLoC (ou state) et rafraîchissement de l’affichage du badge.

---

## 25. Tokens (design_system/tokens)

- **`app_colors.dart`**, **`app_typography.dart`**, **`spacing_tokens.dart`**, **`unionflow_colors.dart`**, **`color_tokens.dart`**, **`typography_tokens.dart`**, **`radius_tokens.dart`**, **`shadow_tokens.dart`** — Aucune tâche identifiée. Pour **theme_selector_widget** (tâche 9.23), remplacer `DashboardTheme.spacing16`, `spacing12`, `borderRadius` par `SpacingTokens.xl`, `SpacingTokens.lg`, `SpacingTokens.radiusLg` (ou équivalents).

---

## 26. Features — Pages (paramètres, organisations)

### 26.0 `lib/features/settings/presentation/pages/privacy_settings_page.dart`
- **L.255-282** — Bouton « Contacter l'administrateur » ne fait que `Navigator.pop()`. **Tâche** : Implémenter l’action : ouvrir un mailto vers l’administrateur (email de contact) pour que l’utilisateur puisse le contacter.
- **L.364** — `Switch(..., activeColor: ...)` : `activeColor` est déprécié (Flutter 3) ; utiliser `activeTrackColor` / `thumbColor`.

### 26.1 `lib/features/settings/presentation/pages/language_settings_page.dart`
- **L.31-34** — `_syncFromProvider()` appelée dans `initState()` avec `context.read<LocaleProvider>()`. **Tâche** : Faire la synchro dans `didChangeDependencies` (ou `addPostFrameCallback`) pour garantir l’accès au provider.

### 26.2 `lib/features/organizations/presentation/pages/edit_organization_page.dart` / `create_organization_page.dart`
- Aucune tâche : BlocListener correctement branché.

---

## 27. Tests

### 27.0 `test/features/dashboard/dashboard_test.dart`
- **L.16-212** — Tous les tests sont des placeholders (`expect(true, true)`), mocks vides, commentaires « TODO: Implémenter ». **Tâche** : Implémenter les tests unitaires et widgets (mocks des repositories/use cases, assertions sur les états et les données) ; supprimer les `expect(true, true)` et remplacer les TODO par du code de test réel. Ne pas laisser de placeholders dans la suite de tests.

### 27.1 `test/unit/core/error/error_handler_test.dart`
- Aucune tâche : tests ErrorHandler complets et corrects.

---

## Résumé par type

| Type | Nombre |
|------|--------|
| Callbacks vides (`onPressed` / `onTap: () {}`) | ~35+ |
| `catch (_)` ou `catch (e)` sans gestion | ~15 |
| TODO / FIXME / Stub dans le code | ~13 |
| Placeholders / « bientôt disponible » / « à implémenter » | ~25+ |
| Données en dur (0, '0', stats fictives, listes mock) | ~18+ |
| Méthodes qui ne font qu’un SnackBar (action non branchée) | ~30+ |
| Routes ou imports à corriger / brancher | ~5 |
| Dialogue fermé sans attendre le résultat BLoC / API | ~5 |
| Composants partagés (ex. confirmation_dialog retour booléen) | ~1 |
| Pages paramètres (privacy / language) — bouton contact, sync provider, Switch déprécié | 3 |
| Tests (dashboard_test.dart — tous placeholders) | 1 fichier |

---

## Détails complémentaires (audit approfondi)

- **Core** : `injection_container`, `register_module`, `environment`, `error_handler`, `exceptions`, `usecase`, `locale_provider`, `app_constants`, `lcb_ft_constants` — aucun problème identifié. `network_info` utilise déjà `result.any(...)` compatible avec l’API List de `connectivity_plus`.
- **Shared design_system** : `union_export_button`, `union_period_filter`, `union_action_button`, `union_balance_card`, `union_transaction_tile`, `uf_app_bar`, `core_card`, `uf_switch_tile` — pas de callbacks vides ; les composants reçoivent `onExport`, `onPeriodChanged`, `onTap`, etc. de l’appelant.
- **Epargne** : `depot_epargne_dialog`, `retrait_epargne_dialog`, `transfert_epargne_dialog` attendent le résultat du repository avant de fermer. `historique_epargne_sheet` et `getByCompte` (retour liste de Map) sont cohérents.
- **Adhesions** : `rejet_adhesion_dialog` ferme immédiatement après `add(RejeterAdhesion)` (tâche 4.3). `adhesion_detail_page` et `adhesions_page` sont correctement branchés.
- **Reports / DI** : `ReportsBloc` et `ReportsRepository` ne sont pas enregistrés dans `injection.config.dart` ; `ReportsPageWrapper` utilise `GetIt.instance<ReportsBloc>()` → risque d’exception à l’ouverture de la page Rapports (tâche 16.0b).
- **BLoCs** : `AdminUsersBloc`, `BackupBloc`, `ProfileBloc`, `OrganizationsBloc`, `SystemSettingsBloc`, `EvenementsBloc`, `MembresBloc`, `ContributionsBloc` gèrent correctement les erreurs (emit d’état d’erreur). `ReportsBloc` gère les erreurs mais n’est pas injectable.

---

*Document généré à partir de l’analyse des fichiers .dart sous `lib/`. Les fichiers `.g.dart` (générés) n’ont pas donné lieu à des tâches métier.*
