Chapitre 18
18 - Projet Fil Rouge — « TaskFlow »
18 - Projet Fil Rouge — « TaskFlow »
18 - Projet Fil Rouge — « TaskFlow » : Cours complet
Niveau : Avancé Durée estimée : 4 h (cours) + 30 h (projet) Objectif : intégrer l'ensemble de la formation dans un projet réel et publié : architecture, auth, persistance, réseau temps réel, tests, CI/CD, performance, sécurité, stores.
Table des matières
- Présentation du projet
- Choix de la stack
- Clean Architecture + MVVM
- Authentification
- Persistance locale + synchronisation
- Networking : REST + WebSocket
- Stratégie de tests
- CI/CD + observabilité
- Performance
- Sécurité et publication
1. Présentation du projet
1.1 Le produit
TaskFlow : application de gestion de tâches cross-platform.
Fonctionnalités :
- Authentification (email/mot de passe, JWT + refresh)
- Création/édition/suppression de tâches (titre, description, dueDate, priorité, projet)
- Listes et filtres (statut, priorité, échéance)
- Temps réel : les changements d'une équipe apparaissent instantanément (WebSocket)
- Hors ligne : création/modification en mode déconnecté puis synchronisation
- Notifications push (échéances, affectations)
- Comptes utilisateurs et partage de projets
1.2 Découpage en sprints
| Sprint | Contenu |
|---|---|
| S1 | Setup + Clean Architecture + CI de base |
| S2 | Auth (login/register/refresh) |
| S3 | CRUD tâches + persistance locale |
| S4 | Sync + WebSocket temps réel |
| S5 | Push + polish + tests E2E |
| S6 | Release (stores) + observabilité |
1.3 Diagramme système
Diagramme en cours de génération...
2. Choix de la stack
2.1 Les 2 options retenues
| Critère | React Native + Expo | Flutter |
|---|---|---|
| Langage | TypeScript | Dart |
| UI | Composants natifs (via Fabric) | Rendu propre (Skia) |
| Hot reload | Oui (Fast Refresh) | Oui (Hot Reload) |
| DevTools | Expo Go / dev build | Dart DevTools |
| Écosystème JS | Énorme (npm) | Packages pub.dev |
| Build iOS | EAS Build (cloud) | Codemagic / Xcode |
| Tests UI | React Native Testing Library | widget tests + integration_test |
| Perf graphique | Bonne | Excellente |
2.2 Règle de décision
Une ADR (section adr/) documente le choix. En 2026, les deux options sont viables : exigence UI très spécifique → Flutter ; équipe TypeScript existante ou besoin d'écosystème JS → Expo.
2.3 Recommandation pédagogique
Ce chapitre montre les deux stacks côte à côte (exemples en TypeScript/RN et en Dart/Flutter). Chaque binôme choisit une seule stack et la justifie dans son adr/README.md.
3. Clean Architecture + MVVM
3.1 Couches
Diagramme en cours de génération...
Règle de dépendance : le domaine ne dépend de rien (pas de Flutter/Android/iOS). Le data dépend du domaine ; la présentation dépend du domaine et des interfaces.
3.2 Exemple de flux
- L'utilisateur crée une tâche →
CreateTaskUseCase.execute(Task). - Le use case valide (règles métier pures) puis appelle
TaskRepository.create(task). - L'implémentation data écrit en local (
queued: true) puis tente l'API ; si échec, Background Sync/WorkManager rejouera. - Le ViewModel expose un
StateFlow/StateNotifiermis à jour → la UI réagit.
3.3 Navigation et état
- RN (Expo) : React Navigation + états locaux (Provider/useReducer) ou Zustand/Redux Toolkit.
- Flutter : go_router (routes typées) + Riverpod (providers) ou Bloc.
4. Authentification
4.1 Flux JWT + refresh
Diagramme en cours de génération...
4.2 Points d'attention
- Stockage : jamais en localStorage/clair → Keystore (Android) / Keychain (iOS) /
expo-secure-store/flutter_secure_storage. - Renouvellement automatique : interceptor (Axios/Dio/http) qui attend le refresh, met les requêtes concurrentes en file, et retente.
- Déconnexion : purge locale + révocation du refresh côté serveur.
- Logout forcé : si le refresh échoue (token révoqué), déconnexion globale.
4.3 Récupération
- Mot de passe oublié :
POST /auth/forgot-password(email) puisPOST /auth/reset-password. - Validation minimale côté client + toujours côté serveur.
5. Persistance locale + synchronisation
5.1 Choix selon stack
| Stack | Base locale | Sync |
|---|---|---|
| RN + Expo | SQLite (expo-sqlite) / MMKV / WatermelonDB | WatermelonDB / custom queue |
| Flutter | SQLite (drift) / Hive | drift sync / custom queue |
Règle : pas de cache simple — on utilise une vraie base locale (SQLite) pour les requêtes, filtres et le hors ligne.
5.2 Modèle de synchronisation
Diagramme en cours de génération...
- Chaque mutation locale est horodatée (
updatedAt) et marquéequeued. - Le serveur applique les mutations dans l'ordre ; conflits résolus last-write-wins (par défaut).
- Le WebSocket pousse les changements des autres clients → l'app met à jour la base locale.
- Le serveur expose une API de replay (
GET /api/tasks/since?ts=...) pour rattraper les événements manqués.
5.3 Replay vs queue
| Mécanisme | Quand |
|---|---|
| Replay (since timestamp) | Reprise après offline long : on redemande les changements depuis notre lastSyncAt |
| Queue de mutations | Actions créées/modifiées hors ligne, rejouées dans l'ordre |
Les deux se combinent : queue pour nos écritures, replay pour les écritures des autres.
6. Networking : REST + WebSocket
6.1 REST
- RN :
fetch/Axios + interceptor auth/refresh. - Flutter :
dioavec intercepteurs ouhttp+ client REST typé.
Bonnes pratiques : DTO → entité (mapping dans le data layer), validation de la réponse, pagination (cursor), retry avec backoff, timeouts.
6.2 WebSocket temps réel
// RN
const ws = new WebSocket('wss://api.taskflow.dev/ws?project=42');
ws.onmessage = (e) => {
const event = JSON.parse(e.data); // { type: 'task.updated', payload: {...} }
taskStore.applyRemoteEvent(event);
};
// Flutter
final ws = IOWebSocketChannel.connect(
Uri.parse('wss://api.taskflow.dev/ws?project=42'),
);
ws.stream.listen((e) {
final event = jsonDecode(e);
taskStore.applyRemoteEvent(event);
});
6.3 Reconnexion et backoff
- Reconnection avec jitter exponentiel (1 s → 2 s → 4 s → … max 60 s).
- Envoi de
pingpériodique pour détecter les connexions mortes. - File d'événements : tout événement reçu doit être idempotent (rejouable) ; l'app filtre par
updatedAt.
7. Stratégie de tests
7.1 Pyramide adaptée
Diagramme en cours de génération...
7.2 Répartition (pourcentage visé)
| Niveau | % | Outils RN | Outils Flutter |
|---|---|---|---|
| Unit (domaine, use cases, mappers) | 60 % | Jest | flutter test |
| Widget/Component + repositories (mock) | 30 % | RNTL + MSW | widget tests + mocktail |
| E2E (login → créer → sync) | 10 % | Maestro / Detox | Maestro / integration_test |
7.3 Ce qu'on ne teste PAS (trop coûteux)
- Le framework (React/Dart), les libs tierces, les styles pixel-perfect.
- On teste le comportement, pas l'implémentation.
8. CI/CD + observabilité
8.1 Pipeline
Diagramme en cours de génération...
8.2 Composants
- CI : GitHub Actions (jobs test / build / distribute).
- Build cloud : EAS Build (Expo) ou Codemagic (Flutter).
- Fastlane : lanes
beta/release;match(iOS) ;supply(Play). - Observabilité : Crashlytics (ou Sentry) + APM + analytics + alertes (crash-free < 99 %, cold start p95 > 2,5 s).
- Release notes : générées depuis les PR (changelog auto).
8.3 Sécurité de la pipeline
- Secrets dans le secret manager ; jamais dans le repo.
- Signing : keystore/matérialisés en CI, App Signing / match.
- Build reproductible : même commit → même binaire (verrouillage des deps).
9. Performance
9.1 Objectifs chiffrés (budget)
| Métrique | Cible |
|---|---|
| Cold start | ≤ 1,5 s (P95) |
| Frame time | ≤ 16 ms (rendu) |
| Taille APK/IPA | ≤ 30 MB (AAB), ≤ 60 MB (IPA) |
| FPS écran liste | ≥ 55 fps moyen |
| Crash-free | ≥ 99 % |
9.2 Checklist RN
- React Navigation avec lazy screens ; mémoïsation (
useMemo/memo). FlashListau lieu deFlatListpour les longues listes.- Images :
expo-image(cache disque), dimensions explicites (éviter le layout shift). - Hermes activé ; bundle décomposé (
metrosplitting) si besoin. - Éviter les rendus inutiles : sélecteurs Zustand/Redux ciblés.
9.3 Checklist Flutter
constwidgets,ListView.builder+itemExtent.RepaintBoundaryautour des zones animées ; éviter les rebuilds globaux.Image.network→cached_network_image.- Tree shaking des fonts ;
--obfuscate+--split-debug-infoà la release. - Isolates pour le calcul lourd (import/export, hachage).
9.4 Mesure
- RN : React DevTools profiler, Flipper/React Native Performance Monitor, Perfetto (Hermes).
- Flutter : DevTools Performance + Timeline, Flutter frame chart.
- Terrain : Firebase Performance, Sentry Performance, Crashlytics custom metrics.
10. Sécurité et publication
10.1 Checklist sécurité (OWASP Top 10 mobile)
- Stockage local chiffré (Keystore/Keychain ; base chiffrée ou colonnes sensibles).
- Transport : TLS 1.2+ + certificate pinning optionnel (avec fallback documenté).
- Auth : JWT court + refresh rotate ; écran de verrouillage au retour en arrière-plan.
- Code : obfuscation (R8 /
--obfuscate) + anti-tampering basique (checks de signature). - Dépendances : scan (Dependabot / osv-scanner /
dart pub outdated). - Permissions : minimales ; pas de permissions runtime inutiles.
- Deep links : Universal Links / App Links vérifiés ; pas de schémas customs sensibles.
10.2 Préparation stores
Play Console :
- AAB, App Signing, fiche produit, politique de confidentialité, consentement données.
- Screenshots, classement des données (Data safety), staged rollout 10 %.
App Store :
- Archive IPA (ou EAS build), TestFlight d'abord, App Store Connect : privacy labels, App Review.
- Export Compliance, screenshot par taille.
10.3 Après publication
- Monitoring des crashs et de l'APM pendant le rollout.
- Plan de rollback (retirer la version, promo de l'ancienne).
- Réponse aux examens de politique (délais ~30 jours pour la plupart des demandes).
Synthèse
- TaskFlow intègre tout le cursus : architecture, auth, persistance, réseau temps réel, tests, DevOps, perf, sécurité, stores.
- Stack : RN+Expo ou Flutter, choix documenté par ADR ; le domaine ne dépend jamais du framework.
- Auth : JWT + refresh en interceptor, stockage sécurisé (Keystore/Keychain).
- Hors ligne : base locale + queue de mutations + replay + WebSocket.
- Tests : 60/30/10 (unitaire / widget / E2E) dans la CI.
- Release : GitHub Actions + Fastlane + EAS/Codemagic, staged rollout, observabilité branchée.
- Perf : budgets chiffrés (cold start, FPS, taille), mesurés en dev et en terrain.
- Sécurité : OWASP Top 10 + secrets en CI + publication conforme.