Suppressions/corrections: - Suppression références ADR inexistants (010, 011, 018-notifications-push) - Suppression liens vers fichiers d'analyse supprimés (ANALYSE_LIBRAIRIES_GO.md, INCONSISTENCIES-ANALYSIS.md) - Correction numéros ADR: 010→012, 018→020, 020→022 - Correction liens relatifs dans domains/README.md - Suppression référence regles-metier/ (structure legacy) Script: scripts/remove-broken-links.sh
247 lines
11 KiB
Markdown
247 lines
11 KiB
Markdown
# ADR-020 : Librairies Flutter du Mobile
|
|
|
|
**Statut** : Accepté
|
|
**Date** : 2026-01-31
|
|
|
|
## Contexte
|
|
|
|
L'application mobile RoadWave (iOS/Android) nécessite des librairies tierces pour audio HLS, géolocalisation, notifications, state management, etc. Le choix doit privilégier :
|
|
- **Licences permissives** (MIT, Apache-2.0, BSD) sans restrictions commerciales
|
|
- **Maturité** et maintenance active (écosystème Flutter)
|
|
- **Performance native** (pas de bridge JS)
|
|
- **Support CarPlay/Android Auto**
|
|
- **Conformité stores** (App Store, Play Store)
|
|
|
|
## Décision
|
|
|
|
Utilisation de **9 librairies open-source** Flutter avec licences permissives, déployées en 2 phases selon la stratégie définie dans [ADR-017 (Notifications Géolocalisées)](017-notifications-geolocalisees.md).
|
|
|
|
### Phase 1 (MVP) : Core Stack
|
|
|
|
| Catégorie | Librairie | Licence | Justification |
|
|
|-----------|-----------|---------|---------------|
|
|
| **State Management** | `flutter_bloc` | MIT | Pattern BLoC, 11K+ stars, reactive streams |
|
|
| **Audio HLS** | `just_audio` | MIT | HLS natif, buffering adaptatif, background playback |
|
|
| **HTTP Client** | `dio` | MIT | Interceptors, retry logic, 12K+ stars |
|
|
| **Stockage sécurisé** | `flutter_secure_storage` | BSD-3 | Keychain iOS, KeyStore Android |
|
|
| **Cache images** | `cached_network_image` | MIT | LRU cache, placeholder support |
|
|
|
|
### Phase 1 (MVP) : Géolocalisation & Notifications
|
|
|
|
| Catégorie | Librairie | Licence | Justification |
|
|
|-----------|-----------|---------|---------------|
|
|
| **GPS temps réel** | `geolocator` | MIT | Mode voiture, WebSocket position updates, high accuracy |
|
|
| **Push APNS/FCM** | `flutter_apns` + `flutter_fcm` | MIT | Intégration native APNS et FCM directe (ADR-017) |
|
|
| **Notifications locales** | `flutter_local_notifications` | BSD-3 | Compteur dynamique, icônes custom, iOS/Android |
|
|
| **Permissions** | `permission_handler` | MIT | Gestion unifiée permissions iOS/Android |
|
|
|
|
### Phase 1 (MVP) : CarPlay/Android Auto (optionnel)
|
|
|
|
| Catégorie | Librairie | Licence | Justification |
|
|
|-----------|-----------|---------|---------------|
|
|
| **CarPlay** | `flutter_carplay` | MIT | Intégration CarPlay native (communautaire) |
|
|
| **Android Auto** | `android_auto_flutter` | Apache-2.0 | Support Android Auto (communautaire) |
|
|
|
|
### Phase 2 (Post-MVP) : Geofencing Local
|
|
|
|
| Catégorie | Librairie | Licence | Justification | Voir ADR |
|
|
|-----------|-----------|---------|---------------|----------|
|
|
| **Geofencing local** | `geofence_service` | MIT | Mode offline, détection rayon 200m, notifications app fermée | [ADR-017](017-notifications-geolocalisees.md) Phase 2 |
|
|
|
|
**Note importante** : Le geofencing local (`geofence_service`) n'est **PAS utilisé en MVP**. La Phase 1 utilise WebSocket + Firebase pour les notifications de proximité (voir [ADR-017](017-notifications-geolocalisees.md) pour l'architecture complète).
|
|
|
|
## Alternatives considérées
|
|
|
|
### State Management
|
|
- **flutter_bloc** (choisi) : Pattern BLoC, testable, reactive
|
|
- **riverpod** : Plus moderne, moins mature
|
|
- **provider** : Simple mais limité pour app complexe
|
|
- **getx** : Performance mais opinions controversées
|
|
|
|
### Audio
|
|
- **just_audio** (choisi) : HLS natif, communauté active
|
|
- **audioplayers** : Moins mature pour streaming
|
|
- **flutter_sound** : Orienté recording, pas streaming
|
|
|
|
### Géolocalisation
|
|
- **geolocator** (choisi) : Standard Flutter, 1.2K+ stars
|
|
- **location** : Moins maintenu
|
|
- **background_location** : Spécifique background uniquement
|
|
|
|
### Notifications Push
|
|
- **flutter_apns + flutter_fcm** (choisi) : Implémentation directe APNS/FCM, pas de vendor lock-in
|
|
- **firebase_messaging** : SDK Firebase, vendor lock-in Google
|
|
- **OneSignal** : Plus cher (500€/mois @ 100K users), vendor lock-in
|
|
- **Custom WebSocket** : Complexe, toujours besoin APNS/FCM au final (voir ADR-017)
|
|
|
|
### Geofencing (Phase 2)
|
|
- **geofence_service** (choisi) : Natif iOS/Android, économie batterie optimale
|
|
- **background_geolocation** : Payant (149$/an par app)
|
|
- **flutter_background_location** : Moins mature
|
|
|
|
## Justification
|
|
|
|
### Licences
|
|
- **7/9 librairies** : MIT (permissive totale)
|
|
- **2/9** : BSD-3 (permissive, compatible commercial)
|
|
- **Compatibilité totale** : Aucun conflit de licence, aucune restriction commerciale
|
|
|
|
### Maturité
|
|
- **flutter_bloc** : 11.6K stars, adoption large (state management standard)
|
|
- **just_audio** : 900+ stars, utilisé production (podcasts apps)
|
|
- **geolocator** : 1.2K stars, maintenu BaseFlow (entreprise Flutter)
|
|
- **dio** : 12K+ stars, client HTTP le plus utilisé Flutter
|
|
|
|
### Performance
|
|
- **Compilation native** : Dart → ARM64 (pas de bridge JS comme React Native)
|
|
- **just_audio** : Utilise AVPlayer (iOS) et ExoPlayer (Android) natifs
|
|
- **geolocator** : Accès direct CoreLocation (iOS) et FusedLocation (Android)
|
|
- **flutter_apns + flutter_fcm** : Utilise services systèmes natifs (APNS, Google Play Services)
|
|
- **geofence_service** (Phase 2) : Geofencing natif, minimise consommation batterie
|
|
|
|
### Conformité Stores
|
|
- **Permissions progressives** : `permission_handler` + stratégie ADR-010
|
|
- **Background modes MVP** : `geolocator` (When In Use) + `firebase_messaging` approuvés stores
|
|
- **Background modes Phase 2** : `geofence_service` nécessite permission "Always" (taux acceptation ~30%)
|
|
- **Notifications** : `flutter_local_notifications` + `firebase_messaging` conformes guidelines iOS/Android
|
|
|
|
## Architecture
|
|
|
|
```mermaid
|
|
graph TB
|
|
subgraph UI["Presentation Layer"]
|
|
Widgets["Flutter Widgets"]
|
|
Bloc["flutter_bloc<br/>(State Management)"]
|
|
end
|
|
|
|
subgraph Data["Data Layer"]
|
|
API["dio<br/>(HTTP Client)"]
|
|
Storage["flutter_secure_storage<br/>(JWT Tokens)"]
|
|
Cache["cached_network_image<br/>(Image Cache)"]
|
|
end
|
|
|
|
subgraph Services["Services Layer - Phase 1 MVP"]
|
|
Audio["just_audio<br/>(HLS Streaming)"]
|
|
GPS["geolocator<br/>(GPS + WebSocket)"]
|
|
Push["flutter_apns + flutter_fcm<br/>(Push Natifs APNS/FCM)"]
|
|
Notif["flutter_local_notifications<br/>(Notifications Locales)"]
|
|
Perms["permission_handler<br/>(Permissions iOS/Android)"]
|
|
end
|
|
|
|
subgraph Phase2["Services Layer - Phase 2"]
|
|
Geofence["geofence_service<br/>(Mode Offline)"]
|
|
end
|
|
|
|
subgraph Platform["Platform Integration"]
|
|
CarPlay["flutter_carplay<br/>(iOS)"]
|
|
AndroidAuto["android_auto_flutter<br/>(Android)"]
|
|
end
|
|
|
|
Widgets --> Bloc
|
|
Bloc --> API
|
|
Bloc --> Audio
|
|
Bloc --> GPS
|
|
Bloc --> Push
|
|
|
|
API --> Storage
|
|
Widgets --> Cache
|
|
|
|
GPS --> Perms
|
|
Push --> Perms
|
|
Push --> Notif
|
|
|
|
Geofence -.->|Phase 2| Perms
|
|
Geofence -.->|Phase 2| Notif
|
|
|
|
Audio --> CarPlay
|
|
Audio --> AndroidAuto
|
|
|
|
classDef uiStyle fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
|
|
classDef dataStyle fill:#f3e5f5,stroke:#6a1b9a,stroke-width:2px
|
|
classDef serviceStyle fill:#fff3e0,stroke:#e65100,stroke-width:2px
|
|
classDef platformStyle fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
|
|
|
|
class UI,Widgets,Bloc uiStyle
|
|
class Data,API,Storage,Cache dataStyle
|
|
class Services,Audio,GPS,FCM,Notif,Perms serviceStyle
|
|
class Phase2,Geofence serviceStyle
|
|
class Platform,CarPlay,AndroidAuto platformStyle
|
|
```
|
|
|
|
## Conséquences
|
|
|
|
### Positives
|
|
- ✅ Aucune restriction licence commerciale (100% permissif)
|
|
- ✅ Stack cohérent avec ADR-010 (Frontend Mobile)
|
|
- ✅ Performance native (compilation ARM64 directe)
|
|
- ✅ Écosystème mature et documenté
|
|
- ✅ Support CarPlay/Android Auto via communauté
|
|
- ✅ Conformité stores (permissions progressives)
|
|
|
|
### Négatives
|
|
- ⚠️ **CarPlay/Android Auto** : Packages communautaires (pas officiels Flutter)
|
|
- ⚠️ **Configuration APNS/FCM** : Gestion certificats et OAuth2, configuration manuelle
|
|
- ⚠️ **Permission "Always" Phase 2** : Taux acceptation ~30% (geofencing local)
|
|
- ❌ **Courbe d'apprentissage** : Dart + pattern BLoC à maîtriser
|
|
- ❌ **Tests stores** : Validation TestFlight (iOS) et Internal Testing (Android) obligatoires
|
|
|
|
### Dépendances pubspec.yaml
|
|
|
|
> **Note** : Les versions exactes seront définies lors de l'implémentation. Cette section indique les packages requis, non les versions à utiliser (qui évoluent rapidement dans l'écosystème Flutter).
|
|
|
|
**Core (Phase 1 MVP)** :
|
|
- `flutter_bloc` - State management
|
|
- `just_audio` - Audio HLS streaming
|
|
- `dio` - HTTP client
|
|
- `flutter_secure_storage` - Stockage sécurisé JWT
|
|
- `cached_network_image` - Cache images
|
|
|
|
**Géolocalisation & Notifications (Phase 1 MVP)** :
|
|
- `geolocator` - GPS haute précision, WebSocket position updates
|
|
- `flutter_apns` - Push notifications APNS natif iOS (ADR-017)
|
|
- `flutter_fcm` - Push notifications FCM natif Android (ADR-017)
|
|
- `flutter_local_notifications` - Notifications locales
|
|
- `permission_handler` - Gestion permissions
|
|
|
|
**CarPlay/Android Auto (optionnels Phase 1)** :
|
|
- `flutter_carplay` - Intégration CarPlay
|
|
- `android_auto_flutter` - Support Android Auto
|
|
|
|
**Geofencing (Phase 2 Post-MVP)** :
|
|
- `geofence_service` - Geofencing local pour mode offline (ADR-017 Phase 2)
|
|
|
|
### Migration depuis ADR-010
|
|
|
|
La section "Packages clés" de l'ADR-010 est désormais obsolète et doit référencer cet ADR :
|
|
|
|
> **Packages Flutter** : Voir [ADR-018 - Librairies Flutter](020-librairies-flutter.md) pour la liste complète, licences et justifications.
|
|
|
|
## Risques et Mitigations
|
|
|
|
### Risque 1 : CarPlay/Android Auto packages communautaires
|
|
- **Impact** : Maintenance non garantie par Flutter team
|
|
- **Mitigation** : Fork privé si besoin, contribution upstream, ou développement custom si critique
|
|
|
|
### Risque 2 : Validation App Store (permissions background)
|
|
- **Impact** : Taux de rejet ~70% si mal justifié
|
|
- **Mitigation Phase 1** : Permission "When In Use" seulement (MVP), moins scrutée par Apple
|
|
- **Mitigation Phase 2** : Stratégie progressive (ADR-010), écrans d'éducation, tests beta TestFlight pour permission "Always"
|
|
|
|
### Risque 3 : Performance audio HLS en arrière-plan
|
|
- **Impact** : Interruptions si OS tue l'app
|
|
- **Mitigation** : Background audio task iOS, foreground service Android (natif dans `just_audio`)
|
|
|
|
## Références
|
|
|
|
- [ADR-010 : Frontend Mobile](012-frontend-mobile.md) (Flutter, architecture permissions)
|
|
- [ADR-017 : Notifications Géolocalisées](017-notifications-geolocalisees.md) (Phase 1 WebSocket vs Phase 2 Geofencing)
|
|
- [ADR-018 : Librairies Go](018-librairies-go.md) (même format de documentation)
|
|
- [flutter_bloc documentation](https://bloclibrary.dev/)
|
|
- [just_audio repository](https://pub.dev/packages/just_audio)
|
|
- [geolocator documentation](https://pub.dev/packages/geolocator)
|
|
- [flutter_apns documentation](https://pub.dev/packages/flutter_apns)
|
|
- [flutter_fcm documentation](https://pub.dev/packages/flutter_fcm)
|
|
- [geofence_service documentation](https://pub.dev/packages/geofence_service)
|
|
- [Apple CarPlay Developer Guide](https://developer.apple.com/carplay/)
|
|
- [Android Auto Developer Guide](https://developer.android.com/training/cars)
|