# RoadWave - Architecture Technique > Les décisions techniques sont documentées dans [adr/](adr/) ## Stack Technologique | Composant | Technologie | ADR | |-----------|-------------|-----| | **Backend** | Go + Fiber | [ADR-001](adr/001-langage-backend.md) | | **Architecture Backend** | Monolithe Modulaire | [ADR-010](adr/010-architecture-backend.md) | | **Authentification** | Zitadel (self-hosted OVH) | [ADR-008](adr/008-authentification.md) | | **Streaming** | HLS | [ADR-002](adr/002-protocole-streaming.md) | | **Codec** | Opus | [ADR-003](adr/003-codec-audio.md) | | **CDN** | NGINX Cache (OVH VPS) | [ADR-004](adr/004-cdn.md) | | **Storage** | OVH Object Storage | [ADR-004](adr/004-cdn.md) | | **Hébergement MVP** | OVH VPS Essential | [ADR-015](adr/015-hebergement.md) | | **Organisation** | Monorepo | [ADR-014](adr/014-organisation-monorepo.md) | | **Base de données** | PostgreSQL + PostGIS | [ADR-005](adr/005-base-de-donnees.md) | | **ORM/Accès données** | sqlc | [ADR-011](adr/011-orm-acces-donnees.md) | | **Cache** | Redis Cluster | [ADR-021](adr/021-solution-cache.md) | | **Chiffrement** | TLS 1.3 | [ADR-006](adr/006-chiffrement.md) | | **Live** | WebRTC | [ADR-002](adr/002-protocole-streaming.md) | | **Frontend Mobile** | Flutter | [ADR-012](adr/012-frontend-mobile.md) | | **Tests** | Testify + Godog (Gherkin) | [ADR-013](adr/013-strategie-tests.md), [ADR-007](adr/007-tests-bdd.md) | | **Paiements** | Mangopay | [ADR-009](adr/009-solution-paiement.md) | | **Emailing** | Brevo | [ADR-016](adr/016-service-emailing.md) | | **Géolocalisation IP** | IP2Location (fallback) | [ADR-019](adr/019-geolocalisation-ip.md) | | **Librairies Mobile** | Flutter packages | [ADR-020](adr/020-librairies-flutter.md) | | **CI/CD** | GitHub Actions (monorepo) | [ADR-022](adr/022-strategie-cicd-monorepo.md) | | **Modération** | Architecture modération | [ADR-023](adr/023-architecture-moderation.md) | | **Monitoring** | Prometheus + Grafana | [ADR-024](adr/024-monitoring-observabilite.md) | | **Secrets** | Vault + sealed secrets | [ADR-025](adr/025-securite-secrets.md) | | **Notifications** | Push géolocalisées (FCM/APNS + geofencing) | [ADR-017](adr/017-notifications-geolocalisees.md) | --- ## Streaming Audio ### Protocole : HLS (HTTP Live Streaming) - Fonctionne à travers firewalls et réseaux mobiles instables - Cache CDN natif (réduction des coûts) - Bitrate adaptatif automatique (tunnels, zones rurales) - Support natif iOS/Android ### Codec : Opus Optimisé pour la voix en environnement bruyant (voiture). | Qualité | Bitrate | Usage | |---------|---------|-------| | Basse | 24 kbps | 2G/Edge | | Standard | 48 kbps | 3G | | Haute | 64 kbps | 4G/5G | Fallback AAC-LC pour appareils legacy. ### Buffering Adaptatif | Réseau | Buffer min | Buffer cible | Buffer max | |--------|------------|--------------|------------| | WiFi | 5s | 30s | 120s | | 4G/5G | 10s | 45s | 120s | | 3G | 30s | 90s | 300s | --- ## Sécurité ### Chiffrement - **TLS 1.3** sur tous les endpoints (overhead ~1-2%) - **DTLS-SRTP** pour WebRTC (radio live) - Pas de DRM initialement (ajout si licences l'exigent) ### Authentification - **Zitadel self-hosted sur OVH France** (Gravelines) pour IAM - Souveraineté totale : 100% données en France (cohérent avec ADR-004) - JWT validation locale (zitadel-go SDK) - OAuth2 PKCE pour mobile (iOS/Android) - MFA et passkeys disponibles - Rate limiting par IP et par utilisateur (Nginx + Zitadel) - PostgreSQL schema partagé avec RoadWave (séparation logique) --- ## Base de Données ### PostgreSQL + PostGIS ```sql -- Requête géolocalisée typique SELECT id, ST_Distance(location::geography, ST_MakePoint($lon, $lat)::geography) as distance FROM contents WHERE ST_DWithin(location::geography, ST_MakePoint($lon, $lat)::geography, 50000) ORDER BY distance LIMIT 20; ``` ### Redis Geospatial (Cache) ``` GEOADD contents:geo longitude latitude content_id GEORADIUS contents:geo user_lon user_lat 50 km WITHDIST COUNT 20 ASC ``` TTL cache : 5 minutes (le contenu ne bouge pas). --- ## Architecture Services ```mermaid flowchart TB subgraph clients["Clients"] mobile["Mobile Apps
iOS/Android
Flutter"] carplay["CarPlay /
Android Auto"] end subgraph ovh["OVH VPS Essential (Gravelines, France)"] nginx["NGINX Cache
+ Let's Encrypt
TLS 1.3, Rate Limiting"] api["API Gateway
Go + Fiber :8080"] subgraph services["Backend Services (Monolithe Modulaire)"] auth["Auth Service
JWT validation"] user["User Service
Profils, Jauges"] content["Content/Geo Service
Recommandations
PostGIS queries"] streaming["Streaming Service
HLS generation"] payment["Payment Service
Mangopay integration"] notif["Notification Service
FCM/APNS"] end zitadel["Zitadel IdP
OAuth2 PKCE
:8081"] ip2loc["IP2Location DB
SQLite ~50MB
Mode dégradé"] subgraph data["Données"] pgbouncer["PgBouncer
Connection pooling
:6432"] postgres["PostgreSQL 16
+ PostGIS 3.4
Schémas:
- roadwave
- zitadel"] redis["Redis 7 Cluster
Cache + Geospatial
GEORADIUS"] end end subgraph external["Services Externes"] storage["OVH Object Storage
Fichiers audio HLS"] mangopay["Mangopay
Paiements, KYC"] brevo["Brevo
Emails transactionnels"] fcm["FCM / APNS
Push notifications"] end mobile --> nginx carplay --> nginx nginx --> api api --> auth api --> user api --> content api --> streaming api --> payment api --> notif api --> ip2loc auth --> zitadel user --> pgbouncer user --> redis content --> pgbouncer content --> redis streaming --> storage payment --> mangopay notif --> fcm zitadel --> pgbouncer pgbouncer --> postgres brevo -.email.-> mobile fcm -.push.-> mobile style ovh fill:#e3f2fd style external fill:#fff3e0 style clients fill:#f3e5f5 style data fill:#e8f5e9 ``` **Souveraineté** : 100% données en France (RGPD compliant) --- ## Scaling 10M Utilisateurs ### Stratégie par phase | Phase | Utilisateurs | Infra | Coût estimé | |-------|--------------|-------|-------------| | MVP | 0-20K | OVH VPS Essential + PostgreSQL + Zitadel + NGINX Cache | ~14€/mois | | Growth | 20K-500K | Scaleway Instances (multi-replicas), OVH Object Storage | 150-500€/mois | | Scale | 500K+ | Multi-région, Kubernetes managé, NGINX origin shield | 2-10K€/mois | ### Métriques cibles | Métrique | Objectif | |----------|----------| | Latence API p99 | < 100ms | | Temps de démarrage audio | < 3s | | Disponibilité | 99.9% | | Connexions/serveur | 100K+ | --- ## Points de vigilance 1. **Buffering mobile** : Pré-chargement agressif avant tunnels (détection GPS) 2. **Handoff réseau** : Buffer suffisant pour survivre aux changements de cellule 3. **Mode offline** : Téléchargement complet sur WiFi 4. **Bande passante** : 48 kbps Opus = ~20 MB/heure (faible consommation data) --- ## Pourquoi pas UDP brut ? | UDP | HLS/TCP | |-----|---------| | Latence minimale | Latence acceptable (5-30s) | | Problèmes NAT/firewall | Passe partout | | Perte de paquets = artefacts | Retransmission automatique | | Pas de cache CDN | Cache CDN = économies | | Complexité++ | Standard de l'industrie | Pour du contenu non-interactif (podcasts, audio-guides), la latence HLS est acceptable. WebRTC réservé à la radio live uniquement.