Files
roadwave/docs/INCONSISTENCIES-ANALYSIS.md
2026-01-31 11:45:11 +01:00

672 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Analyse des Incohérences entre ADR et Règles Métier
**Date d'analyse** : 2026-01-28
**Analysé par** : Audit Architecture RoadWave
**Scope** : 18 ADR × Règles Métier (17 fichiers)
---
## Résumé Exécutif
Cette analyse a identifié **15 incohérences** entre les décisions d'architecture (ADR) et les règles métier du projet RoadWave.
### Répartition par Sévérité
| Sévérité | Nombre | % Total | Statut | Action Required |
|----------|--------|---------|--------|-----------------|
| 🔴 **CRITICAL** | 2 | 13% | ✅ **RÉSOLU** | ~~avant implémentation~~ |
| 🟠 **HIGH** | 4 | 27% | ⏳ 3 restants (1 résolu) | Résolution Sprint 1-2 |
| 🟡 **MODERATE** | 8 | 53% | ⏳ En cours | Résolution Sprint 3-5 |
| 🟢 **LOW** | 1 | 7% | ⏳ En cours | À clarifier lors du développement |
### Impact par Domaine
| Domaine | Nombre d'incohérences | Criticité maximale |
|---------|----------------------|-------------------|
| Streaming & Géolocalisation | 3 | 🔴 CRITICAL |
| Données & Infrastructure | 3 | 🟠 HIGH |
| Authentification & Sécurité | 2 | 🟠 HIGH |
| Tests & Qualité | 2 | 🟡 MODERATE |
| Coûts & Déploiement | 3 | 🟡 MODERATE |
| UX & Engagement | 2 | 🟡 MODERATE |
---
## 🔴 Incohérences Critiques (Blocantes)
### #1 : HLS ne supporte pas les Notifications Push en Arrière-plan
**Statut** : ✅ **RÉSOLU** (ADR-019 créé)
| Élément | Détail |
|---------|--------|
| **ADR concerné** | ADR-002 (Protocole Streaming) |
| **Règle métier** | Règle 05, section 5.1.2 (Mode Piéton, lignes 86-120) |
| **Conflit** | HLS est unidirectionnel (serveur→client), ne peut pas envoyer de push quand l'app est fermée |
| **Impact** | Mode piéton non fonctionnel : notifications "Point d'intérêt à 200m" impossibles |
**Scénario d'échec** :
```
Utilisateur: Marie se promène, app fermée
Position: 150m de la Tour Eiffel
Attendu: Push notification "🗼 À proximité: Histoire de la Tour Eiffel"
Réel: Rien (HLS ne peut pas notifier)
```
**Solution implémentée** :
-**ADR-019** : Architecture hybride WebSocket + Firebase Cloud Messaging
- Phase 1 (MVP) : Push serveur via FCM/APNS
- Phase 2 : Geofencing natif iOS/Android pour mode offline
**Actions requises** :
- [ ] Backend : Implémenter endpoint WebSocket `/ws/location`
- [ ] Backend : Worker PostGIS avec requête `ST_DWithin` (30s interval)
- [ ] Mobile : Intégrer Firebase SDK (`firebase_messaging`)
- [ ] Tests : Validation en conditions réelles (10 testeurs, Paris)
---
### #2 : Latence HLS Incompatible avec ETA de 7 Secondes
**Statut** : ✅ **RÉSOLU** (ADR-002 mis à jour)
| Élément | Détail |
|---------|--------|
| **ADR concerné** | ADR-002 (Protocole Streaming, lignes 40-41) |
| **Règle métier** | Règle 05 (lignes 16-20), Règle 17 (lignes 25-30, 120-124) |
| **Conflit** | ETA de 7s avant le point, mais HLS a 5-30s de latence → audio démarre APRÈS avoir dépassé le point |
| **Impact** | UX catastrophique : utilisateur entend "Vous êtes devant le château" 100m APRÈS l'avoir dépassé |
**Calcul du problème** (90 km/h = 25 m/s) :
```
t=0s → Notification "Suivant: Château dans 7s" (175m avant)
t=7s → Utilisateur arrive au château
t=15s → HLS démarre (latence 15s)
Résultat: Audio démarre 200m APRÈS le point ❌
```
**Solution implémentée** :
-**ADR-002 mis à jour** : Section "Gestion de la Latence et Synchronisation Géolocalisée"
- Pre-buffering à ETA=30s (15 premières secondes en cache local)
- ETA adaptatif : 5s si cache prêt, 15s sinon
- Mesure dynamique de latence HLS par utilisateur
**Actions requises** :
- [ ] Backend : Endpoint `/api/v1/audio/poi/:id/intro` (retourne 15s d'audio)
- [ ] Mobile : Service `PreBufferService` avec cache local (max 100 MB)
- [ ] Mobile : Loader visuel avec progression si buffer > 3s
- [ ] Tests : Validation synchronisation ±10m du POI
---
## 🟠 Incohérences Importantes (Sprint 1-2)
### #3 : Souveraineté des Données (Français vs Suisse)
**Statut** : ✅ **RÉSOLU** (ADR-008 mis à jour)
| Élément | Détail |
|---------|--------|
| **ADR concernés** | ADR-004 (CDN, ligne 26), ADR-008 (Auth, mis à jour) |
| **Règle métier** | Règle 02 (RGPD, section 13.10) |
| **Conflit** | ADR-004 revendique "100% souveraineté française" mais ADR-008 utilisait Zitadel (entreprise suisse) |
| **Impact** | Contradiction marketing + risque juridique si promesse "100% français" |
**Solution implémentée** : **Self-hosting Zitadel sur OVH France**
- ✅ Container Docker sur le même VPS OVH (Gravelines, France)
- ✅ Base de données PostgreSQL partagée (schéma séparé pour Zitadel)
- ✅ Aucune donnée ne transite par des serveurs tiers
- ✅ Souveraineté totale garantie : 100% des données en France
- ✅ Cohérence complète avec ADR-004 (CDN 100% français)
**Changements apportés** :
- ✅ ADR-008 mis à jour avec architecture self-hosted détaillée
- ✅ TECHNICAL.md mis à jour (tableau + diagramme architecture)
- ✅ Clarification : Zitadel est open source, donc aucune dépendance à une entreprise suisse
**Actions complétées** :
- [x] Décision validée : Self-host sur OVH
- [x] ADR-008 mis à jour avec architecture self-hosted
- [x] TECHNICAL.md mis à jour
---
### #4 : ORM sqlc vs Types PostGIS
| Élément | Détail |
|---------|--------|
| **ADR concernés** | ADR-013 (ORM, lignes 12, 33-40), ADR-005 (BDD, lignes 47-56) |
| **Règle métier** | N/A (problème technique pur) |
| **Conflit** | sqlc génère types Go depuis SQL, mais PostGIS geography/geometry ne mappent pas proprement |
| **Impact** | Risque de type `interface{}` ou `[]byte` pour géographie → perte de type safety revendiquée |
**Nature du problème** :
sqlc génère du code Go depuis SQL, mais les types PostGIS (`geography`, `geometry`) ne sont pas mappés proprement en Go. Résultat : types opaques (`[]byte`, `interface{}`) qui perdent la **type safety** revendiquée dans ADR-013.
**Solution retenue** :
1. **Wrapper types Go** avec méthodes `Scan/Value` pour conversion automatique
2. **Utiliser les fonctions PostGIS de conversion** :
- `ST_AsGeoJSON()` → struct GeoJSON typée
- `ST_AsText()` → string WKT
- `geography` brut → `pgtype.Point` (lib pgx)
3. **Documenter le pattern** dans ADR-013 section "Gestion des Types PostGIS"
**Action** :
- [ ] Créer package `internal/geo` avec wrappers `GeoJSON`, `WKT`
- [ ] Mettre à jour ADR-013 section "Types PostGIS"
- [ ] Documenter pattern dans README backend
---
### #5 : Cache Redis (TTL 5min) vs Mode Offline (30 jours)
| Élément | Détail |
|---------|--------|
| **ADR concerné** | ADR-005 (BDD, ligne 60) |
| **Règle métier** | Règle 11 (Mode Offline, lignes 58-77) |
| **Conflit** | Redis avec TTL 5min pour géolocalisation, mais contenu offline valide 30 jours |
| **Impact** | En mode offline, impossible de rafraîchir le cache géolocalisation → POI proches non détectés |
**Analyse du flux** :
```
Mode connecté:
1. Requête POI proches → Redis (cache 5min)
2. Si miss → PostGIS → Cache Redis
3. ✅ Fonctionne
Mode offline (Règle 11):
1. Requête POI proches → Redis (expiré depuis 6 min)
2. Impossible de requêter PostGIS (pas de réseau) ❌
3. Aucun POI détecté
```
**Solution** :
Stratégie de **cache à 2 niveaux** :
| Cache | TTL | Usage | Invalidation |
|-------|-----|-------|--------------|
| **Redis (L1)** | 5 min | Mode connecté | Automatique |
| **SQLite local (L2)** | 30 jours | Mode offline | Manuelle lors sync |
**Architecture** :
```
[Mode Connecté]
→ Redis (L1) → PostGIS → Cache local SQLite (L2)
[Mode Offline]
→ SQLite local (L2) uniquement
```
**Action** :
- [ ] Backend : Ajouter endpoint `/sync/nearby-pois?lat=X&lon=Y&radius=10km`
- [ ] Mobile : Créer `OfflineCacheService` avec SQLite + index spatial
- [ ] Mettre à jour ADR-005 section "Cache" avec stratégie 2 niveaux
- [ ] Règle 11 : Clarifier sync automatique vs manuel
---
### #6 : Package Geofencing vs Permissions iOS/Android
| Élément | Détail |
|---------|--------|
| **ADR concerné** | ADR-014 (Frontend Mobile, ligne 48) |
| **Règle métier** | Règle 05 (lignes 86-134), Règle 11 (RGPD, lignes 51-86) |
| **Conflit** | Package `geofence_service` choisi, mais pas de doc sur compatibilité permissions "optionnelles" |
| **Impact** | Risque de rejet App Store/Play Store si permissions obligatoires mal gérées |
**Problématiques** :
1. **iOS** : Permission "Always Location" exige justification stricte (taux refus 70%)
2. **Android** : Background location nécessite déclaration spéciale (depuis Android 10)
3. **Règle métier** : Permissions optionnelles (app utilisable sans "Always Location")
**Package `geofence_service`** :
- ✅ Supporte iOS/Android
- ⚠️ Documentation peu claire sur permissions optionnelles
- ⚠️ Pas de fallback natif si permission refusée
**Solution** :
**Stratégie de permissions progressive** :
```dart
enum LocationPermissionLevel {
denied, // Pas de permission
whenInUse, // "Quand l'app est ouverte" (iOS)
always, // "Toujours" (iOS) / Background (Android)
}
class GeofencingService {
Future<void> requestPermissions() async {
// Étape 1: Demander "When In Use" (moins intrusif)
var status = await Permission.locationWhenInUse.request();
if (status.isGranted) {
// Mode basique: détection seulement app ouverte
_enableBasicGeofencing();
// Étape 2 (optionnelle): Proposer upgrade vers "Always"
_showUpgradePermissionDialog();
}
}
Future<void> upgradeToAlwaysPermission() async {
// Demandé seulement si utilisateur veut mode piéton complet
await Permission.locationAlways.request();
}
}
```
**Actions** :
- [ ] Mettre à jour ADR-014 avec stratégie permissions progressive
- [ ] Créer doc "Permissions Strategy" dans `/docs/mobile/`
- [ ] Tests : Validation rejet App Store (TestFlight beta)
---
## 🟡 Incohérences Modérées (Sprint 3-5)
### #7 : Points vs Pourcentages dans les Jauges
| Élément | Détail |
|---------|--------|
| **ADR concerné** | ADR-010 (Commandes Volant, lignes 15-21) |
| **Règle métier** | Règle 03 (Centres d'intérêt, lignes 7-14) |
| **Conflit** | ADR dit "+2 **points**", Règle dit "+2**%**" pour même action |
| **Impact** | Ambiguïté sur calcul : +2 points absolus ou +2% relatifs ? |
**Exemple du conflit** :
- **ADR-010 (ligne 18)** : "≥80% d'écoute = +2 **points**"
- **Règle 03 (ligne 9)** : "≥80% d'écoute = +2**%** à la jauge"
**Scénario** :
```
Jauge "Automobile" = 45%
Utilisateur écoute 85% d'un podcast voiture
Option A (points absolus): 45 + 2 = 47%
Option B (pourcentage relatif): 45 * 1.02 = 45.9%
```
**Recommandation** : **Option A (points absolus)** pour simplicité
**Justification** :
- Progression linéaire plus intuitive
- Évite effet "rich get richer" (jauges hautes progressent + vite)
- Cohérent avec système de gamification classique
**Actions** :
- [ ] Clarifier ADR-010 : remplacer "points" par "points de pourcentage"
- [ ] Clarifier Règle 03 : uniformiser terminologie
- [ ] Backend : Documenter formule exacte dans code
---
### #8 : OAuth2 Complexe vs Email/Password Simple
| Élément | Détail |
|---------|--------|
| **ADR concerné** | ADR-008 (Auth, lignes 12, 52-68) |
| **Règle métier** | Règle 01 (Auth, lignes 5-10) |
| **Conflit** | ADR implémente OAuth2 PKCE complet, mais Règle dit "❌ Pas d'OAuth tiers, email/password uniquement" |
| **Impact** | Sur-ingénierie : OAuth2 conçu pour tiers (Google, Facebook) mais non utilisé ici |
**Analyse** :
- **ADR-008** : Architecture OAuth2 avec PKCE, refresh tokens, etc.
- **Règle 01** : "❌ Pas de Google, Apple, Facebook OAuth"
**Zitadel supporte** :
- OAuth2 (pour intégrations tierces)
- Email/Password natif (ce dont on a besoin)
**Question** : Pourquoi implémenter OAuth2 si pas de tiers ?
**Options** :
| Option | Complexité | Justification |
|--------|------------|---------------|
| **A. Garder OAuth2** | Haute | Future-proof pour API partenaires |
| **B. Session simple** | Basse | Suffit pour MVP email/password |
**Recommandation** : **Option A** (garder OAuth2) si :
- Vision long-terme : API pour partenaires (créateurs, annonceurs)
- Coût marginal : Zitadel gère OAuth2 nativement
Sinon **Option B** (session simple) si MVP pur.
**Actions** :
- [ ] Décision : Confirmer besoin OAuth2 avec product owner
- [ ] Si A : Mettre à jour Règle 01 "OAuth tiers en Phase 2"
- [ ] Si B : Simplifier ADR-008 (session JWT classique)
---
### #9 : GeoIP Database (MaxMind)
| Élément | Détail |
|---------|--------|
| **ADR concerné** | ADR-005 (non mentionné) |
| **Règle métier** | Règle 02 (RGPD, lignes 146-149) |
| **Conflit** | Règle cite "MaxMind GeoLite2 (gratuit)", mais offre a changé en 2019 |
| **Impact** | Coût caché : MaxMind nécessite compte + API calls (plus de base offline gratuite) |
**Historique** :
- **Avant 2019** : GeoLite2 database téléchargeable gratuitement
- **Après 2019** : Compte requis + limite 1000 requêtes/jour (gratuit)
- **Dépassement** : 0.003$/requête
**Utilisation RoadWave** :
- Mode dégradé (sans GPS) → GeoIP pour localisation approximative
- Estimation : 10% des utilisateurs (1000 users × 10% = 100 requêtes/jour)
**Options** :
| Option | Coût/mois | Précision | Maintenance |
|--------|-----------|-----------|-------------|
| **A. MaxMind API** | ~10€ | ±50 km | Nulle |
| **B. IP2Location Lite** | Gratuit | ±50 km | Maj mensuelle |
| **C. Self-hosted GeoIP** | Gratuit | ±50 km | +2h/mois |
**Recommandation** : **Option C** (self-hosted avec IP2Location Lite DB)
**Architecture** :
```
[Backend Go] → [GeoIP Service]
[IP2Location SQLite DB]
(màj mensuelle via cron)
```
**Actions** :
- [ ] Backend : Implémenter service GeoIP avec IP2Location
- [ ] DevOps : Cron job màj mensuelle de la DB
- [ ] Mettre à jour Règle 02 ligne 147
---
### #10 : Tests BDD Synchronisés (Backend + Mobile)
| Élément | Détail |
|---------|--------|
| **ADR concernés** | ADR-007 (Tests BDD, lignes 30-68), ADR-015 (Stratégie, lignes 59-62) |
| **Règle métier** | Toutes (Gherkin) |
| **Conflit** | Features partagées `/features`, step definitions séparées → qui exécute quoi ? |
| **Impact** | Risque de divergence backend/mobile si tests pas synchronisés |
**Architecture actuelle** :
```
/features/*.feature (partagé)
/backend/tests/bdd/ (step definitions Go)
/mobile/tests/bdd/ (step definitions Dart)
```
**Question non résolue** :
- Un test "Authentification" concerne-t-il backend ET mobile ?
- Qui est responsable de l'exécuter ?
- Si les implémentations divergent ?
**Recommandation** : **Catégoriser les features**
```
/features/
/api/ → Backend uniquement (tests API REST)
/ui/ → Mobile uniquement (tests interface)
/e2e/ → End-to-end (backend + mobile ensemble)
```
**Exemple** :
```gherkin
# features/api/authentication.feature (backend)
Scénario: Création de compte via API
Étant donné une requête POST /api/v1/auth/register
Quand j'envoie email "test@example.com" et password "Pass123!"
Alors le statut HTTP est 201
Et la réponse contient un token JWT
# features/ui/authentication.feature (mobile)
Scénario: Création de compte via interface
Étant donné que je suis sur l'écran d'inscription
Quand je saisis email "test@example.com"
Et je saisis mot de passe "Pass123!"
Et je clique sur "S'inscrire"
Alors je vois l'écran d'accueil
```
**Actions** :
- [ ] Réorganiser `/features` en 3 catégories (api, ui, e2e)
- [ ] Mettre à jour ADR-007 avec convention de nommage
- [ ] CI/CD : Séparer jobs backend-bdd et mobile-bdd
---
### #11 : 70/30 Split Paiements (Vérification Manquante)
| Élément | Détail |
|---------|--------|
| **ADR concerné** | ADR-009 (Paiement, lignes 32-52) |
| **Règle métier** | Règle 18 (Monétisation, non fournie complète) |
| **Conflit** | ADR assume 70/30 split sans référence règle métier |
| **Impact** | Risque de mauvaise répartition revenus créateurs |
**ADR-009 spécifie** :
- 70% créateur
- 30% plateforme
**Question** : Est-ce validé par les règles métier business ?
**Actions** :
- [ ] Lire Règle 18 (Monétisation Créateurs) complète
- [ ] Vérifier si 70/30 correspond aux attentes
- [ ] Si divergence : mettre à jour ADR-009
---
### #12 : Monorepo Path Filters vs Features Partagées
| Élément | Détail |
|---------|--------|
| **ADR concernés** | ADR-016 (Monorepo, ligne 80), ADR-015 (Tests) |
| **Règle métier** | N/A (problème CI/CD) |
| **Conflit** | Path filters pour éviter rebuild tout, mais features partagées déclenchent tout |
| **Impact** | Optimisation CI/CD inefficace |
**Problème** :
```yaml
# .github/workflows/backend.yml
on:
push:
paths:
- 'backend/**'
- 'features/**' # ❌ Change sur n'importe quel .feature → rebuild backend
```
**Solution** : Path filters **par catégorie** (suite de #10)
```yaml
# .github/workflows/backend.yml
on:
push:
paths:
- 'backend/**'
- 'features/api/**' # ✅ Seulement features API
- 'features/e2e/**' # ✅ E2E impacte backend
# .github/workflows/mobile.yml
on:
push:
paths:
- 'mobile/**'
- 'features/ui/**' # ✅ Seulement features UI
- 'features/e2e/**' # ✅ E2E impacte mobile
```
**Actions** :
- [ ] Implémenter catégorisation features (dépend de #10)
- [ ] Mettre à jour workflows CI/CD
- [ ] Mettre à jour ADR-016 avec stratégie path filters
---
### #13 : Coûts Email (Transition Free → Paid)
| Élément | Détail |
|---------|--------|
| **ADR concernés** | ADR-018 (Email, lignes 49-52), ADR-017 (Hébergement) |
| **Règle métier** | N/A (économique) |
| **Conflit** | ADR cite "gratuit" mais limite 9000 emails/mois → plan transition manquant |
| **Impact** | Coût surprise lors de la croissance |
**ADR-018 spécifie** :
- Brevo gratuit : 300 emails/jour = 9000/mois
- Phase MVP : 0-10K utilisateurs
**Calcul réaliste** :
```
Emails par utilisateur/mois:
- Vérification email: 1
- Reset password: 0.1 (10%)
- Notifications (opt-in 30%): 4
- Paiements créateurs (5%): 1
Total: ~2 emails/user/mois (moyenne)
10K users × 2 = 20K emails/mois → dépassement tier gratuit
```
**Coût Brevo** :
- Free: 0-9K emails
- Lite: 19€/mois (20K emails)
- Business: 49€/mois (50K emails)
**Actions** :
- [ ] Mettre à jour ADR-018 avec projection coûts
- [ ] Implémenter alertes (90% quota atteint)
- [ ] Plan B : Self-hosted SMTP (Postfix) si budget serré
---
### #14 : Kubernetes vs VPS MVP
| Élément | Détail |
|---------|--------|
| **ADR concernés** | ADR-017 (Hébergement, ligne 12), ADR-001 (Go, ligne 27) |
| **Règle métier** | N/A (infrastructure) |
| **Conflit** | ADR-001 justifie Go pour "Kubernetes first-class", mais ADR-017 utilise VPS simple |
| **Impact** | Sur-architecture : pourquoi choisir Go pour K8s si pas utilisé ? |
**Analyse** :
- **ADR-001** : Go choisi notamment pour "excellent support Kubernetes"
- **ADR-017** : MVP sur OVH VPS Essential (single VM, Docker Compose)
- **ADR-012** : Mentionne migration K8s "à 1M+ users"
**Question** : Justification K8s prématurée ?
**Réponse** : **Non, acceptable** si :
- Vision long-terme claire (1M users = besoin K8s)
- Go apporte autres avantages (perf, concurrence, typing)
- Coût marginal (Go vs Node.js comparable en complexité MVP)
**Recommandation** : **Clarifier la vision** dans ADR
**Actions** :
- [ ] Mettre à jour ADR-001 : "Go pour scalabilité future (K8s), mais aussi perf/typage"
- [ ] ADR-017 : Ajouter section "Roadmap Infrastructure" (VPS → K8s)
---
## 🟢 Incohérences Mineures (Clarification)
### #15 : Unlike Manuel sur Contenu Auto-liké
| Élément | Détail |
|---------|--------|
| **ADR concerné** | ADR-010 (ligne 15-21) |
| **Règle métier** | Règle 05 (lignes 248-323), Règle 03 (lignes 93-99) |
| **Conflit** | Auto-like +2% documenté, mais unlike manuel non spécifié |
| **Impact** | Ambiguïté : faut-il annuler (+2%) si unlike ? |
**Scénario** :
```
1. Utilisateur écoute 85% → auto-like → jauge +2%
2. Utilisateur clique "Unlike" (toggle)
3. Que se passe-t-il ?
Option A: Jauge -2% (annulation)
Option B: Jauge reste (unlike n'affecte pas)
```
**Recommandation** : **Option A** (annulation symétrique)
**Justification** : Unlike explicite = signal fort "pas intéressé"
**Actions** :
- [ ] Clarifier Règle 03 : section "Unlike Manuel"
- [ ] Backend : Implémenter logique annulation dans `GaugeService`
---
## Plan d'Action Global
### Phase 1 : Résolutions Critiques (Avant Implémentation)
| # | Tâche | Responsable | Effort | Deadline |
|---|-------|-------------|--------|----------|
| 1 | ✅ Créer ADR-019 (Notifications) | Architecture | 2h | ✅ Fait |
| 2 | ✅ Mettre à jour ADR-002 (Pre-buffering) | Architecture | 1h | ✅ Fait |
| 3 | Implémenter WebSocket backend | Backend Lead | 3j | Sprint 1 |
| 4 | Implémenter Pre-buffer mobile | Mobile Lead | 2j | Sprint 1 |
### Phase 2 : Résolutions Importantes (Sprint 1-2)
| # | Tâche | Responsable | Effort | Statut |
|---|-------|-------------|--------|--------|
| 5 | ✅ Décision souveraineté (Zitadel self-host) | CTO | 1h | ✅ **Fait** |
| 6 | Package geo types (PostGIS) | Backend | 1j | ⏳ Sprint 2 |
| 7 | Cache 2 niveaux (Redis + SQLite) | Backend + Mobile | 3j | ⏳ Sprint 2 |
| 8 | Stratégie permissions progressive | Mobile | 2j | ⏳ Sprint 2 |
### Phase 3 : Résolutions Modérées (Sprint 3-5)
| # | Tâche | Responsable | Effort | Deadline |
|---|-------|-------------|--------|----------|
| 9-15 | Clarifications ADR/Règles | Tech Writer | 5j | Sprint 3-4 |
| 16 | Réorganisation features BDD | QA Lead | 2j | Sprint 4 |
| 17 | Optimisation CI/CD path filters | DevOps | 1j | Sprint 5 |
---
## Métriques de Suivi
| Métrique | Valeur Initiale | Cible | Actuel |
|----------|----------------|-------|--------|
| Incohérences CRITICAL | 2 | 0 | ✅ **0** (2/2 résolues) |
| Incohérences HIGH | 4 | 0 | ⏳ **3** (1/4 résolue) |
| Incohérences MODERATE | 8 | ≤2 | ⏳ 8 |
| ADR à jour | 66% (12/18) | 100% | ⏳ 78% (14/18) |
| Coverage documentation | N/A | >90% | ⏳ 80% |
**Dernière mise à jour** : 2026-01-30
---
## Contacts et Ressources
- **Analyse complète** : Ce document
- **ADR-019** : `/docs/adr/019-notifications-geolocalisees.md`
- **ADR-002 (mis à jour)** : `/docs/adr/002-protocole-streaming.md`
- **Questions** : Créer une issue GitHub avec tag `[architecture]`
---
**Prochaine revue** : 2026-02-15 (après Sprint 2)