docs: améliorer rendu markdown et navigation mkdocs
- Ajouter ADR-018 (librairies Go) dans TECHNICAL.md - Transformer Shared en menu dépliable dans mkdocs (cohérence avec autres domaines) - Corriger listes markdown (ajout lignes vides avant listes) - Corriger line breaks dans génération BDD (étapes "Et" sur nouvelles lignes) - Ajouter script fix-markdown-lists.sh pour corrections futures Impacte 86 fichiers de documentation et 164 fichiers BDD générés.
This commit is contained in:
@@ -47,6 +47,7 @@ Streaming audio vers des utilisateurs mobiles en voiture, avec réseaux instable
|
||||
La latence HLS (5-30s) entre en conflit avec les notifications géolocalisées qui doivent déclencher l'audio **au moment précis** où l'utilisateur atteint un point d'intérêt.
|
||||
|
||||
**Exemple critique** :
|
||||
|
||||
- Utilisateur en voiture à 90 km/h (25 m/s)
|
||||
- ETA de 7 secondes avant le point → notification affichée
|
||||
- Latence HLS de 15 secondes
|
||||
@@ -69,6 +70,7 @@ La latence HLS (5-30s) entre en conflit avec les notifications géolocalisées q
|
||||
```
|
||||
|
||||
**Stratégie de cache** :
|
||||
|
||||
- Télécharge les **15 premières secondes** de chaque POI à proximité
|
||||
- Limite : 3 POI simultanés en cache (max ~25 MB)
|
||||
- Purge automatique après 200m de distance passée
|
||||
@@ -152,16 +154,19 @@ Si le pre-buffer échoue (réseau faible, pas de cache), afficher un **loader av
|
||||
### Impact sur l'Infrastructure
|
||||
|
||||
#### Backend (Go)
|
||||
|
||||
- **Nouveau service** : `audiocache.Service` pour préparer les extraits M4A
|
||||
- **Endpoint** : `GET /api/v1/audio/poi/:id/intro` (retourne 15s d'audio)
|
||||
- **CDN** : Cache NGINX avec TTL 7 jours sur `/audio/*/intro.m4a`
|
||||
|
||||
#### Mobile (Flutter)
|
||||
|
||||
- **Package** : `just_audio` avec cache local (`flutter_cache_manager`)
|
||||
- **Stockage** : Max 100 MB de cache audio (auto-purge LRU)
|
||||
- **Logique** : `PreBufferService` avec scoring de priorité POI
|
||||
|
||||
#### Coûts
|
||||
|
||||
- **Bande passante** : +10-15 MB/utilisateur/session (vs streaming pur)
|
||||
- **Stockage CDN** : +500 MB pour 1000 POI × 5 MB intro (négligeable)
|
||||
- **Économie** : Cache CDN réduit les requêtes origin (-60% selon tests)
|
||||
|
||||
@@ -44,12 +44,14 @@ flowchart LR
|
||||
## Justification
|
||||
|
||||
### PostgreSQL + PostGIS
|
||||
|
||||
- Requêtes géospatiales complexes et précises
|
||||
- Index GIST pour performance
|
||||
- ACID, fiabilité éprouvée
|
||||
- Écosystème mature
|
||||
|
||||
### PgBouncer
|
||||
|
||||
- **Connection pooling** : Réduit l'overhead de création de connexions PostgreSQL
|
||||
- **Mode transaction** : Connexion réutilisée entre transactions (optimal pour API stateless)
|
||||
- **Performance** : Permet de gérer 1000+ connexions concurrentes avec ~100 connexions réelles à PostgreSQL
|
||||
@@ -57,6 +59,7 @@ flowchart LR
|
||||
- **Port** : :6432 (vs :5432 pour PostgreSQL direct)
|
||||
|
||||
### Redis
|
||||
|
||||
- Cache géo natif (`GEORADIUS`) : 100K+ requêtes/sec
|
||||
- Sessions utilisateurs
|
||||
- Pub/sub pour temps réel
|
||||
@@ -81,11 +84,13 @@ LIMIT 20;
|
||||
### Configuration PgBouncer
|
||||
|
||||
**Mode recommandé** : `transaction`
|
||||
|
||||
- Connexion libérée après chaque transaction
|
||||
- Optimal pour API stateless (Go + Fiber)
|
||||
- Maximise la réutilisation des connexions
|
||||
|
||||
**Pool sizing** :
|
||||
|
||||
- `default_pool_size` : 20 (connexions par base)
|
||||
- `max_client_conn` : 1000 (connexions clients max)
|
||||
- `reserve_pool_size` : 5 (connexions de secours)
|
||||
|
||||
@@ -67,11 +67,13 @@ features/
|
||||
**Exécuté par** : Backend (Godog + step definitions Go dans `/backend/tests/bdd/`)
|
||||
|
||||
**Exemples de scénarios** :
|
||||
|
||||
- `POST /api/v1/auth/register` avec email invalide → retourne 400
|
||||
- `GET /api/v1/contents/nearby` avec rayon 500m → retourne POI triés par distance
|
||||
- `DELETE /api/v1/user/account` → supprime données RGPD conformément
|
||||
|
||||
**Caractéristiques** :
|
||||
|
||||
- Focus sur la **logique métier backend** (algorithme, validation, persistance)
|
||||
- Pas d'interface utilisateur
|
||||
- Testable via requêtes HTTP directes
|
||||
@@ -85,11 +87,13 @@ features/
|
||||
**Exécuté par** : Mobile (Flutter `integration_test` + step definitions Dart dans `/mobile/tests/bdd/`)
|
||||
|
||||
**Exemples de scénarios** :
|
||||
|
||||
- Cliquer sur "Lecture" → widget audio player s'affiche avec progress bar
|
||||
- Mode piéton activé → carte interactive affichée + bouton "Télécharger zone"
|
||||
- Scroll dans liste podcasts → lazy loading déclenche pagination
|
||||
|
||||
**Caractéristiques** :
|
||||
|
||||
- Focus sur l'**expérience utilisateur mobile**
|
||||
- Validation visuelle (widgets, animations, navigation)
|
||||
- Mock du backend si nécessaire (tests UI isolés)
|
||||
@@ -103,11 +107,13 @@ features/
|
||||
**Exécuté par** : Backend **ET** Mobile ensemble
|
||||
|
||||
**Exemples de scénarios** :
|
||||
|
||||
- Abonnement Premium : Formulaire mobile → API Zitadel → API RoadWave → Mangopay → Confirmation UI
|
||||
- Erreur réseau : Perte connexion pendant streaming → Fallback mode offline → Reprise auto après reconnexion
|
||||
- Notification géolocalisée : GPS détecte POI → Backend calcule recommandation → Push notification → Ouverture app → Lecture audio
|
||||
|
||||
**Caractéristiques** :
|
||||
|
||||
- Tests **cross-composants** (intégration complète)
|
||||
- Implique souvent des **services tiers** (Zitadel, Mangopay, Firebase)
|
||||
- Validation du **parcours utilisateur de bout en bout**
|
||||
@@ -117,10 +123,12 @@ features/
|
||||
### Implémentation Step Definitions
|
||||
|
||||
**Backend** : `/backend/tests/bdd/`
|
||||
|
||||
- Step definitions Go pour features `api/` et `e2e/`
|
||||
- Utilise `godog` et packages backend (`service`, `repository`)
|
||||
|
||||
**Mobile** : `/mobile/tests/bdd/`
|
||||
|
||||
- Step definitions Dart pour features `ui/` et `e2e/`
|
||||
- Utilise Flutter `integration_test` framework
|
||||
|
||||
|
||||
@@ -14,11 +14,13 @@ RoadWave nécessite un système d'authentification sécurisé pour mobile (iOS/A
|
||||
**Zitadel self-hosted sur OVH France** pour l'IAM avec validation JWT locale côté API Go.
|
||||
|
||||
**Méthode d'authentification** : **Email/Password uniquement** (pas d'OAuth tiers)
|
||||
|
||||
- ✅ Authentification native Zitadel (email + mot de passe)
|
||||
- ❌ **Pas de fournisseurs OAuth externes** (Google, Apple, Facebook)
|
||||
- **Protocole** : OAuth2 PKCE (entre app mobile et Zitadel uniquement)
|
||||
|
||||
**Architecture de déploiement** :
|
||||
|
||||
- Container Docker sur le même VPS OVH (Gravelines, France) que l'API
|
||||
- Base de données PostgreSQL partagée avec RoadWave (séparation logique par schéma)
|
||||
- Aucune donnée d'authentification ne transite par des serveurs tiers
|
||||
@@ -102,12 +104,14 @@ graph TB
|
||||
4. App mobile → Go API avec JWT → validation locale
|
||||
|
||||
**Ce que nous N'UTILISONS PAS** :
|
||||
|
||||
- ❌ "Sign in with Google"
|
||||
- ❌ "Sign in with Apple"
|
||||
- ❌ "Sign in with Facebook"
|
||||
- ❌ Aucun autre fournisseur externe
|
||||
|
||||
**Pourquoi OAuth2 alors ?** :
|
||||
|
||||
- OAuth2 PKCE est le **standard moderne** pour auth mobile (sécurisé, refresh tokens, etc.)
|
||||
- Zitadel implémente OAuth2/OIDC comme **protocole**, mais l'auth reste email/password
|
||||
- Alternative serait session cookies (moins adapté mobile) ou JWT custom (réinventer la roue)
|
||||
|
||||
@@ -45,6 +45,7 @@ RoadWave nécessite applications iOS et Android avec support CarPlay/Android Aut
|
||||
- **Cache images** : `cached_network_image` (LRU cache)
|
||||
|
||||
**Points d'attention** :
|
||||
|
||||
- ⚠️ **Permissions progressives requises** pour `geofence_service` et `geolocator` (voir section "Stratégie de Permissions")
|
||||
- ⚠️ **Licences** : 100% permissives (MIT, BSD-3) - voir ADR-020
|
||||
|
||||
@@ -53,6 +54,7 @@ RoadWave nécessite applications iOS et Android avec support CarPlay/Android Aut
|
||||
### Contexte et Enjeux
|
||||
|
||||
**Problème** : La géolocalisation en arrière-plan (requise pour le mode piéton) est **très scrutée** par Apple et Google :
|
||||
|
||||
- **iOS App Store** : Taux de rejet ~70% si permission "Always Location" mal justifiée
|
||||
- **Android Play Store** : `ACCESS_BACKGROUND_LOCATION` nécessite déclaration spéciale depuis Android 10
|
||||
- **RGPD** : Permissions doivent être **optionnelles** et l'app **utilisable sans**
|
||||
@@ -74,6 +76,7 @@ Trois niveaux de permissions doivent être gérés :
|
||||
**Quand** : Premier lancement de l'app
|
||||
|
||||
**Demande** : `locationWhenInUse` uniquement
|
||||
|
||||
- iOS : "Allow While Using App"
|
||||
- Android : `ACCESS_FINE_LOCATION`
|
||||
|
||||
@@ -136,21 +139,25 @@ Pour vous proposer du contenu audio adapté
|
||||
Le service de gestion des permissions (`lib/core/services/location_permission_service.dart`) doit implémenter :
|
||||
|
||||
**Détection du niveau actuel** :
|
||||
|
||||
- Vérifier le statut de la permission `location` (when in use)
|
||||
- Vérifier le statut de la permission `locationAlways` (background)
|
||||
- Retourner le niveau le plus élevé accordé
|
||||
|
||||
**Demande de permission de base** (Étape 1) :
|
||||
|
||||
- Demander uniquement la permission `location` (when in use)
|
||||
- Utilisée lors de l'onboarding
|
||||
- Aucun écran d'éducation requis
|
||||
|
||||
**Demande de permission arrière-plan** (Étape 2) :
|
||||
|
||||
- **Toujours** afficher un écran d'éducation AVANT la demande OS
|
||||
- Demander la permission `locationAlways` (iOS) ou `ACCESS_BACKGROUND_LOCATION` (Android)
|
||||
- Si refusée de manière permanente, proposer l'ouverture des réglages système
|
||||
|
||||
**Gestion des refus** :
|
||||
|
||||
- Détecter si la permission est refusée de manière permanente
|
||||
- Proposer l'ouverture des réglages de l'appareil avec un message clair
|
||||
- Permettre à l'utilisateur d'annuler
|
||||
@@ -160,6 +167,7 @@ Le service de gestion des permissions (`lib/core/services/location_permission_se
|
||||
#### iOS (`ios/Runner/Info.plist`)
|
||||
|
||||
**Clés requises** :
|
||||
|
||||
- `NSLocationWhenInUseUsageDescription` : Décrire l'usage pour le mode voiture (contenu géolocalisé en temps réel)
|
||||
- `NSLocationAlwaysAndWhenInUseUsageDescription` : Décrire l'usage optionnel pour le mode piéton (notifications audio-guides en arrière-plan), mentionner explicitement que c'est optionnel et désactivable
|
||||
- `UIBackgroundModes` : Activer les modes `location` et `remote-notification`
|
||||
@@ -170,11 +178,13 @@ Le service de gestion des permissions (`lib/core/services/location_permission_se
|
||||
#### Android (`android/app/src/main/AndroidManifest.xml`)
|
||||
|
||||
**Permissions requises** :
|
||||
|
||||
- `ACCESS_FINE_LOCATION` et `ACCESS_COARSE_LOCATION` : Permission de base (when in use)
|
||||
- `ACCESS_BACKGROUND_LOCATION` : Permission arrière-plan (Android 10+), nécessite justification Play Store
|
||||
- `FOREGROUND_SERVICE` et `FOREGROUND_SERVICE_LOCATION` : Service persistant pour mode piéton (Android 12+)
|
||||
|
||||
**Android Play Store** : Déclaration requise dans Play Console lors de la soumission :
|
||||
|
||||
- Justification : "Notifications géolocalisées pour audio-guides touristiques en arrière-plan"
|
||||
- Vidéo démo obligatoire montrant le flow de demande de permission
|
||||
|
||||
@@ -191,12 +201,14 @@ Le service de gestion des permissions (`lib/core/services/location_permission_se
|
||||
### Tests de Validation Stores
|
||||
|
||||
**Checklist App Store (iOS)** :
|
||||
|
||||
- [ ] Permission "Always" demandée **uniquement** si user active mode piéton
|
||||
- [ ] Écran d'éducation **avant** demande OS (requis iOS 13+)
|
||||
- [ ] App fonctionne sans permission "Always" (validation critique)
|
||||
- [ ] Texte `Info.plist` clair et honnête (pas de tracking publicitaire)
|
||||
|
||||
**Checklist Play Store (Android)** :
|
||||
|
||||
- [ ] Déclaration `ACCESS_BACKGROUND_LOCATION` avec justification détaillée
|
||||
- [ ] Vidéo démo flow de permissions (< 30s, requis Play Console)
|
||||
- [ ] App fonctionne sans permission background (validation critique)
|
||||
|
||||
@@ -79,6 +79,7 @@ Approche **multi-niveaux** : unitaires, intégration, BDD (Gherkin), E2E, load t
|
||||
- `github.com/cucumber/godog`
|
||||
- `github.com/testcontainers/testcontainers-go`
|
||||
- `grafana/k6` (AGPL-3.0, usage interne OK)
|
||||
|
||||
- Temps CI : ~3-5 min (tests unitaires + BDD)
|
||||
- Tests intégration/E2E : nightly builds (15-30 min)
|
||||
- Load tests : avant chaque release majeure
|
||||
|
||||
@@ -68,6 +68,7 @@ mobile/tests/bdd/inscription_steps.dart → Teste l'UI mobile
|
||||
```
|
||||
|
||||
Cela garantit que :
|
||||
|
||||
- Les spécifications métier sont uniques et cohérentes
|
||||
- Chaque couche teste sa responsabilité
|
||||
- Les tests valident le contrat entre front et back
|
||||
|
||||
@@ -52,6 +52,7 @@ OVH Object Storage (~1.20€/100GB)
|
||||
| **Scale** | 100K+ | Scaleway Kubernetes (Kapsule) | ~500€ | Auto-scaling OU multi-région |
|
||||
|
||||
**Triggers détaillés** :
|
||||
|
||||
- **Phase 2** : CPU > 70% (7j), latence p99 > 100ms, backups > 1h/semaine, MRR > 2000€
|
||||
- **Phase 3** : Auto-scaling horizontal requis, multi-région Europe, DevOps dédié, > 5 services
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
RoadWave nécessite un service d'envoi d'emails **techniques uniquement** (pas de notifications sociales, alertes marketing, promotions).
|
||||
|
||||
**Périmètre strict** :
|
||||
|
||||
- ✅ **Authentification** : Vérification email (inscription), réinitialisation mot de passe, changement email
|
||||
- ✅ **Sécurité** : Alertes connexion inhabituelle, changement password
|
||||
- ✅ **Modération** : Strikes, suspensions, bannissements
|
||||
|
||||
@@ -45,6 +45,7 @@ Architecture hybride en **2 phases** :
|
||||
5. Utilisateur clique → app s'ouvre → HLS démarre l'audio (ADR-002)
|
||||
|
||||
**Limitations MVP** :
|
||||
|
||||
- Fonctionne uniquement si l'utilisateur a envoyé sa position < 5 minutes
|
||||
- En voiture rapide (>80 km/h), possible de "manquer" un POI si position pas mise à jour
|
||||
|
||||
@@ -96,10 +97,12 @@ Architecture hybride en **2 phases** :
|
||||
### Pourquoi implémentation directe APNS/FCM et pas SDK Firebase ?
|
||||
|
||||
**Réalité technique** : Notifications natives requièrent obligatoirement Google/Apple
|
||||
|
||||
- **APNS (Apple)** : Seul protocole pour notifications iOS → dépendance Apple inévitable
|
||||
- **FCM (Google)** : Protocole standard Android (Google Play Services)
|
||||
|
||||
**Implémentation directe choisie** :
|
||||
|
||||
- **Gratuit** : APNS et FCM sont gratuits (pas de limite de volume)
|
||||
- **Self-hosted** : Code backend 100% maîtrisé, pas de dépendance SDK tiers
|
||||
- **Fiabilité** : Infrastructure Apple/Google avec 99.95% uptime
|
||||
@@ -123,6 +126,7 @@ Architecture hybride en **2 phases** :
|
||||
- ❌ Toujours wrapper autour APNS/FCM
|
||||
|
||||
**Décision technique** :
|
||||
|
||||
- Implémentation directe APNS/FCM dès le MVP
|
||||
- **Cohérence ADR** : Respecte ADR-008 (self-hosted) et ADR-015 (souveraineté française)
|
||||
- **Abstraction layer** : Interface `NotificationProvider` pour faciliter maintenance
|
||||
@@ -150,9 +154,11 @@ Architecture hybride en **2 phases** :
|
||||
- ⚠️ **Gestion certificats APNS** : Renouvellement annuel + configuration
|
||||
- Mitigé par scripts automation (certificats auto-renouvelés)
|
||||
- Documentation complète du processus
|
||||
|
||||
- ⚠️ **Tokens push sensibles** : Tokens FCM/APNS stockés côté backend
|
||||
- Chiffrement tokens en base (conformité RGPD)
|
||||
- Rotation automatique des tokens expirés
|
||||
|
||||
- ❌ WebSocket nécessite maintien de connexion (charge serveur +10-20%)
|
||||
- ❌ Mode offline non disponible au MVP (déception possible des early adopters)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
## Contexte
|
||||
|
||||
Le backend Go de RoadWave nécessite des librairies tierces pour HTTP, base de données, tests, streaming, etc. Le choix doit privilégier :
|
||||
|
||||
- **Licences permissives** (MIT, Apache-2.0, BSD) sans restrictions commerciales
|
||||
- **Performance** (10M utilisateurs, 100K RPS, p99 < 100ms)
|
||||
- **Maturité** et maintenance active
|
||||
@@ -55,6 +56,7 @@ Utilisation de **16 librairies open-source** avec licences permissives.
|
||||
## Alternatives considérées
|
||||
|
||||
Voir pour comparatifs complets :
|
||||
|
||||
- Framework : Fiber vs Gin vs Echo vs Chi
|
||||
- PostgreSQL : pgx vs GORM vs database/sql
|
||||
- Redis : rueidis vs go-redis vs redigo
|
||||
@@ -64,17 +66,20 @@ Voir pour comparatifs complets :
|
||||
## Justification
|
||||
|
||||
### Licences
|
||||
|
||||
- **15/16 librairies** : MIT, Apache-2.0, BSD, ISC (permissives)
|
||||
- **1/16** : AGPL-3.0 (k6 load testing, OK usage interne)
|
||||
- **Compatibilité totale** : Aucun conflit de licence
|
||||
|
||||
### Performance
|
||||
|
||||
- **Fiber** : 36K RPS (5% plus rapide que Gin/Echo)
|
||||
- **pgx** : 30-50% plus rapide que GORM
|
||||
- **rueidis** : Client-side caching automatique
|
||||
- **zerolog** : Zero allocation, benchmarks 2025
|
||||
|
||||
### Maturité
|
||||
|
||||
- **Standards** : testify (27% adoption), golang-migrate, viper
|
||||
- **Production** : Fiber (33K stars), pgx (10K stars), pion (13K stars)
|
||||
- **Maintenance** : Toutes actives (commits 2025-2026)
|
||||
@@ -82,12 +87,14 @@ Voir pour comparatifs complets :
|
||||
## Conséquences
|
||||
|
||||
### Positives
|
||||
|
||||
- ✅ Aucune restriction licence commerciale
|
||||
- ✅ Stack cohérent avec ADR existants (001, 002, 007, 008, 013, 015, 019)
|
||||
- ✅ Performance validée (benchmarks publics)
|
||||
- ✅ Écosystème mature et documenté
|
||||
|
||||
### Négatives
|
||||
|
||||
- ⚠️ **k6 (AGPL-3.0)** : Copyleft, mais OK pour tests internes (pas de SaaS k6 prévu)
|
||||
- ⚠️ **Gestion certificats APNS** : Renouvellement annuel, configuration manuelle
|
||||
- ❌ Courbe d'apprentissage : 16 librairies à maîtriser (doc nécessaire)
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
RoadWave nécessite un service de géolocalisation par IP pour le mode dégradé (utilisateurs sans GPS activé). Ce service permet de détecter la ville/région de l'utilisateur à partir de son adresse IP et d'afficher du contenu régional même sans permission GPS.
|
||||
|
||||
**Évolution du marché** :
|
||||
|
||||
- **Avant 2019** : MaxMind GeoLite2 était téléchargeable gratuitement (base de données locale)
|
||||
- **Depuis 2019** : MaxMind nécessite un compte + limite 1000 requêtes/jour (gratuit), puis 0.003$/requête au-delà
|
||||
|
||||
**Usage RoadWave** :
|
||||
|
||||
- Mode dégradé : ~10% des utilisateurs (estimation)
|
||||
- Volume : 1000 utilisateurs × 10% = 100 requêtes/jour (MVP)
|
||||
- Critère : Aucune dépendance à un service tiers payant
|
||||
@@ -33,6 +35,7 @@ RoadWave nécessite un service de géolocalisation par IP pour le mode dégradé
|
||||
### IP2Location Lite (choix retenu)
|
||||
|
||||
**Avantages** :
|
||||
|
||||
- Gratuit (pas de limite de requêtes)
|
||||
- Self-hosted (souveraineté des données, cohérence avec [ADR-004](004-cdn.md))
|
||||
- Base de données SQLite légère (50-100 MB)
|
||||
@@ -41,12 +44,14 @@ RoadWave nécessite un service de géolocalisation par IP pour le mode dégradé
|
||||
- Pas de compte tiers requis
|
||||
|
||||
**Inconvénients** :
|
||||
|
||||
- Maintenance mensuelle (mise à jour DB)
|
||||
- Précision équivalente à MaxMind (~±50 km)
|
||||
|
||||
### MaxMind GeoLite2 API (rejeté)
|
||||
|
||||
**Pourquoi rejeté** :
|
||||
|
||||
- Coût potentiel en cas de dépassement quota (risque faible mais existant)
|
||||
- Dépendance à un service tiers (perte de souveraineté)
|
||||
- Compte requis (friction opérationnelle)
|
||||
@@ -54,6 +59,7 @@ RoadWave nécessite un service de géolocalisation par IP pour le mode dégradé
|
||||
### Self-hosted MaxMind (rejeté)
|
||||
|
||||
**Pourquoi rejeté** :
|
||||
|
||||
- Compte MaxMind obligatoire pour télécharger la DB (friction)
|
||||
- Complexité identique à IP2Location pour résultat équivalent
|
||||
- IP2Location offre même fonctionnalité sans compte tiers
|
||||
@@ -84,28 +90,33 @@ flowchart TD
|
||||
### Maintenance
|
||||
|
||||
**Mise à jour mensuelle** :
|
||||
|
||||
- Cron job télécharge nouvelle DB IP2Location (1er du mois)
|
||||
- Backup DB actuelle avant remplacement
|
||||
- Rechargement service GeoIP (hot reload sans downtime)
|
||||
|
||||
**Monitoring** :
|
||||
|
||||
- Alertes si DB > 60 jours (DB obsolète)
|
||||
- Logs requêtes "IP non trouvée" (détection problèmes DB)
|
||||
|
||||
## Conséquences
|
||||
|
||||
### Positives
|
||||
|
||||
- Aucun coût récurrent (gratuit à l'infini)
|
||||
- Souveraineté complète des données (cohérence ADR-004)
|
||||
- Pas de dépendance externe (service tiers)
|
||||
- Latence minimale (lookup local SQLite < 1ms)
|
||||
|
||||
### Négatives
|
||||
|
||||
- Maintenance mensuelle requise (automatisable)
|
||||
- Précision limitée (±50 km, acceptable pour mode dégradé)
|
||||
- Taille base de données (~50-100 MB sur disque)
|
||||
|
||||
### Risques atténués
|
||||
|
||||
- **DB obsolète** : Alertes automatiques si > 60 jours
|
||||
- **IP non trouvée** : Fallback "France" par défaut (code pays FR)
|
||||
- **Perte DB** : Backup automatique avant chaque mise à jour
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
## 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)
|
||||
@@ -53,28 +54,33 @@ Utilisation de **9 librairies open-source** Flutter avec licences permissives, d
|
||||
## 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
|
||||
@@ -82,17 +88,20 @@ Utilisation de **9 librairies open-source** Flutter avec licences permissives, d
|
||||
## 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)
|
||||
@@ -100,6 +109,7 @@ Utilisation de **9 librairies open-source** Flutter avec licences permissives, d
|
||||
- **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%)
|
||||
@@ -171,6 +181,7 @@ graph TB
|
||||
## Conséquences
|
||||
|
||||
### Positives
|
||||
|
||||
- ✅ Aucune restriction licence commerciale (100% permissif)
|
||||
- ✅ Stack cohérent avec ADR-010 (Frontend Mobile)
|
||||
- ✅ Performance native (compilation ARM64 directe)
|
||||
@@ -179,6 +190,7 @@ graph TB
|
||||
- ✅ 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)
|
||||
@@ -190,6 +202,7 @@ graph TB
|
||||
> **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
|
||||
@@ -197,6 +210,7 @@ graph TB
|
||||
- `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)
|
||||
@@ -204,10 +218,12 @@ graph TB
|
||||
- `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
|
||||
@@ -219,15 +235,18 @@ La section "Packages clés" de l'ADR-010 est désormais obsolète et doit réfé
|
||||
## 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`)
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ L'application nécessite un système de cache performant pour plusieurs cas d'us
|
||||
- **Rate limiting** : Protection contre les abus API
|
||||
|
||||
Les contraintes de performance sont strictes :
|
||||
|
||||
- Latence p99 < 5ms pour les requêtes de cache
|
||||
- Support de 100K+ requêtes/seconde en lecture
|
||||
- Persistance optionnelle (données non critiques)
|
||||
@@ -24,6 +25,7 @@ Les contraintes de performance sont strictes :
|
||||
**Redis 7+ en mode Cluster** sera utilisé comme solution de cache principale.
|
||||
|
||||
Configuration :
|
||||
|
||||
- Mode Cluster avec 3 nœuds minimum (haute disponibilité)
|
||||
- Persistence RDB désactivée pour les caches chauds (performance maximale)
|
||||
- AOF activé uniquement pour les sessions utilisateurs (durabilité)
|
||||
@@ -76,6 +78,7 @@ Ces commandes permettent de servir les requêtes de proximité directement depui
|
||||
### Écosystème Go
|
||||
|
||||
Librairie `go-redis/redis` (13K+ stars GitHub) :
|
||||
|
||||
- Support complet Redis Cluster
|
||||
- Pipeline et transactions
|
||||
- Context-aware (intégration Go idiomatique)
|
||||
@@ -84,6 +87,7 @@ Librairie `go-redis/redis` (13K+ stars GitHub) :
|
||||
### Pub/Sub pour temps réel
|
||||
|
||||
Support natif de messaging publish/subscribe pour :
|
||||
|
||||
- Notifications push (invalidation de cache)
|
||||
- Événements temps réel (nouveau contenu géolocalisé)
|
||||
- Coordination entre instances API (scaling horizontal)
|
||||
@@ -106,12 +110,14 @@ Support natif de messaging publish/subscribe pour :
|
||||
### Stratégie de cache
|
||||
|
||||
**TTL par type de donnée** :
|
||||
|
||||
- Métadonnées de contenu : 15 minutes (mise à jour rare)
|
||||
- Résultats géolocalisés : 5 minutes (contenus statiques géographiquement)
|
||||
- Sessions utilisateurs : 24 heures (renouvellement automatique)
|
||||
- Rate limiting : 1 minute (fenêtre glissante)
|
||||
|
||||
**Invalidation** :
|
||||
|
||||
- Publication de contenu → `DEL` métadonnées + publication Pub/Sub
|
||||
- Modification géolocalisation → `GEOREM` puis `GEOADD`
|
||||
- Logout utilisateur → `DEL` session
|
||||
@@ -119,21 +125,25 @@ Support natif de messaging publish/subscribe pour :
|
||||
### Configuration production
|
||||
|
||||
**Cluster 3 nœuds** (minimum haute disponibilité) :
|
||||
|
||||
- 1 master + 2 replicas
|
||||
- Répartition sur 3 zones de disponibilité (anti-affinité)
|
||||
- `cluster-require-full-coverage no` → lecture dégradée si nœud down
|
||||
|
||||
**Mémoire** :
|
||||
|
||||
- `maxmemory 2gb` par nœud (ajustable selon charge)
|
||||
- `maxmemory-policy allkeys-lru` → éviction automatique anciennes clés
|
||||
|
||||
**Persistance** :
|
||||
|
||||
- RDB désactivé (`save ""`) pour caches chauds
|
||||
- AOF `appendonly yes` uniquement pour sessions (nœud dédié optionnel)
|
||||
|
||||
### Monitoring
|
||||
|
||||
Métriques critiques à suivre :
|
||||
|
||||
- Taux de hit/miss par namespace (target >95% hit rate)
|
||||
- Latence p99 par commande (alerter si >10ms)
|
||||
- Fragmentation mémoire (rebalance si >1.5)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documentation et features BDD ([ADR-014](014-organisation-monorepo.md)). Sans optimisation, chaque commit déclencherait **tous** les builds (backend + mobile + docs), même si seul un composant a changé.
|
||||
|
||||
**Problématique** :
|
||||
|
||||
- ❌ Temps de CI/CD inutilement longs (rebuild complet ~15 min)
|
||||
- ❌ Gaspillage de ressources GitHub Actions
|
||||
- ❌ Ralentissement du feedback développeur
|
||||
@@ -44,6 +45,7 @@ RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documen
|
||||
#### Workflow Backend (`backend.yml`)
|
||||
|
||||
**Déclencheurs** :
|
||||
|
||||
- Branches : `main`, `develop`
|
||||
- Chemins surveillés :
|
||||
- `backend/**` : Code Go, migrations, configuration
|
||||
@@ -52,6 +54,7 @@ RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documen
|
||||
- `.github/workflows/backend.yml` : Modifications du workflow lui-même
|
||||
|
||||
**Jobs exécutés** :
|
||||
|
||||
- **Tests unitaires** : Exécution `go test` sur tous les packages
|
||||
- **Tests d'intégration** : Utilisation de Testcontainers avec PostgreSQL/PostGIS
|
||||
- **Tests BDD** : Exécution Godog sur features `api/` et `e2e/`
|
||||
@@ -65,6 +68,7 @@ RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documen
|
||||
#### Workflow Mobile (`mobile.yml`)
|
||||
|
||||
**Déclencheurs** :
|
||||
|
||||
- Branches : `main`, `develop`
|
||||
- Chemins surveillés :
|
||||
- `mobile/**` : Code Flutter/Dart, assets, configuration
|
||||
@@ -73,6 +77,7 @@ RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documen
|
||||
- `.github/workflows/mobile.yml` : Modifications du workflow lui-même
|
||||
|
||||
**Jobs exécutés** :
|
||||
|
||||
- **Tests unitaires** : Exécution `flutter test` sur widgets et logique métier
|
||||
- **Tests d'intégration** : Tests d'intégration Flutter (interactions UI complexes)
|
||||
- **Lint** : Analyse statique `flutter analyze`
|
||||
@@ -80,6 +85,7 @@ RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documen
|
||||
- **Build iOS** : Compilation IPA release sans codesign (dépend des tests)
|
||||
|
||||
**Environnement** :
|
||||
|
||||
- Tests/Lint/Build Android : Ubuntu latest
|
||||
- Build iOS : macOS latest (requis pour Xcode)
|
||||
- Flutter 3.16.0+
|
||||
@@ -89,6 +95,7 @@ RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documen
|
||||
#### Workflow Shared (`shared.yml`)
|
||||
|
||||
**Déclencheurs** :
|
||||
|
||||
- Branches : `main`, `develop`
|
||||
- Chemins surveillés :
|
||||
- `docs/**` : ADR, règles métier, documentation technique
|
||||
@@ -96,6 +103,7 @@ RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documen
|
||||
- `.github/workflows/shared.yml` : Modifications du workflow lui-même
|
||||
|
||||
**Jobs exécutés** :
|
||||
|
||||
- **Validation documentation** : Build MkDocs en mode strict (détecte erreurs markdown)
|
||||
- **Vérification liens** : Validation des liens internes/externes dans documentation
|
||||
- **Tests code partagé** : Exécution tests si du code partagé backend-mobile existe
|
||||
@@ -117,6 +125,7 @@ RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documen
|
||||
| **Commit mixte (backend + mobile + docs)** | ✅ | ✅ | ✅ | ~13 min (parallèle) |
|
||||
|
||||
**Économie de temps** :
|
||||
|
||||
- Commit backend-only : ~5 min (vs 15 min sans path filters) = **67% plus rapide**
|
||||
- Commit docs-only : ~30s (vs 15 min) = **97% plus rapide**
|
||||
|
||||
@@ -125,6 +134,7 @@ RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documen
|
||||
Les tests end-to-end dans `/features/e2e/` **déclenchent les deux workflows** (backend ET mobile) car ils testent l'intégration complète :
|
||||
|
||||
**Exemples de features E2E** :
|
||||
|
||||
- `features/e2e/abonnements/` : Formulaire mobile → API Zitadel → API RoadWave → Mangopay → Confirmation UI
|
||||
- `features/e2e/error-handling/` : Perte réseau → Fallback mode offline → Reprise auto après reconnexion
|
||||
|
||||
@@ -159,6 +169,7 @@ Les tests end-to-end dans `/features/e2e/` **déclenchent les deux workflows** (
|
||||
❌ **Complexité initiale** : setup plus complexe que workflow monolithique
|
||||
|
||||
**Mitigation** :
|
||||
|
||||
- Utiliser des **composite actions** pour partager la config commune
|
||||
- Documentation claire dans ce ADR
|
||||
- Coût initial faible (~2h setup) vs gains à long terme importants
|
||||
@@ -177,15 +188,18 @@ Les tests end-to-end dans `/features/e2e/` **déclenchent les deux workflows** (
|
||||
### Plan d'Implémentation
|
||||
|
||||
**Phase 1** : Setup workflows de base (~1h)
|
||||
|
||||
- Créer `backend.yml` avec jobs test + lint + build
|
||||
- Créer `mobile.yml` avec jobs test + lint + build
|
||||
- Créer `shared.yml` avec validation docs
|
||||
|
||||
**Phase 2** : Configuration path filters (~30 min)
|
||||
|
||||
- Ajouter `paths:` à chaque workflow
|
||||
- Tester avec commits isolés (backend-only, mobile-only, docs-only)
|
||||
|
||||
**Phase 3** : Optimisations (~30 min)
|
||||
|
||||
- Ajouter caching (Go modules, Flutter dependencies, node_modules)
|
||||
- Créer composite actions pour config partagée
|
||||
- Ajouter badges status dans README
|
||||
@@ -226,6 +240,7 @@ Les tests end-to-end dans `/features/e2e/` **déclenchent les deux workflows** (
|
||||
⚠️ **Faux négatifs** : path filter mal configuré → test non exécuté → bug en production
|
||||
|
||||
**Mitigation** :
|
||||
|
||||
- Features E2E déclenchent toujours backend + mobile (safety net)
|
||||
- Tests de validation dans le plan d'implémentation
|
||||
- Review obligatoire des modifications de workflows
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
## Contexte
|
||||
|
||||
Le système de modération RoadWave doit traiter des signalements de contenu audio problématique (haine, spam, droits d'auteur, etc.) avec :
|
||||
|
||||
- **SLA stricts** : 2h (critique), 24h (haute), 72h (standard) définis dans [Règle 14](../domains/moderation/rules/moderation-flows.md)
|
||||
- **Scalabilité** : 0-10K+ signalements/mois
|
||||
- **Conformité DSA** : transparence, traçabilité, délais garantis
|
||||
@@ -165,12 +166,14 @@ graph TB
|
||||
### Dépendances
|
||||
|
||||
**Backend Go** :
|
||||
|
||||
- `gofiber/fiber/v3` : API Dashboard
|
||||
- `jackc/pgx/v5` : PostgreSQL + LISTEN/NOTIFY
|
||||
- `redis/rueidis` : Cache priorisation
|
||||
- Whisper : via Python subprocess ou go-whisper bindings
|
||||
|
||||
**Frontend Dashboard** :
|
||||
|
||||
- `react` : Framework UI
|
||||
- `@tanstack/react-table` : Tables performantes
|
||||
- `wavesurfer.js` : Player audio avec waveform
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
## Contexte
|
||||
|
||||
RoadWave nécessite un système de monitoring pour garantir la disponibilité cible 99.9% (SLO) définie dans :
|
||||
|
||||
- **Métriques** : latency p99 < 100ms, throughput API, erreurs
|
||||
- **Alerting** : détection pannes, dégradations performance
|
||||
- **Incident response** : runbooks, escalation, post-mortems
|
||||
@@ -93,16 +94,19 @@ graph TB
|
||||
### Métriques Clés
|
||||
|
||||
**API Performance** (requêtes PromQL) :
|
||||
|
||||
- Latency p99 : histogramme quantile 99e percentile sur durée requêtes HTTP (fenêtre 5 min)
|
||||
- Error rate : ratio requêtes 5xx / total requêtes (fenêtre 5 min)
|
||||
- Throughput : taux de requêtes par seconde (fenêtre 5 min)
|
||||
|
||||
**Infrastructure** :
|
||||
|
||||
- CPU usage : taux utilisation CPU (mode non-idle, fenêtre 5 min)
|
||||
- Memory usage : ratio mémoire disponible / totale
|
||||
- Disk I/O : temps I/O disque (fenêtre 5 min)
|
||||
|
||||
**Business** (compteurs custom) :
|
||||
|
||||
- Active users (DAU) : `roadwave_active_users_total`
|
||||
- Audio streams actifs : `roadwave_hls_streams_active`
|
||||
- Signalements modération : `roadwave_moderation_reports_total`
|
||||
@@ -182,6 +186,7 @@ graph TB
|
||||
### Dashboards Grafana
|
||||
|
||||
**Dashboard principal** :
|
||||
|
||||
- Latency p50/p95/p99 API (5 min, 1h, 24h)
|
||||
- Error rate 5xx/4xx (seuil alerte >1%)
|
||||
- Throughput requests/sec
|
||||
@@ -189,12 +194,14 @@ graph TB
|
||||
- Business : DAU, streams actifs, signalements modération
|
||||
|
||||
**Dashboard PostgreSQL** :
|
||||
|
||||
- Slow queries (>100ms)
|
||||
- Connections actives vs max
|
||||
- Cache hit ratio (cible >95%)
|
||||
- Deadlocks count
|
||||
|
||||
**Dashboard Redis** :
|
||||
|
||||
- Memory usage
|
||||
- Evictions count
|
||||
- Commands/sec
|
||||
@@ -203,27 +210,32 @@ graph TB
|
||||
### Alerting Rules
|
||||
|
||||
**Alertes critiques** (Telegram + Email immédiat) :
|
||||
|
||||
- **API Down** : Job API indisponible pendant >1 min → Notification immédiate
|
||||
- **High Error Rate** : Taux erreurs 5xx >1% pendant >5 min → Notification immédiate
|
||||
- **Database Down** : PostgreSQL indisponible pendant >1 min → Notification immédiate
|
||||
|
||||
**Alertes warnings** (Email uniquement) :
|
||||
|
||||
- **High Latency** : Latency p99 >100ms pendant >10 min → Investigation requise
|
||||
- **Disk Space Running Out** : Espace disque <10% pendant >30 min → Nettoyage requis
|
||||
|
||||
### Backup & Disaster Recovery
|
||||
|
||||
**PostgreSQL WAL-E** :
|
||||
|
||||
- Méthode : Backup continu Write-Ahead Log (WAL)
|
||||
- Rétention : 7 jours full + WAL incrémentaux
|
||||
- Stockage : S3 OVH région GRA (France)
|
||||
- Chiffrement : AES-256 server-side
|
||||
|
||||
**RTO (Recovery Time Objective)** : 1h
|
||||
|
||||
- Restore depuis S3 : ~30 min (DB 10 GB)
|
||||
- Validation + relance services : ~30 min
|
||||
|
||||
**RPO (Recovery Point Objective)** : 15 min
|
||||
|
||||
- Fréquence archivage WAL : toutes les 15 min
|
||||
- Perte maximale : 15 min de transactions
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
## Contexte
|
||||
|
||||
RoadWave manipule des données sensibles nécessitant une protection renforcée :
|
||||
|
||||
- **Secrets applicatifs** : JWT signing key, DB credentials, Mangopay API keys
|
||||
- **PII utilisateurs** : Positions GPS précises, emails, données bancaires (via Mangopay)
|
||||
- **Conformité** : RGPD (minimisation données, encryption at rest), PCI-DSS (paiements)
|
||||
@@ -88,11 +89,13 @@ graph TB
|
||||
3. Login root + activation KV-v2 engine (path : `roadwave/`)
|
||||
|
||||
**Secrets stockés** :
|
||||
|
||||
- **JWT signing key** : Paire RS256 privée/publique
|
||||
- **Database credentials** : Host, port, user, password (généré aléatoire 32 caractères)
|
||||
- **Mangopay API** : Client ID, API key, webhook secret
|
||||
|
||||
**Récupération depuis Backend Go** :
|
||||
|
||||
- Utilisation SDK `hashicorp/vault/api`
|
||||
- Authentification via token Vault (variable env VAULT_TOKEN)
|
||||
- Récupération secrets via KVv2 engine
|
||||
@@ -100,28 +103,33 @@ graph TB
|
||||
### Encryption PII (Field-level)
|
||||
|
||||
**Données chiffrées** (AES-256-GCM) :
|
||||
|
||||
- **GPS précis** : lat/lon conservés 24h puis réduits à geohash-5 (~5km²) ([Règle 02](../domains/_shared/rules/rgpd.md))
|
||||
- **Email** : chiffré en base, déchiffré uniquement à l'envoi
|
||||
- **Numéro téléphone** : si ajouté (Phase 2)
|
||||
|
||||
**Architecture encryption** :
|
||||
|
||||
- Utilisation bibliothèque standard Go `crypto/aes` avec mode GCM (AEAD)
|
||||
- Master key 256 bits (32 bytes) récupérée depuis Vault
|
||||
- Chiffrement : génération nonce aléatoire + seal GCM → encodage base64
|
||||
- Stockage : colonne `email_encrypted` en base PostgreSQL
|
||||
|
||||
**Contraintes** :
|
||||
|
||||
- Index direct sur champ chiffré impossible
|
||||
- Solution : index sur hash SHA-256 de l'email chiffré pour recherche
|
||||
|
||||
### HTTPS/TLS Configuration
|
||||
|
||||
**Let's Encrypt wildcard certificate** :
|
||||
|
||||
- Méthode : Certbot avec DNS-01 challenge (API OVH)
|
||||
- Domaines couverts : `roadwave.fr` + `*.roadwave.fr` (wildcard)
|
||||
- Renouvellement : automatique via cron quotidien (30j avant expiration)
|
||||
|
||||
**Nginx TLS configuration** :
|
||||
|
||||
- Protocol : TLS 1.3 uniquement (pas de TLS 1.2 ou inférieur)
|
||||
- Ciphers : TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384
|
||||
- HSTS : max-age 1 an, includeSubDomains
|
||||
@@ -214,12 +222,14 @@ graph TB
|
||||
### Rate Limiting (Protection DDoS/Brute-force)
|
||||
|
||||
**Configuration** :
|
||||
|
||||
- Middleware Fiber `limiter` avec backend Redis
|
||||
- Limite : 100 requêtes par minute par IP (global)
|
||||
- Clé de limitation : adresse IP client
|
||||
- Réponse limitation : HTTP 429 "Too many requests"
|
||||
|
||||
**Rate limits par endpoint** :
|
||||
|
||||
- `/auth/login` : 5 req/min/IP (protection brute-force)
|
||||
- `/moderation/report` : 10 req/24h/user (anti-spam)
|
||||
- API générale : 100 req/min/IP
|
||||
@@ -236,6 +246,7 @@ graph TB
|
||||
| **Encryption master key** | Jamais (re-encryption massive) | Backup sécurisé uniquement |
|
||||
|
||||
**Process rotation DB credentials** :
|
||||
|
||||
- Vault génère automatiquement nouveau password
|
||||
- Vault met à jour PostgreSQL avec nouveau password
|
||||
- Application récupère nouveau password au prochain accès Vault
|
||||
|
||||
@@ -103,10 +103,12 @@ Quelles autres options ont été évaluées ?
|
||||
## Conséquences
|
||||
|
||||
### Positives
|
||||
|
||||
- Avantage 1
|
||||
- Avantage 2
|
||||
|
||||
### Négatives
|
||||
|
||||
- Limitation 1
|
||||
- Compromis accepté
|
||||
|
||||
|
||||
Reference in New Issue
Block a user