# RoadWave - Architecture Technique > Les décisions techniques sont documentées dans [docs/adr/](docs/adr/) ## Stack Technologique | Composant | Technologie | ADR | |-----------|-------------|-----| | **Backend** | Go + Fiber | [ADR-001](docs/adr/001-langage-backend.md) | | **Architecture Backend** | Monolithe Modulaire | [ADR-012](docs/adr/012-architecture-backend.md) | | **Authentification** | Zitadel (self-hosted OVH) | [ADR-008](docs/adr/008-authentification.md) | | **Streaming** | HLS | [ADR-002](docs/adr/002-protocole-streaming.md) | | **Codec** | Opus | [ADR-003](docs/adr/003-codec-audio.md) | | **CDN** | NGINX Cache (OVH VPS) | [ADR-004](docs/adr/004-cdn.md) | | **Storage** | OVH Object Storage | [ADR-004](docs/adr/004-cdn.md) | | **Hébergement MVP** | OVH VPS Essential | [ADR-017](docs/adr/017-hebergement.md) | | **Organisation** | Monorepo | [ADR-016](docs/adr/016-organisation-monorepo.md) | | **Base de données** | PostgreSQL + PostGIS | [ADR-005](docs/adr/005-base-de-donnees.md) | | **ORM/Accès données** | sqlc | [ADR-013](docs/adr/013-orm-acces-donnees.md) | | **Cache** | Redis Cluster | [ADR-005](docs/adr/005-base-de-donnees.md) | | **Chiffrement** | TLS 1.3 | [ADR-006](docs/adr/006-chiffrement.md) | | **Live** | WebRTC | [ADR-002](docs/adr/002-protocole-streaming.md) | | **Frontend Mobile** | Flutter | [ADR-014](docs/adr/014-frontend-mobile.md) | | **Tests** | Testify + Godog (Gherkin) | [ADR-015](docs/adr/015-strategie-tests.md), [ADR-007](docs/adr/007-tests-bdd.md) | | **Paiements** | Mangopay | [ADR-009](docs/adr/009-solution-paiement.md) | | **Emailing** | Brevo | [ADR-018](docs/adr/018-service-emailing.md) | | **Commandes volant** | Like automatique | [ADR-010](docs/adr/010-commandes-volant.md) | | **Conformité stores** | CarPlay, Android Auto, App/Play Store | [ADR-011](docs/adr/011-conformite-stores-carplay-android-auto.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 ``` ┌─────────────────────────────────────────────┐ │ OVH VPS (Gravelines, France) │ │ │ │ ┌─────────────────┐ │ │ │ NGINX Cache │ Cache HLS │ │ │ + Let's Encrypt│ SSL, rate limiting │ │ └────────┬────────┘ │ │ │ │ │ ┌────────┴────────┐ │ │ │ API Gateway │ Go + Fiber │ │ └────────┬────────┘ │ │ │ │ │ ┌────┴────┬─────────────┬──────────┐ │ │ │ │ │ │ │ │ ┌───▼───┐ ┌──▼───┐ ┌───────▼────┐ ┌──▼─────┐ │ │ Auth │ │ User │ │Content/Geo │ │Zitadel │ │ │Service│ │Svc │ │ Service │ │ IdP │ │ └───┬───┘ └──┬───┘ └──────┬─────┘ └───┬────┘ │ │ │ │ │ │ │ └────────┴────────────┴───────────┘ │ │ │ │ │ ┌───────────┴──────────┐ │ │ │ │ │ │ ┌────▼────┐ ┌──────▼──────┐ │ │ │ Redis │ │ PostgreSQL │ │ │ │ Cluster │ │ + PostGIS │ │ │ └─────────┘ │ │ │ │ │ Schémas: │ │ │ │ - roadwave │ │ │ │ - zitadel │ │ │ └─────────────┘ │ └─────────────────────────────────────────────┘ │ ┌──────────┴──────────┐ │ │ ┌────────▼────────┐ ┌────────▼────────┐ │ OVH Object │ │ Mobile Apps │ │ Storage (S3) │ │ iOS/Android │ │ Fichiers audio │ │ │ └─────────────────┘ └─────────────────┘ Souveraineté : 100% données en France ``` --- ## 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.