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:
jpgiannetti
2026-02-09 20:49:52 +01:00
parent 95c65b8be1
commit 35aaa105d0
87 changed files with 1044 additions and 91 deletions

View File

@@ -74,6 +74,7 @@ Fonctionnalité: Recherche avancée de contenus
``` ```
**Conventions Gherkin** : **Conventions Gherkin** :
- Langue française (`# language: fr`) - Langue française (`# language: fr`)
- Mots-clés : `Fonctionnalité`, `Scénario`, `Étant donné`, `Quand`, `Alors` - Mots-clés : `Fonctionnalité`, `Scénario`, `Étant donné`, `Quand`, `Alors`
- Commentaires pour référencer les règles DDD - Commentaires pour référencer les règles DDD
@@ -94,6 +95,7 @@ Cette commande :
Si la catégorie n'existe pas encore, l'ajouter : Si la catégorie n'existe pas encore, l'ajouter :
```yaml ```yaml
- '🎯 Recommendation': - '🎯 Recommendation':
# ... # ...
- Tests BDD: - Tests BDD:
@@ -156,6 +158,7 @@ Description du contexte métier...
**Justification** : Parce que... **Justification** : Parce que...
**Exemple** : **Exemple** :
- Cas nominal : ... - Cas nominal : ...
- Cas d'erreur : ... - Cas d'erreur : ...
@@ -177,6 +180,7 @@ Les règles métier doivent être testables → créer des features BDD.
### Étape 5 : Ajouter dans `mkdocs.yml` ### Étape 5 : Ajouter dans `mkdocs.yml`
```yaml ```yaml
- '🎙️ Content': - '🎙️ Content':
- Règles: - Règles:
- Création & Publication: domains/content/rules/creation-publication.md - Création & Publication: domains/content/rules/creation-publication.md
@@ -234,6 +238,7 @@ Requêtes sqlc : `backend/queries/nouvelle_thing.sql`
### Ajouter dans `mkdocs.yml` ### Ajouter dans `mkdocs.yml`
```yaml ```yaml
- Entités: - Entités:
- Vue d'ensemble: domains/[domain]/entities/vue-ensemble.md - Vue d'ensemble: domains/[domain]/entities/vue-ensemble.md
- Nouvelle Entité: domains/[domain]/entities/nouvelle-entite.md # ← NOUVEAU - Nouvelle Entité: domains/[domain]/entities/nouvelle-entite.md # ← NOUVEAU
@@ -268,6 +273,7 @@ sequenceDiagram
## Légende ## Légende
**Acteurs** : **Acteurs** :
- Utilisateur : Client de l'API - Utilisateur : Client de l'API
- API : Backend RoadWave - API : Backend RoadWave
- Database : PostgreSQL - Database : PostgreSQL

View File

@@ -80,6 +80,7 @@ Lorsque plusieurs contenus sont disponibles dans une zone, **seul le plus pertin
Chaque utilisateur possède des **jauges d'intérêt** qui évoluent dynamiquement : Chaque utilisateur possède des **jauges d'intérêt** qui évoluent dynamiquement :
### Catégories ### Catégories
- Automobile - Automobile
- Voyage - Voyage
- Famille - Famille
@@ -116,6 +117,7 @@ Interactions simplifiées pour sécurité routière maximale :
| **Play/Pause** | Mettre en pause / reprendre la lecture | | **Play/Pause** | Mettre en pause / reprendre la lecture |
**Like automatique** : Le système détecte automatiquement vos préférences selon votre temps d'écoute : **Like automatique** : Le système détecte automatiquement vos préférences selon votre temps d'écoute :
- Écoute ≥80% du contenu → Like renforcé (+2 points jauge) - Écoute ≥80% du contenu → Like renforcé (+2 points jauge)
- Écoute 30-79% du contenu → Like standard (+1 point jauge) - Écoute 30-79% du contenu → Like standard (+1 point jauge)
- Skip après <10s → Signal négatif (-0.5 point) - Skip après <10s → Signal négatif (-0.5 point)
@@ -198,6 +200,7 @@ Approche hybride combinant participation communautaire, IA et modérateurs dédi
| **Strike 4** | Ban définitif du compte créateur | Permanent | | **Strike 4** | Ban définitif du compte créateur | Permanent |
**Notes** : **Notes** :
- **Tolérance 1ère fois** (droits d'auteur uniquement) : avertissement sans strike - **Tolérance 1ère fois** (droits d'auteur uniquement) : avertissement sans strike
- **Violations graves** (haine, illégalité, violence) : strike immédiat sans tolérance - **Violations graves** (haine, illégalité, violence) : strike immédiat sans tolérance
- **Réhabilitation** : -1 strike tous les 6 mois sans nouvelle violation - **Réhabilitation** : -1 strike tous les 6 mois sans nouvelle violation

View File

@@ -8,6 +8,7 @@
|-----------|-------------|-----| |-----------|-------------|-----|
| **Backend** | Go + Fiber | [ADR-001](adr/001-langage-backend.md) | | **Backend** | Go + Fiber | [ADR-001](adr/001-langage-backend.md) |
| **Architecture Backend** | Monolithe Modulaire | [ADR-010](adr/010-architecture-backend.md) | | **Architecture Backend** | Monolithe Modulaire | [ADR-010](adr/010-architecture-backend.md) |
| **Librairies Backend** | Fiber, pgx, rueidis, sqlc, etc. | [ADR-018](adr/018-librairies-go.md) |
| **Authentification** | Zitadel (self-hosted OVH) | [ADR-008](adr/008-authentification.md) | | **Authentification** | Zitadel (self-hosted OVH) | [ADR-008](adr/008-authentification.md) |
| **Streaming** | HLS | [ADR-002](adr/002-protocole-streaming.md) | | **Streaming** | HLS | [ADR-002](adr/002-protocole-streaming.md) |
| **Codec** | Opus | [ADR-003](adr/003-codec-audio.md) | | **Codec** | Opus | [ADR-003](adr/003-codec-audio.md) |

View File

@@ -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. 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** : **Exemple critique** :
- Utilisateur en voiture à 90 km/h (25 m/s) - Utilisateur en voiture à 90 km/h (25 m/s)
- ETA de 7 secondes avant le point → notification affichée - ETA de 7 secondes avant le point → notification affichée
- Latence HLS de 15 secondes - 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** : **Stratégie de cache** :
- Télécharge les **15 premières secondes** de chaque POI à proximité - Télécharge les **15 premières secondes** de chaque POI à proximité
- Limite : 3 POI simultanés en cache (max ~25 MB) - Limite : 3 POI simultanés en cache (max ~25 MB)
- Purge automatique après 200m de distance passée - 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 ### Impact sur l'Infrastructure
#### Backend (Go) #### Backend (Go)
- **Nouveau service** : `audiocache.Service` pour préparer les extraits M4A - **Nouveau service** : `audiocache.Service` pour préparer les extraits M4A
- **Endpoint** : `GET /api/v1/audio/poi/:id/intro` (retourne 15s d'audio) - **Endpoint** : `GET /api/v1/audio/poi/:id/intro` (retourne 15s d'audio)
- **CDN** : Cache NGINX avec TTL 7 jours sur `/audio/*/intro.m4a` - **CDN** : Cache NGINX avec TTL 7 jours sur `/audio/*/intro.m4a`
#### Mobile (Flutter) #### Mobile (Flutter)
- **Package** : `just_audio` avec cache local (`flutter_cache_manager`) - **Package** : `just_audio` avec cache local (`flutter_cache_manager`)
- **Stockage** : Max 100 MB de cache audio (auto-purge LRU) - **Stockage** : Max 100 MB de cache audio (auto-purge LRU)
- **Logique** : `PreBufferService` avec scoring de priorité POI - **Logique** : `PreBufferService` avec scoring de priorité POI
#### Coûts #### Coûts
- **Bande passante** : +10-15 MB/utilisateur/session (vs streaming pur) - **Bande passante** : +10-15 MB/utilisateur/session (vs streaming pur)
- **Stockage CDN** : +500 MB pour 1000 POI × 5 MB intro (négligeable) - **Stockage CDN** : +500 MB pour 1000 POI × 5 MB intro (négligeable)
- **Économie** : Cache CDN réduit les requêtes origin (-60% selon tests) - **Économie** : Cache CDN réduit les requêtes origin (-60% selon tests)

View File

@@ -44,12 +44,14 @@ flowchart LR
## Justification ## Justification
### PostgreSQL + PostGIS ### PostgreSQL + PostGIS
- Requêtes géospatiales complexes et précises - Requêtes géospatiales complexes et précises
- Index GIST pour performance - Index GIST pour performance
- ACID, fiabilité éprouvée - ACID, fiabilité éprouvée
- Écosystème mature - Écosystème mature
### PgBouncer ### PgBouncer
- **Connection pooling** : Réduit l'overhead de création de connexions PostgreSQL - **Connection pooling** : Réduit l'overhead de création de connexions PostgreSQL
- **Mode transaction** : Connexion réutilisée entre transactions (optimal pour API stateless) - **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 - **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) - **Port** : :6432 (vs :5432 pour PostgreSQL direct)
### Redis ### Redis
- Cache géo natif (`GEORADIUS`) : 100K+ requêtes/sec - Cache géo natif (`GEORADIUS`) : 100K+ requêtes/sec
- Sessions utilisateurs - Sessions utilisateurs
- Pub/sub pour temps réel - Pub/sub pour temps réel
@@ -81,11 +84,13 @@ LIMIT 20;
### Configuration PgBouncer ### Configuration PgBouncer
**Mode recommandé** : `transaction` **Mode recommandé** : `transaction`
- Connexion libérée après chaque transaction - Connexion libérée après chaque transaction
- Optimal pour API stateless (Go + Fiber) - Optimal pour API stateless (Go + Fiber)
- Maximise la réutilisation des connexions - Maximise la réutilisation des connexions
**Pool sizing** : **Pool sizing** :
- `default_pool_size` : 20 (connexions par base) - `default_pool_size` : 20 (connexions par base)
- `max_client_conn` : 1000 (connexions clients max) - `max_client_conn` : 1000 (connexions clients max)
- `reserve_pool_size` : 5 (connexions de secours) - `reserve_pool_size` : 5 (connexions de secours)

View File

@@ -67,11 +67,13 @@ features/
**Exécuté par** : Backend (Godog + step definitions Go dans `/backend/tests/bdd/`) **Exécuté par** : Backend (Godog + step definitions Go dans `/backend/tests/bdd/`)
**Exemples de scénarios** : **Exemples de scénarios** :
- `POST /api/v1/auth/register` avec email invalide → retourne 400 - `POST /api/v1/auth/register` avec email invalide → retourne 400
- `GET /api/v1/contents/nearby` avec rayon 500m → retourne POI triés par distance - `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 - `DELETE /api/v1/user/account` → supprime données RGPD conformément
**Caractéristiques** : **Caractéristiques** :
- Focus sur la **logique métier backend** (algorithme, validation, persistance) - Focus sur la **logique métier backend** (algorithme, validation, persistance)
- Pas d'interface utilisateur - Pas d'interface utilisateur
- Testable via requêtes HTTP directes - 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/`) **Exécuté par** : Mobile (Flutter `integration_test` + step definitions Dart dans `/mobile/tests/bdd/`)
**Exemples de scénarios** : **Exemples de scénarios** :
- Cliquer sur "Lecture" → widget audio player s'affiche avec progress bar - Cliquer sur "Lecture" → widget audio player s'affiche avec progress bar
- Mode piéton activé → carte interactive affichée + bouton "Télécharger zone" - Mode piéton activé → carte interactive affichée + bouton "Télécharger zone"
- Scroll dans liste podcasts → lazy loading déclenche pagination - Scroll dans liste podcasts → lazy loading déclenche pagination
**Caractéristiques** : **Caractéristiques** :
- Focus sur l'**expérience utilisateur mobile** - Focus sur l'**expérience utilisateur mobile**
- Validation visuelle (widgets, animations, navigation) - Validation visuelle (widgets, animations, navigation)
- Mock du backend si nécessaire (tests UI isolés) - Mock du backend si nécessaire (tests UI isolés)
@@ -103,11 +107,13 @@ features/
**Exécuté par** : Backend **ET** Mobile ensemble **Exécuté par** : Backend **ET** Mobile ensemble
**Exemples de scénarios** : **Exemples de scénarios** :
- Abonnement Premium : Formulaire mobile → API Zitadel → API RoadWave → Mangopay → Confirmation UI - 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 - 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 - Notification géolocalisée : GPS détecte POI → Backend calcule recommandation → Push notification → Ouverture app → Lecture audio
**Caractéristiques** : **Caractéristiques** :
- Tests **cross-composants** (intégration complète) - Tests **cross-composants** (intégration complète)
- Implique souvent des **services tiers** (Zitadel, Mangopay, Firebase) - Implique souvent des **services tiers** (Zitadel, Mangopay, Firebase)
- Validation du **parcours utilisateur de bout en bout** - Validation du **parcours utilisateur de bout en bout**
@@ -117,10 +123,12 @@ features/
### Implémentation Step Definitions ### Implémentation Step Definitions
**Backend** : `/backend/tests/bdd/` **Backend** : `/backend/tests/bdd/`
- Step definitions Go pour features `api/` et `e2e/` - Step definitions Go pour features `api/` et `e2e/`
- Utilise `godog` et packages backend (`service`, `repository`) - Utilise `godog` et packages backend (`service`, `repository`)
**Mobile** : `/mobile/tests/bdd/` **Mobile** : `/mobile/tests/bdd/`
- Step definitions Dart pour features `ui/` et `e2e/` - Step definitions Dart pour features `ui/` et `e2e/`
- Utilise Flutter `integration_test` framework - Utilise Flutter `integration_test` framework

View File

@@ -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. **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) **Méthode d'authentification** : **Email/Password uniquement** (pas d'OAuth tiers)
- ✅ Authentification native Zitadel (email + mot de passe) - ✅ Authentification native Zitadel (email + mot de passe)
-**Pas de fournisseurs OAuth externes** (Google, Apple, Facebook) -**Pas de fournisseurs OAuth externes** (Google, Apple, Facebook)
- **Protocole** : OAuth2 PKCE (entre app mobile et Zitadel uniquement) - **Protocole** : OAuth2 PKCE (entre app mobile et Zitadel uniquement)
**Architecture de déploiement** : **Architecture de déploiement** :
- Container Docker sur le même VPS OVH (Gravelines, France) que l'API - 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) - 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 - 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 4. App mobile → Go API avec JWT → validation locale
**Ce que nous N'UTILISONS PAS** : **Ce que nous N'UTILISONS PAS** :
- ❌ "Sign in with Google" - ❌ "Sign in with Google"
- ❌ "Sign in with Apple" - ❌ "Sign in with Apple"
- ❌ "Sign in with Facebook" - ❌ "Sign in with Facebook"
- ❌ Aucun autre fournisseur externe - ❌ Aucun autre fournisseur externe
**Pourquoi OAuth2 alors ?** : **Pourquoi OAuth2 alors ?** :
- OAuth2 PKCE est le **standard moderne** pour auth mobile (sécurisé, refresh tokens, etc.) - 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 - 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) - Alternative serait session cookies (moins adapté mobile) ou JWT custom (réinventer la roue)

View File

@@ -45,6 +45,7 @@ RoadWave nécessite applications iOS et Android avec support CarPlay/Android Aut
- **Cache images** : `cached_network_image` (LRU cache) - **Cache images** : `cached_network_image` (LRU cache)
**Points d'attention** : **Points d'attention** :
- ⚠️ **Permissions progressives requises** pour `geofence_service` et `geolocator` (voir section "Stratégie de Permissions") - ⚠️ **Permissions progressives requises** pour `geofence_service` et `geolocator` (voir section "Stratégie de Permissions")
- ⚠️ **Licences** : 100% permissives (MIT, BSD-3) - voir ADR-020 - ⚠️ **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 ### 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 : **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 - **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 - **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** - **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 **Quand** : Premier lancement de l'app
**Demande** : `locationWhenInUse` uniquement **Demande** : `locationWhenInUse` uniquement
- iOS : "Allow While Using App" - iOS : "Allow While Using App"
- Android : `ACCESS_FINE_LOCATION` - 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 : Le service de gestion des permissions (`lib/core/services/location_permission_service.dart`) doit implémenter :
**Détection du niveau actuel** : **Détection du niveau actuel** :
- Vérifier le statut de la permission `location` (when in use) - Vérifier le statut de la permission `location` (when in use)
- Vérifier le statut de la permission `locationAlways` (background) - Vérifier le statut de la permission `locationAlways` (background)
- Retourner le niveau le plus élevé accordé - Retourner le niveau le plus élevé accordé
**Demande de permission de base** (Étape 1) : **Demande de permission de base** (Étape 1) :
- Demander uniquement la permission `location` (when in use) - Demander uniquement la permission `location` (when in use)
- Utilisée lors de l'onboarding - Utilisée lors de l'onboarding
- Aucun écran d'éducation requis - Aucun écran d'éducation requis
**Demande de permission arrière-plan** (Étape 2) : **Demande de permission arrière-plan** (Étape 2) :
- **Toujours** afficher un écran d'éducation AVANT la demande OS - **Toujours** afficher un écran d'éducation AVANT la demande OS
- Demander la permission `locationAlways` (iOS) ou `ACCESS_BACKGROUND_LOCATION` (Android) - 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 - Si refusée de manière permanente, proposer l'ouverture des réglages système
**Gestion des refus** : **Gestion des refus** :
- Détecter si la permission est refusée de manière permanente - 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 - Proposer l'ouverture des réglages de l'appareil avec un message clair
- Permettre à l'utilisateur d'annuler - 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`) #### iOS (`ios/Runner/Info.plist`)
**Clés requises** : **Clés requises** :
- `NSLocationWhenInUseUsageDescription` : Décrire l'usage pour le mode voiture (contenu géolocalisé en temps réel) - `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 - `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` - `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`) #### Android (`android/app/src/main/AndroidManifest.xml`)
**Permissions requises** : **Permissions requises** :
- `ACCESS_FINE_LOCATION` et `ACCESS_COARSE_LOCATION` : Permission de base (when in use) - `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 - `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+) - `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 : **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" - 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 - 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 ### Tests de Validation Stores
**Checklist App Store (iOS)** : **Checklist App Store (iOS)** :
- [ ] Permission "Always" demandée **uniquement** si user active mode piéton - [ ] Permission "Always" demandée **uniquement** si user active mode piéton
- [ ] Écran d'éducation **avant** demande OS (requis iOS 13+) - [ ] Écran d'éducation **avant** demande OS (requis iOS 13+)
- [ ] App fonctionne sans permission "Always" (validation critique) - [ ] App fonctionne sans permission "Always" (validation critique)
- [ ] Texte `Info.plist` clair et honnête (pas de tracking publicitaire) - [ ] Texte `Info.plist` clair et honnête (pas de tracking publicitaire)
**Checklist Play Store (Android)** : **Checklist Play Store (Android)** :
- [ ] Déclaration `ACCESS_BACKGROUND_LOCATION` avec justification détaillée - [ ] Déclaration `ACCESS_BACKGROUND_LOCATION` avec justification détaillée
- [ ] Vidéo démo flow de permissions (< 30s, requis Play Console) - [ ] Vidéo démo flow de permissions (< 30s, requis Play Console)
- [ ] App fonctionne sans permission background (validation critique) - [ ] App fonctionne sans permission background (validation critique)

View File

@@ -79,6 +79,7 @@ Approche **multi-niveaux** : unitaires, intégration, BDD (Gherkin), E2E, load t
- `github.com/cucumber/godog` - `github.com/cucumber/godog`
- `github.com/testcontainers/testcontainers-go` - `github.com/testcontainers/testcontainers-go`
- `grafana/k6` (AGPL-3.0, usage interne OK) - `grafana/k6` (AGPL-3.0, usage interne OK)
- Temps CI : ~3-5 min (tests unitaires + BDD) - Temps CI : ~3-5 min (tests unitaires + BDD)
- Tests intégration/E2E : nightly builds (15-30 min) - Tests intégration/E2E : nightly builds (15-30 min)
- Load tests : avant chaque release majeure - Load tests : avant chaque release majeure

View File

@@ -68,6 +68,7 @@ mobile/tests/bdd/inscription_steps.dart → Teste l'UI mobile
``` ```
Cela garantit que : Cela garantit que :
- Les spécifications métier sont uniques et cohérentes - Les spécifications métier sont uniques et cohérentes
- Chaque couche teste sa responsabilité - Chaque couche teste sa responsabilité
- Les tests valident le contrat entre front et back - Les tests valident le contrat entre front et back

View File

@@ -52,6 +52,7 @@ OVH Object Storage (~1.20€/100GB)
| **Scale** | 100K+ | Scaleway Kubernetes (Kapsule) | ~500€ | Auto-scaling OU multi-région | | **Scale** | 100K+ | Scaleway Kubernetes (Kapsule) | ~500€ | Auto-scaling OU multi-région |
**Triggers détaillés** : **Triggers détaillés** :
- **Phase 2** : CPU > 70% (7j), latence p99 > 100ms, backups > 1h/semaine, MRR > 2000€ - **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 - **Phase 3** : Auto-scaling horizontal requis, multi-région Europe, DevOps dédié, > 5 services

View File

@@ -8,6 +8,7 @@
RoadWave nécessite un service d'envoi d'emails **techniques uniquement** (pas de notifications sociales, alertes marketing, promotions). RoadWave nécessite un service d'envoi d'emails **techniques uniquement** (pas de notifications sociales, alertes marketing, promotions).
**Périmètre strict** : **Périmètre strict** :
-**Authentification** : Vérification email (inscription), réinitialisation mot de passe, changement email -**Authentification** : Vérification email (inscription), réinitialisation mot de passe, changement email
-**Sécurité** : Alertes connexion inhabituelle, changement password -**Sécurité** : Alertes connexion inhabituelle, changement password
-**Modération** : Strikes, suspensions, bannissements -**Modération** : Strikes, suspensions, bannissements

View File

@@ -45,6 +45,7 @@ Architecture hybride en **2 phases** :
5. Utilisateur clique → app s'ouvre → HLS démarre l'audio (ADR-002) 5. Utilisateur clique → app s'ouvre → HLS démarre l'audio (ADR-002)
**Limitations MVP** : **Limitations MVP** :
- Fonctionne uniquement si l'utilisateur a envoyé sa position < 5 minutes - 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 - 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 ? ### Pourquoi implémentation directe APNS/FCM et pas SDK Firebase ?
**Réalité technique** : Notifications natives requièrent obligatoirement Google/Apple **Réalité technique** : Notifications natives requièrent obligatoirement Google/Apple
- **APNS (Apple)** : Seul protocole pour notifications iOS → dépendance Apple inévitable - **APNS (Apple)** : Seul protocole pour notifications iOS → dépendance Apple inévitable
- **FCM (Google)** : Protocole standard Android (Google Play Services) - **FCM (Google)** : Protocole standard Android (Google Play Services)
**Implémentation directe choisie** : **Implémentation directe choisie** :
- **Gratuit** : APNS et FCM sont gratuits (pas de limite de volume) - **Gratuit** : APNS et FCM sont gratuits (pas de limite de volume)
- **Self-hosted** : Code backend 100% maîtrisé, pas de dépendance SDK tiers - **Self-hosted** : Code backend 100% maîtrisé, pas de dépendance SDK tiers
- **Fiabilité** : Infrastructure Apple/Google avec 99.95% uptime - **Fiabilité** : Infrastructure Apple/Google avec 99.95% uptime
@@ -123,6 +126,7 @@ Architecture hybride en **2 phases** :
- ❌ Toujours wrapper autour APNS/FCM - ❌ Toujours wrapper autour APNS/FCM
**Décision technique** : **Décision technique** :
- Implémentation directe APNS/FCM dès le MVP - Implémentation directe APNS/FCM dès le MVP
- **Cohérence ADR** : Respecte ADR-008 (self-hosted) et ADR-015 (souveraineté française) - **Cohérence ADR** : Respecte ADR-008 (self-hosted) et ADR-015 (souveraineté française)
- **Abstraction layer** : Interface `NotificationProvider` pour faciliter maintenance - **Abstraction layer** : Interface `NotificationProvider` pour faciliter maintenance
@@ -150,9 +154,11 @@ Architecture hybride en **2 phases** :
- ⚠️ **Gestion certificats APNS** : Renouvellement annuel + configuration - ⚠️ **Gestion certificats APNS** : Renouvellement annuel + configuration
- Mitigé par scripts automation (certificats auto-renouvelés) - Mitigé par scripts automation (certificats auto-renouvelés)
- Documentation complète du processus - Documentation complète du processus
- ⚠️ **Tokens push sensibles** : Tokens FCM/APNS stockés côté backend - ⚠️ **Tokens push sensibles** : Tokens FCM/APNS stockés côté backend
- Chiffrement tokens en base (conformité RGPD) - Chiffrement tokens en base (conformité RGPD)
- Rotation automatique des tokens expirés - Rotation automatique des tokens expirés
- ❌ WebSocket nécessite maintien de connexion (charge serveur +10-20%) - ❌ WebSocket nécessite maintien de connexion (charge serveur +10-20%)
- ❌ Mode offline non disponible au MVP (déception possible des early adopters) - ❌ Mode offline non disponible au MVP (déception possible des early adopters)

View File

@@ -6,6 +6,7 @@
## Contexte ## 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 : 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 - **Licences permissives** (MIT, Apache-2.0, BSD) sans restrictions commerciales
- **Performance** (10M utilisateurs, 100K RPS, p99 < 100ms) - **Performance** (10M utilisateurs, 100K RPS, p99 < 100ms)
- **Maturité** et maintenance active - **Maturité** et maintenance active
@@ -55,6 +56,7 @@ Utilisation de **16 librairies open-source** avec licences permissives.
## Alternatives considérées ## Alternatives considérées
Voir pour comparatifs complets : Voir pour comparatifs complets :
- Framework : Fiber vs Gin vs Echo vs Chi - Framework : Fiber vs Gin vs Echo vs Chi
- PostgreSQL : pgx vs GORM vs database/sql - PostgreSQL : pgx vs GORM vs database/sql
- Redis : rueidis vs go-redis vs redigo - Redis : rueidis vs go-redis vs redigo
@@ -64,17 +66,20 @@ Voir pour comparatifs complets :
## Justification ## Justification
### Licences ### Licences
- **15/16 librairies** : MIT, Apache-2.0, BSD, ISC (permissives) - **15/16 librairies** : MIT, Apache-2.0, BSD, ISC (permissives)
- **1/16** : AGPL-3.0 (k6 load testing, OK usage interne) - **1/16** : AGPL-3.0 (k6 load testing, OK usage interne)
- **Compatibilité totale** : Aucun conflit de licence - **Compatibilité totale** : Aucun conflit de licence
### Performance ### Performance
- **Fiber** : 36K RPS (5% plus rapide que Gin/Echo) - **Fiber** : 36K RPS (5% plus rapide que Gin/Echo)
- **pgx** : 30-50% plus rapide que GORM - **pgx** : 30-50% plus rapide que GORM
- **rueidis** : Client-side caching automatique - **rueidis** : Client-side caching automatique
- **zerolog** : Zero allocation, benchmarks 2025 - **zerolog** : Zero allocation, benchmarks 2025
### Maturité ### Maturité
- **Standards** : testify (27% adoption), golang-migrate, viper - **Standards** : testify (27% adoption), golang-migrate, viper
- **Production** : Fiber (33K stars), pgx (10K stars), pion (13K stars) - **Production** : Fiber (33K stars), pgx (10K stars), pion (13K stars)
- **Maintenance** : Toutes actives (commits 2025-2026) - **Maintenance** : Toutes actives (commits 2025-2026)
@@ -82,12 +87,14 @@ Voir pour comparatifs complets :
## Conséquences ## Conséquences
### Positives ### Positives
- ✅ Aucune restriction licence commerciale - ✅ Aucune restriction licence commerciale
- ✅ Stack cohérent avec ADR existants (001, 002, 007, 008, 013, 015, 019) - ✅ Stack cohérent avec ADR existants (001, 002, 007, 008, 013, 015, 019)
- ✅ Performance validée (benchmarks publics) - ✅ Performance validée (benchmarks publics)
- ✅ Écosystème mature et documenté - ✅ Écosystème mature et documenté
### Négatives ### Négatives
- ⚠️ **k6 (AGPL-3.0)** : Copyleft, mais OK pour tests internes (pas de SaaS k6 prévu) - ⚠️ **k6 (AGPL-3.0)** : Copyleft, mais OK pour tests internes (pas de SaaS k6 prévu)
- ⚠️ **Gestion certificats APNS** : Renouvellement annuel, configuration manuelle - ⚠️ **Gestion certificats APNS** : Renouvellement annuel, configuration manuelle
- ❌ Courbe d'apprentissage : 16 librairies à maîtriser (doc nécessaire) - ❌ Courbe d'apprentissage : 16 librairies à maîtriser (doc nécessaire)

View File

@@ -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. 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é** : **Évolution du marché** :
- **Avant 2019** : MaxMind GeoLite2 était téléchargeable gratuitement (base de données locale) - **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à - **Depuis 2019** : MaxMind nécessite un compte + limite 1000 requêtes/jour (gratuit), puis 0.003$/requête au-delà
**Usage RoadWave** : **Usage RoadWave** :
- Mode dégradé : ~10% des utilisateurs (estimation) - Mode dégradé : ~10% des utilisateurs (estimation)
- Volume : 1000 utilisateurs × 10% = 100 requêtes/jour (MVP) - Volume : 1000 utilisateurs × 10% = 100 requêtes/jour (MVP)
- Critère : Aucune dépendance à un service tiers payant - 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) ### IP2Location Lite (choix retenu)
**Avantages** : **Avantages** :
- Gratuit (pas de limite de requêtes) - Gratuit (pas de limite de requêtes)
- Self-hosted (souveraineté des données, cohérence avec [ADR-004](004-cdn.md)) - 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) - 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 - Pas de compte tiers requis
**Inconvénients** : **Inconvénients** :
- Maintenance mensuelle (mise à jour DB) - Maintenance mensuelle (mise à jour DB)
- Précision équivalente à MaxMind (~±50 km) - Précision équivalente à MaxMind (~±50 km)
### MaxMind GeoLite2 API (rejeté) ### MaxMind GeoLite2 API (rejeté)
**Pourquoi rejeté** : **Pourquoi rejeté** :
- Coût potentiel en cas de dépassement quota (risque faible mais existant) - Coût potentiel en cas de dépassement quota (risque faible mais existant)
- Dépendance à un service tiers (perte de souveraineté) - Dépendance à un service tiers (perte de souveraineté)
- Compte requis (friction opérationnelle) - 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é) ### Self-hosted MaxMind (rejeté)
**Pourquoi rejeté** : **Pourquoi rejeté** :
- Compte MaxMind obligatoire pour télécharger la DB (friction) - Compte MaxMind obligatoire pour télécharger la DB (friction)
- Complexité identique à IP2Location pour résultat équivalent - Complexité identique à IP2Location pour résultat équivalent
- IP2Location offre même fonctionnalité sans compte tiers - IP2Location offre même fonctionnalité sans compte tiers
@@ -84,28 +90,33 @@ flowchart TD
### Maintenance ### Maintenance
**Mise à jour mensuelle** : **Mise à jour mensuelle** :
- Cron job télécharge nouvelle DB IP2Location (1er du mois) - Cron job télécharge nouvelle DB IP2Location (1er du mois)
- Backup DB actuelle avant remplacement - Backup DB actuelle avant remplacement
- Rechargement service GeoIP (hot reload sans downtime) - Rechargement service GeoIP (hot reload sans downtime)
**Monitoring** : **Monitoring** :
- Alertes si DB > 60 jours (DB obsolète) - Alertes si DB > 60 jours (DB obsolète)
- Logs requêtes "IP non trouvée" (détection problèmes DB) - Logs requêtes "IP non trouvée" (détection problèmes DB)
## Conséquences ## Conséquences
### Positives ### Positives
- Aucun coût récurrent (gratuit à l'infini) - Aucun coût récurrent (gratuit à l'infini)
- Souveraineté complète des données (cohérence ADR-004) - Souveraineté complète des données (cohérence ADR-004)
- Pas de dépendance externe (service tiers) - Pas de dépendance externe (service tiers)
- Latence minimale (lookup local SQLite < 1ms) - Latence minimale (lookup local SQLite < 1ms)
### Négatives ### Négatives
- Maintenance mensuelle requise (automatisable) - Maintenance mensuelle requise (automatisable)
- Précision limitée (±50 km, acceptable pour mode dégradé) - Précision limitée (±50 km, acceptable pour mode dégradé)
- Taille base de données (~50-100 MB sur disque) - Taille base de données (~50-100 MB sur disque)
### Risques atténués ### Risques atténués
- **DB obsolète** : Alertes automatiques si > 60 jours - **DB obsolète** : Alertes automatiques si > 60 jours
- **IP non trouvée** : Fallback "France" par défaut (code pays FR) - **IP non trouvée** : Fallback "France" par défaut (code pays FR)
- **Perte DB** : Backup automatique avant chaque mise à jour - **Perte DB** : Backup automatique avant chaque mise à jour

View File

@@ -6,6 +6,7 @@
## Contexte ## 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 : 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 - **Licences permissives** (MIT, Apache-2.0, BSD) sans restrictions commerciales
- **Maturité** et maintenance active (écosystème Flutter) - **Maturité** et maintenance active (écosystème Flutter)
- **Performance native** (pas de bridge JS) - **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 ## Alternatives considérées
### State Management ### State Management
- **flutter_bloc** (choisi) : Pattern BLoC, testable, reactive - **flutter_bloc** (choisi) : Pattern BLoC, testable, reactive
- **riverpod** : Plus moderne, moins mature - **riverpod** : Plus moderne, moins mature
- **provider** : Simple mais limité pour app complexe - **provider** : Simple mais limité pour app complexe
- **getx** : Performance mais opinions controversées - **getx** : Performance mais opinions controversées
### Audio ### Audio
- **just_audio** (choisi) : HLS natif, communauté active - **just_audio** (choisi) : HLS natif, communauté active
- **audioplayers** : Moins mature pour streaming - **audioplayers** : Moins mature pour streaming
- **flutter_sound** : Orienté recording, pas streaming - **flutter_sound** : Orienté recording, pas streaming
### Géolocalisation ### Géolocalisation
- **geolocator** (choisi) : Standard Flutter, 1.2K+ stars - **geolocator** (choisi) : Standard Flutter, 1.2K+ stars
- **location** : Moins maintenu - **location** : Moins maintenu
- **background_location** : Spécifique background uniquement - **background_location** : Spécifique background uniquement
### Notifications Push ### Notifications Push
- **flutter_apns + flutter_fcm** (choisi) : Implémentation directe APNS/FCM, pas de vendor lock-in - **flutter_apns + flutter_fcm** (choisi) : Implémentation directe APNS/FCM, pas de vendor lock-in
- **firebase_messaging** : SDK Firebase, vendor lock-in Google - **firebase_messaging** : SDK Firebase, vendor lock-in Google
- **OneSignal** : Plus cher (500€/mois @ 100K users), vendor lock-in - **OneSignal** : Plus cher (500€/mois @ 100K users), vendor lock-in
- **Custom WebSocket** : Complexe, toujours besoin APNS/FCM au final (voir ADR-017) - **Custom WebSocket** : Complexe, toujours besoin APNS/FCM au final (voir ADR-017)
### Geofencing (Phase 2) ### Geofencing (Phase 2)
- **geofence_service** (choisi) : Natif iOS/Android, économie batterie optimale - **geofence_service** (choisi) : Natif iOS/Android, économie batterie optimale
- **background_geolocation** : Payant (149$/an par app) - **background_geolocation** : Payant (149$/an par app)
- **flutter_background_location** : Moins mature - **flutter_background_location** : Moins mature
@@ -82,17 +88,20 @@ Utilisation de **9 librairies open-source** Flutter avec licences permissives, d
## Justification ## Justification
### Licences ### Licences
- **7/9 librairies** : MIT (permissive totale) - **7/9 librairies** : MIT (permissive totale)
- **2/9** : BSD-3 (permissive, compatible commercial) - **2/9** : BSD-3 (permissive, compatible commercial)
- **Compatibilité totale** : Aucun conflit de licence, aucune restriction commerciale - **Compatibilité totale** : Aucun conflit de licence, aucune restriction commerciale
### Maturité ### Maturité
- **flutter_bloc** : 11.6K stars, adoption large (state management standard) - **flutter_bloc** : 11.6K stars, adoption large (state management standard)
- **just_audio** : 900+ stars, utilisé production (podcasts apps) - **just_audio** : 900+ stars, utilisé production (podcasts apps)
- **geolocator** : 1.2K stars, maintenu BaseFlow (entreprise Flutter) - **geolocator** : 1.2K stars, maintenu BaseFlow (entreprise Flutter)
- **dio** : 12K+ stars, client HTTP le plus utilisé Flutter - **dio** : 12K+ stars, client HTTP le plus utilisé Flutter
### Performance ### Performance
- **Compilation native** : Dart → ARM64 (pas de bridge JS comme React Native) - **Compilation native** : Dart → ARM64 (pas de bridge JS comme React Native)
- **just_audio** : Utilise AVPlayer (iOS) et ExoPlayer (Android) natifs - **just_audio** : Utilise AVPlayer (iOS) et ExoPlayer (Android) natifs
- **geolocator** : Accès direct CoreLocation (iOS) et FusedLocation (Android) - **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 - **geofence_service** (Phase 2) : Geofencing natif, minimise consommation batterie
### Conformité Stores ### Conformité Stores
- **Permissions progressives** : `permission_handler` + stratégie ADR-010 - **Permissions progressives** : `permission_handler` + stratégie ADR-010
- **Background modes MVP** : `geolocator` (When In Use) + `firebase_messaging` approuvés stores - **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%) - **Background modes Phase 2** : `geofence_service` nécessite permission "Always" (taux acceptation ~30%)
@@ -171,6 +181,7 @@ graph TB
## Conséquences ## Conséquences
### Positives ### Positives
- ✅ Aucune restriction licence commerciale (100% permissif) - ✅ Aucune restriction licence commerciale (100% permissif)
- ✅ Stack cohérent avec ADR-010 (Frontend Mobile) - ✅ Stack cohérent avec ADR-010 (Frontend Mobile)
- ✅ Performance native (compilation ARM64 directe) - ✅ Performance native (compilation ARM64 directe)
@@ -179,6 +190,7 @@ graph TB
- ✅ Conformité stores (permissions progressives) - ✅ Conformité stores (permissions progressives)
### Négatives ### Négatives
- ⚠️ **CarPlay/Android Auto** : Packages communautaires (pas officiels Flutter) - ⚠️ **CarPlay/Android Auto** : Packages communautaires (pas officiels Flutter)
- ⚠️ **Configuration APNS/FCM** : Gestion certificats et OAuth2, configuration manuelle - ⚠️ **Configuration APNS/FCM** : Gestion certificats et OAuth2, configuration manuelle
- ⚠️ **Permission "Always" Phase 2** : Taux acceptation ~30% (geofencing local) - ⚠️ **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). > **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)** : **Core (Phase 1 MVP)** :
- `flutter_bloc` - State management - `flutter_bloc` - State management
- `just_audio` - Audio HLS streaming - `just_audio` - Audio HLS streaming
- `dio` - HTTP client - `dio` - HTTP client
@@ -197,6 +210,7 @@ graph TB
- `cached_network_image` - Cache images - `cached_network_image` - Cache images
**Géolocalisation & Notifications (Phase 1 MVP)** : **Géolocalisation & Notifications (Phase 1 MVP)** :
- `geolocator` - GPS haute précision, WebSocket position updates - `geolocator` - GPS haute précision, WebSocket position updates
- `flutter_apns` - Push notifications APNS natif iOS (ADR-017) - `flutter_apns` - Push notifications APNS natif iOS (ADR-017)
- `flutter_fcm` - Push notifications FCM natif Android (ADR-017) - `flutter_fcm` - Push notifications FCM natif Android (ADR-017)
@@ -204,10 +218,12 @@ graph TB
- `permission_handler` - Gestion permissions - `permission_handler` - Gestion permissions
**CarPlay/Android Auto (optionnels Phase 1)** : **CarPlay/Android Auto (optionnels Phase 1)** :
- `flutter_carplay` - Intégration CarPlay - `flutter_carplay` - Intégration CarPlay
- `android_auto_flutter` - Support Android Auto - `android_auto_flutter` - Support Android Auto
**Geofencing (Phase 2 Post-MVP)** : **Geofencing (Phase 2 Post-MVP)** :
- `geofence_service` - Geofencing local pour mode offline (ADR-017 Phase 2) - `geofence_service` - Geofencing local pour mode offline (ADR-017 Phase 2)
### Migration depuis ADR-010 ### 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 ## Risques et Mitigations
### Risque 1 : CarPlay/Android Auto packages communautaires ### Risque 1 : CarPlay/Android Auto packages communautaires
- **Impact** : Maintenance non garantie par Flutter team - **Impact** : Maintenance non garantie par Flutter team
- **Mitigation** : Fork privé si besoin, contribution upstream, ou développement custom si critique - **Mitigation** : Fork privé si besoin, contribution upstream, ou développement custom si critique
### Risque 2 : Validation App Store (permissions background) ### Risque 2 : Validation App Store (permissions background)
- **Impact** : Taux de rejet ~70% si mal justifié - **Impact** : Taux de rejet ~70% si mal justifié
- **Mitigation Phase 1** : Permission "When In Use" seulement (MVP), moins scrutée par Apple - **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" - **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 ### Risque 3 : Performance audio HLS en arrière-plan
- **Impact** : Interruptions si OS tue l'app - **Impact** : Interruptions si OS tue l'app
- **Mitigation** : Background audio task iOS, foreground service Android (natif dans `just_audio`) - **Mitigation** : Background audio task iOS, foreground service Android (natif dans `just_audio`)

View File

@@ -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 - **Rate limiting** : Protection contre les abus API
Les contraintes de performance sont strictes : Les contraintes de performance sont strictes :
- Latence p99 < 5ms pour les requêtes de cache - Latence p99 < 5ms pour les requêtes de cache
- Support de 100K+ requêtes/seconde en lecture - Support de 100K+ requêtes/seconde en lecture
- Persistance optionnelle (données non critiques) - 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. **Redis 7+ en mode Cluster** sera utilisé comme solution de cache principale.
Configuration : Configuration :
- Mode Cluster avec 3 nœuds minimum (haute disponibilité) - Mode Cluster avec 3 nœuds minimum (haute disponibilité)
- Persistence RDB désactivée pour les caches chauds (performance maximale) - Persistence RDB désactivée pour les caches chauds (performance maximale)
- AOF activé uniquement pour les sessions utilisateurs (durabilité) - 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 ### Écosystème Go
Librairie `go-redis/redis` (13K+ stars GitHub) : Librairie `go-redis/redis` (13K+ stars GitHub) :
- Support complet Redis Cluster - Support complet Redis Cluster
- Pipeline et transactions - Pipeline et transactions
- Context-aware (intégration Go idiomatique) - Context-aware (intégration Go idiomatique)
@@ -84,6 +87,7 @@ Librairie `go-redis/redis` (13K+ stars GitHub) :
### Pub/Sub pour temps réel ### Pub/Sub pour temps réel
Support natif de messaging publish/subscribe pour : Support natif de messaging publish/subscribe pour :
- Notifications push (invalidation de cache) - Notifications push (invalidation de cache)
- Événements temps réel (nouveau contenu géolocalisé) - Événements temps réel (nouveau contenu géolocalisé)
- Coordination entre instances API (scaling horizontal) - Coordination entre instances API (scaling horizontal)
@@ -106,12 +110,14 @@ Support natif de messaging publish/subscribe pour :
### Stratégie de cache ### Stratégie de cache
**TTL par type de donnée** : **TTL par type de donnée** :
- Métadonnées de contenu : 15 minutes (mise à jour rare) - Métadonnées de contenu : 15 minutes (mise à jour rare)
- Résultats géolocalisés : 5 minutes (contenus statiques géographiquement) - Résultats géolocalisés : 5 minutes (contenus statiques géographiquement)
- Sessions utilisateurs : 24 heures (renouvellement automatique) - Sessions utilisateurs : 24 heures (renouvellement automatique)
- Rate limiting : 1 minute (fenêtre glissante) - Rate limiting : 1 minute (fenêtre glissante)
**Invalidation** : **Invalidation** :
- Publication de contenu → `DEL` métadonnées + publication Pub/Sub - Publication de contenu → `DEL` métadonnées + publication Pub/Sub
- Modification géolocalisation → `GEOREM` puis `GEOADD` - Modification géolocalisation → `GEOREM` puis `GEOADD`
- Logout utilisateur → `DEL` session - Logout utilisateur → `DEL` session
@@ -119,21 +125,25 @@ Support natif de messaging publish/subscribe pour :
### Configuration production ### Configuration production
**Cluster 3 nœuds** (minimum haute disponibilité) : **Cluster 3 nœuds** (minimum haute disponibilité) :
- 1 master + 2 replicas - 1 master + 2 replicas
- Répartition sur 3 zones de disponibilité (anti-affinité) - Répartition sur 3 zones de disponibilité (anti-affinité)
- `cluster-require-full-coverage no` → lecture dégradée si nœud down - `cluster-require-full-coverage no` → lecture dégradée si nœud down
**Mémoire** : **Mémoire** :
- `maxmemory 2gb` par nœud (ajustable selon charge) - `maxmemory 2gb` par nœud (ajustable selon charge)
- `maxmemory-policy allkeys-lru` → éviction automatique anciennes clés - `maxmemory-policy allkeys-lru` → éviction automatique anciennes clés
**Persistance** : **Persistance** :
- RDB désactivé (`save ""`) pour caches chauds - RDB désactivé (`save ""`) pour caches chauds
- AOF `appendonly yes` uniquement pour sessions (nœud dédié optionnel) - AOF `appendonly yes` uniquement pour sessions (nœud dédié optionnel)
### Monitoring ### Monitoring
Métriques critiques à suivre : Métriques critiques à suivre :
- Taux de hit/miss par namespace (target >95% hit rate) - Taux de hit/miss par namespace (target >95% hit rate)
- Latence p99 par commande (alerter si >10ms) - Latence p99 par commande (alerter si >10ms)
- Fragmentation mémoire (rebalance si >1.5) - Fragmentation mémoire (rebalance si >1.5)

View File

@@ -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é. 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** : **Problématique** :
- ❌ Temps de CI/CD inutilement longs (rebuild complet ~15 min) - ❌ Temps de CI/CD inutilement longs (rebuild complet ~15 min)
- ❌ Gaspillage de ressources GitHub Actions - ❌ Gaspillage de ressources GitHub Actions
- ❌ Ralentissement du feedback développeur - ❌ Ralentissement du feedback développeur
@@ -44,6 +45,7 @@ RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documen
#### Workflow Backend (`backend.yml`) #### Workflow Backend (`backend.yml`)
**Déclencheurs** : **Déclencheurs** :
- Branches : `main`, `develop` - Branches : `main`, `develop`
- Chemins surveillés : - Chemins surveillés :
- `backend/**` : Code Go, migrations, configuration - `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 - `.github/workflows/backend.yml` : Modifications du workflow lui-même
**Jobs exécutés** : **Jobs exécutés** :
- **Tests unitaires** : Exécution `go test` sur tous les packages - **Tests unitaires** : Exécution `go test` sur tous les packages
- **Tests d'intégration** : Utilisation de Testcontainers avec PostgreSQL/PostGIS - **Tests d'intégration** : Utilisation de Testcontainers avec PostgreSQL/PostGIS
- **Tests BDD** : Exécution Godog sur features `api/` et `e2e/` - **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`) #### Workflow Mobile (`mobile.yml`)
**Déclencheurs** : **Déclencheurs** :
- Branches : `main`, `develop` - Branches : `main`, `develop`
- Chemins surveillés : - Chemins surveillés :
- `mobile/**` : Code Flutter/Dart, assets, configuration - `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 - `.github/workflows/mobile.yml` : Modifications du workflow lui-même
**Jobs exécutés** : **Jobs exécutés** :
- **Tests unitaires** : Exécution `flutter test` sur widgets et logique métier - **Tests unitaires** : Exécution `flutter test` sur widgets et logique métier
- **Tests d'intégration** : Tests d'intégration Flutter (interactions UI complexes) - **Tests d'intégration** : Tests d'intégration Flutter (interactions UI complexes)
- **Lint** : Analyse statique `flutter analyze` - **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) - **Build iOS** : Compilation IPA release sans codesign (dépend des tests)
**Environnement** : **Environnement** :
- Tests/Lint/Build Android : Ubuntu latest - Tests/Lint/Build Android : Ubuntu latest
- Build iOS : macOS latest (requis pour Xcode) - Build iOS : macOS latest (requis pour Xcode)
- Flutter 3.16.0+ - Flutter 3.16.0+
@@ -89,6 +95,7 @@ RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documen
#### Workflow Shared (`shared.yml`) #### Workflow Shared (`shared.yml`)
**Déclencheurs** : **Déclencheurs** :
- Branches : `main`, `develop` - Branches : `main`, `develop`
- Chemins surveillés : - Chemins surveillés :
- `docs/**` : ADR, règles métier, documentation technique - `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 - `.github/workflows/shared.yml` : Modifications du workflow lui-même
**Jobs exécutés** : **Jobs exécutés** :
- **Validation documentation** : Build MkDocs en mode strict (détecte erreurs markdown) - **Validation documentation** : Build MkDocs en mode strict (détecte erreurs markdown)
- **Vérification liens** : Validation des liens internes/externes dans documentation - **Vérification liens** : Validation des liens internes/externes dans documentation
- **Tests code partagé** : Exécution tests si du code partagé backend-mobile existe - **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) | | **Commit mixte (backend + mobile + docs)** | ✅ | ✅ | ✅ | ~13 min (parallèle) |
**Économie de temps** : **Économie de temps** :
- Commit backend-only : ~5 min (vs 15 min sans path filters) = **67% plus rapide** - Commit backend-only : ~5 min (vs 15 min sans path filters) = **67% plus rapide**
- Commit docs-only : ~30s (vs 15 min) = **97% 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 : 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** : **Exemples de features E2E** :
- `features/e2e/abonnements/` : Formulaire mobile → API Zitadel → API RoadWave → Mangopay → Confirmation UI - `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 - `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 **Complexité initiale** : setup plus complexe que workflow monolithique
**Mitigation** : **Mitigation** :
- Utiliser des **composite actions** pour partager la config commune - Utiliser des **composite actions** pour partager la config commune
- Documentation claire dans ce ADR - Documentation claire dans ce ADR
- Coût initial faible (~2h setup) vs gains à long terme importants - 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 ### Plan d'Implémentation
**Phase 1** : Setup workflows de base (~1h) **Phase 1** : Setup workflows de base (~1h)
- Créer `backend.yml` avec jobs test + lint + build - Créer `backend.yml` avec jobs test + lint + build
- Créer `mobile.yml` avec jobs test + lint + build - Créer `mobile.yml` avec jobs test + lint + build
- Créer `shared.yml` avec validation docs - Créer `shared.yml` avec validation docs
**Phase 2** : Configuration path filters (~30 min) **Phase 2** : Configuration path filters (~30 min)
- Ajouter `paths:` à chaque workflow - Ajouter `paths:` à chaque workflow
- Tester avec commits isolés (backend-only, mobile-only, docs-only) - Tester avec commits isolés (backend-only, mobile-only, docs-only)
**Phase 3** : Optimisations (~30 min) **Phase 3** : Optimisations (~30 min)
- Ajouter caching (Go modules, Flutter dependencies, node_modules) - Ajouter caching (Go modules, Flutter dependencies, node_modules)
- Créer composite actions pour config partagée - Créer composite actions pour config partagée
- Ajouter badges status dans README - 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 ⚠️ **Faux négatifs** : path filter mal configuré → test non exécuté → bug en production
**Mitigation** : **Mitigation** :
- Features E2E déclenchent toujours backend + mobile (safety net) - Features E2E déclenchent toujours backend + mobile (safety net)
- Tests de validation dans le plan d'implémentation - Tests de validation dans le plan d'implémentation
- Review obligatoire des modifications de workflows - Review obligatoire des modifications de workflows

View File

@@ -6,6 +6,7 @@
## Contexte ## Contexte
Le système de modération RoadWave doit traiter des signalements de contenu audio problématique (haine, spam, droits d'auteur, etc.) avec : 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) - **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 - **Scalabilité** : 0-10K+ signalements/mois
- **Conformité DSA** : transparence, traçabilité, délais garantis - **Conformité DSA** : transparence, traçabilité, délais garantis
@@ -165,12 +166,14 @@ graph TB
### Dépendances ### Dépendances
**Backend Go** : **Backend Go** :
- `gofiber/fiber/v3` : API Dashboard - `gofiber/fiber/v3` : API Dashboard
- `jackc/pgx/v5` : PostgreSQL + LISTEN/NOTIFY - `jackc/pgx/v5` : PostgreSQL + LISTEN/NOTIFY
- `redis/rueidis` : Cache priorisation - `redis/rueidis` : Cache priorisation
- Whisper : via Python subprocess ou go-whisper bindings - Whisper : via Python subprocess ou go-whisper bindings
**Frontend Dashboard** : **Frontend Dashboard** :
- `react` : Framework UI - `react` : Framework UI
- `@tanstack/react-table` : Tables performantes - `@tanstack/react-table` : Tables performantes
- `wavesurfer.js` : Player audio avec waveform - `wavesurfer.js` : Player audio avec waveform

View File

@@ -6,6 +6,7 @@
## Contexte ## Contexte
RoadWave nécessite un système de monitoring pour garantir la disponibilité cible 99.9% (SLO) définie dans : 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 - **Métriques** : latency p99 < 100ms, throughput API, erreurs
- **Alerting** : détection pannes, dégradations performance - **Alerting** : détection pannes, dégradations performance
- **Incident response** : runbooks, escalation, post-mortems - **Incident response** : runbooks, escalation, post-mortems
@@ -93,16 +94,19 @@ graph TB
### Métriques Clés ### Métriques Clés
**API Performance** (requêtes PromQL) : **API Performance** (requêtes PromQL) :
- Latency p99 : histogramme quantile 99e percentile sur durée requêtes HTTP (fenêtre 5 min) - 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) - Error rate : ratio requêtes 5xx / total requêtes (fenêtre 5 min)
- Throughput : taux de requêtes par seconde (fenêtre 5 min) - Throughput : taux de requêtes par seconde (fenêtre 5 min)
**Infrastructure** : **Infrastructure** :
- CPU usage : taux utilisation CPU (mode non-idle, fenêtre 5 min) - CPU usage : taux utilisation CPU (mode non-idle, fenêtre 5 min)
- Memory usage : ratio mémoire disponible / totale - Memory usage : ratio mémoire disponible / totale
- Disk I/O : temps I/O disque (fenêtre 5 min) - Disk I/O : temps I/O disque (fenêtre 5 min)
**Business** (compteurs custom) : **Business** (compteurs custom) :
- Active users (DAU) : `roadwave_active_users_total` - Active users (DAU) : `roadwave_active_users_total`
- Audio streams actifs : `roadwave_hls_streams_active` - Audio streams actifs : `roadwave_hls_streams_active`
- Signalements modération : `roadwave_moderation_reports_total` - Signalements modération : `roadwave_moderation_reports_total`
@@ -182,6 +186,7 @@ graph TB
### Dashboards Grafana ### Dashboards Grafana
**Dashboard principal** : **Dashboard principal** :
- Latency p50/p95/p99 API (5 min, 1h, 24h) - Latency p50/p95/p99 API (5 min, 1h, 24h)
- Error rate 5xx/4xx (seuil alerte >1%) - Error rate 5xx/4xx (seuil alerte >1%)
- Throughput requests/sec - Throughput requests/sec
@@ -189,12 +194,14 @@ graph TB
- Business : DAU, streams actifs, signalements modération - Business : DAU, streams actifs, signalements modération
**Dashboard PostgreSQL** : **Dashboard PostgreSQL** :
- Slow queries (>100ms) - Slow queries (>100ms)
- Connections actives vs max - Connections actives vs max
- Cache hit ratio (cible >95%) - Cache hit ratio (cible >95%)
- Deadlocks count - Deadlocks count
**Dashboard Redis** : **Dashboard Redis** :
- Memory usage - Memory usage
- Evictions count - Evictions count
- Commands/sec - Commands/sec
@@ -203,27 +210,32 @@ graph TB
### Alerting Rules ### Alerting Rules
**Alertes critiques** (Telegram + Email immédiat) : **Alertes critiques** (Telegram + Email immédiat) :
- **API Down** : Job API indisponible pendant >1 min → Notification immédiate - **API Down** : Job API indisponible pendant >1 min → Notification immédiate
- **High Error Rate** : Taux erreurs 5xx >1% pendant >5 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 - **Database Down** : PostgreSQL indisponible pendant >1 min → Notification immédiate
**Alertes warnings** (Email uniquement) : **Alertes warnings** (Email uniquement) :
- **High Latency** : Latency p99 >100ms pendant >10 min → Investigation requise - **High Latency** : Latency p99 >100ms pendant >10 min → Investigation requise
- **Disk Space Running Out** : Espace disque <10% pendant >30 min → Nettoyage requis - **Disk Space Running Out** : Espace disque <10% pendant >30 min → Nettoyage requis
### Backup & Disaster Recovery ### Backup & Disaster Recovery
**PostgreSQL WAL-E** : **PostgreSQL WAL-E** :
- Méthode : Backup continu Write-Ahead Log (WAL) - Méthode : Backup continu Write-Ahead Log (WAL)
- Rétention : 7 jours full + WAL incrémentaux - Rétention : 7 jours full + WAL incrémentaux
- Stockage : S3 OVH région GRA (France) - Stockage : S3 OVH région GRA (France)
- Chiffrement : AES-256 server-side - Chiffrement : AES-256 server-side
**RTO (Recovery Time Objective)** : 1h **RTO (Recovery Time Objective)** : 1h
- Restore depuis S3 : ~30 min (DB 10 GB) - Restore depuis S3 : ~30 min (DB 10 GB)
- Validation + relance services : ~30 min - Validation + relance services : ~30 min
**RPO (Recovery Point Objective)** : 15 min **RPO (Recovery Point Objective)** : 15 min
- Fréquence archivage WAL : toutes les 15 min - Fréquence archivage WAL : toutes les 15 min
- Perte maximale : 15 min de transactions - Perte maximale : 15 min de transactions

View File

@@ -6,6 +6,7 @@
## Contexte ## Contexte
RoadWave manipule des données sensibles nécessitant une protection renforcée : RoadWave manipule des données sensibles nécessitant une protection renforcée :
- **Secrets applicatifs** : JWT signing key, DB credentials, Mangopay API keys - **Secrets applicatifs** : JWT signing key, DB credentials, Mangopay API keys
- **PII utilisateurs** : Positions GPS précises, emails, données bancaires (via Mangopay) - **PII utilisateurs** : Positions GPS précises, emails, données bancaires (via Mangopay)
- **Conformité** : RGPD (minimisation données, encryption at rest), PCI-DSS (paiements) - **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/`) 3. Login root + activation KV-v2 engine (path : `roadwave/`)
**Secrets stockés** : **Secrets stockés** :
- **JWT signing key** : Paire RS256 privée/publique - **JWT signing key** : Paire RS256 privée/publique
- **Database credentials** : Host, port, user, password (généré aléatoire 32 caractères) - **Database credentials** : Host, port, user, password (généré aléatoire 32 caractères)
- **Mangopay API** : Client ID, API key, webhook secret - **Mangopay API** : Client ID, API key, webhook secret
**Récupération depuis Backend Go** : **Récupération depuis Backend Go** :
- Utilisation SDK `hashicorp/vault/api` - Utilisation SDK `hashicorp/vault/api`
- Authentification via token Vault (variable env VAULT_TOKEN) - Authentification via token Vault (variable env VAULT_TOKEN)
- Récupération secrets via KVv2 engine - Récupération secrets via KVv2 engine
@@ -100,28 +103,33 @@ graph TB
### Encryption PII (Field-level) ### Encryption PII (Field-level)
**Données chiffrées** (AES-256-GCM) : **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)) - **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 - **Email** : chiffré en base, déchiffré uniquement à l'envoi
- **Numéro téléphone** : si ajouté (Phase 2) - **Numéro téléphone** : si ajouté (Phase 2)
**Architecture encryption** : **Architecture encryption** :
- Utilisation bibliothèque standard Go `crypto/aes` avec mode GCM (AEAD) - Utilisation bibliothèque standard Go `crypto/aes` avec mode GCM (AEAD)
- Master key 256 bits (32 bytes) récupérée depuis Vault - Master key 256 bits (32 bytes) récupérée depuis Vault
- Chiffrement : génération nonce aléatoire + seal GCM → encodage base64 - Chiffrement : génération nonce aléatoire + seal GCM → encodage base64
- Stockage : colonne `email_encrypted` en base PostgreSQL - Stockage : colonne `email_encrypted` en base PostgreSQL
**Contraintes** : **Contraintes** :
- Index direct sur champ chiffré impossible - Index direct sur champ chiffré impossible
- Solution : index sur hash SHA-256 de l'email chiffré pour recherche - Solution : index sur hash SHA-256 de l'email chiffré pour recherche
### HTTPS/TLS Configuration ### HTTPS/TLS Configuration
**Let's Encrypt wildcard certificate** : **Let's Encrypt wildcard certificate** :
- Méthode : Certbot avec DNS-01 challenge (API OVH) - Méthode : Certbot avec DNS-01 challenge (API OVH)
- Domaines couverts : `roadwave.fr` + `*.roadwave.fr` (wildcard) - Domaines couverts : `roadwave.fr` + `*.roadwave.fr` (wildcard)
- Renouvellement : automatique via cron quotidien (30j avant expiration) - Renouvellement : automatique via cron quotidien (30j avant expiration)
**Nginx TLS configuration** : **Nginx TLS configuration** :
- Protocol : TLS 1.3 uniquement (pas de TLS 1.2 ou inférieur) - Protocol : TLS 1.3 uniquement (pas de TLS 1.2 ou inférieur)
- Ciphers : TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384 - Ciphers : TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384
- HSTS : max-age 1 an, includeSubDomains - HSTS : max-age 1 an, includeSubDomains
@@ -214,12 +222,14 @@ graph TB
### Rate Limiting (Protection DDoS/Brute-force) ### Rate Limiting (Protection DDoS/Brute-force)
**Configuration** : **Configuration** :
- Middleware Fiber `limiter` avec backend Redis - Middleware Fiber `limiter` avec backend Redis
- Limite : 100 requêtes par minute par IP (global) - Limite : 100 requêtes par minute par IP (global)
- Clé de limitation : adresse IP client - Clé de limitation : adresse IP client
- Réponse limitation : HTTP 429 "Too many requests" - Réponse limitation : HTTP 429 "Too many requests"
**Rate limits par endpoint** : **Rate limits par endpoint** :
- `/auth/login` : 5 req/min/IP (protection brute-force) - `/auth/login` : 5 req/min/IP (protection brute-force)
- `/moderation/report` : 10 req/24h/user (anti-spam) - `/moderation/report` : 10 req/24h/user (anti-spam)
- API générale : 100 req/min/IP - 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 | | **Encryption master key** | Jamais (re-encryption massive) | Backup sécurisé uniquement |
**Process rotation DB credentials** : **Process rotation DB credentials** :
- Vault génère automatiquement nouveau password - Vault génère automatiquement nouveau password
- Vault met à jour PostgreSQL avec nouveau password - Vault met à jour PostgreSQL avec nouveau password
- Application récupère nouveau password au prochain accès Vault - Application récupère nouveau password au prochain accès Vault

View File

@@ -103,10 +103,12 @@ Quelles autres options ont été évaluées ?
## Conséquences ## Conséquences
### Positives ### Positives
- Avantage 1 - Avantage 1
- Avantage 2 - Avantage 2
### Négatives ### Négatives
- Limitation 1 - Limitation 1
- Compromis accepté - Compromis accepté

View File

@@ -7,6 +7,7 @@
## Contexte ## Contexte
RoadWave est une app audio géolocalisée utilisée en conduite (CarPlay/Android Auto) avec : RoadWave est une app audio géolocalisée utilisée en conduite (CarPlay/Android Auto) avec :
- Contenu généré par utilisateurs (UGC) - Contenu généré par utilisateurs (UGC)
- Monétisation : publicités géolocalisées + Premium (4.99€ web / 5.99€ IAP) - Monétisation : publicités géolocalisées + Premium (4.99€ web / 5.99€ IAP)
- GPS en arrière-plan - GPS en arrière-plan
@@ -15,6 +16,7 @@ RoadWave est une app audio géolocalisée utilisée en conduite (CarPlay/Android
## Stratégie de conformité ## Stratégie de conformité
**Approche multi-plateforme** avec : **Approche multi-plateforme** avec :
- Modération UGC robuste (IA + humain) - Modération UGC robuste (IA + humain)
- Prix différenciés selon région (US/EU/Monde) - Prix différenciés selon région (US/EU/Monde)
- GPS avec disclosure complète - GPS avec disclosure complète
@@ -32,6 +34,7 @@ RoadWave est une app audio géolocalisée utilisée en conduite (CarPlay/Android
## Conformité détaillée ## Conformité détaillée
### Android Auto / CarPlay ✅ ### Android Auto / CarPlay ✅
- 100% audio (pas de vidéo) - 100% audio (pas de vidéo)
- Commandes standard au volant - Commandes standard au volant
- Aucun achat in-car - Aucun achat in-car
@@ -42,16 +45,19 @@ RoadWave est une app audio géolocalisée utilisée en conduite (CarPlay/Android
### Google Play ⚠️ ### Google Play ⚠️
**UGC (critique)** : **UGC (critique)** :
- Modération hybride IA + humain ✅ - Modération hybride IA + humain ✅
- 3 premiers contenus validés manuellement ✅ - 3 premiers contenus validés manuellement ✅
- Système de strikes (4 = ban) ✅ - Système de strikes (4 = ban) ✅
- Signalement + blocage utilisateurs ✅ - Signalement + blocage utilisateurs ✅
**GPS Background (critique)** : **GPS Background (critique)** :
- Permission "Always Location" = **OPTIONNELLE** - Permission "Always Location" = **OPTIONNELLE**
- Demandée uniquement pour mode piéton (notifications arrière-plan audio-guides) - Demandée uniquement pour mode piéton (notifications arrière-plan audio-guides)
- Justification Play Console : - Justification Play Console :
> "RoadWave permet aux utilisateurs de recevoir des alertes audio-guides lorsqu'ils passent à pied près de monuments/musées, même quand l'app est en arrière-plan. Cette fonctionnalité est optionnelle et peut être désactivée dans les paramètres." > "RoadWave permet aux utilisateurs de recevoir des alertes audio-guides lorsqu'ils passent à pied près de monuments/musées, même quand l'app est en arrière-plan. Cette fonctionnalité est optionnelle et peut être désactivée dans les paramètres."
- In-app disclosure obligatoire (écran dédié avant demande permission) - In-app disclosure obligatoire (écran dédié avant demande permission)
- Si refusée : app fonctionne en mode voiture uniquement - Si refusée : app fonctionne en mode voiture uniquement
- **Action** : Remplir formulaire background location Play Console avec justification - **Action** : Remplir formulaire background location Play Console avec justification
@@ -68,19 +74,23 @@ RoadWave est une app audio géolocalisée utilisée en conduite (CarPlay/Android
### App Store ⚠️ ### App Store ⚠️
**Prix différenciés (légaux depuis 2025-2026)** : **Prix différenciés (légaux depuis 2025-2026)** :
- 🇺🇸 US : Lien externe autorisé (0% commission) - 🇺🇸 US : Lien externe autorisé (0% commission)
- 🇪🇺 EU : Paiement externe DMA (7-20% commission réduite) - 🇪🇺 EU : Paiement externe DMA (7-20% commission réduite)
- 🌍 Monde : IAP obligatoire (30% commission) - 🌍 Monde : IAP obligatoire (30% commission)
**UGC** : **UGC** :
- Mode Kids obligatoire (filtrage selon âge) ✅ - Mode Kids obligatoire (filtrage selon âge) ✅
- Système de modération + signalement ✅ - Système de modération + signalement ✅
**GPS Background (critique)** : **GPS Background (critique)** :
- Permission "Always Location" = **OPTIONNELLE** - Permission "Always Location" = **OPTIONNELLE**
- Deux strings Info.plist requises : - Deux strings Info.plist requises :
- `NSLocationWhenInUseUsageDescription` : explication mode voiture - `NSLocationWhenInUseUsageDescription` : explication mode voiture
- `NSLocationAlwaysAndWhenInUseUsageDescription` : explication mode piéton (optionnel) - `NSLocationAlwaysAndWhenInUseUsageDescription` : explication mode piéton (optionnel)
- In-app disclosure obligatoire avant demande "Always" - In-app disclosure obligatoire avant demande "Always"
- Flux two-step : When In Use → Always (si user active mode piéton) - Flux two-step : When In Use → Always (si user active mode piéton)
- Si refusée : app fonctionne en mode voiture uniquement - Si refusée : app fonctionne en mode voiture uniquement
@@ -89,6 +99,7 @@ RoadWave est une app audio géolocalisée utilisée en conduite (CarPlay/Android
### Revenus créateurs ### Revenus créateurs
**Position** : Paiements créateurs = "services" (comme YouTube/Uber), pas IAP **Position** : Paiements créateurs = "services" (comme YouTube/Uber), pas IAP
- Paiement via Mangopay Connect (externe) - Paiement via Mangopay Connect (externe)
- Commission stores uniquement sur Premium (IAP) - Commission stores uniquement sur Premium (IAP)
- Comparables : YouTube AdSense, TikTok Creator Fund, Uber - Comparables : YouTube AdSense, TikTok Creator Fund, Uber
@@ -110,12 +121,14 @@ RoadWave est une app audio géolocalisée utilisée en conduite (CarPlay/Android
## Stratégie de lancement ## Stratégie de lancement
**Phase 1 - MVP** : **Phase 1 - MVP** :
- IAP uniquement (5.99€/mois mondial) - IAP uniquement (5.99€/mois mondial)
- Modération UGC active - Modération UGC active
- GPS avec disclosure - GPS avec disclosure
- CarPlay/Android Auto basique - CarPlay/Android Auto basique
**Phase 2 - Post-validation** : **Phase 2 - Post-validation** :
- Prix différenciés US (lien externe 4.99€) - Prix différenciés US (lien externe 4.99€)
- Paiement externe EU (DMA) - Paiement externe EU (DMA)
- Monétisation créateurs (Mangopay) - Monétisation créateurs (Mangopay)

View File

@@ -200,13 +200,6 @@ domains/<domain>/
└── features/ # Tests BDD Gherkin (*.feature) └── features/ # Tests BDD Gherkin (*.feature)
``` ```
## Navigation
- *(structure legacy, déprécié)*
- [🏛️ ADR (Architecture Decision Records)](../adr/README.md)
- [⚖️ Documentation légale](../legal/README.md)
- [🔧 Documentation technique](../TECHNICAL.md)
## Ubiquitous Language Global ## Ubiquitous Language Global
**Termes transversaux utilisés dans tous les domaines** : **Termes transversaux utilisés dans tous les domaines** :

View File

@@ -24,6 +24,7 @@ Le domaine **Shared** constitue le **Core Domain** de RoadWave. Il contient les
## Ubiquitous Language ## Ubiquitous Language
**Termes métier du domaine partagé** : **Termes métier du domaine partagé** :
- **User** : Utilisateur de la plateforme (auditeur, créateur, ou les deux) - **User** : Utilisateur de la plateforme (auditeur, créateur, ou les deux)
- **Content** : Tout contenu audio diffusé sur la plateforme - **Content** : Tout contenu audio diffusé sur la plateforme
- **Subscription** : Abonnement d'un utilisateur à un créateur ou une catégorie - **Subscription** : Abonnement d'un utilisateur à un créateur ou une catégorie

View File

@@ -25,6 +25,7 @@ erDiagram
## Légende ## Légende
**Statuts** : **Statuts** :
- `pending`: Grace period actif (30j), compte désactivé, annulation possible - `pending`: Grace period actif (30j), compte désactivé, annulation possible
- `cancelled`: Utilisateur a annulé via lien email - `cancelled`: Utilisateur a annulé via lien email
- `completed`: Suppression effective réalisée après 30j - `completed`: Suppression effective réalisée après 30j
@@ -36,5 +37,6 @@ erDiagram
4. Si 30j écoulés → job cron supprime données, anonymise contenus 4. Si 30j écoulés → job cron supprime données, anonymise contenus
**Données supprimées** : **Données supprimées** :
- Profil utilisateur, historique GPS/écoute, sessions - Profil utilisateur, historique GPS/écoute, sessions
- Contenus créés : anonymisés (`créateur = "Utilisateur supprimé"`) - Contenus créés : anonymisés (`créateur = "Utilisateur supprimé"`)

View File

@@ -36,16 +36,19 @@ erDiagram
## Légende ## Légende
**Sévérité** : **Sévérité** :
- `low`: Pas de notification requise (mesures techniques suffisantes) - `low`: Pas de notification requise (mesures techniques suffisantes)
- `medium`: Notification CNIL uniquement - `medium`: Notification CNIL uniquement
- `high`: Notification CNIL + utilisateurs - `high`: Notification CNIL + utilisateurs
- `critical`: Notification immédiate tous canaux + SMS fondateur - `critical`: Notification immédiate tous canaux + SMS fondateur
**Timeline 72h** : **Timeline 72h** :
- H+0 : Détection, confinement - H+0 : Détection, confinement
- H+24 : Évaluation gravité - H+24 : Évaluation gravité
- H+48 : Notification CNIL si requis - H+48 : Notification CNIL si requis
- H+72 : Notification utilisateurs si risque élevé - H+72 : Notification utilisateurs si risque élevé
**Catégories de données** : **Catégories de données** :
- `data_categories_affected`: JSON `["gps", "email", "listening_history"]` - `data_categories_affected`: JSON `["gps", "email", "listening_history"]`

View File

@@ -23,17 +23,20 @@ erDiagram
## Légende ## Légende
**Types de consentement** : **Types de consentement** :
- `geolocation_precise` : Géolocalisation GPS précise (obligatoire pour contenu hyperlocal) - `geolocation_precise` : Géolocalisation GPS précise (obligatoire pour contenu hyperlocal)
- `analytics` : Analytics Matomo (optionnel) - `analytics` : Analytics Matomo (optionnel)
- `push_notifications` : Notifications push (optionnel) - `push_notifications` : Notifications push (optionnel)
- `cookies_analytics` : Cookies analytiques (optionnel) - `cookies_analytics` : Cookies analytiques (optionnel)
**Versioning** : **Versioning** :
- Chaque changement de CGU/politique = nouvelle version - Chaque changement de CGU/politique = nouvelle version
- Historique complet conservé (preuve légale) - Historique complet conservé (preuve légale)
- Format version : `v1.0`, `v2.0`, etc. - Format version : `v1.0`, `v2.0`, etc.
**Conformité RGPD** : **Conformité RGPD** :
- Granularité : fonctionnel / analytique / marketing - Granularité : fonctionnel / analytique / marketing
- Consentement libre et éclairé - Consentement libre et éclairé
- Révocable à tout moment - Révocable à tout moment

View File

@@ -21,11 +21,13 @@ erDiagram
## Légende ## Légende
**Action types** : **Action types** :
- `check_inactive`: Vérification quotidienne comptes inactifs > 5 ans - `check_inactive`: Vérification quotidienne comptes inactifs > 5 ans
- `send_warnings`: Envoi notifications (90j/30j/7j avant suppression) - `send_warnings`: Envoi notifications (90j/30j/7j avant suppression)
- `delete_accounts`: Suppression effective comptes inactifs - `delete_accounts`: Suppression effective comptes inactifs
**Règles de conservation** : **Règles de conservation** :
- Auditeur : 5 ans inactivité → suppression - Auditeur : 5 ans inactivité → suppression
- Créateur actif : jamais (tant que contenus écoutés) - Créateur actif : jamais (tant que contenus écoutés)
- Créateur inactif : 5 ans + 2 ans sans écoute → suppression - Créateur inactif : 5 ans + 2 ans sans écoute → suppression

View File

@@ -29,17 +29,20 @@ erDiagram
## Légende ## Légende
**Types d'appareil** : **Types d'appareil** :
- `mobile` : Smartphone Android/iOS - `mobile` : Smartphone Android/iOS
- `tablet` : Tablette - `tablet` : Tablette
- `desktop` : Ordinateur - `desktop` : Ordinateur
- `car` : Système embarqué (CarPlay/Android Auto) - `car` : Système embarqué (CarPlay/Android Auto)
**Appareil de confiance** : **Appareil de confiance** :
- Option "Ne plus demander sur cet appareil" → bypass 2FA pendant **30 jours** - Option "Ne plus demander sur cet appareil" → bypass 2FA pendant **30 jours**
- Révocable depuis paramètres compte - Révocable depuis paramètres compte
- Liste des appareils de confiance visible - Liste des appareils de confiance visible
**Sécurité** : **Sécurité** :
- Détection automatique nouveau device → notification push + email - Détection automatique nouveau device → notification push + email
- Localisation suspecte (pays différent) → alerte - Localisation suspecte (pays différent) → alerte
- Révocation individuelle ou globale possible - Révocation individuelle ou globale possible

View File

@@ -25,11 +25,13 @@ erDiagram
## Légende ## Légende
**Formats d'export** : **Formats d'export** :
- `json` : Machine-readable (données brutes) - `json` : Machine-readable (données brutes)
- `html` : Human-readable (page web stylée) - `html` : Human-readable (page web stylée)
- `zip` : Archive complète (JSON + HTML + audio files) - `zip` : Archive complète (JSON + HTML + audio files)
**Contenu de l'export** : **Contenu de l'export** :
- Profil utilisateur (email, pseudo, date inscription, bio) - Profil utilisateur (email, pseudo, date inscription, bio)
- Historique d'écoute (titres, dates, durées) - Historique d'écoute (titres, dates, durées)
- Contenus créés (audio + métadonnées) - Contenus créés (audio + métadonnées)
@@ -38,6 +40,7 @@ erDiagram
- Historique consentements RGPD - Historique consentements RGPD
**Statuts** : **Statuts** :
- `pending` : Demande en file d'attente - `pending` : Demande en file d'attente
- `generating` : Génération en cours (worker background) - `generating` : Génération en cours (worker background)
- `ready` : Export disponible au téléchargement - `ready` : Export disponible au téléchargement
@@ -45,6 +48,7 @@ erDiagram
- `expired` : Export expiré (supprimé automatiquement) - `expired` : Export expiré (supprimé automatiquement)
**Règles** : **Règles** :
- Génération asynchrone (worker background) - Génération asynchrone (worker background)
- Délai max : **48h** (conformité RGPD) - Délai max : **48h** (conformité RGPD)
- Conservation : **7 jours** après génération - Conservation : **7 jours** après génération

View File

@@ -21,6 +21,7 @@ erDiagram
## Légende ## Légende
**Catégories** : **Catégories** :
- `automobile` : Voitures, mécanique, course automobile - `automobile` : Voitures, mécanique, course automobile
- `travel` : Voyages, tourisme, découverte - `travel` : Voyages, tourisme, découverte
- `music` : Musique, concerts, artistes - `music` : Musique, concerts, artistes
@@ -33,12 +34,14 @@ erDiagram
- `nature` : Nature, randonnée, écologie - `nature` : Nature, randonnée, écologie
**Score** : **Score** :
- Échelle : **0-100** - Échelle : **0-100**
- Augmentation : +2% par like, +5% par abonnement créateur - Augmentation : +2% par like, +5% par abonnement créateur
- Diminution : -1% par skip rapide (<30s), -5% par signalement - Diminution : -1% par skip rapide (<30s), -5% par signalement
- Calcul combiné : Distance GPS + matching intérêts - Calcul combiné : Distance GPS + matching intérêts
**Algorithme recommandation** : **Algorithme recommandation** :
- **70% géolocalisation** : Proximité GPS - **70% géolocalisation** : Proximité GPS
- **30% centres d'intérêt** : Score jauges - **30% centres d'intérêt** : Score jauges
- Boost si créateur suivi : +0.3 au score final - Boost si créateur suivi : +0.3 au score final

View File

@@ -25,23 +25,27 @@ erDiagram
## Légende ## Légende
**Anonymisation progressive** : **Anonymisation progressive** :
- Données précises conservées **24h** (recommandation personnalisée) - Données précises conservées **24h** (recommandation personnalisée)
- Après 24h : conversion en **geohash précision 5** (~5km²) - Après 24h : conversion en **geohash précision 5** (~5km²)
- Coordonnées originales supprimées définitivement - Coordonnées originales supprimées définitivement
- Job quotidien PostGIS automatique - Job quotidien PostGIS automatique
**Exceptions** : **Exceptions** :
- Historique personnel visible (liste trajets) : conservation intégrale tant que compte actif - Historique personnel visible (liste trajets) : conservation intégrale tant que compte actif
- Analytics globales : uniquement geohash anonyme - Analytics globales : uniquement geohash anonyme
- Suppression complète si suppression du compte - Suppression complète si suppression du compte
**Contexte** : **Contexte** :
- `listening` : Position pendant écoute de contenu - `listening` : Position pendant écoute de contenu
- `search` : Position lors d'une recherche - `search` : Position lors d'une recherche
- `background` : Tracking en arrière-plan - `background` : Tracking en arrière-plan
- `manual` : Position partagée manuellement - `manual` : Position partagée manuellement
**Conformité RGPD** : **Conformité RGPD** :
- Vraie anonymisation (CNIL compliant) - Vraie anonymisation (CNIL compliant)
- Permet analytics agrégées (heatmaps trafic) - Permet analytics agrégées (heatmaps trafic)
- PostGIS natif, 0€ - PostGIS natif, 0€

View File

@@ -43,6 +43,7 @@ erDiagram
4. Révocation possible → `revoked_at` renseigné 4. Révocation possible → `revoked_at` renseigné
**Restrictions par défaut (13-15 ans)** : **Restrictions par défaut (13-15 ans)** :
- `gps_enabled`: `false` (GeoIP uniquement) - `gps_enabled`: `false` (GeoIP uniquement)
- `messaging_enabled`: `false` - `messaging_enabled`: `false`
- `content_16plus_enabled`: `false` - `content_16plus_enabled`: `false`

View File

@@ -32,10 +32,12 @@ erDiagram
## Légende ## Légende
**Versioning** : **Versioning** :
- `major_change`: `true` → popup obligatoire pour tous les utilisateurs - `major_change`: `true` → popup obligatoire pour tous les utilisateurs
- `major_change`: `false` → notification simple - `major_change`: `false` → notification simple
- Fichier source : `docs/legal/politique-confidentialite.md` (versionné Git) - Fichier source : `docs/legal/politique-confidentialite.md` (versionné Git)
**Popup si changement majeur** : **Popup si changement majeur** :
- Utilisateur doit accepter nouvelle version pour continuer - Utilisateur doit accepter nouvelle version pour continuer
- Refus → compte gelé (lecture seule) - Refus → compte gelé (lecture seule)

View File

@@ -29,6 +29,7 @@ erDiagram
## Légende ## Légende
**Catégories de signalement** : **Catégories de signalement** :
- `spam` : Contenu publicitaire non sollicité - `spam` : Contenu publicitaire non sollicité
- `hate_speech` : Discours haineux, discrimination - `hate_speech` : Discours haineux, discrimination
- `violence` : Violence explicite - `violence` : Violence explicite
@@ -39,6 +40,7 @@ erDiagram
- `other` : Autre raison (commentaire obligatoire) - `other` : Autre raison (commentaire obligatoire)
**Statuts** : **Statuts** :
- `pending` : En attente de revue - `pending` : En attente de revue
- `under_review` : En cours d'examen par modérateur - `under_review` : En cours d'examen par modérateur
- `actioned` : Action prise (contenu retiré/édité) - `actioned` : Action prise (contenu retiré/édité)
@@ -46,6 +48,7 @@ erDiagram
- `duplicate` : Doublon d'un signalement existant - `duplicate` : Doublon d'un signalement existant
**Actions possibles** : **Actions possibles** :
- `content_removed` : Contenu supprimé - `content_removed` : Contenu supprimé
- `content_edited` : Métadonnées modifiées (âge, tags) - `content_edited` : Métadonnées modifiées (âge, tags)
- `warning_sent` : Avertissement au créateur - `warning_sent` : Avertissement au créateur
@@ -54,6 +57,7 @@ erDiagram
- `no_action` : Aucune action (signalement infondé) - `no_action` : Aucune action (signalement infondé)
**Workflow modération** : **Workflow modération** :
- **3 premiers contenus** : Modération préalable obligatoire - **3 premiers contenus** : Modération préalable obligatoire
- **Après validation** : Modération a posteriori (signalements) - **Après validation** : Modération a posteriori (signalements)
- **Priorisation** : Nombre de signalements (>3 = urgent) - **Priorisation** : Nombre de signalements (>3 = urgent)

View File

@@ -30,16 +30,19 @@ erDiagram
## Légende ## Légende
**Durées de vie** : **Durées de vie** :
- Access token : **15 minutes** - Access token : **15 minutes**
- Refresh token : **30 jours** (rotatif) - Refresh token : **30 jours** (rotatif)
- Inactivité : Déconnexion automatique après **30 jours** - Inactivité : Déconnexion automatique après **30 jours**
**Sécurité** : **Sécurité** :
- Tokens stockés en **SHA256** (jamais en clair) - Tokens stockés en **SHA256** (jamais en clair)
- Rotation automatique des refresh tokens - Rotation automatique des refresh tokens
- Détection replay attack - Détection replay attack
**Multi-device** : **Multi-device** :
- Sessions simultanées **illimitées** - Sessions simultanées **illimitées**
- Révocation individuelle ou globale possible - Révocation individuelle ou globale possible
- Alertes si connexion depuis nouveau device ou pays différent - Alertes si connexion depuis nouveau device ou pays différent

View File

@@ -23,16 +23,19 @@ erDiagram
## Légende ## Légende
**Champs trackés** : **Champs trackés** :
- `email`: Re-vérification requise - `email`: Re-vérification requise
- `username`: Limite 1 changement/30j - `username`: Limite 1 changement/30j
- `bio`, `avatar_url`, `date_of_birth` - `bio`, `avatar_url`, `date_of_birth`
**Change reasons** : **Change reasons** :
- `user_edit`: Modification self-service utilisateur - `user_edit`: Modification self-service utilisateur
- `admin_correction`: Correction par admin - `admin_correction`: Correction par admin
- `gdpr_request`: Suite demande RGPD formelle - `gdpr_request`: Suite demande RGPD formelle
**Audit** : **Audit** :
- Historique complet conservé (preuve légale) - Historique complet conservé (preuve légale)
- Accessible utilisateur : "Historique de mes modifications" - Accessible utilisateur : "Historique de mes modifications"
- Accessible DPO : investigations - Accessible DPO : investigations

View File

@@ -19,6 +19,7 @@
### Contexte du report ### Contexte du report
**Raisons** : **Raisons** :
- **Coût modération** : Classification manuelle humaine très coûteuse (~2000€/mois pour 1-2 modérateurs senior full-time) - **Coût modération** : Classification manuelle humaine très coûteuse (~2000€/mois pour 1-2 modérateurs senior full-time)
- **Risque juridique** : Accusations de biais éditorial, contentieux DSA - **Risque juridique** : Accusations de biais éditorial, contentieux DSA
- **Complexité technique** : Dashboard audit, logs 3 ans, alertes déséquilibre - **Complexité technique** : Dashboard audit, logs 3 ans, alertes déséquilibre
@@ -26,6 +27,7 @@
- **Pas essentiel MVP** : L'application fonctionne sans ce système - **Pas essentiel MVP** : L'application fonctionne sans ce système
**Version MVP** (actuelle) : **Version MVP** (actuelle) :
- Tag "Politique" simple (comme "Économie", "Sport") - Tag "Politique" simple (comme "Économie", "Sport")
- Pas de classification gauche/droite - Pas de classification gauche/droite
- Pas d'équilibrage imposé - Pas d'équilibrage imposé
@@ -36,6 +38,7 @@
### Spécifications complètes (future implémentation) ### Spécifications complètes (future implémentation)
**Échelle de classification** (5 niveaux) : **Échelle de classification** (5 niveaux) :
- 🔴 **Extrême gauche** (anticapitalisme radical, révolution) - 🔴 **Extrême gauche** (anticapitalisme radical, révolution)
- 🟠 **Gauche** (écologie, social, critique capitalisme modérée) - 🟠 **Gauche** (écologie, social, critique capitalisme modérée)
-**Centre/Neutre** (pas de positionnement politique clair) -**Centre/Neutre** (pas de positionnement politique clair)
@@ -44,11 +47,13 @@
- 🟢 **Non politique** (enfants, musique, fiction, culture générale) - 🟢 **Non politique** (enfants, musique, fiction, culture générale)
**Qui classifie** : **Qui classifie** :
- ❌ Pas de classification automatique IA (outil informatif uniquement, jamais décisionnaire) - ❌ Pas de classification automatique IA (outil informatif uniquement, jamais décisionnaire)
- ✅ Modérateurs senior après transcription - ✅ Modérateurs senior après transcription
- ✅ Créateur peut contester via processus d'appel - ✅ Créateur peut contester via processus d'appel
**Affichage** : **Affichage** :
- Badge politique visible : **au choix de l'utilisateur** (paramètre "Afficher orientation politique") - Badge politique visible : **au choix de l'utilisateur** (paramètre "Afficher orientation politique")
- Par défaut : badges masqués (UX neutre) - Par défaut : badges masqués (UX neutre)
@@ -62,17 +67,20 @@
| **Masquer politique** | 0% gauche / 0% droite / 100% centre-neutre + non politique | Option apolitique | | **Masquer politique** | 0% gauche / 0% droite / 100% centre-neutre + non politique | Option apolitique |
**Audit et conformité DSA** : **Audit et conformité DSA** :
- Rapport hebdomadaire automatique : % gauche/droite/centre diffusé par utilisateur - Rapport hebdomadaire automatique : % gauche/droite/centre diffusé par utilisateur
- Alerte si déséquilibre global plateforme (>55% d'un bord) - Alerte si déséquilibre global plateforme (>55% d'un bord)
- Logs conservés **3 ans** (exigence Digital Services Act EU) - Logs conservés **3 ans** (exigence Digital Services Act EU)
- Dashboard admin : visualisation répartition temps réel - Dashboard admin : visualisation répartition temps réel
**Sanctions mauvaise classification** : **Sanctions mauvaise classification** :
- Classification volontairement incorrecte = Strike 1 - Classification volontairement incorrecte = Strike 1
- Récidive = Strike 2 (suspension 7j) - Récidive = Strike 2 (suspension 7j)
- Détection via signalements utilisateurs + audit modération - Détection via signalements utilisateurs + audit modération
**Justification** : **Justification** :
- **Conformité juridique DSA** (obligation neutralité plateforme EU) - **Conformité juridique DSA** (obligation neutralité plateforme EU)
- Protection contre accusations de biais éditorial - Protection contre accusations de biais éditorial
- Transparence auditable - Transparence auditable
@@ -90,6 +98,7 @@
5. Validation juridique du processus de classification 5. Validation juridique du processus de classification
**Chronologie estimée** : **Chronologie estimée** :
- Phase 1 (Post-MVP+3 mois) : Validation demande utilisateurs via sondages - Phase 1 (Post-MVP+3 mois) : Validation demande utilisateurs via sondages
- Phase 2 (Post-MVP+6 mois) : Recrutement modérateurs + développement dashboard - Phase 2 (Post-MVP+6 mois) : Recrutement modérateurs + développement dashboard
- Phase 3 (Post-MVP+9 mois) : Tests bêta avec utilisateurs volontaires - Phase 3 (Post-MVP+9 mois) : Tests bêta avec utilisateurs volontaires
@@ -104,12 +113,14 @@
### Contexte du report ### Contexte du report
**Raisons** : **Raisons** :
- **Complexité technique** : Intégration Lightning Network, gestion wallets crypto - **Complexité technique** : Intégration Lightning Network, gestion wallets crypto
- **Réglementation** : Incertitude juridique crypto en EU (MiCA 2025) - **Réglementation** : Incertitude juridique crypto en EU (MiCA 2025)
- **Focus MVP** : Priorité sur monétisation via abonnements Premium et publicités - **Focus MVP** : Priorité sur monétisation via abonnements Premium et publicités
- **Adoption utilisateurs** : Nécessite éducation et adoption crypto préalables - **Adoption utilisateurs** : Nécessite éducation et adoption crypto préalables
**Version MVP** (actuelle) : **Version MVP** (actuelle) :
- Monétisation créateurs via : - Monétisation créateurs via :
- Partage revenus publicités (3€ CPM) - Partage revenus publicités (3€ CPM)
- 70% revenus abonnements Premium - 70% revenus abonnements Premium
@@ -128,6 +139,7 @@
5. Conversion EUR/BTC automatique (optionnelle) 5. Conversion EUR/BTC automatique (optionnelle)
**Avantages Lightning Network** : **Avantages Lightning Network** :
- ✅ Frais quasi-nuls (<1%) vs 1.8% Mangopay - ✅ Frais quasi-nuls (<1%) vs 1.8% Mangopay
- ✅ Transactions instantanées (<1 seconde) - ✅ Transactions instantanées (<1 seconde)
- ✅ Micropaiements possibles (dès 0.01€) - ✅ Micropaiements possibles (dès 0.01€)
@@ -135,12 +147,14 @@
- ✅ Pas d'intermédiaire (peer-to-peer) - ✅ Pas d'intermédiaire (peer-to-peer)
**Contraintes** : **Contraintes** :
- ❌ Adoption crypto limitée (2-5% population EU en 2026) - ❌ Adoption crypto limitée (2-5% population EU en 2026)
- ❌ Volatilité BTC (nécessite conversion EUR immédiate) - ❌ Volatilité BTC (nécessite conversion EUR immédiate)
- ❌ UX complexe pour utilisateurs non-crypto - ❌ UX complexe pour utilisateurs non-crypto
- ❌ Réglementation MiCA en évolution - ❌ Réglementation MiCA en évolution
**Alternatives étudiées** : **Alternatives étudiées** :
- Ko-fi / Buy Me a Coffee : simple mais frais 5% - Ko-fi / Buy Me a Coffee : simple mais frais 5%
- PayPal/Stripe : frais 2.9% + 0.30€ (non viable pour micropaiements) - PayPal/Stripe : frais 2.9% + 0.30€ (non viable pour micropaiements)
- Mangopay : déjà utilisé, mais frais élevés pour petits montants - Mangopay : déjà utilisé, mais frais élevés pour petits montants
@@ -157,6 +171,7 @@
5. Demande créateurs confirmée via sondages 5. Demande créateurs confirmée via sondages
**Chronologie estimée** : **Chronologie estimée** :
- Phase 1 (Post-MVP+6 mois) : Étude de marché et demande utilisateurs - Phase 1 (Post-MVP+6 mois) : Étude de marché et demande utilisateurs
- Phase 2 (Post-MVP+12 mois) : Développement intégration Lightning - Phase 2 (Post-MVP+12 mois) : Développement intégration Lightning
- Phase 3 (Post-MVP+15 mois) : Tests bêta avec créateurs volontaires - Phase 3 (Post-MVP+15 mois) : Tests bêta avec créateurs volontaires
@@ -171,6 +186,7 @@
### Contexte du report ### Contexte du report
**Raisons** : **Raisons** :
- **Masse critique requise** : Nécessite pool suffisant d'utilisateurs simultanés (>500) pour matching rapide (<30s) - **Masse critique requise** : Nécessite pool suffisant d'utilisateurs simultanés (>500) pour matching rapide (<30s)
- **Infrastructure WebRTC** : Coût serveurs TURN/STUN supplémentaire (~500€/mois pour 1000 utilisateurs actifs) - **Infrastructure WebRTC** : Coût serveurs TURN/STUN supplémentaire (~500€/mois pour 1000 utilisateurs actifs)
- **Complexité modération** : Contenu live non enregistré = risques abus, nécessite système de confiance et signalement robuste - **Complexité modération** : Contenu live non enregistré = risques abus, nécessite système de confiance et signalement robuste
@@ -178,6 +194,7 @@
- **UX conducteur** : Commandes vocales avancées nécessaires pour sécurité routière - **UX conducteur** : Commandes vocales avancées nécessaires pour sécurité routière
**Version MVP** (actuelle) : **Version MVP** (actuelle) :
- Radio live créateurs uniquement (1 vers N) - Radio live créateurs uniquement (1 vers N)
- Pas de connexion P2P entre auditeurs - Pas de connexion P2P entre auditeurs
- Chat textuel limité aux POIs et commentaires - Chat textuel limité aux POIs et commentaires
@@ -220,12 +237,14 @@
- Badge "En roulette" visible sur profil (transparence) - Badge "En roulette" visible sur profil (transparence)
**Avantages** : **Avantages** :
- ✅ Sérendipité et découverte (esprit "Chatroulette audio") - ✅ Sérendipité et découverte (esprit "Chatroulette audio")
- ✅ Complémentarité conducteur/piéton (récit route vs récit urbain) - ✅ Complémentarité conducteur/piéton (récit route vs récit urbain)
- ✅ Fidèle concept RoadWave (usagers de la route connectés) - ✅ Fidèle concept RoadWave (usagers de la route connectés)
- ✅ Réutilisation infrastructure WebRTC existante (radio live) - ✅ Réutilisation infrastructure WebRTC existante (radio live)
**Contraintes** : **Contraintes** :
- ❌ Nécessite pool minimum 500 utilisateurs actifs simultanés - ❌ Nécessite pool minimum 500 utilisateurs actifs simultanés
- ❌ Modération temps réel complexe (contenu éphémère) - ❌ Modération temps réel complexe (contenu éphémère)
- ❌ Coût infrastructure TURN/STUN significatif - ❌ Coût infrastructure TURN/STUN significatif
@@ -233,10 +252,12 @@
- ❌ Commandes vocales avancées requises pour conducteurs - ❌ Commandes vocales avancées requises pour conducteurs
**Monétisation** : **Monétisation** :
- Gratuit avec limitation : 3 sessions/jour de 5 min - Gratuit avec limitation : 3 sessions/jour de 5 min
- Premium : sessions illimitées + matching prioritaire (moins d'attente) - Premium : sessions illimitées + matching prioritaire (moins d'attente)
**Aspects légaux** : **Aspects légaux** :
- Âge minimum : 18 ans pour accès roulette - Âge minimum : 18 ans pour accès roulette
- Charte d'utilisation spécifique (respect, pas de contenu sexuel/violent, pas de sollicitation commerciale) - Charte d'utilisation spécifique (respect, pas de contenu sexuel/violent, pas de sollicitation commerciale)
- Anonymat relatif : pseudo + ville visible, pas de photo - Anonymat relatif : pseudo + ville visible, pas de photo
@@ -254,12 +275,14 @@
6. Commandes vocales avancées implémentées pour conducteurs 6. Commandes vocales avancées implémentées pour conducteurs
**Chronologie estimée** : **Chronologie estimée** :
- Phase 1 (Post-MVP+3 mois) : Validation demande utilisateurs via sondages, analyse concurrence (Clubhouse, Twitter Spaces) - Phase 1 (Post-MVP+3 mois) : Validation demande utilisateurs via sondages, analyse concurrence (Clubhouse, Twitter Spaces)
- Phase 2 (Post-MVP+6 mois) : Développement matchmaking + WebRTC P2P renforcé - Phase 2 (Post-MVP+6 mois) : Développement matchmaking + WebRTC P2P renforcé
- Phase 3 (Post-MVP+9 mois) : Tests bêta avec 100 utilisateurs volontaires - Phase 3 (Post-MVP+9 mois) : Tests bêta avec 100 utilisateurs volontaires
- Phase 4 (Post-MVP+12 mois) : Déploiement progressif si KPI positifs (>70% satisfaction, <5% signalements) - Phase 4 (Post-MVP+12 mois) : Déploiement progressif si KPI positifs (>70% satisfaction, <5% signalements)
**KPI de succès** : **KPI de succès** :
- Temps moyen d'attente matching : <30 secondes - Temps moyen d'attente matching : <30 secondes
- Taux satisfaction post-session : >70% - Taux satisfaction post-session : >70%
- Taux signalement : <5% - Taux signalement : <5%
@@ -275,12 +298,14 @@
### Contexte du report ### Contexte du report
**Raisons** : **Raisons** :
- **Coût SMS** : ~0.04€/SMS en France via Brevo (400€/mois pour 10K inscriptions) - **Coût SMS** : ~0.04€/SMS en France via Brevo (400€/mois pour 10K inscriptions)
- **Complexité UX** : Étape supplémentaire à l'inscription (friction) - **Complexité UX** : Étape supplémentaire à l'inscription (friction)
- **Focus MVP** : Priorité sur l'expérience utilisateur fluide - **Focus MVP** : Priorité sur l'expérience utilisateur fluide
- **Modération suffisante** : Système de strikes et signalements couvre les cas d'abus initiaux - **Modération suffisante** : Système de strikes et signalements couvre les cas d'abus initiaux
**Version MVP** (actuelle) : **Version MVP** (actuelle) :
- Inscription par email uniquement (via Zitadel) - Inscription par email uniquement (via Zitadel)
- Confirmation email obligatoire - Confirmation email obligatoire
- Détection basique emails jetables (liste noire publique) - Détection basique emails jetables (liste noire publique)
@@ -321,28 +346,33 @@
- Au-delà → signalement automatique modération - Au-delà → signalement automatique modération
**Affichage** : **Affichage** :
- Badge "Vérifié ✓" visible sur profil créateur - Badge "Vérifié ✓" visible sur profil créateur
- Non obligatoire pour auditeurs simples (seulement créateurs) - Non obligatoire pour auditeurs simples (seulement créateurs)
- Option "Vérifier mon compte" dans paramètres - Option "Vérifier mon compte" dans paramètres
**Règles de diffusion** : **Règles de diffusion** :
- Contenus créateurs non-vérifiés : portée limitée à 10 km pendant 30 premiers jours - Contenus créateurs non-vérifiés : portée limitée à 10 km pendant 30 premiers jours
- Après 30 jours sans signalement : levée restriction - Après 30 jours sans signalement : levée restriction
- Créateurs vérifiés : aucune restriction - Créateurs vérifiés : aucune restriction
**Avantages** : **Avantages** :
- ✅ Réduction spam et comptes multiples - ✅ Réduction spam et comptes multiples
- ✅ Amélioration confiance plateforme - ✅ Amélioration confiance plateforme
- ✅ Conformité anti-fraude (KYC léger) - ✅ Conformité anti-fraude (KYC léger)
- ✅ Réutilisation infrastructure Brevo (emails + SMS) - ✅ Réutilisation infrastructure Brevo (emails + SMS)
**Contraintes** : **Contraintes** :
- ❌ Coût SMS : ~400€/mois pour 10K inscriptions/mois - ❌ Coût SMS : ~400€/mois pour 10K inscriptions/mois
- ❌ Friction UX (étape supplémentaire) - ❌ Friction UX (étape supplémentaire)
- ❌ Numéros virtuels (Twilio, etc.) contournent vérification - ❌ Numéros virtuels (Twilio, etc.) contournent vérification
- ❌ Certains utilisateurs réticents (vie privée) - ❌ Certains utilisateurs réticents (vie privée)
**Alternatives étudiées** : **Alternatives étudiées** :
- **Captcha reCAPTCHA v3** : efficace mais contournable, pas de coût - **Captcha reCAPTCHA v3** : efficace mais contournable, pas de coût
- **Email reputation API** : ~0.01€/vérification (kickbox.io) - **Email reputation API** : ~0.01€/vérification (kickbox.io)
- **Vérification bancaire** : trop contraignant pour MVP - **Vérification bancaire** : trop contraignant pour MVP
@@ -359,12 +389,14 @@
5. Conformité RGPD : consentement stockage numéro mobile 5. Conformité RGPD : consentement stockage numéro mobile
**Chronologie estimée** : **Chronologie estimée** :
- Phase 1 (Post-MVP+3 mois) : Analyse taux spam/abus, validation besoin - Phase 1 (Post-MVP+3 mois) : Analyse taux spam/abus, validation besoin
- Phase 2 (Post-MVP+4 mois) : Développement détection emails temporaires + API Brevo SMS - Phase 2 (Post-MVP+4 mois) : Développement détection emails temporaires + API Brevo SMS
- Phase 3 (Post-MVP+5 mois) : Tests bêta avec créateurs volontaires - Phase 3 (Post-MVP+5 mois) : Tests bêta avec créateurs volontaires
- Phase 4 (Post-MVP+6 mois) : Déploiement progressif selon catégorie utilisateur (créateurs en priorité) - Phase 4 (Post-MVP+6 mois) : Déploiement progressif selon catégorie utilisateur (créateurs en priorité)
**KPI de succès** : **KPI de succès** :
- Réduction comptes spam : >50% - Réduction comptes spam : >50%
- Taux vérification volontaire (créateurs) : >70% - Taux vérification volontaire (créateurs) : >70%
- Friction UX acceptable : taux abandon inscription <10% - Friction UX acceptable : taux abandon inscription <10%
@@ -379,6 +411,7 @@
### Contexte du report ### Contexte du report
**Raisons** : **Raisons** :
- **Complexité technique** : Intégration API TTS (Text-to-Speech), OCR pour PDF scannés, parsing multi-formats - **Complexité technique** : Intégration API TTS (Text-to-Speech), OCR pour PDF scannés, parsing multi-formats
- **Coût infrastructure** : ~0.016€/1000 caractères (Google Cloud TTS) = ~1.60€ par livre moyen (100K caractères) - **Coût infrastructure** : ~0.016€/1000 caractères (Google Cloud TTS) = ~1.60€ par livre moyen (100K caractères)
- **Conformité droits d'auteur** : Risque juridique si conversion de contenus protégés sans licence - **Conformité droits d'auteur** : Risque juridique si conversion de contenus protégés sans licence
@@ -386,6 +419,7 @@
- **Usage limité** : Cas d'usage minoritaire vs contenu audio créé par la communauté - **Usage limité** : Cas d'usage minoritaire vs contenu audio créé par la communauté
**Version MVP** (actuelle) : **Version MVP** (actuelle) :
- Contenu audio uniquement créé par les créateurs - Contenu audio uniquement créé par les créateurs
- Pas de conversion automatique document → audio - Pas de conversion automatique document → audio
- Utilisateurs doivent uploader directement fichiers audio - Utilisateurs doivent uploader directement fichiers audio
@@ -452,12 +486,14 @@
| **Allemand** | Anna, Max | Google Cloud TTS WaveNet | | **Allemand** | Anna, Max | Google Cloud TTS WaveNet |
**Avantages** : **Avantages** :
- ✅ Différenciation Premium forte (feature exclusive) - ✅ Différenciation Premium forte (feature exclusive)
- ✅ Fidélisation utilisateurs (consommation contenu personnel) - ✅ Fidélisation utilisateurs (consommation contenu personnel)
- ✅ Réutilisation infrastructure audio existante (HLS, NGINX Cache) - ✅ Réutilisation infrastructure audio existante (HLS, NGINX Cache)
- ✅ Cas d'usage trajets longs (livres, articles longs) - ✅ Cas d'usage trajets longs (livres, articles longs)
**Contraintes** : **Contraintes** :
- ❌ Coût TTS : ~1.60€/livre moyen (Google Cloud TTS WaveNet) - ❌ Coût TTS : ~1.60€/livre moyen (Google Cloud TTS WaveNet)
- ❌ Coût stockage : ~0.01€/GB/mois (temporaire 90 jours) - ❌ Coût stockage : ~0.01€/GB/mois (temporaire 90 jours)
- ❌ Risque juridique : conversion contenus protégés (livres, articles premium) - ❌ Risque juridique : conversion contenus protégés (livres, articles premium)
@@ -502,12 +538,14 @@
5. Infrastructure existante stable (HLS, CDN, backend Go) 5. Infrastructure existante stable (HLS, CDN, backend Go)
**Chronologie estimée** : **Chronologie estimée** :
- Phase 1 (Post-MVP+6 mois) : Étude de marché, sondage utilisateurs Premium, validation juridique - Phase 1 (Post-MVP+6 mois) : Étude de marché, sondage utilisateurs Premium, validation juridique
- Phase 2 (Post-MVP+9 mois) : Développement MVP TTS (PDF texte uniquement, FR/EN) - Phase 2 (Post-MVP+9 mois) : Développement MVP TTS (PDF texte uniquement, FR/EN)
- Phase 3 (Post-MVP+10 mois) : Tests bêta avec 100 utilisateurs Premium volontaires - Phase 3 (Post-MVP+10 mois) : Tests bêta avec 100 utilisateurs Premium volontaires
- Phase 4 (Post-MVP+12 mois) : Déploiement progressif si KPI positifs + ajout formats (EPUB, OCR) - Phase 4 (Post-MVP+12 mois) : Déploiement progressif si KPI positifs + ajout formats (EPUB, OCR)
**KPI de succès** : **KPI de succès** :
- Adoption feature : >30% utilisateurs Premium l'utilisent au moins 1 fois/mois - Adoption feature : >30% utilisateurs Premium l'utilisent au moins 1 fois/mois
- Satisfaction : >75% note positive (4-5/5) - Satisfaction : >75% note positive (4-5/5)
- Rétention Premium : augmentation >10% grâce à cette feature - Rétention Premium : augmentation >10% grâce à cette feature
@@ -525,6 +563,7 @@
| **Total** | **~650€/mois** | | **Total** | **~650€/mois** |
**Rentabilité** : **Rentabilité** :
- Revenus Premium 1000 users : 4990€/mois (4.99€/mois × 1000) - Revenus Premium 1000 users : 4990€/mois (4.99€/mois × 1000)
- Coût TTS : 650€/mois (13% revenus) - Coût TTS : 650€/mois (13% revenus)
- Marge après TTS : 4340€/mois (87%) - Marge après TTS : 4340€/mois (87%)
@@ -539,6 +578,7 @@
### Contexte du report ### Contexte du report
**Raisons** : **Raisons** :
- **Couverture limitée** : ~30-40% du parc automobile EU en 2026 (CarPlay/Android Auto) - **Couverture limitée** : ~30-40% du parc automobile EU en 2026 (CarPlay/Android Auto)
- **Complexité technique** : Intégration Siri Intents (iOS) + Google Actions (Android) - **Complexité technique** : Intégration Siri Intents (iOS) + Google Actions (Android)
- **Modération vocale** : Signalements vocaux nécessitent enregistrement + transcription audio - **Modération vocale** : Signalements vocaux nécessitent enregistrement + transcription audio
@@ -546,6 +586,7 @@
- **Accessibilité secondaire** : Like automatique couvre déjà engagement conducteurs - **Accessibilité secondaire** : Like automatique couvre déjà engagement conducteurs
**Version MVP** (actuelle) : **Version MVP** (actuelle) :
- ❌ Pas de commandes vocales - ❌ Pas de commandes vocales
- ✅ Like automatique basé sur temps d'écoute (en voiture) - ✅ Like automatique basé sur temps d'écoute (en voiture)
- ✅ Actions manuelles disponibles seulement en mode piéton - ✅ Actions manuelles disponibles seulement en mode piéton
@@ -591,6 +632,7 @@
**Implémentation technique** : **Implémentation technique** :
**iOS** : **iOS** :
- Siri Intents (framework iOS 12+) - Siri Intents (framework iOS 12+)
- Clés Intent à ajouter dans `Info.plist` : - Clés Intent à ajouter dans `Info.plist` :
```xml ```xml
@@ -602,25 +644,30 @@
</dict> </dict>
</array> </array>
``` ```
- Paramètres vocaux : détection "like", "abonne", "signale" - Paramètres vocaux : détection "like", "abonne", "signale"
**Android** : **Android** :
- Google Actions on Google Assistant (via assistant voice queries) - Google Actions on Google Assistant (via assistant voice queries)
- Intégration avec Android App Actions - Intégration avec Android App Actions
- Paremeters: Intent extras pour passer contenu actuel - Paremeters: Intent extras pour passer contenu actuel
- Fallback : repérer contenu par titre + créateur - Fallback : repérer contenu par titre + créateur
**Limitation importante** : **Limitation importante** :
- ⚠️ **CarPlay/Android Auto requis** : Fonctionalité non disponible sur interface mobile - ⚠️ **CarPlay/Android Auto requis** : Fonctionalité non disponible sur interface mobile
- ⚠️ **Reconnaissance vocale réseau** : Nécessite connexion data - ⚠️ **Reconnaissance vocale réseau** : Nécessite connexion data
- ⚠️ **Latence acceptable** : <2 secondes entre commande et confirmation - ⚠️ **Latence acceptable** : <2 secondes entre commande et confirmation
**UX - Feedback utilisateur** : **UX - Feedback utilisateur** :
- Siri : "✓ J'ai ajouté ce contenu à vos favoris" - Siri : "✓ J'ai ajouté ce contenu à vos favoris"
- Google Assistant : "✓ Vous êtes maintenant abonné à [Créateur]" - Google Assistant : "✓ Vous êtes maintenant abonné à [Créateur]"
- Confirmation audio pour signalement : "Signalement envoyé. Catégorie : Spam" - Confirmation audio pour signalement : "Signalement envoyé. Catégorie : Spam"
**Signalements vocaux** : **Signalements vocaux** :
- Enregistrement automatique de la voix (tampon 30 secondes) - Enregistrement automatique de la voix (tampon 30 secondes)
- Transcription audio → texte (via Google Cloud Speech ou similaire) - Transcription audio → texte (via Google Cloud Speech ou similaire)
- Catégorie pré-remplie selon réponse vocale ("Spam" → catégorie Spam) - Catégorie pré-remplie selon réponse vocale ("Spam" → catégorie Spam)
@@ -638,12 +685,14 @@
5. Système de confiance utilisateur en place (éviter abus signalements) 5. Système de confiance utilisateur en place (éviter abus signalements)
**Chronologie estimée** : **Chronologie estimée** :
- Phase 1 (Post-MVP+2 mois) : Validation demande utilisateurs (CarPlay/Android Auto) - Phase 1 (Post-MVP+2 mois) : Validation demande utilisateurs (CarPlay/Android Auto)
- Phase 2 (Post-MVP+4 mois) : Développement Siri Intents + Google Actions - Phase 2 (Post-MVP+4 mois) : Développement Siri Intents + Google Actions
- Phase 3 (Post-MVP+6 mois) : Tests bêta avec conducteurs volontaires - Phase 3 (Post-MVP+6 mois) : Tests bêta avec conducteurs volontaires
- Phase 4 (Post-MVP+8 mois) : Déploiement progressif si KPI positifs - Phase 4 (Post-MVP+8 mois) : Déploiement progressif si KPI positifs
**KPI de succès** : **KPI de succès** :
- Adoption commandes vocales : >30% utilisateurs CarPlay/Android Auto - Adoption commandes vocales : >30% utilisateurs CarPlay/Android Auto
- Taux erreur reconnaissance vocale : <10% - Taux erreur reconnaissance vocale : <10%
- Satisfaction utilisateurs : >75% (4-5/5) - Satisfaction utilisateurs : >75% (4-5/5)
@@ -667,6 +716,7 @@
### Contexte du report ### Contexte du report
**Raisons** : **Raisons** :
- **Masse critique requise** : Partenariats avec organismes officiels nécessitent base utilisateurs solide (>50K MAU) - **Masse critique requise** : Partenariats avec organismes officiels nécessitent base utilisateurs solide (>50K MAU)
- **Complexité technique** : Intégration APIs externes, système de priorités, TTS automatisé - **Complexité technique** : Intégration APIs externes, système de priorités, TTS automatisé
- **Responsabilité légale** : Diffusion alertes sécurité = engagement fort, nécessite infrastructure stable - **Responsabilité légale** : Diffusion alertes sécurité = engagement fort, nécessite infrastructure stable
@@ -674,6 +724,7 @@
- **ROI incertain** : Valeur ajoutée forte mais sans revenus directs (service public) - **ROI incertain** : Valeur ajoutée forte mais sans revenus directs (service public)
**Version MVP** (actuelle) : **Version MVP** (actuelle) :
- Tous contenus = créateurs classiques - Tous contenus = créateurs classiques
- Pas de système de priorité - Pas de système de priorité
- Pas de comptes officiels vérifiés - Pas de comptes officiels vérifiés
@@ -696,6 +747,7 @@
| **Compte Officiel** | Validation RoadWave manuelle + contrat partenariat | 🏛️ | **Configurable (0-3)** | **Aucune** | | **Compte Officiel** | Validation RoadWave manuelle + contrat partenariat | 🏛️ | **Configurable (0-3)** | **Aucune** |
**Exemples comptes officiels** : **Exemples comptes officiels** :
- **Gestionnaires autoroutes** : SANEF, Vinci Autoroutes, APRR, ASF - **Gestionnaires autoroutes** : SANEF, Vinci Autoroutes, APRR, ASF
- **Services météo** : Météo France, vigilance.gouv.fr - **Services météo** : Météo France, vigilance.gouv.fr
- **Sécurité civile** : Préfectures, Plan alerte enlèvement - **Sécurité civile** : Préfectures, Plan alerte enlèvement
@@ -796,6 +848,7 @@ Podcast reprend automatiquement à position exacte
``` ```
**Paramètres techniques** : **Paramètres techniques** :
- **Rayon déclenchement** : 500m-2km selon vitesse (calcul dynamique) - **Rayon déclenchement** : 500m-2km selon vitesse (calcul dynamique)
- **Son d'alerte** : Bip distinctif (pas agressif, mais audible) - **Son d'alerte** : Bip distinctif (pas agressif, mais audible)
- **Durée max alerte** : 30 secondes (format court, info essentielle) - **Durée max alerte** : 30 secondes (format court, info essentielle)
@@ -803,6 +856,7 @@ Podcast reprend automatiquement à position exacte
- **Annulation** : bouton "Ignorer" disponible pendant countdown (mais déconseillé) - **Annulation** : bouton "Ignorer" disponible pendant countdown (mais déconseillé)
**Traçabilité** : **Traçabilité** :
- Log : `user_id`, `alert_id`, `action` (played / ignored), `timestamp` - Log : `user_id`, `alert_id`, `action` (played / ignored), `timestamp`
- Statistiques : taux d'écoute alertes vs taux ignore (KPI efficacité) - Statistiques : taux d'écoute alertes vs taux ignore (KPI efficacité)
@@ -855,12 +909,14 @@ Podcast reprend automatiquement à position exacte
``` ```
**TTS (Text-to-Speech)** : **TTS (Text-to-Speech)** :
- **Fournisseur** : Google Cloud TTS WaveNet (voix neurale professionnelle) - **Fournisseur** : Google Cloud TTS WaveNet (voix neurale professionnelle)
- **Coût** : ~0.016€/1000 caractères - **Coût** : ~0.016€/1000 caractères
- **Voix** : "Léa" (féminine, française, ton calme mais ferme pour alertes) - **Voix** : "Léa" (féminine, française, ton calme mais ferme pour alertes)
- **Normalisation audio** : -14 LUFS (comme autres contenus) - **Normalisation audio** : -14 LUFS (comme autres contenus)
**Expiration automatique** : **Expiration automatique** :
- Alertes météo : 12h après fin vigilance - Alertes météo : 12h après fin vigilance
- Obstacles autoroute : 2h après signalement (si non mis à jour) - Obstacles autoroute : 2h après signalement (si non mis à jour)
- Alertes enlèvement : 48h ou jusqu'à résolution officielle - Alertes enlèvement : 48h ou jusqu'à résolution officielle
@@ -909,6 +965,7 @@ Podcast reprend automatiquement à position exacte
``` ```
**Création alerte manuelle** : **Création alerte manuelle** :
- Use case : information non automatisée (événement exceptionnel) - Use case : information non automatisée (événement exceptionnel)
- Champs : Texte (TTS auto), Zone (carte), Priorité (1-3), Durée vie - Champs : Texte (TTS auto), Zone (carte), Priorité (1-3), Durée vie
- Validation admin RoadWave requise (pas auto-publication) - Validation admin RoadWave requise (pas auto-publication)
@@ -943,6 +1000,7 @@ Podcast reprend automatiquement à position exacte
5. Tests A/B réussis sur interruption priorité 3 (acceptabilité utilisateurs) 5. Tests A/B réussis sur interruption priorité 3 (acceptabilité utilisateurs)
**Chronologie estimée** : **Chronologie estimée** :
- Phase 1 (Post-MVP+6 mois) : Développement système priorités + dashboard admin + TTS - Phase 1 (Post-MVP+6 mois) : Développement système priorités + dashboard admin + TTS
- Phase 2 (Post-MVP+9 mois) : Premier partenariat (Météo France, API publique simple) - Phase 2 (Post-MVP+9 mois) : Premier partenariat (Météo France, API publique simple)
- Phase 3 (Post-MVP+12 mois) : Tests bêta alertes météo avec utilisateurs volontaires - Phase 3 (Post-MVP+12 mois) : Tests bêta alertes météo avec utilisateurs volontaires
@@ -950,6 +1008,7 @@ Podcast reprend automatiquement à position exacte
- Phase 5 (Post-MVP+18 mois) : Déploiement complet si KPI positifs - Phase 5 (Post-MVP+18 mois) : Déploiement complet si KPI positifs
**KPI de succès** : **KPI de succès** :
- Taux écoute alertes priorité 3 : >95% (faible taux ignore) - Taux écoute alertes priorité 3 : >95% (faible taux ignore)
- Satisfaction utilisateurs : >80% jugent alertes utiles (sondage post-alerte) - Satisfaction utilisateurs : >80% jugent alertes utiles (sondage post-alerte)
- Taux faux positifs : <2% (alerte diffusée à tort ou obsolète) - Taux faux positifs : <2% (alerte diffusée à tort ou obsolète)
@@ -968,6 +1027,7 @@ Podcast reprend automatiquement à position exacte
| **Total** | **~255€/mois** | | **Total** | **~255€/mois** |
**ROI** : **ROI** :
- Pas de revenus directs (service public) - Pas de revenus directs (service public)
- Valeur indirecte : **différenciation produit majeure** - Valeur indirecte : **différenciation produit majeure**
- Argument commercial : "RoadWave vous protège en temps réel" - Argument commercial : "RoadWave vous protège en temps réel"

View File

@@ -10,11 +10,13 @@
- ✅ Option "Appareil de confiance" (skip 2FA pour 30 jours) - ✅ Option "Appareil de confiance" (skip 2FA pour 30 jours)
**Clarification technique** : **Clarification technique** :
- Zitadel utilise OAuth2/OIDC comme **protocole** (standard moderne pour mobile) - Zitadel utilise OAuth2/OIDC comme **protocole** (standard moderne pour mobile)
- Mais l'authentification reste 100% **email/password natif** - Mais l'authentification reste 100% **email/password natif**
- **Aucun fournisseur externe** (Google, Apple, etc.) n'est intégré - **Aucun fournisseur externe** (Google, Apple, etc.) n'est intégré
**Justification** : **Justification** :
- Souveraineté : pas de dépendance externe - Souveraineté : pas de dépendance externe
- RGPD : données 100% contrôlées - RGPD : données 100% contrôlées
- Coût : 0€ (Zitadel intégré) - Coût : 0€ (Zitadel intégré)
@@ -35,11 +37,13 @@
| **Email vérifié** | Toutes fonctionnalités débloquées | | **Email vérifié** | Toutes fonctionnalités débloquées |
**Paramètres** : **Paramètres** :
- Lien de vérification expire après **7 jours** - Lien de vérification expire après **7 jours**
- Possibilité de renvoyer le lien (max 3 fois/jour) - Possibilité de renvoyer le lien (max 3 fois/jour)
- Rappel in-app après création du 3ème contenu - Rappel in-app après création du 3ème contenu
**Justification** : **Justification** :
- Friction minimale à l'inscription - Friction minimale à l'inscription
- Anti-spam sans bloquer l'essai du produit - Anti-spam sans bloquer l'essai du produit
- Incitation naturelle à vérifier (déblocage) - Incitation naturelle à vérifier (déblocage)
@@ -47,11 +51,13 @@
#### Pour les créateurs (monétisation) #### Pour les créateurs (monétisation)
**Vérification obligatoire sous 7 jours** pour : **Vérification obligatoire sous 7 jours** pour :
- Accès au programme de monétisation - Accès au programme de monétisation
- KYC et reversement des revenus (conformité Mangopay) - KYC et reversement des revenus (conformité Mangopay)
- Publication illimitée de contenus - Publication illimitée de contenus
**Justification** : **Justification** :
- **Conformité légale** : KYC obligatoire pour transferts financiers - **Conformité légale** : KYC obligatoire pour transferts financiers
- **Anti-fraude** : Vérification identité réelle pour paiements - **Anti-fraude** : Vérification identité réelle pour paiements
- **Responsabilité** : RoadWave doit pouvoir prouver identité créateurs monétisés - **Responsabilité** : RoadWave doit pouvoir prouver identité créateurs monétisés
@@ -61,22 +67,26 @@
### 1.3 Données requises à l'inscription ### 1.3 Données requises à l'inscription
**Obligatoires** : **Obligatoires** :
- ✅ Email (format validé) - ✅ Email (format validé)
- ✅ Mot de passe (voir règles ci-dessous) - ✅ Mot de passe (voir règles ci-dessous)
- ✅ Pseudo (3-30 caractères, alphanumérique + underscore) - ✅ Pseudo (3-30 caractères, alphanumérique + underscore)
- ✅ Date de naissance (vérification âge minimum) - ✅ Date de naissance (vérification âge minimum)
**Optionnelles** : **Optionnelles** :
- ❌ Nom complet (privacy by design) - ❌ Nom complet (privacy by design)
- ❌ Photo de profil (avatar par défaut généré) - ❌ Photo de profil (avatar par défaut généré)
- ❌ Bio (ajout ultérieur) - ❌ Bio (ajout ultérieur)
**Âge minimum** : **Âge minimum** :
- **13 ans minimum** (conformité réglementation réseaux sociaux EU) - **13 ans minimum** (conformité réglementation réseaux sociaux EU)
- Vérification à l'inscription via date de naissance - Vérification à l'inscription via date de naissance
- Blocage inscription si <13 ans avec message explicite - Blocage inscription si <13 ans avec message explicite
**Justification** : **Justification** :
- RGPD minimal data - RGPD minimal data
- Friction réduite (4 champs max) - Friction réduite (4 champs max)
- Protection mineurs (obligation légale) - Protection mineurs (obligation légale)
@@ -88,22 +98,26 @@
**Décision** : Classification obligatoire des contenus **Décision** : Classification obligatoire des contenus
**Catégories** : **Catégories** :
- 🟢 **Tout public** (défaut) - 🟢 **Tout public** (défaut)
- 🟡 **13+** : contenu mature léger (débats, actualité sensible) - 🟡 **13+** : contenu mature léger (débats, actualité sensible)
- 🟠 **16+** : contenu mature (violence verbale, sujets sensibles) - 🟠 **16+** : contenu mature (violence verbale, sujets sensibles)
- 🔴 **18+** : contenu adulte (langage explicite, sujets réservés) - 🔴 **18+** : contenu adulte (langage explicite, sujets réservés)
**Règles de diffusion** : **Règles de diffusion** :
- Utilisateur 13-15 ans → contenus 🟢 🟡 (Tout public + 13+) - Utilisateur 13-15 ans → contenus 🟢 🟡 (Tout public + 13+)
- Utilisateur 16-17 ans → contenus 🟢 🟡 🟠 (Tout public + 13+ + 16+) - Utilisateur 16-17 ans → contenus 🟢 🟡 🟠 (Tout public + 13+ + 16+)
- Utilisateur 18+ → tous contenus 🟢 🟡 🟠 🔴 - Utilisateur 18+ → tous contenus 🟢 🟡 🟠 🔴
**Modération** : **Modération** :
- Vérification obligatoire de la classification lors de la validation - Vérification obligatoire de la classification lors de la validation
- Reclassification possible par modérateurs - Reclassification possible par modérateurs
- Strike si classification volontairement incorrecte - Strike si classification volontairement incorrecte
**Justification** : **Justification** :
- Protection mineurs (obligation légale) - Protection mineurs (obligation légale)
- Responsabilité plateforme - Responsabilité plateforme
- Coût : champ supplémentaire + règle algo - Coût : champ supplémentaire + règle algo
@@ -113,17 +127,20 @@
### 1.5 Validation mot de passe ### 1.5 Validation mot de passe
**Règles** : **Règles** :
- ✅ Minimum **8 caractères** - ✅ Minimum **8 caractères**
- ✅ Au moins **1 majuscule** - ✅ Au moins **1 majuscule**
- ✅ Au moins **1 chiffre** - ✅ Au moins **1 chiffre**
- ❌ Pas de symbole obligatoire (simplicité) - ❌ Pas de symbole obligatoire (simplicité)
**Validation** : **Validation** :
- Côté client (feedback temps réel) - Côté client (feedback temps réel)
- Côté backend (sécurité) - Côté backend (sécurité)
- Message d'erreur explicite par règle non respectée - Message d'erreur explicite par règle non respectée
**Justification** : **Justification** :
- Standard industrie - Standard industrie
- Bloque 95% des mots de passe faibles - Bloque 95% des mots de passe faibles
- UX acceptable (pas trop restrictif) - UX acceptable (pas trop restrictif)
@@ -135,16 +152,19 @@
**Décision** : Optionnel mais recommandé **Décision** : Optionnel mais recommandé
**Méthodes disponibles** : **Méthodes disponibles** :
- ✅ TOTP (Time-based One-Time Password) via app (Google Authenticator, Authy) - ✅ TOTP (Time-based One-Time Password) via app (Google Authenticator, Authy)
- ✅ Email (code 6 chiffres, expire 10 min) - ✅ Email (code 6 chiffres, expire 10 min)
- ❌ SMS (coût élevé ~0.05€/SMS) - ❌ SMS (coût élevé ~0.05€/SMS)
**Appareil de confiance** : **Appareil de confiance** :
- Option "Ne plus demander sur cet appareil" → bypass 2FA pendant **30 jours** - Option "Ne plus demander sur cet appareil" → bypass 2FA pendant **30 jours**
- Révocable depuis paramètres compte - Révocable depuis paramètres compte
- Liste des appareils de confiance visible - Liste des appareils de confiance visible
**Justification** : **Justification** :
- Sécurité renforcée sans coût SMS - Sécurité renforcée sans coût SMS
- UX : appareil de confiance évite friction quotidienne - UX : appareil de confiance évite friction quotidienne
- Zitadel natif (0€) - Zitadel natif (0€)
@@ -154,16 +174,19 @@
### 1.7 Tentatives de connexion ### 1.7 Tentatives de connexion
**Règles** : **Règles** :
- Maximum **5 tentatives** par période de **15 minutes** - Maximum **5 tentatives** par période de **15 minutes**
- Blocage temporaire après 5 échecs - Blocage temporaire après 5 échecs
- Compteur reset automatique après 15 min - Compteur reset automatique après 15 min
- Notification email si blocage (tentative suspecte) - Notification email si blocage (tentative suspecte)
**Déblocage** : **Déblocage** :
- Automatique après 15 min - Automatique après 15 min
- Ou via lien "Mot de passe oublié" - Ou via lien "Mot de passe oublié"
**Justification** : **Justification** :
- Anti brute-force - Anti brute-force
- Standard industrie (équilibre sécurité/UX) - Standard industrie (équilibre sécurité/UX)
- Zitadel natif (0€) - Zitadel natif (0€)
@@ -173,19 +196,23 @@
### 1.8 Sessions et refresh tokens ### 1.8 Sessions et refresh tokens
**Durée de vie** : **Durée de vie** :
- **Access token** : 15 minutes - **Access token** : 15 minutes
- **Refresh token** : 30 jours - **Refresh token** : 30 jours
**Rotation** : **Rotation** :
- Refresh token rotatif (nouveau token à chaque refresh) - Refresh token rotatif (nouveau token à chaque refresh)
- Ancien token invalidé immédiatement - Ancien token invalidé immédiatement
- Détection token replay attack - Détection token replay attack
**Extension automatique** : **Extension automatique** :
- Si app utilisée, session prolongée automatiquement - Si app utilisée, session prolongée automatiquement
- Inactivité 30 jours → déconnexion - Inactivité 30 jours → déconnexion
**Justification** : **Justification** :
- Sécurité (token court-vie) - Sécurité (token court-vie)
- UX (pas de reconnexion fréquente) - UX (pas de reconnexion fréquente)
- Standard OAuth2/OIDC - Standard OAuth2/OIDC
@@ -197,15 +224,18 @@
**Décision** : Sessions simultanées illimitées **Décision** : Sessions simultanées illimitées
**Gestion** : **Gestion** :
- Liste des devices connectés visible (OS, navigateur, dernière connexion, IP/ville) - Liste des devices connectés visible (OS, navigateur, dernière connexion, IP/ville)
- Révocation individuelle possible - Révocation individuelle possible
- Révocation globale "Déconnecter tous les appareils" - Révocation globale "Déconnecter tous les appareils"
**Alertes** : **Alertes** :
- Notification push + email si connexion depuis nouveau device - Notification push + email si connexion depuis nouveau device
- Détection localisation suspecte (IP pays différent) - Détection localisation suspecte (IP pays différent)
**Justification** : **Justification** :
- UX maximale (écoute voiture + tablette maison + web) - UX maximale (écoute voiture + tablette maison + web)
- Sécurité via transparence (utilisateur voit tout) - Sécurité via transparence (utilisateur voit tout)
- Coût : table sessions PostgreSQL - Coût : table sessions PostgreSQL
@@ -224,13 +254,16 @@
5. Confirmation + déconnexion tous devices (sauf celui en cours) 5. Confirmation + déconnexion tous devices (sauf celui en cours)
**Notifications** : **Notifications** :
- Email immédiat si changement mot de passe - Email immédiat si changement mot de passe
- Push si changement depuis appareil non reconnu - Push si changement depuis appareil non reconnu
**Limite** : **Limite** :
- Maximum **3 demandes/heure** (anti-spam) - Maximum **3 demandes/heure** (anti-spam)
**Justification** : **Justification** :
- Standard sécurité - Standard sécurité
- Pas de coût SMS - Pas de coût SMS
- Protection contre attaque sociale - Protection contre attaque sociale

View File

@@ -23,6 +23,7 @@
| **Contenu national** | "Aucun contenu local disponible. Voici du contenu national qui pourrait vous intéresser" | | **Contenu national** | "Aucun contenu local disponible. Voici du contenu national qui pourrait vous intéresser" |
**Justification** : **Justification** :
- **UX fluide** : pas de message d'erreur bloquant "Aucun contenu" - **UX fluide** : pas de message d'erreur bloquant "Aucun contenu"
- **User ne reste jamais sans contenu** - **User ne reste jamais sans contenu**
- **Contenu national = filet de sécurité** : actualités Le Monde, podcasts génériques - **Contenu national = filet de sécurité** : actualités Le Monde, podcasts génériques
@@ -44,10 +45,12 @@
``` ```
**Si tentative "Précédent" manuellement** : **Si tentative "Précédent" manuellement** :
- Message : "Ce contenu n'est plus disponible" - Message : "Ce contenu n'est plus disponible"
- Retour au contenu actuel - Retour au contenu actuel
**Justification** : **Justification** :
- **Sécurité routière** : pas d'interruption brutale pendant conduite - **Sécurité routière** : pas d'interruption brutale pendant conduite
- **User informé mais pas alarmé** : message discret - **User informé mais pas alarmé** : message discret
- **Empêche réécoute** : contenu modéré inaccessible - **Empêche réécoute** : contenu modéré inaccessible
@@ -67,30 +70,36 @@
**Comportement détaillé** : **Comportement détaillé** :
**Phase 1 : Connexion instable** (latence élevée, paquets perdus) **Phase 1 : Connexion instable** (latence élevée, paquets perdus)
- Aucun message immédiat - Aucun message immédiat
- Lecture continue sur buffer - Lecture continue sur buffer
- Si > 10s latence : toast discret "Connexion instable" - Si > 10s latence : toast discret "Connexion instable"
**Phase 2 : Perte totale réseau** **Phase 2 : Perte totale réseau**
- Lecture continue jusqu'à épuisement buffer - Lecture continue jusqu'à épuisement buffer
- Toast : "Hors ligne, lecture sur buffer (30s restantes)" - Toast : "Hors ligne, lecture sur buffer (30s restantes)"
- Compte à rebours visible - Compte à rebours visible
**Phase 3 : Buffer épuisé sans reconnexion** **Phase 3 : Buffer épuisé sans reconnexion**
- Pause automatique - Pause automatique
- Overlay : "Connexion perdue. Reconnexion en cours..." - Overlay : "Connexion perdue. Reconnexion en cours..."
- Retry automatique toutes les 5s (max 6 tentatives = 30s) - Retry automatique toutes les 5s (max 6 tentatives = 30s)
**Phase 4 : Basculement mode offline** (après 30s échec) **Phase 4 : Basculement mode offline** (après 30s échec)
- Popup : "Voulez-vous continuer avec vos contenus téléchargés ?" - Popup : "Voulez-vous continuer avec vos contenus téléchargés ?"
- Boutons : "Réessayer" / "Mode offline" - Boutons : "Réessayer" / "Mode offline"
- Si "Mode offline" → lecture contenus téléchargés - Si "Mode offline" → lecture contenus téléchargés
**Reconnexion réussie** : **Reconnexion réussie** :
- Reprise automatique lecture au point d'arrêt exact - Reprise automatique lecture au point d'arrêt exact
- Toast : "Connexion rétablie" - Toast : "Connexion rétablie"
**Justification** : **Justification** :
- **Expérience fluide zones blanches** (tunnels, campagne) - **Expérience fluide zones blanches** (tunnels, campagne)
- **Buffer généreux** : absorbe fluctuations réseau mobile - **Buffer généreux** : absorbe fluctuations réseau mobile
- **Mode offline secours** : si coupure prolongée - **Mode offline secours** : si coupure prolongée
@@ -113,19 +122,23 @@
| **Notifications push géo-déclenchées** | ❌ | | **Notifications push géo-déclenchées** | ❌ |
**Popup au lancement** : **Popup au lancement** :
- **Apparition** : Premier lancement après refus géolocalisation - **Apparition** : Premier lancement après refus géolocalisation
- **Message** : "RoadWave fonctionne mieux avec la géolocalisation activée. Sans elle, seul le contenu national sera disponible." - **Message** : "RoadWave fonctionne mieux avec la géolocalisation activée. Sans elle, seul le contenu national sera disponible."
- **Boutons** : - **Boutons** :
- "Activer" → Redirection paramètres OS - "Activer" → Redirection paramètres OS
- "Continuer sans" → Mode dégradé - "Continuer sans" → Mode dégradé
- **Checkbox** : "Ne plus me demander" - **Checkbox** : "Ne plus me demander"
**Banner permanent si refus** : **Banner permanent si refus** :
- Bandeau haut écran : "Mode limité : géolocalisation désactivée. [Activer]" - Bandeau haut écran : "Mode limité : géolocalisation désactivée. [Activer]"
- Pas intrusif mais rappel constant - Pas intrusif mais rappel constant
- Disparaît si géolocalisation réactivée - Disparaît si géolocalisation réactivée
**Justification** : **Justification** :
- **App reste fonctionnelle** sans GPS (pas de blocage) - **App reste fonctionnelle** sans GPS (pas de blocage)
- **Incitation forte** à activer (meilleure UX) - **Incitation forte** à activer (meilleure UX)
- **Respecte choix user** (RGPD : consentement libre) - **Respecte choix user** (RGPD : consentement libre)

View File

@@ -5,21 +5,25 @@
**Décision** : Tarteaucitron.js + PostgreSQL backend **Décision** : Tarteaucitron.js + PostgreSQL backend
**Implémentation web** : **Implémentation web** :
- ✅ Tarteaucitron.js (opensource, self-hosted) - ✅ Tarteaucitron.js (opensource, self-hosted)
- ✅ Banner RGPD français, customisable - ✅ Banner RGPD français, customisable
- ✅ Granularité : fonctionnel / analytique / marketing - ✅ Granularité : fonctionnel / analytique / marketing
**Implémentation backend** : **Implémentation backend** :
- Table `user_consents` avec versioning - Table `user_consents` avec versioning
- Champs : user_id, consent_type, version, accepted, timestamp - Champs : user_id, consent_type, version, accepted, timestamp
- Historique complet conservé (preuve légale) - Historique complet conservé (preuve légale)
**Consentements requis** : **Consentements requis** :
- **Géolocalisation précise** : obligatoire (banner + permission OS) - **Géolocalisation précise** : obligatoire (banner + permission OS)
- **Analytics** : optionnel (Matomo) - **Analytics** : optionnel (Matomo)
- **Notifications push** : optionnel (permission OS) - **Notifications push** : optionnel (permission OS)
**Justification** : **Justification** :
- Opensource, 0€, conformité RGPD garantie - Opensource, 0€, conformité RGPD garantie
- Historique backend = preuve légale en cas de contrôle - Historique backend = preuve légale en cas de contrôle
- Granularité conforme recommandations CNIL - Granularité conforme recommandations CNIL
@@ -37,10 +41,12 @@
4. Job quotidien automatique via cron 4. Job quotidien automatique via cron
**Exceptions** : **Exceptions** :
- ✅ Historique personnel visible (liste trajets) : conservation intégrale tant que compte actif - ✅ Historique personnel visible (liste trajets) : conservation intégrale tant que compte actif
- ❌ Analytics globales : uniquement geohash anonyme - ❌ Analytics globales : uniquement geohash anonyme
**Justification** : **Justification** :
- Vraie anonymisation RGPD (CNIL compliant) - Vraie anonymisation RGPD (CNIL compliant)
- Permet analytics agrégées (heatmaps trafic) - Permet analytics agrégées (heatmaps trafic)
- PostGIS natif, 0€ - PostGIS natif, 0€
@@ -54,6 +60,7 @@
**Format export** : Archive ZIP contenant JSON (machine-readable), HTML (human-readable), fichiers audio, README **Format export** : Archive ZIP contenant JSON (machine-readable), HTML (human-readable), fichiers audio, README
**Données exportées** : **Données exportées** :
- Profil utilisateur (email, pseudo, date inscription, bio) - Profil utilisateur (email, pseudo, date inscription, bio)
- Historique d'écoute (titres, dates, durées) - Historique d'écoute (titres, dates, durées)
- Contenus créés (audio + métadonnées) - Contenus créés (audio + métadonnées)
@@ -68,9 +75,11 @@
4. Délai : **48h maximum** (conformité RGPD) 4. Délai : **48h maximum** (conformité RGPD)
**Limite** : **Limite** :
- Maximum **1 export/mois** (anti-abus) - Maximum **1 export/mois** (anti-abus)
**Justification** : **Justification** :
- Conformité article 20 RGPD (portabilité) - Conformité article 20 RGPD (portabilité)
- Double format (human + machine) - Double format (human + machine)
- Worker asynchrone évite timeout - Worker asynchrone évite timeout
@@ -89,6 +98,7 @@
5. Après 30j sans annulation : suppression effective 5. Après 30j sans annulation : suppression effective
**Suppression effective** : **Suppression effective** :
- ✅ Compte utilisateur supprimé (données personnelles) - ✅ Compte utilisateur supprimé (données personnelles)
- ✅ Historique d'écoute supprimé - ✅ Historique d'écoute supprimé
- ✅ GPS historique supprimé - ✅ GPS historique supprimé
@@ -97,11 +107,13 @@
- ⚠️ Likes et abonnements supprimés (mais compteurs préservés) - ⚠️ Likes et abonnements supprimés (mais compteurs préservés)
**Contenus conservés anonymement** : **Contenus conservés anonymement** :
- Audio files (CDN) - Audio files (CDN)
- Métadonnées (titre, description, tags, géolocalisation) - Métadonnées (titre, description, tags, géolocalisation)
- Statistiques d'écoute - Statistiques d'écoute
**Justification** : **Justification** :
- Grace period évite suppressions impulsives - Grace period évite suppressions impulsives
- Anonymisation contenus = intérêt légitime communauté - Anonymisation contenus = intérêt légitime communauté
- Conforme RGPD si créateur = donnée supprimée - Conforme RGPD si créateur = donnée supprimée
@@ -121,16 +133,19 @@
| **Précis** | GPS | Tous contenus (hyperlocaux inclus) | ✅ Requis | | **Précis** | GPS | Tous contenus (hyperlocaux inclus) | ✅ Requis |
**Implémentation** : **Implémentation** :
- Démarrage app : GeoIP automatique (IP → ville) - Démarrage app : GeoIP automatique (IP → ville)
- Banner in-app : "Activez la géolocalisation pour découvrir du contenu près de chez vous" - Banner in-app : "Activez la géolocalisation pour découvrir du contenu près de chez vous"
- Upgrade volontaire vers GPS - Upgrade volontaire vers GPS
**API GeoIP** : **API GeoIP** :
- IP2Location Lite (gratuit, self-hosted, voir [ADR-019](../../../adr/019-geolocalisation-ip.md)) - IP2Location Lite (gratuit, self-hosted, voir [ADR-019](../../../adr/019-geolocalisation-ip.md))
- Update DB mensuelle automatique - Update DB mensuelle automatique
- Précision ~80% au niveau ville - Précision ~80% au niveau ville
**Justification** : **Justification** :
- RGPD : pas de consentement requis pour GeoIP (pas de donnée personnelle) - RGPD : pas de consentement requis pour GeoIP (pas de donnée personnelle)
- UX dégradée acceptable (contenus disponibles) - UX dégradée acceptable (contenus disponibles)
- Progressive disclosure (upgrade optionnel) - Progressive disclosure (upgrade optionnel)
@@ -150,15 +165,18 @@
| **Créateur inactif** | 5 ans sans connexion + 2 ans sans écoute | Suppression automatique | | **Créateur inactif** | 5 ans sans connexion + 2 ans sans écoute | Suppression automatique |
**Notifications avant suppression** : **Notifications avant suppression** :
- Email + push : **90 jours** avant - Email + push : **90 jours** avant
- Email + push : **30 jours** avant - Email + push : **30 jours** avant
- Email + push : **7 jours** avant - Email + push : **7 jours** avant
- Toute connexion = reset compteur inactivité - Toute connexion = reset compteur inactivité
**Contenu conservé** : **Contenu conservé** :
- Contenus créés par comptes supprimés (anonymisés) : conservation indéfinie - Contenus créés par comptes supprimés (anonymisés) : conservation indéfinie
**Justification** : **Justification** :
- Conformité principe minimisation RGPD - Conformité principe minimisation RGPD
- 5 ans = équilibre raisonnable (standard industrie) - 5 ans = équilibre raisonnable (standard industrie)
- Exception créateurs actifs = intérêt légitime plateforme - Exception créateurs actifs = intérêt légitime plateforme
@@ -178,17 +196,20 @@
| `_pk_id` | Analytique | 13 mois | Matomo (IP anonyme) | ✅ Requis | | `_pk_id` | Analytique | 13 mois | Matomo (IP anonyme) | ✅ Requis |
**Analytics : Matomo self-hosted** : **Analytics : Matomo self-hosted** :
- Hébergé sur nos serveurs (Docker) - Hébergé sur nos serveurs (Docker)
- IP anonymisées automatiquement (2 derniers octets) - IP anonymisées automatiquement (2 derniers octets)
- Pas de cookie si consentement refusé - Pas de cookie si consentement refusé
- Alternative : Plausible (SaaS EU, 9€/mois) - Alternative : Plausible (SaaS EU, 9€/mois)
**Trackers interdits** : **Trackers interdits** :
- ❌ Google Analytics - ❌ Google Analytics
- ❌ Facebook Pixel - ❌ Facebook Pixel
- ❌ Hotjar, Mixpanel, etc. - ❌ Hotjar, Mixpanel, etc.
**Justification** : **Justification** :
- Souveraineté données (pas de transfert US) - Souveraineté données (pas de transfert US)
- Conformité RGPD max (CNIL compatible) - Conformité RGPD max (CNIL compatible)
- Matomo = opensource, 0€ infra - Matomo = opensource, 0€ infra
@@ -200,10 +221,12 @@
**Décision** : Document Markdown versionné Git (MVP) **Décision** : Document Markdown versionné Git (MVP)
**Emplacement** : **Emplacement** :
- `docs/rgpd/registre-traitements.md` - `docs/rgpd/registre-traitements.md`
- Versionné Git (historique modifications) - Versionné Git (historique modifications)
**Contenu obligatoire par traitement** : **Contenu obligatoire par traitement** :
- Nom et finalité du traitement - Nom et finalité du traitement
- Catégories de données collectées - Catégories de données collectées
- Base légale (consentement / contrat / intérêt légitime) - Base légale (consentement / contrat / intérêt légitime)
@@ -212,14 +235,17 @@
- Transferts hors UE (aucun prévu) - Transferts hors UE (aucun prévu)
**Responsable** : **Responsable** :
- DPO / Fondateur - DPO / Fondateur
- Review trimestrielle obligatoire - Review trimestrielle obligatoire
- Update immédiate si nouveau traitement - Update immédiate si nouveau traitement
**Migration future** : **Migration future** :
- Si > 100K utilisateurs : interface admin PostgreSQL - Si > 100K utilisateurs : interface admin PostgreSQL
**Justification** : **Justification** :
- Obligation RGPD Article 30 - Obligation RGPD Article 30
- Markdown = simple, versionné, auditable - Markdown = simple, versionné, auditable
- 0€ - 0€
@@ -240,6 +266,7 @@
| Authentification suspecte | Zitadel alerts | Email équipe | | Authentification suspecte | Zitadel alerts | Email équipe |
**Procédure breach** : **Procédure breach** :
- Runbook : `docs/rgpd/procedure-breach.md` - Runbook : `docs/rgpd/procedure-breach.md`
- Checklist 72h CNIL : - Checklist 72h CNIL :
1. H+0 : Détection et confinement 1. H+0 : Détection et confinement
@@ -248,10 +275,12 @@
4. H+72 : Notification utilisateurs si risque élevé 4. H+72 : Notification utilisateurs si risque élevé
**Contact CNIL** : **Contact CNIL** :
- Email pré-rédigé (template) - Email pré-rédigé (template)
- Formulaire en ligne (account CNIL créé) - Formulaire en ligne (account CNIL créé)
**Justification** : **Justification** :
- Obligation RGPD Article 33 (notification 72h) - Obligation RGPD Article 33 (notification 72h)
- Monitoring proactif évite découverte tardive - Monitoring proactif évite découverte tardive
- Sentry gratuit < 5K events/mois - Sentry gratuit < 5K events/mois
@@ -263,25 +292,30 @@
**Décision** : Fondateur = DPO temporaire (MVP) **Décision** : Fondateur = DPO temporaire (MVP)
**Raison légale** : **Raison légale** :
- Non obligatoire si : - Non obligatoire si :
- < 250 employés - < 250 employés
- Pas de traitement à grande échelle de données sensibles - Pas de traitement à grande échelle de données sensibles
- RoadWave : données localisation = sensible MAIS échelle MVP - RoadWave : données localisation = sensible MAIS échelle MVP
**Formation** : **Formation** :
- CNIL : formation gratuite en ligne (4h) - CNIL : formation gratuite en ligne (4h)
- Certification CNIL "Atelier RGPD" (gratuit) - Certification CNIL "Atelier RGPD" (gratuit)
**Contact** : **Contact** :
- Email : dpo@roadwave.fr - Email : dpo@roadwave.fr
- Publié dans CGU et mentions légales - Publié dans CGU et mentions légales
- Délai réponse : **1 mois** (RGPD) - Délai réponse : **1 mois** (RGPD)
**Migration future** : **Migration future** :
- Si > 100K utilisateurs : DPO externe mutualisé (~200€/mois) - Si > 100K utilisateurs : DPO externe mutualisé (~200€/mois)
- Ou recrutement DPO interne si > 10 employés - Ou recrutement DPO interne si > 10 employés
**Justification** : **Justification** :
- Conforme RGPD (non obligatoire en phase MVP) - Conforme RGPD (non obligatoire en phase MVP)
- 0€, contrôle total - 0€, contrôle total
- Bonne pratique : avoir un contact identifié - Bonne pratique : avoir un contact identifié
@@ -293,6 +327,7 @@
**Décision** : Interface self-service + validation immédiate **Décision** : Interface self-service + validation immédiate
**Données rectifiables** : **Données rectifiables** :
- Email (avec re-vérification) - Email (avec re-vérification)
- Pseudo (unique, disponibilité vérifiée) - Pseudo (unique, disponibilité vérifiée)
- Bio / description - Bio / description
@@ -300,11 +335,13 @@
- Photo de profil - Photo de profil
**Processus** : **Processus** :
- Changements immédiats (sauf email) - Changements immédiats (sauf email)
- Email : lien vérification → validation sous 24h - Email : lien vérification → validation sous 24h
- Historique modifications conservé (audit trail) - Historique modifications conservé (audit trail)
**Limitations** : **Limitations** :
- Pseudo : max 1 changement/30j (anti-squat) - Pseudo : max 1 changement/30j (anti-squat)
**Justification** : Conformité Article 16 RGPD, self-service 0€ **Justification** : Conformité Article 16 RGPD, self-service 0€
@@ -323,6 +360,7 @@
| **Recommandations personnalisées** | "Mode anonyme" | Reco génériques uniquement | | **Recommandations personnalisées** | "Mode anonyme" | Reco génériques uniquement |
**Mode anonyme** : **Mode anonyme** :
- Désactive algorithme (jauges ignorées) - Désactive algorithme (jauges ignorées)
- Recommandations = top contenus zone géo uniquement - Recommandations = top contenus zone géo uniquement
- Historique non utilisé - Historique non utilisé
@@ -336,6 +374,7 @@
**Décision** : "Geler mon compte" temporaire **Décision** : "Geler mon compte" temporaire
**Effets** : **Effets** :
- Compte gelé, contenus cachés, profil invisible - Compte gelé, contenus cachés, profil invisible
- Connexion lecture seule OK - Connexion lecture seule OK
- Réactivation à tout moment - Réactivation à tout moment
@@ -349,6 +388,7 @@
**Décision** : Page web + popup in-app + versioning Git **Décision** : Page web + popup in-app + versioning Git
**Emplacement** : **Emplacement** :
- Web : `roadwave.fr/confidentialite` - Web : `roadwave.fr/confidentialite`
- App : page dédiée paramètres - App : page dédiée paramètres
- Popup première connexion (scroll requis) - Popup première connexion (scroll requis)
@@ -450,6 +490,7 @@
4. Validation parent → compte ado activé avec restrictions 4. Validation parent → compte ado activé avec restrictions
**Restrictions 13-15 ans** : **Restrictions 13-15 ans** :
- ✅ Écoute contenus autorisés - ✅ Écoute contenus autorisés
- ✅ Création contenus (modération renforcée) - ✅ Création contenus (modération renforcée)
- ⚠️ GPS précis : consentement parental explicite requis - ⚠️ GPS précis : consentement parental explicite requis
@@ -458,6 +499,7 @@
- ⚠️ Profil public limité (pas d'affichage ville précise) - ⚠️ Profil public limité (pas d'affichage ville précise)
**Contrôles parentaux** : **Contrôles parentaux** :
- Dashboard parent : `roadwave.fr/parent/[child_id]` - Dashboard parent : `roadwave.fr/parent/[child_id]`
- Visualisation historique écoute - Visualisation historique écoute
- Activation/désactivation GPS précis - Activation/désactivation GPS précis
@@ -466,6 +508,7 @@
- Notification hebdomadaire activité - Notification hebdomadaire activité
**Vérification légère identité parent** : **Vérification légère identité parent** :
- Email parent ≠ email ado (vérification domaine) - Email parent ≠ email ado (vérification domaine)
- Lien expiration 7 jours - Lien expiration 7 jours
- Pas de vérification identité forte (MVP) - Pas de vérification identité forte (MVP)
@@ -475,6 +518,7 @@
**App dédiée** : Version séparée avec contrôles renforcés **App dédiée** : Version séparée avec contrôles renforcés
**Caractéristiques** : **Caractéristiques** :
- ❌ Pas de GPS précis (GeoIP ville uniquement) - ❌ Pas de GPS précis (GeoIP ville uniquement)
- ❌ Pas de création contenu - ❌ Pas de création contenu
- ❌ Pas de profil public - ❌ Pas de profil public
@@ -484,6 +528,7 @@
- ✅ Contrôle parental obligatoire - ✅ Contrôle parental obligatoire
**Contenus autorisés** : **Contenus autorisés** :
- Contes audio enfants - Contes audio enfants
- Guides touristiques famille - Guides touristiques famille
- Podcasts éducatifs labellisés - Podcasts éducatifs labellisés
@@ -496,17 +541,20 @@
4. Pas de compte autonome enfant 4. Pas de compte autonome enfant
**Modération** : **Modération** :
- 100% contenus présélectionnés par équipe éditoriale - 100% contenus présélectionnés par équipe éditoriale
- Aucun UGC accessible - Aucun UGC accessible
- Whitelist créateurs vérifiés uniquement - Whitelist créateurs vérifiés uniquement
**Justification** : **Justification** :
- Conformité Article 8 RGPD (13-16 ans selon pays) - Conformité Article 8 RGPD (13-16 ans selon pays)
- 13 ans France = seuil légal avec consentement parental - 13 ans France = seuil légal avec consentement parental
- App Kids = protection renforcée < 13 ans - App Kids = protection renforcée < 13 ans
- Alignement marché (YouTube 13+, YouTube Kids) - Alignement marché (YouTube 13+, YouTube Kids)
**Roadmap** : **Roadmap** :
- **MVP** : App principale 16+ uniquement (simplicité) - **MVP** : App principale 16+ uniquement (simplicité)
- **Phase 2** : Workflow 13-15 ans + consentement parental - **Phase 2** : Workflow 13-15 ans + consentement parental
- **Phase 3** : RoadWave Kids (app séparée) - **Phase 3** : RoadWave Kids (app séparée)
@@ -537,6 +585,7 @@
**Décision** : DPIA obligatoire (GPS + profilage grande échelle) **Décision** : DPIA obligatoire (GPS + profilage grande échelle)
**Raisons** : **Raisons** :
- Traitement grande échelle données GPS sensibles - Traitement grande échelle données GPS sensibles
- Profilage automatisé recommandations - Profilage automatisé recommandations
- Surveillance zones publiques - Surveillance zones publiques

View File

@@ -49,6 +49,7 @@ sequenceDiagram
``` ```
**Légende** : **Légende** :
- **< 24h** : GPS précis conservé (recommandations hyperlocales) - **< 24h** : GPS précis conservé (recommandations hyperlocales)
- **> 24h** : Conversion automatique en geohash précision 5 (~5km²) - **> 24h** : Conversion automatique en geohash précision 5 (~5km²)
- **Exception** : Historique personnel conservé intact tant que compte actif - **Exception** : Historique personnel conservé intact tant que compte actif

View File

@@ -29,14 +29,17 @@ sequenceDiagram
## Légende ## Légende
**Acteurs** : **Acteurs** :
- Zitadel : Gère l'authentification OAuth2/OIDC - Zitadel : Gère l'authentification OAuth2/OIDC
- Backend API : Valide les tokens et accède aux données - Backend API : Valide les tokens et accède aux données
**Tokens** : **Tokens** :
- Access token : 15 min (JWT), utilisé pour chaque requête API - Access token : 15 min (JWT), utilisé pour chaque requête API
- Refresh token : 30 jours, permet renouvellement access token - Refresh token : 30 jours, permet renouvellement access token
**Sécurité** : **Sécurité** :
- Tokens stockés hashés (SHA256) en DB - Tokens stockés hashés (SHA256) en DB
- Device fingerprinting (OS, navigateur, IP) - Device fingerprinting (OS, navigateur, IP)
- Notification si nouveau device - Notification si nouveau device

View File

@@ -38,6 +38,7 @@ sequenceDiagram
``` ```
**Légende** : **Légende** :
- Délai expiration lien : 7 jours - Délai expiration lien : 7 jours
- Restrictions 13-15 ans : GPS précis, messagerie, contenus +16 (configurables par parent) - Restrictions 13-15 ans : GPS précis, messagerie, contenus +16 (configurables par parent)
- Dashboard parent : `roadwave.fr/parent/[child_id]` - Dashboard parent : `roadwave.fr/parent/[child_id]`

View File

@@ -59,6 +59,7 @@ sequenceDiagram
``` ```
**Légende** : **Légende** :
- Limite : 1 export / 30 jours (anti-abus) - Limite : 1 export / 30 jours (anti-abus)
- Délai génération : 48h maximum (conformité RGPD Article 20) - Délai génération : 48h maximum (conformité RGPD Article 20)
- Expiration lien : 7 jours - Expiration lien : 7 jours

View File

@@ -56,6 +56,7 @@ sequenceDiagram
``` ```
**Légende** : **Légende** :
- **H+0 à H+24** : Détection, confinement, évaluation périmètre - **H+0 à H+24** : Détection, confinement, évaluation périmètre
- **H+24 à H+48** : Évaluation gravité, préparation rapport - **H+24 à H+48** : Évaluation gravité, préparation rapport
- **H+48 à H+72** : Notification CNIL (si risque) + utilisateurs (si risque élevé) - **H+48 à H+72** : Notification CNIL (si risque) + utilisateurs (si risque élevé)

View File

@@ -29,10 +29,12 @@ sequenceDiagram
## Légende ## Légende
**Rotation** : **Rotation** :
- Nouveau refresh_token à chaque refresh - Nouveau refresh_token à chaque refresh
- Ancien token invalidé immédiatement - Ancien token invalidé immédiatement
- Prévient replay attack - Prévient replay attack
**Sécurité** : **Sécurité** :
- Si ancien token réutilisé → révocation globale - Si ancien token réutilisé → révocation globale
- Logs sécurité + notification utilisateur - Logs sécurité + notification utilisateur

View File

@@ -46,6 +46,7 @@ sequenceDiagram
``` ```
**Légende** : **Légende** :
- Grace period : 30 jours - Grace period : 30 jours
- Pendant grace period : compte inaccessible, contenus cachés - Pendant grace period : compte inaccessible, contenus cachés
- Après 30j : suppression définitive, contenus anonymisés conservés - Après 30j : suppression définitive, contenus anonymisés conservés

View File

@@ -30,12 +30,14 @@ stateDiagram-v2
**Grace period** : 30 jours **Grace period** : 30 jours
**Pendant grace period** : **Pendant grace period** :
- Compte désactivé (login impossible) - Compte désactivé (login impossible)
- Contenus cachés (non diffusés) - Contenus cachés (non diffusés)
- Sessions/tokens révoqués - Sessions/tokens révoqués
- Email avec token annulation (valide 30j) - Email avec token annulation (valide 30j)
**Après 30j** : **Après 30j** :
- Données personnelles supprimées - Données personnelles supprimées
- Contenus créés anonymisés (créateur = "Utilisateur supprimé") - Contenus créés anonymisés (créateur = "Utilisateur supprimé")
- Historique GPS/écoute supprimé - Historique GPS/écoute supprimé

View File

@@ -47,6 +47,7 @@ stateDiagram-v2
| Deleted | `deleted` | Données supprimées, contenus anonymisés, irréversible | | Deleted | `deleted` | Données supprimées, contenus anonymisés, irréversible |
**Restrictions Active Minor** : **Restrictions Active Minor** :
- GPS précis : configurable par parent - GPS précis : configurable par parent
- Messagerie privée : désactivée par défaut - Messagerie privée : désactivée par défaut
- Contenus +16 : filtrés - Contenus +16 : filtrés

View File

@@ -30,12 +30,14 @@ stateDiagram-v2
**Grace period** : 30 jours **Grace period** : 30 jours
**Pendant grace period** : **Pendant grace period** :
- Compte désactivé (login impossible) - Compte désactivé (login impossible)
- Contenus cachés (non diffusés) - Contenus cachés (non diffusés)
- Sessions/tokens révoqués - Sessions/tokens révoqués
- Email avec token annulation (valide 30j) - Email avec token annulation (valide 30j)
**Après 30j** : **Après 30j** :
- Données personnelles supprimées - Données personnelles supprimées
- Contenus créés anonymisés (créateur = "Utilisateur supprimé") - Contenus créés anonymisés (créateur = "Utilisateur supprimé")
- Historique GPS/écoute supprimé - Historique GPS/écoute supprimé

View File

@@ -22,6 +22,7 @@ Le domaine **Advertising** gère la diffusion de publicités audio ciblées. C'e
## Ubiquitous Language ## Ubiquitous Language
**Termes métier du domaine** : **Termes métier du domaine** :
- **Ad Campaign** : Campagne publicitaire avec budget et durée - **Ad Campaign** : Campagne publicitaire avec budget et durée
- **Ad Impression** : Affichage/lecture d'une publicité - **Ad Impression** : Affichage/lecture d'une publicité
- **Ad Targeting** : Critères de ciblage (geo + intérêts) - **Ad Targeting** : Critères de ciblage (geo + intérêts)

View File

@@ -63,6 +63,7 @@ if (campaign.hours.includes(userHour)) {
**Règle 2 : Ciblage "France" = Métropole + DOM** **Règle 2 : Ciblage "France" = Métropole + DOM**
**France entière inclut** : **France entière inclut** :
- France métropolitaine (96 départements) - France métropolitaine (96 départements)
- Guadeloupe (971) - Guadeloupe (971)
- Martinique (972) - Martinique (972)
@@ -71,6 +72,7 @@ if (campaign.hours.includes(userHour)) {
- Mayotte (976) - Mayotte (976)
**Publicitaire peut affiner** : **Publicitaire peut affiner** :
- "Région Provence-Alpes-Côte d'Azur" → Métropole uniquement - "Région Provence-Alpes-Côte d'Azur" → Métropole uniquement
- "Département 971" → Guadeloupe uniquement - "Département 971" → Guadeloupe uniquement
- "Ville Pointe-à-Pitre" → Guadeloupe uniquement - "Ville Pointe-à-Pitre" → Guadeloupe uniquement
@@ -102,6 +104,7 @@ if (campaign.hours.includes(userHour)) {
``` ```
Restaurant à Pointe-à-Pitre Restaurant à Pointe-à-Pitre
Campagne : Campagne :
- Zone : Guadeloupe (département 971) - Zone : Guadeloupe (département 971)
- Horaires : 12h-14h (rush déjeuner) - Horaires : 12h-14h (rush déjeuner)
@@ -114,6 +117,7 @@ User Martinique à 12h30 locale → ❌ Pas diffusion (hors zone géo)
``` ```
Assureur national Assureur national
Campagne : Campagne :
- Zone : France (nationale) - Zone : France (nationale)
- Horaires : 7h-9h + 17h-19h - Horaires : 7h-9h + 17h-19h
@@ -136,6 +140,7 @@ Filtrage pubs :
``` ```
**Justification** : **Justification** :
-**UX intuitive pour publicitaires** : "7h-9h" = matin partout (pas besoin comprendre UTC) -**UX intuitive pour publicitaires** : "7h-9h" = matin partout (pas besoin comprendre UTC)
-**Équité géographique** : pas de discrimination DOM-TOM, publicitaires locaux peuvent cibler local, campagnes nationales touchent tous Français -**Équité géographique** : pas de discrimination DOM-TOM, publicitaires locaux peuvent cibler local, campagnes nationales touchent tous Français
-**Simplicité technique** : détection fuseau automatique (GPS ou device), PostgreSQL `AT TIME ZONE` pour calculs backend -**Simplicité technique** : détection fuseau automatique (GPS ou device), PostgreSQL `AT TIME ZONE` pour calculs backend
@@ -144,6 +149,7 @@ Filtrage pubs :
**Étalement budget** : **Étalement budget** :
``` ```
Exemple campagne : Exemple campagne :
- Budget : 300€ - Budget : 300€
- Durée : 14 jours - Durée : 14 jours
- Zone : Département du Var - Zone : Département du Var
@@ -156,6 +162,7 @@ Calcul automatique :
``` ```
**Mode de paiement** : **Mode de paiement** :
- ✅ Prépaiement obligatoire (évite impayés) - ✅ Prépaiement obligatoire (évite impayés)
- ✅ Carte bancaire uniquement (Mangopay) - ✅ Carte bancaire uniquement (Mangopay)
- ✅ Recharge automatique optionnelle (si budget <10%) - ✅ Recharge automatique optionnelle (si budget <10%)
@@ -171,6 +178,7 @@ Calcul automatique :
4. Si refusé → email avec raison + remboursement automatique 4. Si refusé → email avec raison + remboursement automatique
**Contenus interdits en pub** : **Contenus interdits en pub** :
- ❌ Alcool, tabac (réglementation française) - ❌ Alcool, tabac (réglementation française)
- ❌ Jeux d'argent - ❌ Jeux d'argent
- ❌ Contenu politique (pendant campagnes électorales) - ❌ Contenu politique (pendant campagnes électorales)
@@ -194,11 +202,13 @@ Calcul automatique :
| **Répartition horaire** | Graphique par heure | Optimisation horaires | | **Répartition horaire** | Graphique par heure | Optimisation horaires |
**Métriques engagement avancées** : **Métriques engagement avancées** :
- **Taux complétion par tranche d'âge** : identifier audience réceptive - **Taux complétion par tranche d'âge** : identifier audience réceptive
- **Carte de chaleur GPS** : visualiser zones forte écoute - **Carte de chaleur GPS** : visualiser zones forte écoute
- **Comparatif campagnes** : A/B testing créatifs publicitaires - **Comparatif campagnes** : A/B testing créatifs publicitaires
**Export données** : **Export données** :
- ✅ CSV/Excel pour analyse externe - ✅ CSV/Excel pour analyse externe
- ✅ Graphiques interactifs (Chart.js) - ✅ Graphiques interactifs (Chart.js)
- ✅ Rapport PDF automatique fin de campagne - ✅ Rapport PDF automatique fin de campagne
@@ -206,6 +216,7 @@ Calcul automatique :
#### Gestion budget et alertes #### Gestion budget et alertes
**Suivi temps réel** : **Suivi temps réel** :
- Dashboard : Budget restant, % consommé, jours restants - Dashboard : Budget restant, % consommé, jours restants
- Projection : "À ce rythme, budget épuisé dans X jours" - Projection : "À ce rythme, budget épuisé dans X jours"
- Alerte email/push si : - Alerte email/push si :
@@ -215,6 +226,7 @@ Calcul automatique :
- Campagne terminée (rapport final) - Campagne terminée (rapport final)
**Ajustements en cours** : **Ajustements en cours** :
- ✅ Pause campagne (budget conservé) - ✅ Pause campagne (budget conservé)
- ✅ Prolonger campagne (recharge budget) - ✅ Prolonger campagne (recharge budget)
- ✅ Modifier ciblage horaire/géo (si <50% budget consommé) - ✅ Modifier ciblage horaire/géo (si <50% budget consommé)
@@ -223,12 +235,14 @@ Calcul automatique :
#### Système d'enchères (post-MVP) #### Système d'enchères (post-MVP)
**Optionnel future** : **Optionnel future** :
- Enchère au CPM (coût pour 1000 impressions) - Enchère au CPM (coût pour 1000 impressions)
- Priorité selon prix : pub prix élevé → diffusion privilégiée - Priorité selon prix : pub prix élevé → diffusion privilégiée
- Floor price : 2€ CPM minimum - Floor price : 2€ CPM minimum
- Évite surcharge pub : max 1 pub / 5 contenus stricte - Évite surcharge pub : max 1 pub / 5 contenus stricte
**Justification décision MVP** : **Justification décision MVP** :
- Tarif fixe simple : 0.05€/écoute complète - Tarif fixe simple : 0.05€/écoute complète
- Pas de complexité enchères immédiatement - Pas de complexité enchères immédiatement
- Scalable : passage enchères ultérieur si demande forte - Scalable : passage enchères ultérieur si demande forte
@@ -240,22 +254,26 @@ Calcul automatique :
**Décision** : Paramétrable admin + respect expérience utilisateur **Décision** : Paramétrable admin + respect expérience utilisateur
**Fréquence d'insertion** : **Fréquence d'insertion** :
- **Défaut : 1 pub / 5 contenus** (utilisateurs gratuits) - **Défaut : 1 pub / 5 contenus** (utilisateurs gratuits)
- **Paramétrable admin** : curseur 1/3 à 1/10 - **Paramétrable admin** : curseur 1/3 à 1/10
- **Utilisateurs Premium** : 0 pub (modèle sans publicité) - **Utilisateurs Premium** : 0 pub (modèle sans publicité)
**Règles strictes** : **Règles strictes** :
- ⚠️ **Jamais d'interruption** contenu en cours - ⚠️ **Jamais d'interruption** contenu en cours
- Pub s'insère uniquement **entre deux contenus** (pendant délai 2s) - Pub s'insère uniquement **entre deux contenus** (pendant délai 2s)
- Rotation : même pub max **3 fois/jour** par utilisateur (évite saturation) - Rotation : même pub max **3 fois/jour** par utilisateur (évite saturation)
- Limite : max **6 pubs/heure** par utilisateur (évite spam) - Limite : max **6 pubs/heure** par utilisateur (évite spam)
**Ciblage intelligent** : **Ciblage intelligent** :
- Géolocalisation prioritaire (point GPS > ville > département > région > national) - Géolocalisation prioritaire (point GPS > ville > département > région > national)
- Centres d'intérêt secondaires (tags utilisateur) - Centres d'intérêt secondaires (tags utilisateur)
- Horaire (campagne 7h-9h → diffusion uniquement pendant plage **heure locale utilisateur**, voir section 6.1 pour détails fuseaux horaires et DOM-TOM) - Horaire (campagne 7h-9h → diffusion uniquement pendant plage **heure locale utilisateur**, voir section 6.1 pour détails fuseaux horaires et DOM-TOM)
**Volume audio normalisé** : **Volume audio normalisé** :
- Pub normalisée à **-14 LUFS** (standard broadcast) - Pub normalisée à **-14 LUFS** (standard broadcast)
- Évite effet "pub trop forte" (frustration utilisateur) - Évite effet "pub trop forte" (frustration utilisateur)
- Validation automatique via FFmpeg lors encodage - Validation automatique via FFmpeg lors encodage
@@ -265,21 +283,25 @@ Calcul automatique :
### 6.3 Caractéristiques publicités ### 6.3 Caractéristiques publicités
**Durée** : **Durée** :
- Minimum : **10 secondes** - Minimum : **10 secondes**
- Maximum : **60 secondes** - Maximum : **60 secondes**
- Recommandé : **15-30 secondes** (sweet spot engagement) - Recommandé : **15-30 secondes** (sweet spot engagement)
**Skippable** : **Skippable** :
- Délai minimum obligatoire : **5 secondes** (paramétrable admin : 3-10s) - Délai minimum obligatoire : **5 secondes** (paramétrable admin : 3-10s)
- Bouton "Passer la publicité" apparaît après délai - Bouton "Passer la publicité" apparaît après délai
- Durée minimale comptabilisée pour facturation - Durée minimale comptabilisée pour facturation
**Facturation** : **Facturation** :
- **Écoute complète** (>80%) : 0.05€ facturé publicitaire - **Écoute complète** (>80%) : 0.05€ facturé publicitaire
- **Skip après délai min** : 0.02€ (exposition partielle) - **Skip après délai min** : 0.02€ (exposition partielle)
- **Skip immédiat** (<5s) : 0€ (pas d'engagement) - **Skip immédiat** (<5s) : 0€ (pas d'engagement)
**Justification modèle tarif** : **Justification modèle tarif** :
- Incitatif qualité : pub engageante = coût réduit - Incitatif qualité : pub engageante = coût réduit
- Équitable : publicitaire paie pour attention réelle - Équitable : publicitaire paie pour attention réelle
- Transparent : dashboard montre écoutes complètes vs skips - Transparent : dashboard montre écoutes complètes vs skips

View File

@@ -28,6 +28,7 @@ Le domaine **Content** gère toute la création, publication et diffusion des co
## Ubiquitous Language ## Ubiquitous Language
**Termes métier du domaine** : **Termes métier du domaine** :
- **Audio Guide** : Contenu structuré en séquences géolocalisées - **Audio Guide** : Contenu structuré en séquences géolocalisées
- **Guide Sequence** : Segment d'un audio-guide déclenché à un point GPS précis - **Guide Sequence** : Segment d'un audio-guide déclenché à un point GPS précis
- **Live Stream** : Diffusion audio en temps réel - **Live Stream** : Diffusion audio en temps réel

View File

@@ -14,11 +14,13 @@
| **🚌 Transport** | Variable | Auto GPS + Manuel possible | Bus touristiques, trains panoramiques | | **🚌 Transport** | Variable | Auto GPS + Manuel possible | Bus touristiques, trains panoramiques |
**Détection automatique** : **Détection automatique** :
- Vitesse moyenne calculée sur 30 secondes - Vitesse moyenne calculée sur 30 secondes
- Suggestion mode au démarrage : "Détection : 🚗 Voiture. Est-ce correct ? [Oui] [Changer]" - Suggestion mode au démarrage : "Détection : 🚗 Voiture. Est-ce correct ? [Oui] [Changer]"
- User peut forcer mode manuellement (settings) - User peut forcer mode manuellement (settings)
**Justification** : **Justification** :
- Flexibilité maximale créateurs et utilisateurs - Flexibilité maximale créateurs et utilisateurs
- Expériences optimisées par type de déplacement - Expériences optimisées par type de déplacement
- Gestion cas limites (vélo lent vs piéton rapide) - Gestion cas limites (vélo lent vs piéton rapide)
@@ -93,12 +95,14 @@
| **Zone diffusion** | ✅ | Polygon géographique | | **Zone diffusion** | ✅ | Polygon géographique |
**Wizard de création** : **Wizard de création** :
- Étape 1 : Infos générales (titre, description, mode) - Étape 1 : Infos générales (titre, description, mode)
- Étape 2 : Ajout séquences une par une - Étape 2 : Ajout séquences une par une
- Étape 3 : Preview carte (trace + points) - Étape 3 : Preview carte (trace + points)
- Étape 4 : Validation modération (3 premiers audio-guides) - Étape 4 : Validation modération (3 premiers audio-guides)
**Justification** : **Justification** :
- Contrôle total créateur sur expérience - Contrôle total créateur sur expérience
- Carte preview aide visualiser parcours - Carte preview aide visualiser parcours
- Wizard guidé = réduction friction création - Wizard guidé = réduction friction création
@@ -133,10 +137,12 @@ Séquence 1 [fin] → PAUSE → User clique → Séquence 2 [fin] → PUB AUTO-P
``` ```
**Fréquence pub** : **Fréquence pub** :
- Gratuits : 1 pub toutes les 5 séquences (paramétrable admin 1/3 à 1/10) - Gratuits : 1 pub toutes les 5 séquences (paramétrable admin 1/3 à 1/10)
- Premium : 0 pub - Premium : 0 pub
**Justification** : **Justification** :
- Pub s'insère naturellement (pas d'attente utilisateur pour déclencher) - Pub s'insère naturellement (pas d'attente utilisateur pour déclencher)
- User garde contrôle rythme visite (pause après pub) - User garde contrôle rythme visite (pause après pub)
- Monétisation effective créateurs - Monétisation effective créateurs
@@ -199,15 +205,18 @@ Séquence 1 [fin] → PAUSE → User clique → Séquence 2 [fin] → PUB AUTO-P
``` ```
**Navigation libre** : **Navigation libre** :
- User peut sauter séquences déjà connues - User peut sauter séquences déjà connues
- User peut revenir en arrière à tout moment - User peut revenir en arrière à tout moment
- User peut aller directement à séquence 8 (même si 4-7 non écoutées) - User peut aller directement à séquence 8 (même si 4-7 non écoutées)
**Sauvegarde progression** : **Sauvegarde progression** :
- Checkmarks ✅ sur séquences écoutées >80% - Checkmarks ✅ sur séquences écoutées >80%
- Position exacte sauvegardée dans séquence en cours - Position exacte sauvegardée dans séquence en cours
**Justification** : **Justification** :
- Utilisateur contrôle 100% son rythme - Utilisateur contrôle 100% son rythme
- Adapté musées : visitor peut voir physiquement une œuvre lointaine et vouloir écouter sa description - Adapté musées : visitor peut voir physiquement une œuvre lointaine et vouloir écouter sa description
- Pas de frustration (liberté totale) - Pas de frustration (liberté totale)
@@ -241,6 +250,7 @@ Séquence 1 [fin] → PAUSE → User clique → Séquence 2 [fin] → PUB AUTO-P
8. Séquence suivante démarre immédiatement (pas de décompte) 8. Séquence suivante démarre immédiatement (pas de décompte)
**Pas de système "7 secondes avant" pour les audio-guides** : **Pas de système "7 secondes avant" pour les audio-guides** :
- Contrairement aux contenus géolocalisés simples (voir [../../recommendation/rules/interactions-navigation.md](../../recommendation/rules/interactions-navigation.md#511-file-dattente-et-commande-suivant)) - Contrairement aux contenus géolocalisés simples (voir [../../recommendation/rules/interactions-navigation.md](../../recommendation/rules/interactions-navigation.md#511-file-dattente-et-commande-suivant))
- Les séquences se déclenchent **au point GPS exact** (rayon 30m) - Les séquences se déclenchent **au point GPS exact** (rayon 30m)
- Raison : expérience guidée continue, user sait qu'il suit un parcours - Raison : expérience guidée continue, user sait qu'il suit un parcours
@@ -268,6 +278,7 @@ Séquence 1 [fin] → PAUSE → User clique → Séquence 2 [fin] → PUB AUTO-P
- Si vitesse **>10 km/h** ET user clique bouton (Suivant/Précédent) : - Si vitesse **>10 km/h** ET user clique bouton (Suivant/Précédent) :
- Toast 3 secondes : "⚠️ Manipulation en conduite détectée. Pour votre sécurité, demandez à un passager." - Toast 3 secondes : "⚠️ Manipulation en conduite détectée. Pour votre sécurité, demandez à un passager."
- **Action quand même exécutée** (pas de blocage) - **Action quand même exécutée** (pas de blocage)
- Justification : sensibilisation sans bloquer (passager peut légitimement manipuler) - Justification : sensibilisation sans bloquer (passager peut légitimement manipuler)
**Schéma flux** : **Schéma flux** :
@@ -278,6 +289,7 @@ Point GPS 1 (30m) → Séquence 1 AUTO → User roule → Distance affichée →
``` ```
**Justification** : **Justification** :
- Flexibilité maximale : GPS optimise expérience MAIS user garde contrôle - Flexibilité maximale : GPS optimise expérience MAIS user garde contrôle
- Gestion cas limites : routes fermées, détours, embouteillages - Gestion cas limites : routes fermées, détours, embouteillages
- Sécurité : warning sensibilise sans bloquer (passager légitime) - Sécurité : warning sensibilise sans bloquer (passager légitime)
@@ -361,12 +373,14 @@ Quand une séquence se termine et qu'il reste un point GPS suivant, l'interface
``` ```
**Progress bar dynamique** : **Progress bar dynamique** :
- Se remplit au fur et à mesure qu'on se rapproche du point - Se remplit au fur et à mesure qu'on se rapproche du point
- Calcul : `progress = 100 - (distance_actuelle / distance_initiale * 100)` - Calcul : `progress = 100 - (distance_actuelle / distance_initiale * 100)`
- Exemple : distance initiale 500m, distance actuelle 175m → progress = 65% - Exemple : distance initiale 500m, distance actuelle 175m → progress = 65%
- Couleur : vert (#4CAF50) pour la partie remplie, gris (#E0E0E0) pour le reste - Couleur : vert (#4CAF50) pour la partie remplie, gris (#E0E0E0) pour le reste
**Bouton "Rejouer séq."** : **Bouton "Rejouer séq."** :
- Permet de réécouter la séquence qui vient de se terminer - Permet de réécouter la séquence qui vient de se terminer
- User clique → séquence actuelle redémarre depuis 0:00 - User clique → séquence actuelle redémarre depuis 0:00
- Utile si distraction pendant l'écoute - Utile si distraction pendant l'écoute
@@ -414,6 +428,7 @@ if (currentSpeed > 5) {
``` ```
**Justification** : **Justification** :
- Distance + ETA = info essentielle sans surcharge visuelle - Distance + ETA = info essentielle sans surcharge visuelle
- Direction (flèche) = aide se repérer sans carte complexe - Direction (flèche) = aide se repérer sans carte complexe
- Simplicité = moins distraction conducteur - Simplicité = moins distraction conducteur
@@ -470,10 +485,12 @@ Popup 5 secondes :
| **Faire demi-tour** | Lance navigation GPS externe (Google Maps / Waze) vers point manqué | | **Faire demi-tour** | Lance navigation GPS externe (Google Maps / Waze) vers point manqué |
**Si user au-delà rayon tolérance (>100m)** : **Si user au-delà rayon tolérance (>100m)** :
- Aucun popup (point trop loin, probablement hors itinéraire) - Aucun popup (point trop loin, probablement hors itinéraire)
- User peut naviguer manuellement (bouton Suivant) - User peut naviguer manuellement (bouton Suivant)
**Justification** : **Justification** :
- Flexibilité créateur (ajuste selon terrain, vitesse prévue) - Flexibilité créateur (ajuste selon terrain, vitesse prévue)
- Gestion intelligente imprévus (détours, routes fermées) - Gestion intelligente imprévus (détours, routes fermées)
- User pas bloqué (toujours moyen avancer) - User pas bloqué (toujours moyen avancer)
@@ -489,6 +506,7 @@ Popup 5 secondes :
##### Comportement bouton [▶|] Suivant ##### Comportement bouton [▶|] Suivant
**1. Premier clic (mode GPS auto actif)** : **1. Premier clic (mode GPS auto actif)** :
- Désactive GPS automatique - Désactive GPS automatique
- Passe à la séquence suivante immédiatement - Passe à la séquence suivante immédiatement
- Bascule en **mode manuel** - Bascule en **mode manuel**
@@ -496,12 +514,14 @@ Popup 5 secondes :
- Timer 10 secondes démarre - Timer 10 secondes démarre
**2. Deuxième clic (dans les 10 secondes suivantes)** : **2. Deuxième clic (dans les 10 secondes suivantes)** :
- Sort de l'audio-guide - Sort de l'audio-guide
- Audio-guide mis en **pause** (historique conservé) - Audio-guide mis en **pause** (historique conservé)
- Retour au **flux normal** (algorithme de recommandation) - Retour au **flux normal** (algorithme de recommandation)
- Toast 2s : "Audio-guide en pause" - Toast 2s : "Audio-guide en pause"
**3. Clics suivants (après 10 secondes)** : **3. Clics suivants (après 10 secondes)** :
- Passe à la séquence suivante (comportement standard mode manuel) - Passe à la séquence suivante (comportement standard mode manuel)
- Timer 10 secondes redémarre à chaque clic - Timer 10 secondes redémarre à chaque clic
@@ -584,6 +604,7 @@ function onSuivantClick() {
``` ```
**Justification** : **Justification** :
- Résout le problème des embouteillages (30 min sans contenu) - Résout le problème des embouteillages (30 min sans contenu)
- Double intention claire : désactiver GPS puis sortir - Double intention claire : désactiver GPS puis sortir
- User garde toujours le contrôle (peut reprendre audio-guide plus tard) - User garde toujours le contrôle (peut reprendre audio-guide plus tard)
@@ -625,6 +646,7 @@ function onSuivantClick() {
- Pub entre séquences - Pub entre séquences
**Justification** : **Justification** :
- Vélo : moins de contrôle qu'auto (obstacles, arrêts), nécessite tolérance - Vélo : moins de contrôle qu'auto (obstacles, arrêts), nécessite tolérance
- Transport : moins de contrôle utilisateur (suit ligne fixe), rayon large compense - Transport : moins de contrôle utilisateur (suit ligne fixe), rayon large compense
- Même UX globale = cohérence - Même UX globale = cohérence
@@ -677,6 +699,7 @@ Séquence 2 [fin]
| **Transport** | Attente GPS OU user clique Suivant | Attente GPS OU user clique Suivant | | **Transport** | Attente GPS OU user clique Suivant | Attente GPS OU user clique Suivant |
**Justification** : **Justification** :
- Monétisation équitable créateurs (tous modes participent) - Monétisation équitable créateurs (tous modes participent)
- Pub s'insère naturellement (auto-play, pas d'attente utilisateur) - Pub s'insère naturellement (auto-play, pas d'attente utilisateur)
- User garde contrôle : piéton clique Suivant, voiture peut skip manuel - User garde contrôle : piéton clique Suivant, voiture peut skip manuel
@@ -697,10 +720,12 @@ Séquence 2 [fin]
| **Revenus pub audio-guides** | 3€ / 1000 écoutes complètes (6% CA pub) | | **Revenus pub audio-guides** | 3€ / 1000 écoutes complètes (6% CA pub) |
**Distinction contenus normaux vs audio-guides** : **Distinction contenus normaux vs audio-guides** :
- Dashboard sépare : "Revenus contenus classiques" / "Revenus audio-guides" - Dashboard sépare : "Revenus contenus classiques" / "Revenus audio-guides"
- Permet créateur voir performance par type - Permet créateur voir performance par type
**Justification** : **Justification** :
- Transparence créateur (comprend revenus) - Transparence créateur (comprend revenus)
- Incite création audio-guides (nouvelle source revenus) - Incite création audio-guides (nouvelle source revenus)
@@ -731,10 +756,12 @@ Séquence 2 [fin]
| **Cloud** | PostgreSQL (sync auto) | Multi-device (reprendre sur autre appareil) | | **Cloud** | PostgreSQL (sync auto) | Multi-device (reprendre sur autre appareil) |
**Synchronisation** : **Synchronisation** :
- Sauvegarde locale : chaque fin de séquence + chaque 30s - Sauvegarde locale : chaque fin de séquence + chaque 30s
- Sync cloud : à la reconnexion réseau (batch) - Sync cloud : à la reconnexion réseau (batch)
**Justification** : **Justification** :
- Expérience fluide (pas de perte progression) - Expérience fluide (pas de perte progression)
- Multi-device (démarrer sur iPhone, continuer sur iPad) - Multi-device (démarrer sur iPhone, continuer sur iPad)
- Offline-first (fonctionne sans réseau) - Offline-first (fonctionne sans réseau)
@@ -744,6 +771,7 @@ Séquence 2 [fin]
#### 16.6.2 Interface de reprise #### 16.6.2 Interface de reprise
**Conditions popup** : **Conditions popup** :
- Dernière écoute **<30 jours** - Dernière écoute **<30 jours**
- Progression **>0%** et **<100%** (pas terminé) - Progression **>0%** et **<100%** (pas terminé)
@@ -776,11 +804,13 @@ Séquence 2 [fin]
| **Voir séquences** | Affiche liste complète, user choisit séquence départ | | **Voir séquences** | Affiche liste complète, user choisit séquence départ |
**Expiration progression** : **Expiration progression** :
- Progression conservée **30 jours** - Progression conservée **30 jours**
- Après 30j : popup "Audio-guide expiré. Recommencez depuis le début ?" - Après 30j : popup "Audio-guide expiré. Recommencez depuis le début ?"
- Suppression données progression (mais historique "écouté" préservé) - Suppression données progression (mais historique "écouté" préservé)
**Justification** : **Justification** :
- Contexte clair : user sait exactement où il en est - Contexte clair : user sait exactement où il en est
- Flexibilité : reprendre OU recommencer (choix utilisateur) - Flexibilité : reprendre OU recommencer (choix utilisateur)
- 30 jours = raisonnable pour tourisme multi-jours ou retour ultérieur - 30 jours = raisonnable pour tourisme multi-jours ou retour ultérieur
@@ -798,10 +828,12 @@ Séquence 2 [fin]
5. User clique Reprendre → continue séquence 4 5. User clique Reprendre → continue séquence 4
**Conflit de version** : **Conflit de version** :
- Si modifications simultanées 2 appareils (rare) : **dernière modification gagne** - Si modifications simultanées 2 appareils (rare) : **dernière modification gagne**
- Toast : "Progression mise à jour depuis votre autre appareil" - Toast : "Progression mise à jour depuis votre autre appareil"
**Justification** : **Justification** :
- Confort utilisateur (change d'appareil librement) - Confort utilisateur (change d'appareil librement)
- Use case réel : planning trajet sur tablette, écoute sur smartphone en voiture - Use case réel : planning trajet sur tablette, écoute sur smartphone en voiture

View File

@@ -5,6 +5,7 @@
**Objectif** : Proposer des contenus audio au moment précis où l'utilisateur passe devant un point d'intérêt géographique, pour enrichir son trajet avec des informations contextuelles liées au paysage. **Objectif** : Proposer des contenus audio au moment précis où l'utilisateur passe devant un point d'intérêt géographique, pour enrichir son trajet avec des informations contextuelles liées au paysage.
**Contrainte principale** : **Sécurité routière** **Contrainte principale** : **Sécurité routière**
- Aucune distraction visuelle (pas de texte à lire) - Aucune distraction visuelle (pas de texte à lire)
- Notification sonore uniquement + icône minimale - Notification sonore uniquement + icône minimale
- Validation par un seul bouton physique au volant ("Suivant") - Validation par un seul bouton physique au volant ("Suivant")
@@ -26,6 +27,7 @@
**Méthode** : API GPS native iOS/Android **Méthode** : API GPS native iOS/Android
**Principe** : **Principe** :
- Calcul temps d'arrivée au point GPS basé sur vitesse actuelle et distance - Calcul temps d'arrivée au point GPS basé sur vitesse actuelle et distance
- Notification déclenchée **7 secondes avant** d'atteindre le point - Notification déclenchée **7 secondes avant** d'atteindre le point
- Permet au conducteur d'avoir le temps de réagir (2s) + décompte (5s) - Permet au conducteur d'avoir le temps de réagir (2s) + décompte (5s)
@@ -118,11 +120,13 @@ class GeoContentDetector(private val fusedLocationClient: FusedLocationProviderC
``` ```
**Cas particulier : vitesse nulle ou très faible** : **Cas particulier : vitesse nulle ou très faible** :
- Si vitesse < 5 km/h (1.4 m/s) ET distance < 50m → notification immédiate - Si vitesse < 5 km/h (1.4 m/s) ET distance < 50m → notification immédiate
- Exemple : user arrêté à un feu rouge à 30m du point - Exemple : user arrêté à un feu rouge à 30m du point
- Évite notification trop tardive quand user redémarre - Évite notification trop tardive quand user redémarre
**Fréquence de vérification** : **Fréquence de vérification** :
- GPS updates : toutes les 1 seconde (balance batterie/précision) - GPS updates : toutes les 1 seconde (balance batterie/précision)
- Calcul ETA : à chaque update GPS - Calcul ETA : à chaque update GPS
- Notification : déclenchée immédiatement quand ETA ≤ 7s - Notification : déclenchée immédiatement quand ETA ≤ 7s
@@ -134,6 +138,7 @@ class GeoContentDetector(private val fusedLocationClient: FusedLocationProviderC
**Philosophie** : **Minimalisme absolu** pour sécurité routière **Philosophie** : **Minimalisme absolu** pour sécurité routière
**Pas de** : **Pas de** :
- Titre texte à lire - Titre texte à lire
- Description longue - Description longue
- Bouton "Annuler" ou "Plus tard" - Bouton "Annuler" ou "Plus tard"
@@ -141,6 +146,7 @@ class GeoContentDetector(private val fusedLocationClient: FusedLocationProviderC
- Image/cover du contenu - Image/cover du contenu
**Uniquement** : **Uniquement** :
- Son bref (notification) - Son bref (notification)
- Icône selon tag du contenu - Icône selon tag du contenu
- Compteur chiffres (7→1) - Compteur chiffres (7→1)
@@ -179,12 +185,14 @@ class GeoContentDetector(private val fusedLocationClient: FusedLocationProviderC
``` ```
**Évolution du compteur** : **Évolution du compteur** :
- Affichage pendant 7 secondes - Affichage pendant 7 secondes
- Compteur décrémente : 7 → 6 → 5 → 4 → 3 → 2 → 1 → disparaît - Compteur décrémente : 7 → 6 → 5 → 4 → 3 → 2 → 1 → disparaît
- Police grande (72pt), bold, couleur blanche - Police grande (72pt), bold, couleur blanche
- Background semi-transparent (noir 50% opacity) - Background semi-transparent (noir 50% opacity)
**Notification sonore** : **Notification sonore** :
- **Son** : bip court (0.5s) ou "ding" doux personnalisé RoadWave - **Son** : bip court (0.5s) ou "ding" doux personnalisé RoadWave
- **Volume** : suit le volume système notification (indépendant du volume media) - **Volume** : suit le volume système notification (indépendant du volume media)
- **Pas de vibration** : inutile en voiture (téléphone sur support) - **Pas de vibration** : inutile en voiture (téléphone sur support)
@@ -200,6 +208,7 @@ class GeoContentDetector(private val fusedLocationClient: FusedLocationProviderC
**Décision** : Notification sonore uniquement en mode CarPlay/Android Auto **Décision** : Notification sonore uniquement en mode CarPlay/Android Auto
**Contexte** : **Contexte** :
- [CarPlay Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/carplay) interdisent les overlays qui "takeover" l'écran - [CarPlay Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/carplay) interdisent les overlays qui "takeover" l'écran
- [Android Auto Media Apps Guidelines](https://developer.android.com/training/cars/media) imposent des interactions minimales - [Android Auto Media Apps Guidelines](https://developer.android.com/training/cars/media) imposent des interactions minimales
- Sécurité routière maximale = pas de distraction visuelle - Sécurité routière maximale = pas de distraction visuelle
@@ -207,11 +216,13 @@ class GeoContentDetector(private val fusedLocationClient: FusedLocationProviderC
**Comportement en mode CarPlay/Android Auto** : **Comportement en mode CarPlay/Android Auto** :
**Désactivé** : **Désactivé** :
- Icône overlay - Icône overlay
- Compteur visuel (7...6...5...) - Compteur visuel (7...6...5...)
- Tout élément graphique supplémentaire - Tout élément graphique supplémentaire
**Activé uniquement** : **Activé uniquement** :
- Notification sonore (bip ou ding) - Notification sonore (bip ou ding)
- Bouton "Suivant" standard (déjà présent) - Bouton "Suivant" standard (déjà présent)
@@ -280,12 +291,14 @@ class NotificationManager(private val context: Context) {
6. Contenu géolocalisé démarre après 5s 6. Contenu géolocalisé démarre après 5s
**Justification** : **Justification** :
- ✅ Conformité maximale CarPlay/Android Auto guidelines - ✅ Conformité maximale CarPlay/Android Auto guidelines
- ✅ Sécurité routière (pas de distraction visuelle) - ✅ Sécurité routière (pas de distraction visuelle)
- ✅ User peut toujours valider via bouton "Suivant" standard - ✅ User peut toujours valider via bouton "Suivant" standard
- ✅ Apps comparables (Waze, Apple Maps) utilisent alertes sonores similaires - ✅ Apps comparables (Waze, Apple Maps) utilisent alertes sonores similaires
**Alternative envisagée** : Mini-badge sur bouton "Suivant" **Alternative envisagée** : Mini-badge sur bouton "Suivant"
- Moins invasif qu'un compteur - Moins invasif qu'un compteur
- Mais toujours considéré comme overlay (zone grise) - Mais toujours considéré comme overlay (zone grise)
- **Décision** : Privilégier conformité maximale (sonore uniquement) - **Décision** : Privilégier conformité maximale (sonore uniquement)
@@ -297,15 +310,18 @@ class NotificationManager(private val context: Context) {
**User appuie sur "Suivant"** : **User appuie sur "Suivant"** :
**Étape 1 : Transition visuelle (0.3s)** **Étape 1 : Transition visuelle (0.3s)**
- Icône + compteur "7" disparaissent avec fade out - Icône + compteur "7" disparaissent avec fade out
- Nouveau compteur "5" apparaît (plus grand, centré) - Nouveau compteur "5" apparaît (plus grand, centré)
**Étape 2 : Décompte 5 secondes** **Étape 2 : Décompte 5 secondes**
- Compteur décrémente : 5 → 4 → 3 → 2 → 1 - Compteur décrémente : 5 → 4 → 3 → 2 → 1
- Contenu actuel continue de jouer **normalement** (pas de baisse volume) - Contenu actuel continue de jouer **normalement** (pas de baisse volume)
- User entend le contenu en cours pendant le décompte - User entend le contenu en cours pendant le décompte
**Étape 3 : Fin du décompte** **Étape 3 : Fin du décompte**
- Compteur atteint "0" - Compteur atteint "0"
- Fade out 0.3s du contenu actuel - Fade out 0.3s du contenu actuel
- Fade in 0.3s du contenu géolocalisé - Fade in 0.3s du contenu géolocalisé
@@ -327,6 +343,7 @@ T+5s : Décompte atteint 0
``` ```
**Justification** : **Justification** :
- Évite silence inconfortable pendant décompte - Évite silence inconfortable pendant décompte
- User continue d'écouter du contenu intéressant - User continue d'écouter du contenu intéressant
- Transition naturelle - Transition naturelle
@@ -353,6 +370,7 @@ T+5s : Décompte atteint 0
### 17.3 Limitation anti-spam ### 17.3 Limitation anti-spam
**Problème identifié** : **Problème identifié** :
- Routes riches en points d'intérêt (parcours touristiques) - Routes riches en points d'intérêt (parcours touristiques)
- Risque de notifier toutes les 30 secondes - Risque de notifier toutes les 30 secondes
- Fatigue utilisateur + distraction conducteur - Fatigue utilisateur + distraction conducteur
@@ -362,6 +380,7 @@ T+5s : Décompte atteint 0
#### 17.3.1 Quota : 6 contenus géolocalisés par heure #### 17.3.1 Quota : 6 contenus géolocalisés par heure
**Règle** : **Règle** :
- Maximum **6 contenus géolocalisés** notifiés par heure - Maximum **6 contenus géolocalisés** notifiés par heure
- Fenêtre glissante : calcul sur les 60 dernières minutes (pas réinitialisation à 0h) - Fenêtre glissante : calcul sur les 60 dernières minutes (pas réinitialisation à 0h)
- Si quota atteint : notifications suivantes ignorées silencieusement - Si quota atteint : notifications suivantes ignorées silencieusement
@@ -380,6 +399,7 @@ T+5s : Décompte atteint 0
``` ```
**Exception : audio-guides multi-séquences** : **Exception : audio-guides multi-séquences** :
- Un audio-guide avec N séquences compte comme **1 seul contenu** dans le quota - Un audio-guide avec N séquences compte comme **1 seul contenu** dans le quota
- Une fois démarré, toutes ses séquences sont jouables (pas de limite) - Une fois démarré, toutes ses séquences sont jouables (pas de limite)
- Exemple : audio-guide 8 séquences = 1 quota, contenus simples restants = 5 - Exemple : audio-guide 8 séquences = 1 quota, contenus simples restants = 5
@@ -422,12 +442,14 @@ func RecordNotification(userID string, contentID string) {
#### 17.3.2 Cooldown : 10 minutes après notification ignorée #### 17.3.2 Cooldown : 10 minutes après notification ignorée
**Règle** : **Règle** :
- Si user ne clique pas sur "Suivant" pendant les 7 secondes - Si user ne clique pas sur "Suivant" pendant les 7 secondes
- → Cooldown de **10 minutes** activé - → Cooldown de **10 minutes** activé
- → Aucune nouvelle notification pendant ce délai - → Aucune nouvelle notification pendant ce délai
- → Même si quota non atteint - → Même si quota non atteint
**Justification** : **Justification** :
- User a probablement une raison de ne pas vouloir de contenu géolocalisé maintenant - User a probablement une raison de ne pas vouloir de contenu géolocalisé maintenant
- Évite harcèlement (notifications répétées ignorées) - Évite harcèlement (notifications répétées ignorées)
- Respecte choix implicite de l'utilisateur - Respecte choix implicite de l'utilisateur
@@ -458,6 +480,7 @@ func ActivateCooldown(userID string) {
``` ```
**Exception : notification validée (user a cliqué)** : **Exception : notification validée (user a cliqué)** :
- Pas de cooldown si user a cliqué sur "Suivant" - Pas de cooldown si user a cliqué sur "Suivant"
- Même si user skip le contenu ensuite (pendant le décompte ou après) - Même si user skip le contenu ensuite (pendant le décompte ou après)
- Cooldown = pénalité uniquement pour notification complètement ignorée - Cooldown = pénalité uniquement pour notification complètement ignorée
@@ -503,6 +526,7 @@ Timeline :
6. User appuie "Précédent" → **retour au contenu géolocalisé à 42s** 6. User appuie "Précédent" → **retour au contenu géolocalisé à 42s**
**Règle** : Comme décrit dans [../../recommendation/rules/interactions-navigation.md](../../recommendation/rules/interactions-navigation.md#52-commande-précédent) : **Règle** : Comme décrit dans [../../recommendation/rules/interactions-navigation.md](../../recommendation/rules/interactions-navigation.md#52-commande-précédent) :
- Si temps écouté ≥ 10 secondes → replay contenu actuel depuis début - Si temps écouté ≥ 10 secondes → replay contenu actuel depuis début
- Si temps écouté < 10 secondes → retour contenu précédent (position exacte) - Si temps écouté < 10 secondes → retour contenu précédent (position exacte)
@@ -567,6 +591,7 @@ if (avgSpeedKmh < 5) {
``` ```
**Hysteresis (éviter basculements intempestifs)** : **Hysteresis (éviter basculements intempestifs)** :
- Nouvelle vitesse doit être stable pendant **10 secondes** avant basculement - Nouvelle vitesse doit être stable pendant **10 secondes** avant basculement
- Exemple : user passe de 20 km/h à 3 km/h (arrêt feu rouge) - Exemple : user passe de 20 km/h à 3 km/h (arrêt feu rouge)
- Si vitesse remonte à 20 km/h après 8s → pas de basculement - Si vitesse remonte à 20 km/h après 8s → pas de basculement
@@ -595,6 +620,7 @@ if (avgSpeedKmh < 5) {
| **Type contenu** | Audio-guides uniquement | Tous contenus géolocalisés | | **Type contenu** | Audio-guides uniquement | Tous contenus géolocalisés |
**Transition fluide** : **Transition fluide** :
- Pas de popup ou message à l'utilisateur - Pas de popup ou message à l'utilisateur
- Basculement invisible et automatique - Basculement invisible et automatique
- Permissions ajustées automatiquement (si déjà accordées) - Permissions ajustées automatiquement (si déjà accordées)
@@ -608,6 +634,7 @@ if (avgSpeedKmh < 5) {
**Scénario** : Autoroute A6, vitesse 130 km/h, contenu géolocalisé détecté. **Scénario** : Autoroute A6, vitesse 130 km/h, contenu géolocalisé détecté.
**Calcul** : **Calcul** :
- Vitesse : 130 km/h = 36.1 m/s - Vitesse : 130 km/h = 36.1 m/s
- ETA 7s → distance notification : 7 × 36.1 = **252 mètres** avant le point - ETA 7s → distance notification : 7 × 36.1 = **252 mètres** avant le point
- User a 7s pour cliquer "Suivant" - User a 7s pour cliquer "Suivant"
@@ -618,6 +645,7 @@ if (avgSpeedKmh < 5) {
**Conclusion** : Le système fonctionne même à très haute vitesse ✅ **Conclusion** : Le système fonctionne même à très haute vitesse ✅
**Cas extrême : 180 km/h** (illégal mais théoriquement possible) : **Cas extrême : 180 km/h** (illégal mais théoriquement possible) :
- Vitesse : 180 km/h = 50 m/s - Vitesse : 180 km/h = 50 m/s
- ETA 7s → distance notification : 350m avant le point - ETA 7s → distance notification : 350m avant le point
- Décompte 5s : user parcourt 250m - Décompte 5s : user parcourt 250m
@@ -655,6 +683,7 @@ T+57s : User clique "Suivant" → contenu Château B démarre
**Solution proposée** : **Ajuster le cooldown selon validation précédente** **Solution proposée** : **Ajuster le cooldown selon validation précédente**
Nouvelle règle : Nouvelle règle :
- Notification validée (user a cliqué) : pas de cooldown - Notification validée (user a cliqué) : pas de cooldown
- Notification ignorée (user n'a pas cliqué) : cooldown 10 min - Notification ignorée (user n'a pas cliqué) : cooldown 10 min
- Exception : si 2+ notifications validées consécutives, cooldown réduit à 5 min - Exception : si 2+ notifications validées consécutives, cooldown réduit à 5 min
@@ -687,18 +716,21 @@ func CalculateCooldown(userID string) time.Duration {
**Scénario** : User se gare à 30m d'un château, sort de voiture, visite 1h, revient. **Scénario** : User se gare à 30m d'un château, sort de voiture, visite 1h, revient.
**Problème** : **Problème** :
- Vitesse < 5 km/h + distance < 50m → notification immédiate - Vitesse < 5 km/h + distance < 50m → notification immédiate
- Mais user en mode "stationnement", pas en mode "conduite" - Mais user en mode "stationnement", pas en mode "conduite"
**Solution** : **Détection mode stationnement** **Solution** : **Détection mode stationnement**
Règle : Règle :
- Si vitesse < 1 km/h pendant **2 minutes** consécutives - Si vitesse < 1 km/h pendant **2 minutes** consécutives
- → Mode "stationnement" activé - → Mode "stationnement" activé
- → Pas de notification de contenus géolocalisés - → Pas de notification de contenus géolocalisés
- → Basculement automatique en mode piéton (push arrière-plan) - → Basculement automatique en mode piéton (push arrière-plan)
**Reprise conduite** : **Reprise conduite** :
- Vitesse > 5 km/h pendant 10s - Vitesse > 5 km/h pendant 10s
- → Mode "voiture" réactivé - → Mode "voiture" réactivé
- → Notifications reprennent (si quota non atteint) - → Notifications reprennent (si quota non atteint)

View File

@@ -5,6 +5,7 @@
**Décision** : Formats universels avec encodage asynchrone **Décision** : Formats universels avec encodage asynchrone
**Formats acceptés** : **Formats acceptés** :
- ✅ MP3 (`.mp3`) - ✅ MP3 (`.mp3`)
- ✅ AAC (`.aac`, `.m4a`) - ✅ AAC (`.aac`, `.m4a`)
- ❌ WAV, FLAC (trop lourds, inutiles en voiture) - ❌ WAV, FLAC (trop lourds, inutiles en voiture)
@@ -31,6 +32,7 @@
``` ```
**Temps d'encodage estimé** : **Temps d'encodage estimé** :
- Contenu 5 min → ~30 secondes - Contenu 5 min → ~30 secondes
- Podcast 1h → ~5 minutes - Podcast 1h → ~5 minutes
- Podcast 4h → ~20 minutes - Podcast 4h → ~20 minutes
@@ -54,11 +56,13 @@
| 2.0x | Survol rapide (modérateurs) | | 2.0x | Survol rapide (modérateurs) |
**Disponible pour** : **Disponible pour** :
- ✅ Modérateurs (validation rapide : 30s → 15s à 2x) - ✅ Modérateurs (validation rapide : 30s → 15s à 2x)
- ✅ Auditeurs (tous les contenus) - ✅ Auditeurs (tous les contenus)
- ✅ Standard industrie (YouTube, Spotify, Apple Podcasts) - ✅ Standard industrie (YouTube, Spotify, Apple Podcasts)
**Justification** : **Justification** :
- **Simplicité** : 2 formats couvrent 95% des cas d'usage - **Simplicité** : 2 formats couvrent 95% des cas d'usage
- **Coût optimisé** : pas de conversion WAV/FLAC lourds - **Coût optimisé** : pas de conversion WAV/FLAC lourds
- **Stockage réduit** : suppression original après encodage - **Stockage réduit** : suppression original après encodage
@@ -84,6 +88,7 @@
**Zone de diffusion (obligatoire)** : **Zone de diffusion (obligatoire)** :
Options mutuellement exclusives : Options mutuellement exclusives :
- **Point GPS** : latitude + longitude + rayon (100m à 10km) - **Point GPS** : latitude + longitude + rayon (100m à 10km)
- **Ville** : sélection dans référentiel INSEE - **Ville** : sélection dans référentiel INSEE
- **Département** : sélection liste - **Département** : sélection liste
@@ -91,6 +96,7 @@ Options mutuellement exclusives :
- **National** : France entière - **National** : France entière
**Tags disponibles** (1 à 3 obligatoires) : **Tags disponibles** (1 à 3 obligatoires) :
- Automobile - Automobile
- Voyage - Voyage
- Famille - Famille
@@ -105,12 +111,14 @@ Options mutuellement exclusives :
- Santé - Santé
**Champs optionnels** : **Champs optionnels** :
- ❌ Description (ajout ultérieur) - ❌ Description (ajout ultérieur)
- ❌ Image couverture (génération auto) - ❌ Image couverture (génération auto)
**Image de couverture par défaut** : **Image de couverture par défaut** :
Génération automatique selon règles : Génération automatique selon règles :
- Icône selon type géo : 📍 Ancré / 🌍 Contextuel / 🎧 Neutre - Icône selon type géo : 📍 Ancré / 🌍 Contextuel / 🎧 Neutre
- Couleur selon tag principal : bleu (Auto), vert (Voyage), rouge (Musique), etc. - Couleur selon tag principal : bleu (Auto), vert (Voyage), rouge (Musique), etc.
- Format 800×800px, PNG - Format 800×800px, PNG
@@ -127,6 +135,7 @@ Classification : Tout public
``` ```
**Justification** : **Justification** :
- **Friction minimale** : 5 champs max = 2 min de publication - **Friction minimale** : 5 champs max = 2 min de publication
- **Publication rapide** : pas de blocage sur description/image - **Publication rapide** : pas de blocage sur description/image
- **Coût 0** : pas de génération IA au MVP - **Coût 0** : pas de génération IA au MVP
@@ -161,6 +170,7 @@ Classification : Tout public
| **Zone diffusion** | Cohérente (pas "Tour Eiffel" avec zone "National") | | **Zone diffusion** | Cohérente (pas "Tour Eiffel" avec zone "National") |
**Délai de validation** : **Délai de validation** :
- Objectif : **24-48h** (jours ouvrés) - Objectif : **24-48h** (jours ouvrés)
- Priorité : FIFO (First In First Out) - Priorité : FIFO (First In First Out)
- Weekend : délai peut atteindre 72h - Weekend : délai peut atteindre 72h
@@ -169,11 +179,13 @@ Classification : Tout public
**Notification créateur** : **Notification créateur** :
**Si accepté** : **Si accepté** :
- Email + push : "✅ Votre contenu '[Titre]' est en ligne !" - Email + push : "✅ Votre contenu '[Titre]' est en ligne !"
- Lien direct vers le contenu - Lien direct vers le contenu
- Compteur : "2/3 contenus validés pour devenir créateur vérifié" - Compteur : "2/3 contenus validés pour devenir créateur vérifié"
**Si refusé** : **Si refusé** :
- Email + push : "❌ Contenu '[Titre]' refusé" - Email + push : "❌ Contenu '[Titre]' refusé"
- Raison détaillée : "Qualité audio insuffisante" / "Tags non pertinents" / "Classification incorrecte" / etc. - Raison détaillée : "Qualité audio insuffisante" / "Tags non pertinents" / "Classification incorrecte" / etc.
- Lien vers règles de publication - Lien vers règles de publication
@@ -182,11 +194,13 @@ Classification : Tout public
**Après 3 validations** : **Après 3 validations** :
Créateur obtient **statut "Vérifié"** : Créateur obtient **statut "Vérifié"** :
- Badge ✓ visible sur profil - Badge ✓ visible sur profil
- Contenus futurs publiés **immédiatement** (modération a posteriori uniquement) - Contenus futurs publiés **immédiatement** (modération a posteriori uniquement)
- Modération seulement si signalé par utilisateurs - Modération seulement si signalé par utilisateurs
**Outils modérateur** : **Outils modérateur** :
- Écoute accélérée (1.5x ou 2x) = double productivité - Écoute accélérée (1.5x ou 2x) = double productivité
- Interface dédiée : queue de contenus à valider - Interface dédiée : queue de contenus à valider
- Raccourcis clavier : A (Accepter), R (Rejeter), Espace (Pause) - Raccourcis clavier : A (Accepter), R (Rejeter), Espace (Pause)
@@ -197,6 +211,7 @@ Créateur obtient **statut "Vérifié"** :
⚠️ **Non implémenté au MVP** (complexité juridique) ⚠️ **Non implémenté au MVP** (complexité juridique)
Vision future (envisageable) : Vision future (envisageable) :
- Créateurs établis peuvent opt-in "Modérateur communautaire" - Créateurs établis peuvent opt-in "Modérateur communautaire"
- Formation obligatoire (30 min) + quiz (80%) - Formation obligatoire (30 min) + quiz (80%)
- Pré-validation uniquement (validation finale toujours par équipe RoadWave) - Pré-validation uniquement (validation finale toujours par équipe RoadWave)
@@ -204,6 +219,7 @@ Vision future (envisageable) :
- Attribution aléatoire (pas de collusion) - Attribution aléatoire (pas de collusion)
**Justification décision MVP** : **Justification décision MVP** :
- **Responsabilité juridique** : plateforme reste responsable (DSA EU) - **Responsabilité juridique** : plateforme reste responsable (DSA EU)
- **Qualité garantie** : modérateurs formés et mandatés - **Qualité garantie** : modérateurs formés et mandatés
- **Anti-spam efficace** : bloque 95% des abus dès le début - **Anti-spam efficace** : bloque 95% des abus dès le début
@@ -233,18 +249,22 @@ Vision future (envisageable) :
**Raisons restrictions** : **Raisons restrictions** :
**Audio non modifiable** : **Audio non modifiable** :
- Évite fraude : uploader contenu validé → remplacer par spam - Évite fraude : uploader contenu validé → remplacer par spam
- Intégrité : auditeurs doivent écouter ce qui a été validé - Intégrité : auditeurs doivent écouter ce qui a été validé
**Zone/Type non modifiables** : **Zone/Type non modifiables** :
- Évite manipulation : créer "Local Paris" → changer en "National" pour boost visibilité - Évite manipulation : créer "Local Paris" → changer en "National" pour boost visibilité
- Évite abus : créer "Neutre" (faible pondération géo) → changer en "Ancré" (forte pondération) - Évite abus : créer "Neutre" (faible pondération géo) → changer en "Ancré" (forte pondération)
**Classification non modifiable** : **Classification non modifiable** :
- Évite contournement : uploader "Tout public" → passer en "18+" sans revalidation - Évite contournement : uploader "Tout public" → passer en "18+" sans revalidation
- Sécurité : garantit que classification a été vérifiée - Sécurité : garantit que classification a été vérifiée
**Si besoin de changer audio/zone/classification** : **Si besoin de changer audio/zone/classification** :
- Action : **Supprimer contenu + republier** - Action : **Supprimer contenu + republier**
- Si créateur <3 contenus validés : retourne en file validation - Si créateur <3 contenus validés : retourne en file validation
- Si créateur ≥3 contenus validés : publication immédiate - Si créateur ≥3 contenus validés : publication immédiate
@@ -269,11 +289,13 @@ Créateur supprime podcast écouté par 1000 personnes
``` ```
**Notifications suppression** : **Notifications suppression** :
- Pas de notification aux auditeurs (pour éviter effet Streisand) - Pas de notification aux auditeurs (pour éviter effet Streisand)
- Historique reste consultable : "Vous avez écouté ce contenu le [date]" - Historique reste consultable : "Vous avez écouté ce contenu le [date]"
- Si auditeur tente de réécouter : "Ce contenu n'est plus disponible" - Si auditeur tente de réécouter : "Ce contenu n'est plus disponible"
**Justification** : **Justification** :
- **Simplicité** : règles claires et non-ambiguës - **Simplicité** : règles claires et non-ambiguës
- **Sécurité** : évite manipulations algorithme et contournements modération - **Sécurité** : évite manipulations algorithme et contournements modération
- **Contrôle créateur** : liberté totale de supprimer (RGPD) - **Contrôle créateur** : liberté totale de supprimer (RGPD)

View File

@@ -60,6 +60,7 @@
4. Mention titre + artiste dans métadonnées (recommandé) 4. Mention titre + artiste dans métadonnées (recommandé)
**Justification juridique** : **Justification juridique** :
- Directive UE 2019/790 : exception citation à des fins de critique - Directive UE 2019/790 : exception citation à des fins de critique
- Jurisprudence FR : citation courte autorisée si justifiée - Jurisprudence FR : citation courte autorisée si justifiée
- 30s = standard industrie (YouTube, TikTok) - 30s = standard industrie (YouTube, TikTok)
@@ -108,6 +109,7 @@ Validation normale continue
- ✅ Modération **a posteriori uniquement** (si signalé) - ✅ Modération **a posteriori uniquement** (si signalé)
**Justification** : **Justification** :
- **Coût 0€** : réutilise écoute 30s déjà effectuée - **Coût 0€** : réutilise écoute 30s déjà effectuée
- **Scalable** : pas de validation pour créateurs établis - **Scalable** : pas de validation pour créateurs établis
- **Pragmatique** : détecte violations évidentes (90% des cas) - **Pragmatique** : détecte violations évidentes (90% des cas)
@@ -175,6 +177,7 @@ Validation normale continue
**Détail sanctions** : **Détail sanctions** :
**Avertissement (1ère fois)** : **Avertissement (1ère fois)** :
- Suppression contenu immédiate - Suppression contenu immédiate
- Email + push + in-app : "⚠️ Contenu retiré pour violation droits d'auteur" - Email + push + in-app : "⚠️ Contenu retiré pour violation droits d'auteur"
- Explication pédagogique : règles musique, lien vers CGU - Explication pédagogique : règles musique, lien vers CGU
@@ -182,22 +185,26 @@ Validation normale continue
- Créateur peut republier version corrigée - Créateur peut republier version corrigée
**Strike 1 (2e fois)** : **Strike 1 (2e fois)** :
- Suppression contenu - Suppression contenu
- Strike ajouté au compteur (visible profil créateur) - Strike ajouté au compteur (visible profil créateur)
- Suspension upload **3 jours** - Suspension upload **3 jours**
- Email détaillé : titre détecté, timestamp, règle violée - Email détaillé : titre détecté, timestamp, règle violée
**Strike 2 (3e fois)** : **Strike 2 (3e fois)** :
- Idem Strike 1 - Idem Strike 1
- Suspension upload **7 jours** - Suspension upload **7 jours**
- Warning : "Strike 2/4 - Vous approchez du seuil critique" - Warning : "Strike 2/4 - Vous approchez du seuil critique"
**Strike 3 (4e fois)** : **Strike 3 (4e fois)** :
- Idem Strike 2 - Idem Strike 2
- Suspension upload **30 jours** - Suspension upload **30 jours**
- Warning : "Strike 3/4 - Prochaine violation = ban définitif" - Warning : "Strike 3/4 - Prochaine violation = ban définitif"
**Strike 4 - Ban définitif (5e fois)** : **Strike 4 - Ban définitif (5e fois)** :
- Désactivation compte créateur - Désactivation compte créateur
- Tous contenus dépubliés - Tous contenus dépubliés
- Pas de création nouveau compte (email/téléphone blacklisté) - Pas de création nouveau compte (email/téléphone blacklisté)
@@ -226,6 +233,7 @@ Créateur a Strike 2 (7 jours de suspension)
``` ```
**Justification** : **Justification** :
- **Tolérance 1ère fois** : évite punir erreurs honnêtes - **Tolérance 1ère fois** : évite punir erreurs honnêtes
- **Escalade progressive** : dissuasion sans brutalité - **Escalade progressive** : dissuasion sans brutalité
- **4 strikes avant ban** : cohérent avec système global (sections 9, 14) - **4 strikes avant ban** : cohérent avec système global (sections 9, 14)
@@ -239,6 +247,7 @@ Créateur a Strike 2 (7 jours de suspension)
**Décision** : Réutilise système existant section 14.3.3 **Décision** : Réutilise système existant section 14.3.3
**Accès** : **Accès** :
- Bouton "Contester cette décision" dans notification sanction - Bouton "Contester cette décision" dans notification sanction
- Délai : **7 jours** après notification - Délai : **7 jours** après notification
@@ -266,11 +275,13 @@ Champs standards (voir section 14) **+** champs spécifiques :
**Cas particulier : Musique libre mal détectée** **Cas particulier : Musique libre mal détectée**
Si créateur prouve musique = licence Epidemic Sound / Artlist : Si créateur prouve musique = licence Epidemic Sound / Artlist :
- ✅ Appel automatiquement accepté - ✅ Appel automatiquement accepté
- ✅ Ajout titre à **whitelist interne** (évite futures erreurs) - ✅ Ajout titre à **whitelist interne** (évite futures erreurs)
- ✅ Excuse + compensation (ex: 1 mois Premium offert) - ✅ Excuse + compensation (ex: 1 mois Premium offert)
**Justification** : **Justification** :
- Réutilise processus éprouvé (section 14) - Réutilise processus éprouvé (section 14)
- Preuve licence = résout 90% des cas - Preuve licence = résout 90% des cas
- Délai 72h acceptable (pas de suspension immédiate sur appel) - Délai 72h acceptable (pas de suspension immédiate sur appel)
@@ -309,6 +320,7 @@ Interdit :
``` ```
**Justification** : **Justification** :
- Prévention > sanction (économie modération) - Prévention > sanction (économie modération)
- Créateurs informés = moins de violations - Créateurs informés = moins de violations
- Coût : 0€ (documentation statique) - Coût : 0€ (documentation statique)
@@ -382,12 +394,14 @@ Modérateur humain vérifie :
**Coût total MVP** : **0€** (validation manuelle intégrée) **Coût total MVP** : **0€** (validation manuelle intégrée)
**Conformité juridique** : **Conformité juridique** :
- ✅ Directive UE 2019/790 (droit d'auteur + exception citation) - ✅ Directive UE 2019/790 (droit d'auteur + exception citation)
- ✅ DSA (Digital Services Act) : modération réactive + droit d'appel - ✅ DSA (Digital Services Act) : modération réactive + droit d'appel
- ✅ SACEM/SDRM : protection ayants droit + processus contentieux - ✅ SACEM/SDRM : protection ayants droit + processus contentieux
- ✅ Fair use : tolérance 30s conforme jurisprudence FR/UE - ✅ Fair use : tolérance 30s conforme jurisprudence FR/UE
**Scalabilité** : **Scalabilité** :
- 0-1000 contenus/mois : validation manuelle suffisante (3h/mois modération) - 0-1000 contenus/mois : validation manuelle suffisante (3h/mois modération)
- 1000-10K contenus/mois : fingerprinting open-source requis - 1000-10K contenus/mois : fingerprinting open-source requis
- 10K+ contenus/mois : API commerciale à considérer (ACRCloud) - 10K+ contenus/mois : API commerciale à considérer (ACRCloud)
@@ -404,6 +418,7 @@ Modérateur humain vérifie :
--- ---
**Lien avec autres sections** : **Lien avec autres sections** :
- Section 4.3 : Validation des 3 premiers contenus (workflow intégré) - Section 4.3 : Validation des 3 premiers contenus (workflow intégré)
- Section 7.2 : Interdictions lives + fingerprinting post-MVP - Section 7.2 : Interdictions lives + fingerprinting post-MVP
- Section 14 : Système modération (signalements, sanctions, appels) - Section 14 : Système modération (signalements, sanctions, appels)

View File

@@ -18,12 +18,14 @@
4. Après 15s → **Live public**, auditeurs peuvent rejoindre 4. Après 15s → **Live public**, auditeurs peuvent rejoindre
**Notification abonnés** : **Notification abonnés** :
-**Push notification immédiate** à tous les abonnés dans la zone géographique -**Push notification immédiate** à tous les abonnés dans la zone géographique
- Message : "🔴 [Nom créateur] est en direct : [Titre live]" - Message : "🔴 [Nom créateur] est en direct : [Titre live]"
- Tap notification → ouverture app + lecture live immédiate - Tap notification → ouverture app + lecture live immédiate
- **Filtrage géographique** : si abonné hors zone, pas de notif (évite frustration) - **Filtrage géographique** : si abonné hors zone, pas de notif (évite frustration)
**Limite de durée** : **Limite de durée** :
- **Maximum 8 heures** par session live - **Maximum 8 heures** par session live
- Warning créateur à 7h30 : "Votre live se terminera dans 30 min" - Warning créateur à 7h30 : "Votre live se terminera dans 30 min"
- Si besoin continuer → arrêt + redémarrage nouveau live (évite abus ressources serveur) - Si besoin continuer → arrêt + redémarrage nouveau live (évite abus ressources serveur)
@@ -56,12 +58,14 @@
``` ```
**Détection violations** : **Détection violations** :
- **Signalement utilisateurs** : bouton "Signaler" accessible pendant live - **Signalement utilisateurs** : bouton "Signaler" accessible pendant live
- **IA audio fingerprint** : détection musique protégée en arrière-plan (post-MVP, voir [Section 18](detection-contenu-protege.md)) - **IA audio fingerprint** : détection musique protégée en arrière-plan (post-MVP, voir [Section 18](detection-contenu-protege.md))
- **Modération réactive** : modérateurs peuvent écouter lives signalés en temps réel - **Modération réactive** : modérateurs peuvent écouter lives signalés en temps réel
- **Coupure immédiate** : modérateur peut arrêter live si contenu illégal évident - **Coupure immédiate** : modérateur peut arrêter live si contenu illégal évident
**Justification** : **Justification** :
- **Buffer 15s** : équilibre entre test qualité et friction minimale - **Buffer 15s** : équilibre entre test qualité et friction minimale
- **Notification abonnés** : engagement maximal, valeur ajoutée live - **Notification abonnés** : engagement maximal, valeur ajoutée live
- **8h max** : couvre 99% cas usage (podcasts longs, émissions radio) sans abus - **8h max** : couvre 99% cas usage (podcasts longs, émissions radio) sans abus
@@ -117,11 +121,13 @@
| **Modifier replay** | ❌ Non | Intégrité enregistrement | | **Modifier replay** | ❌ Non | Intégrité enregistrement |
**Conservation fichier source** : **Conservation fichier source** :
- Opus raw conservé **7 jours** après fin live (backup) - Opus raw conservé **7 jours** après fin live (backup)
- Suppression automatique après 7j (économie stockage) - Suppression automatique après 7j (économie stockage)
- Si replay supprimé par créateur → fichier raw supprimé immédiatement - Si replay supprimé par créateur → fichier raw supprimé immédiatement
**Justification** : **Justification** :
- **Compte à rebours 5s** : outro propre, pas de coupure brutale - **Compte à rebours 5s** : outro propre, pas de coupure brutale
- **Tolérance 60s** : évite arrêts intempestifs (tunnel, changement cellule) - **Tolérance 60s** : évite arrêts intempestifs (tunnel, changement cellule)
- **Enregistrement auto** : valorisation contenu éphémère, génération contenu pérenne - **Enregistrement auto** : valorisation contenu éphémère, génération contenu pérenne
@@ -172,6 +178,7 @@
**Décision ferme** : ❌ **Aucun chat en direct, ni maintenant ni dans le futur** **Décision ferme** : ❌ **Aucun chat en direct, ni maintenant ni dans le futur**
**Raisons** : **Raisons** :
- **Sécurité routière** : pas de distraction en voiture (focus UX) - **Sécurité routière** : pas de distraction en voiture (focus UX)
- **Harcèlement** : évite contenu haineux, insultes, trolling - **Harcèlement** : évite contenu haineux, insultes, trolling
- **Modération** : pas de coût modération temps réel (impossible à scale) - **Modération** : pas de coût modération temps réel (impossible à scale)
@@ -189,9 +196,11 @@
| **Réactions emoji** | ❌ | Jamais implémenté (décision définitive) | | **Réactions emoji** | ❌ | Jamais implémenté (décision définitive) |
**Messages utilisateur** : **Messages utilisateur** :
- "💬 Les discussions ne sont pas disponibles sur RoadWave pour garantir votre sécurité en voiture et éviter le harcèlement." - "💬 Les discussions ne sont pas disponibles sur RoadWave pour garantir votre sécurité en voiture et éviter le harcèlement."
**Justification décision définitive** : **Justification décision définitive** :
- **UX cohérente** : RoadWave = écoute en conduisant, pas réseau social interactif - **UX cohérente** : RoadWave = écoute en conduisant, pas réseau social interactif
- **Bien-être** : évite toxicité, harcèlement, haine (fléau réseaux sociaux) - **Bien-être** : évite toxicité, harcèlement, haine (fléau réseaux sociaux)
- **Juridique** : pas de risque contentieux modération chat (DSA EU) - **Juridique** : pas de risque contentieux modération chat (DSA EU)
@@ -223,6 +232,7 @@ Auditeurs (App mobile, HLS natif)
6. **Post-live** → Job async : Opus → MP3 256 kbps → Publication replay 6. **Post-live** → Job async : Opus → MP3 256 kbps → Publication replay
**Dépendances** : **Dépendances** :
-**Pion WebRTC** (Go library, open source, MIT license) -**Pion WebRTC** (Go library, open source, MIT license)
-**FFmpeg** (conversion audio, LGPL/GPL) -**FFmpeg** (conversion audio, LGPL/GPL)
-**NGINX** (cache et distribution HLS, open source) -**NGINX** (cache et distribution HLS, open source)
@@ -230,6 +240,7 @@ Auditeurs (App mobile, HLS natif)
-**PostgreSQL + Redis** (métadonnées live + cache) -**PostgreSQL + Redis** (métadonnées live + cache)
**Avantages** : **Avantages** :
- ✅ Pas de dépendance Google/Facebook/Cloudflare (souveraineté) - ✅ Pas de dépendance Google/Facebook/Cloudflare (souveraineté)
- ✅ WebRTC standard ouvert (Pion = lib Go pure) - ✅ WebRTC standard ouvert (Pion = lib Go pure)
- ✅ Réutilise infra HLS existante (pas de doublon) - ✅ Réutilise infra HLS existante (pas de doublon)
@@ -245,6 +256,7 @@ Auditeurs (App mobile, HLS natif)
| **Scale** | 1M-10M | Kubernetes auto-scale (2000+ lives) | +1K€ + bande passante | | **Scale** | 1M-10M | Kubernetes auto-scale (2000+ lives) | +1K€ + bande passante |
**Bande passante** : **Bande passante** :
- Live : 48 kbps × nb_auditeurs (via NGINX Cache, segments) - Live : 48 kbps × nb_auditeurs (via NGINX Cache, segments)
- Exemple : 100 auditeurs = 4.8 Mbps = ~2 Go/heure via cache - Exemple : 100 auditeurs = 4.8 Mbps = ~2 Go/heure via cache
- Coût estimé : ~0.02€/heure pour 100 auditeurs - Coût estimé : ~0.02€/heure pour 100 auditeurs

View File

@@ -35,6 +35,7 @@ Le domaine **Moderation** gère la modération des contenus et des utilisateurs,
## Ubiquitous Language ## Ubiquitous Language
**Termes métier du domaine** : **Termes métier du domaine** :
- **Report** : Signalement d'un contenu ou utilisateur problématique - **Report** : Signalement d'un contenu ou utilisateur problématique
- **Strike** : Avertissement comptabilisé (3 strikes = ban) - **Strike** : Avertissement comptabilisé (3 strikes = ban)
- **Sanction** : Mesure disciplinaire (warning, suspension, ban) - **Sanction** : Mesure disciplinaire (warning, suspension, ban)

View File

@@ -67,6 +67,7 @@ flowchart TD
## Légende ## Légende
**Priorités de traitement** : **Priorités de traitement** :
- 🔴 **CRITIQUE** (score ≥90) : <2h - Violence, suicide, danger immédiat - 🔴 **CRITIQUE** (score ≥90) : <2h - Violence, suicide, danger immédiat
- 🟠 **HAUTE** (70-89) : <24h - Haine, harcèlement - 🟠 **HAUTE** (70-89) : <24h - Haine, harcèlement
- 🟡 **MOYENNE** (40-69) : <24h - Spam, contenu inapproprié - 🟡 **MOYENNE** (40-69) : <24h - Spam, contenu inapproprié

View File

@@ -9,6 +9,7 @@
**Disponibilité** : Partout dans l'application **Disponibilité** : Partout dans l'application
**Emplacements** : **Emplacements** :
- Player en lecture (bouton dans contrôles) - Player en lecture (bouton dans contrôles)
- Page profil créateur (sur chaque contenu) - Page profil créateur (sur chaque contenu)
- Liste de recherche (menu contextuel) - Liste de recherche (menu contextuel)
@@ -17,6 +18,7 @@
**Icône** : ⬆️ (universelle iOS/Android) **Icône** : ⬆️ (universelle iOS/Android)
**Menu options** : **Menu options** :
- Copier le lien - Copier le lien
- WhatsApp - WhatsApp
- Email - Email
@@ -24,6 +26,7 @@
- Plus... (sheet natif OS) - Plus... (sheet natif OS)
**Justification** : **Justification** :
- Viralité = croissance organique gratuite - Viralité = croissance organique gratuite
- Aucune friction, partage universel - Aucune friction, partage universel
@@ -93,11 +96,13 @@ Page web responsive
``` ```
**Deep linking** : **Deep linking** :
- iOS : Universal Links (configuration `apple-app-site-association`) - iOS : Universal Links (configuration `apple-app-site-association`)
- Android : App Links (configuration `assetlinks.json`) - Android : App Links (configuration `assetlinks.json`)
- URL scheme : `roadwave://content/[content_id]` - URL scheme : `roadwave://content/[content_id]`
**Justification** : **Justification** :
- Meilleure viralité (partage social optimisé) - Meilleure viralité (partage social optimisé)
- SEO (contenus indexés Google) - SEO (contenus indexés Google)
- UX optimale (web + app) - UX optimale (web + app)
@@ -137,10 +142,12 @@ Page web responsive
- Rejouer les 30 premières secondes (illimité) - Rejouer les 30 premières secondes (illimité)
**Tracking** : **Tracking** :
- Métriques créateur : "Partages Premium" + "Conversions Premium" - Métriques créateur : "Partages Premium" + "Conversions Premium"
- Créateur touche sa part si conversion (70%) - Créateur touche sa part si conversion (70%)
**Justification** : **Justification** :
- Équilibre viralité / monétisation - Équilibre viralité / monétisation
- 30s = assez pour donner envie, pas assez pour satisfaire - 30s = assez pour donner envie, pas assez pour satisfaire
- Protège revenus créateurs - Protège revenus créateurs
@@ -219,10 +226,12 @@ Page web responsive
| **Par tag** | Filtre multi-sélection tags | | **Par tag** | Filtre multi-sélection tags |
**Recherche locale** : **Recherche locale** :
- Barre recherche dans profil : "Rechercher dans les contenus de @pseudo" - Barre recherche dans profil : "Rechercher dans les contenus de @pseudo"
- Recherche full-text sur titres + descriptions - Recherche full-text sur titres + descriptions
**Actions menu [•••]** : **Actions menu [•••]** :
- Partager profil - Partager profil
- Signaler profil (spam, usurpation) - Signaler profil (spam, usurpation)
- Bloquer créateur (masque tous ses contenus) - Bloquer créateur (masque tous ses contenus)
@@ -254,6 +263,7 @@ Page web responsive
| **Démographie** | Âge / zone géo (agrégée, anonymisée) | | **Démographie** | Âge / zone géo (agrégée, anonymisée) |
**Justification** : **Justification** :
- Arrondi = évite comparaisons anxiogènes - Arrondi = évite comparaisons anxiogènes
- Preuve sociale pour nouveaux auditeurs (trust) - Preuve sociale pour nouveaux auditeurs (trust)
- Gamification douce (motivation créateurs) - Gamification douce (motivation créateurs)
@@ -272,6 +282,7 @@ Page web responsive
3. **Communauté significative** : ≥10K abonnés + compte actif >6 mois 3. **Communauté significative** : ≥10K abonnés + compte actif >6 mois
**Affichage** : **Affichage** :
- Badge bleu **✓** accolé au pseudo (partout : profil, player, recherche) - Badge bleu **✓** accolé au pseudo (partout : profil, player, recherche)
- Tooltip au survol/appui long : "Compte vérifié" - Tooltip au survol/appui long : "Compte vérifié"
@@ -284,11 +295,13 @@ Page web responsive
| **Automatique (10K)** | Badge attribué automatiquement à 10K abonnés si compte >6 mois | | **Automatique (10K)** | Badge attribué automatiquement à 10K abonnés si compte >6 mois |
**Retrait du badge** : **Retrait du badge** :
- Suspension monétisation → badge retiré temporairement - Suspension monétisation → badge retiré temporairement
- Strikes multiples → badge retiré définitivement - Strikes multiples → badge retiré définitivement
- Usurpation identité détectée → ban + retrait - Usurpation identité détectée → ban + retrait
**Justification** : **Justification** :
- Combat usurpations d'identité - Combat usurpations d'identité
- Trust auditeurs (surtout pour médias/personnalités) - Trust auditeurs (surtout pour médias/personnalités)
- Simplicité (1 seul badge, pas de gamification excessive) - Simplicité (1 seul badge, pas de gamification excessive)
@@ -332,6 +345,7 @@ LIMIT 20;
``` ```
**Champs indexés** : **Champs indexés** :
- Titre du contenu (poids × 3) - Titre du contenu (poids × 3)
- Description (poids × 1) - Description (poids × 1)
- Pseudo créateur (poids × 2) - Pseudo créateur (poids × 2)
@@ -350,10 +364,12 @@ LIMIT 20;
**Coût** : 0€ (PostgreSQL natif) **Coût** : 0€ (PostgreSQL natif)
**Migration future** : **Migration future** :
- Si >100K contenus : Meilisearch (typo-tolerance avancée, ~20-50€/mois) - Si >100K contenus : Meilisearch (typo-tolerance avancée, ~20-50€/mois)
- Si >1M contenus : Elasticsearch cluster - Si >1M contenus : Elasticsearch cluster
**Justification** : **Justification** :
- PostgreSQL full-text = performant jusqu'à 500K contenus - PostgreSQL full-text = performant jusqu'à 500K contenus
- Stemming français natif - Stemming français natif
- 0€, aucune dépendance externe - 0€, aucune dépendance externe
@@ -411,15 +427,18 @@ ORDER BY distance ASC;
``` ```
**Affichage résultats** : **Affichage résultats** :
- Tri par défaut : distance croissante - Tri par défaut : distance croissante
- Indication distance : "À 2.3 km" / "À 15 km" / "À 142 km" - Indication distance : "À 2.3 km" / "À 15 km" / "À 142 km"
- Option carte : markers cliquables (clustering si >50 résultats) - Option carte : markers cliquables (clustering si >50 résultats)
**Coût** : **Coût** :
- MVP : 0€ (Nominatim public) - MVP : 0€ (Nominatim public)
- Scale : 20-50€/mois (Nominatim self-hosted Docker) - Scale : 20-50€/mois (Nominatim self-hosted Docker)
**Justification** : **Justification** :
- Essentiel pour tourisme / planification trajet - Essentiel pour tourisme / planification trajet
- OpenStreetMap = pas de dépendance Google - OpenStreetMap = pas de dépendance Google
- PostGIS = performant (index GIST natif) - PostGIS = performant (index GIST natif)
@@ -520,6 +539,7 @@ CREATE INDEX idx_content_tags ON contents USING GIN(tags);
**Coût** : 0€ (PostgreSQL + index standards) **Coût** : 0€ (PostgreSQL + index standards)
**Justification** : **Justification** :
- Filtres essentiels pour découvrabilité - Filtres essentiels pour découvrabilité
- Combinables = puissance maximale - Combinables = puissance maximale
- Sauvegarde = gain temps utilisateurs réguliers - Sauvegarde = gain temps utilisateurs réguliers
@@ -575,17 +595,20 @@ CREATE INDEX idx_content_tags ON contents USING GIN(tags);
| **Distance** | Si recherche géo : "À 2.3 km" | | **Distance** | Si recherche géo : "À 2.3 km" |
**Actions contextuelles [⋮]** : **Actions contextuelles [⋮]** :
- Partager - Partager
- Ajouter à une playlist (future feature) - Ajouter à une playlist (future feature)
- Télécharger (offline) - Télécharger (offline)
- Signaler - Signaler
**Pagination** : **Pagination** :
- **20 résultats** par page - **20 résultats** par page
- Infinite scroll (charger automatiquement si scroll >80%) - Infinite scroll (charger automatiquement si scroll >80%)
- Bouton "Charger 20 suivants" en bas (fallback si scroll auto désactivé) - Bouton "Charger 20 suivants" en bas (fallback si scroll auto désactivé)
**Vue carte (alternative)** : **Vue carte (alternative)** :
- Bouton toggle "Liste / Carte" - Bouton toggle "Liste / Carte"
- Map Leaflet (OpenStreetMap) - Map Leaflet (OpenStreetMap)
- Markers cliquables → popup avec preview - Markers cliquables → popup avec preview
@@ -594,6 +617,7 @@ CREATE INDEX idx_content_tags ON contents USING GIN(tags);
**Coût** : 0€ (Leaflet open source + OSM tiles gratuit) **Coût** : 0€ (Leaflet open source + OSM tiles gratuit)
**Justification** : **Justification** :
- Équilibre information / compacité - Équilibre information / compacité
- Lazy loading = performances - Lazy loading = performances
- Infinite scroll = UX moderne - Infinite scroll = UX moderne

View File

@@ -3,6 +3,7 @@
**Contexte** : Système de gamification pour encourager les utilisateurs à signaler du contenu inapproprié de manière pertinente et qualitative. **Contexte** : Système de gamification pour encourager les utilisateurs à signaler du contenu inapproprié de manière pertinente et qualitative.
**Objectifs** : **Objectifs** :
- Améliorer la qualité des signalements (réduire les signalements abusifs) - Améliorer la qualité des signalements (réduire les signalements abusifs)
- Réduire la charge de travail des modérateurs (priorisation automatique) - Réduire la charge de travail des modérateurs (priorisation automatique)
- Récompenser les contributeurs actifs et fiables - Récompenser les contributeurs actifs et fiables
@@ -22,6 +23,7 @@
| 🥇 | **Contributeur Or** | 50 signalements validés + 90% taux pertinence | Signalements prioritaires (+30 points) + Badge visible + Réduction Premium | | 🥇 | **Contributeur Or** | 50 signalements validés + 90% taux pertinence | Signalements prioritaires (+30 points) + Badge visible + Réduction Premium |
**Règles d'éligibilité** : **Règles d'éligibilité** :
- Minimum **10 signalements envoyés** pour être éligible aux badges - Minimum **10 signalements envoyés** pour être éligible aux badges
- Les signalements "En cours" ne comptent pas dans le calcul - Les signalements "En cours" ne comptent pas dans le calcul
- Les signalements rejetés font baisser le taux de pertinence - Les signalements rejetés font baisser le taux de pertinence
@@ -32,10 +34,12 @@ Taux de pertinence = (Signalements validés / Total signalements envoyés) × 10
``` ```
**Période de calcul** : **Période de calcul** :
- Seuls les **6 derniers mois** comptent (période glissante) - Seuls les **6 derniers mois** comptent (période glissante)
- Évite que les utilisateurs se reposent sur leurs lauriers - Évite que les utilisateurs se reposent sur leurs lauriers
**Justification** : **Justification** :
- **Simple** : 3 niveaux seulement (pas d'over-engineering) - **Simple** : 3 niveaux seulement (pas d'over-engineering)
- **Gratuit** : logique backend + affichage frontend - **Gratuit** : logique backend + affichage frontend
- **Efficace** : incite la qualité plutôt que la quantité - **Efficace** : incite la qualité plutôt que la quantité
@@ -52,6 +56,7 @@ Taux de pertinence = (Signalements validés / Total signalements envoyés) × 10
| **Argent → Or** | 60 jours | | **Argent → Or** | 60 jours |
**Justification** : **Justification** :
- Évite la montée en badge trop rapide (anti-farming) - Évite la montée en badge trop rapide (anti-farming)
- Force une contribution régulière sur la durée - Force une contribution régulière sur la durée
- Détecte les patterns suspects (audit modérateur si trop rapide) - Détecte les patterns suspects (audit modérateur si trop rapide)
@@ -63,6 +68,7 @@ Taux de pertinence = (Signalements validés / Total signalements envoyés) × 10
**IMPORTANT** : L'utilisateur doit être informé du système de récompenses **dès son premier signalement**. **IMPORTANT** : L'utilisateur doit être informé du système de récompenses **dès son premier signalement**.
**Moment d'affichage** : **Moment d'affichage** :
- Après avoir envoyé le **premier signalement** - Après avoir envoyé le **premier signalement**
- Juste après le toast de confirmation standard - Juste après le toast de confirmation standard
- **2 secondes de délai** avant affichage de la modal - **2 secondes de délai** avant affichage de la modal
@@ -102,6 +108,7 @@ Taux de pertinence = (Signalements validés / Total signalements envoyés) × 10
``` ```
**Lien "En savoir plus"** : **Lien "En savoir plus"** :
- Redirection vers page dédiée expliquant : - Redirection vers page dédiée expliquant :
- Calcul détaillé du taux de pertinence - Calcul détaillé du taux de pertinence
- Critères d'obtention pour chaque badge - Critères d'obtention pour chaque badge
@@ -116,6 +123,7 @@ Taux de pertinence = (Signalements validés / Total signalements envoyés) × 10
#### 19.1.4 Affichage badges et statistiques #### 19.1.4 Affichage badges et statistiques
**Badge visible** : **Badge visible** :
- **Profil utilisateur** : visible par tous les autres utilisateurs - **Profil utilisateur** : visible par tous les autres utilisateurs
- **Historique signalements** : visible uniquement par l'utilisateur lui-même - **Historique signalements** : visible uniquement par l'utilisateur lui-même
- **Toast après obtention** : - **Toast après obtention** :
@@ -136,10 +144,12 @@ Prochain palier : 🥇 Contributeur Or (30 signalements validés restants)
``` ```
**Toast après traitement signalement** : **Toast après traitement signalement** :
- Si validé : "✅ Bravo ! Votre signalement a aidé la communauté. Progression : 3/5 pour badge Bronze 🥉" - Si validé : "✅ Bravo ! Votre signalement a aidé la communauté. Progression : 3/5 pour badge Bronze 🥉"
- Si rejeté : "❌ Signalement non retenu. Taux de pertinence : 60%. Continuez vos efforts !" - Si rejeté : "❌ Signalement non retenu. Taux de pertinence : 60%. Continuez vos efforts !"
**Justification** : **Justification** :
- **Transparence totale** : l'utilisateur voit sa progression en temps réel - **Transparence totale** : l'utilisateur voit sa progression en temps réel
- **Motivation** : gamification saine (pas de pression, juste encouragement) - **Motivation** : gamification saine (pas de pression, juste encouragement)
- **Gratifiant** : messages positifs valorisant la contribution - **Gratifiant** : messages positifs valorisant la contribution
@@ -157,6 +167,7 @@ Score fiabilité = min(100, (Validés × 10 - Rejetés × 5 + Bonus_Or × 20))
``` ```
**Détails** : **Détails** :
- **Validés** : nombre de signalements validés par modérateurs - **Validés** : nombre de signalements validés par modérateurs
- **Rejetés** : nombre de signalements rejetés - **Rejetés** : nombre de signalements rejetés
- **Bonus_Or** : +20 points si badge Or actif - **Bonus_Or** : +20 points si badge Or actif
@@ -181,10 +192,12 @@ Priorité = (Score_IA × 0.7) + (Signalements_cumulés × 0.2) + (Fiabilité_sig
``` ```
**Intégration** : **Intégration** :
- **Fiabilité_signaleur** = Score fiabilité / 100 (normalisé 0-1) - **Fiabilité_signaleur** = Score fiabilité / 100 (normalisé 0-1)
- Les signalements des utilisateurs avec badge Argent/Or passent automatiquement devant les autres (même score IA) - Les signalements des utilisateurs avec badge Argent/Or passent automatiquement devant les autres (même score IA)
**Affichage à l'utilisateur** : **Affichage à l'utilisateur** :
- **NON affiché** publiquement (risque de gamification abusive) - **NON affiché** publiquement (risque de gamification abusive)
- **Visible** uniquement dans les stats personnelles : - **Visible** uniquement dans les stats personnelles :
``` ```
@@ -201,6 +214,7 @@ Priorité = (Score_IA × 0.7) + (Signalements_cumulés × 0.2) + (Fiabilité_sig
**Décision** : Statut automatique pour utilisateurs Badge Argent ou Or **Décision** : Statut automatique pour utilisateurs Badge Argent ou Or
**Critère** : **Critère** :
- Badge **Argent OU Or** actif = automatiquement "Utilisateur de confiance" - Badge **Argent OU Or** actif = automatiquement "Utilisateur de confiance"
**Avantages** : **Avantages** :
@@ -209,6 +223,7 @@ Priorité = (Score_IA × 0.7) + (Signalements_cumulés × 0.2) + (Fiabilité_sig
3. **Notification différée** : résultats sous 12h (au lieu de 24-48h standards) 3. **Notification différée** : résultats sous 12h (au lieu de 24-48h standards)
**Révocation** : **Révocation** :
- Perte badge Argent/Or → perte statut confiance automatique - Perte badge Argent/Or → perte statut confiance automatique
- Retour au statut normal, aucune sanction supplémentaire - Retour au statut normal, aucune sanction supplémentaire
@@ -259,10 +274,12 @@ Merci de contribuer à rendre RoadWave meilleur chaque jour !
``` ```
**Rappels** : **Rappels** :
- Email + Push J-7 : "Il vous reste 7 jours pour profiter de votre réduction Premium -50%" - Email + Push J-7 : "Il vous reste 7 jours pour profiter de votre réduction Premium -50%"
- Email + Push J-1 : "Dernière chance ! Votre réduction Premium -50% expire demain" - Email + Push J-1 : "Dernière chance ! Votre réduction Premium -50% expire demain"
**Si non activée après 30 jours** : **Si non activée après 30 jours** :
- Offre expirée (notification : "Votre offre Premium -50% a expiré") - Offre expirée (notification : "Votre offre Premium -50% a expiré")
- Badge Or conservé (seule l'offre expire, pas le badge) - Badge Or conservé (seule l'offre expire, pas le badge)
@@ -271,16 +288,19 @@ Merci de contribuer à rendre RoadWave meilleur chaque jour !
#### 19.4.3 Perte du badge Or #### 19.4.3 Perte du badge Or
**Conditions** : **Conditions** :
- Taux de pertinence descend sous **90%** après audit trimestriel - Taux de pertinence descend sous **90%** après audit trimestriel
- Signalements abusifs détectés (voir Section 19.5) - Signalements abusifs détectés (voir Section 19.5)
**Conséquences** : **Conséquences** :
- **Badge Or révoqué** immédiatement - **Badge Or révoqué** immédiatement
- **Abonnement Premium en cours** reste actif jusqu'à sa fin normale - **Abonnement Premium en cours** reste actif jusqu'à sa fin normale
- **Nouvelle souscription** à prix normal (4.99€/mois) - **Nouvelle souscription** à prix normal (4.99€/mois)
- **Pas de nouvelle offre -50%** même si badge Or réobtenu ultérieurement - **Pas de nouvelle offre -50%** même si badge Or réobtenu ultérieurement
**Justification** : **Justification** :
- Maintien qualité badges sur le long terme - Maintien qualité badges sur le long terme
- Évite abus système - Évite abus système
@@ -291,11 +311,13 @@ Merci de contribuer à rendre RoadWave meilleur chaque jour !
**Coût maximum** : **200€/mois** (si 50 utilisateurs Or simultanés avec réduction active) **Coût maximum** : **200€/mois** (si 50 utilisateurs Or simultanés avec réduction active)
**ROI attendu** : **ROI attendu** :
- **1 utilisateur Or** = économie ~5-10h modération/mois = 75-150€ économisés (taux horaire modérateur ~15€/h) - **1 utilisateur Or** = économie ~5-10h modération/mois = 75-150€ économisés (taux horaire modérateur ~15€/h)
- **10 utilisateurs Or actifs** = 750-1500€ économisés > 200€ coût réductions - **10 utilisateurs Or actifs** = 750-1500€ économisés > 200€ coût réductions
- **ROI positif dès 2-3 utilisateurs Or actifs** - **ROI positif dès 2-3 utilisateurs Or actifs**
**Justification** : **Justification** :
- **Incitation forte** pour meilleurs contributeurs uniquement - **Incitation forte** pour meilleurs contributeurs uniquement
- **Conversion** : utilisateurs gratuits très engagés → Premium payant après 3 mois - **Conversion** : utilisateurs gratuits très engagés → Premium payant après 3 mois
- **Risque limité** : coût max plafonné, largement compensé par économie modération - **Risque limité** : coût max plafonné, largement compensé par économie modération
@@ -311,11 +333,13 @@ Merci de contribuer à rendre RoadWave meilleur chaque jour !
**Décision** : Maximum 10 signalements / 24h par utilisateur **Décision** : Maximum 10 signalements / 24h par utilisateur
**Règles** : **Règles** :
- Au-delà de 10 signalements/24h → signalements automatiquement rejetés - Au-delà de 10 signalements/24h → signalements automatiquement rejetés
- Alerte modérateur automatique (enquête manuelle) - Alerte modérateur automatique (enquête manuelle)
- Message utilisateur : "Limite quotidienne atteinte (10 signalements/24h). Réessayez demain." - Message utilisateur : "Limite quotidienne atteinte (10 signalements/24h). Réessayez demain."
**Justification** : **Justification** :
- Évite signalement massif (farming) - Évite signalement massif (farming)
- 10/jour = largement suffisant pour usage légitime - 10/jour = largement suffisant pour usage légitime
- Coût : 0€ - Coût : 0€
@@ -336,10 +360,12 @@ HAVING COUNT(*) > 30
``` ```
**Action** : **Action** :
- Enquête manuelle modérateur - Enquête manuelle modérateur
- Révocation badge si abus confirmé - Révocation badge si abus confirmé
**Patterns détectés** : **Patterns détectés** :
- Signalement massif (>30/semaine) - Signalement massif (>30/semaine)
- Taux de pertinence <50% malgré volume élevé - Taux de pertinence <50% malgré volume élevé
- Signalements tous rejetés sur période 7 jours - Signalements tous rejetés sur période 7 jours
@@ -368,10 +394,12 @@ HAVING COUNT(*) > 30
``` ```
**Après audit** : **Après audit** :
- Email résultat : "Badge conservé ✓" ou "Badge révoqué ✗" - Email résultat : "Badge conservé ✓" ou "Badge révoqué ✗"
- Possibilité de réobtenir badge ultérieurement (pas de ban) - Possibilité de réobtenir badge ultérieurement (pas de ban)
**Justification** : **Justification** :
- Maintien qualité badges sur le long terme - Maintien qualité badges sur le long terme
- Évite repos sur lauriers - Évite repos sur lauriers
- Coût : 0€ (script automatique) - Coût : 0€ (script automatique)
@@ -387,6 +415,7 @@ HAVING COUNT(*) > 30
| **Grave** | Signalements massifs coordonnés (farming) | Ban permanent fonctionnalité signalement + révocation tous badges | | **Grave** | Signalements massifs coordonnés (farming) | Ban permanent fonctionnalité signalement + révocation tous badges |
**Notification sanction** : **Notification sanction** :
- Email + Push + In-app - Email + Push + In-app
- Explication détaillée de l'abus détecté - Explication détaillée de l'abus détecté
- Durée sanction - Durée sanction
@@ -416,11 +445,13 @@ HAVING COUNT(*) > 30
--- ---
**Conformité** : **Conformité** :
- ✅ RGPD : données modération anonymisées après 3 ans - ✅ RGPD : données modération anonymisées après 3 ans
- ✅ Transparence : utilisateur informé dès le 1er signalement - ✅ Transparence : utilisateur informé dès le 1er signalement
- ✅ Anti-discrimination : système accessible à tous, basé uniquement sur pertinence - ✅ Anti-discrimination : système accessible à tous, basé uniquement sur pertinence
**Scalabilité** : **Scalabilité** :
- 0-100 utilisateurs actifs : système automatique, 0€ - 0-100 utilisateurs actifs : système automatique, 0€
- 100-1000 utilisateurs actifs : 0-50€/mois (quelques badges Or) - 100-1000 utilisateurs actifs : 0-50€/mois (quelques badges Or)
- 1000+ utilisateurs actifs : 50-200€/mois (max 50 badges Or simultanés) - 1000+ utilisateurs actifs : 50-200€/mois (max 50 badges Or simultanés)

View File

@@ -19,6 +19,7 @@ Liste déroulante avec 7 options :
| 🔧 **Autre** | Champ texte obligatoire si sélectionné | | 🔧 **Autre** | Champ texte obligatoire si sélectionné |
**Justification** : **Justification** :
- Équilibre entre simplicité (pas trop de choix) et précision (aide les modérateurs) - Équilibre entre simplicité (pas trop de choix) et précision (aide les modérateurs)
- Coût : 0€ (liste déroulante standard) - Coût : 0€ (liste déroulante standard)
@@ -33,6 +34,7 @@ Liste déroulante avec 7 options :
- Non bloquant : le signalement peut être envoyé sans commentaire - Non bloquant : le signalement peut être envoyé sans commentaire
**Justification** : **Justification** :
- Encourage la qualité des signalements sans créer de friction - Encourage la qualité des signalements sans créer de friction
- Aide les modérateurs à comprendre le contexte - Aide les modérateurs à comprendre le contexte
- Pas de risque d'abandon du processus - Pas de risque d'abandon du processus
@@ -44,16 +46,19 @@ Liste déroulante avec 7 options :
**Décision** : Toast in-app avec lien historique **Décision** : Toast in-app avec lien historique
**Affichage** : **Affichage** :
- Toast notification : "✓ Signalement envoyé. Nous l'examinerons sous 24-48h." - Toast notification : "✓ Signalement envoyé. Nous l'examinerons sous 24-48h."
- Durée affichage : 5 secondes - Durée affichage : 5 secondes
- Bouton optionnel "Voir mes signalements" (accès historique) - Bouton optionnel "Voir mes signalements" (accès historique)
**Historique personnel** : **Historique personnel** :
- Liste des signalements envoyés par l'utilisateur - Liste des signalements envoyés par l'utilisateur
- Statut : En cours / Traité / Rejeté - Statut : En cours / Traité / Rejeté
- Notification in-app si action prise (contenu retiré, signalement rejeté) - Notification in-app si action prise (contenu retiré, signalement rejeté)
**Justification** : **Justification** :
- Transparence maximale - Transparence maximale
- Coût : 0€ (aucun email automatique) - Coût : 0€ (aucun email automatique)
- Bonne UX - Bonne UX
@@ -85,15 +90,18 @@ Liste déroulante avec 7 options :
4. Priorisation automatique selon score 4. Priorisation automatique selon score
**Délais** : **Délais** :
- Audio <5 min : 1-3 minutes - Audio <5 min : 1-3 minutes
- Audio 5-30 min : 3-10 minutes - Audio 5-30 min : 3-10 minutes
- Audio >30 min : 10-20 minutes - Audio >30 min : 10-20 minutes
**Coût** : **Coût** :
- **MVP** : 0€ (CPU standard, processing asynchrone) - **MVP** : 0€ (CPU standard, processing asynchrone)
- **Scale** : 50-200€/mois (GPU VPS si >1000 signalements/jour) - **Scale** : 50-200€/mois (GPU VPS si >1000 signalements/jour)
**Justification** : **Justification** :
- 100% open source, pas de dépendance GAFAM - 100% open source, pas de dépendance GAFAM
- Coût maîtrisé (scaling progressif) - Coût maîtrisé (scaling progressif)
- Gain productivité modérateurs ×3-5 - Gain productivité modérateurs ×3-5
@@ -112,10 +120,12 @@ Liste déroulante avec 7 options :
| **BASSE** | <72h (jours ouvrés) | Qualité audio, tags incorrects → Modérateur junior | | **BASSE** | <72h (jours ouvrés) | Qualité audio, tags incorrects → Modérateur junior |
**Traitement automatique** : **Traitement automatique** :
- Score IA >95% + catégorie évidente (ex: spam répété) → Action automatique immédiate - Score IA >95% + catégorie évidente (ex: spam répété) → Action automatique immédiate
- Notification créateur + possibilité d'appel - Notification créateur + possibilité d'appel
**Justification** : **Justification** :
- Réaliste et conforme DSA (Digital Services Act) - Réaliste et conforme DSA (Digital Services Act)
- Scalable : priorisation automatique - Scalable : priorisation automatique
- Ressources humaines optimisées - Ressources humaines optimisées
@@ -133,17 +143,20 @@ Priorité = (Score_IA × 0.7) + (Signalements_cumulés × 0.2) + (Fiabilité_sig
``` ```
**Détails** : **Détails** :
- **Score_IA** : 0-100% (confiance analyse automatique) - **Score_IA** : 0-100% (confiance analyse automatique)
- **Signalements_cumulés** : nombre de signalements du même contenu (boost priorité) - **Signalements_cumulés** : nombre de signalements du même contenu (boost priorité)
- **Fiabilité_signaleur** : score utilisateur (historique signalements pertinents) - **Fiabilité_signaleur** : score utilisateur (historique signalements pertinents)
**Classification résultante** : **Classification résultante** :
- Priorité ≥90 → **CRITIQUE** (traitement immédiat) - Priorité ≥90 → **CRITIQUE** (traitement immédiat)
- Priorité 70-89 → **HAUTE** (file prioritaire) - Priorité 70-89 → **HAUTE** (file prioritaire)
- Priorité 40-69 → **MOYENNE** (file normale) - Priorité 40-69 → **MOYENNE** (file normale)
- Priorité <40 → **BASSE** (file différée) - Priorité <40 → **BASSE** (file différée)
**Justification** : **Justification** :
- Optimise le temps des modérateurs - Optimise le temps des modérateurs
- Traite les cas graves en priorité - Traite les cas graves en priorité
- Coût : 0€ (algorithme simple) - Coût : 0€ (algorithme simple)
@@ -186,11 +199,13 @@ L'équipe RoadWave
``` ```
**Coût** : **Coût** :
- Email : ~0.001€/notification (Brevo, Resend) - Email : ~0.001€/notification (Brevo, Resend)
- Push : 0€ (APNS / FCM natifs) - Push : 0€ (APNS / FCM natifs)
- In-app : 0€ - In-app : 0€
**Justification** : **Justification** :
- Conformité DSA (transparence obligatoire) - Conformité DSA (transparence obligatoire)
- Multi-canal garantit réception - Multi-canal garantit réception
- Coût négligeable - Coût négligeable
@@ -232,6 +247,7 @@ L'équipe RoadWave
``` ```
**Justification** : **Justification** :
- Transparence maximale (obligation DSA) - Transparence maximale (obligation DSA)
- Créateur comprend l'erreur → amélioration future - Créateur comprend l'erreur → amélioration future
- Réduit les appels non fondés - Réduit les appels non fondés
@@ -243,6 +259,7 @@ L'équipe RoadWave
**Décision** : Formulaire in-app structuré **Décision** : Formulaire in-app structuré
**Accès** : **Accès** :
- Bouton "Contester cette décision" dans notification - Bouton "Contester cette décision" dans notification
- Section "Mes sanctions" dans profil créateur - Section "Mes sanctions" dans profil créateur
@@ -256,15 +273,18 @@ L'équipe RoadWave
| **Preuves** | Upload fichiers (max 5, 10 MB total) | ❌ | | **Preuves** | Upload fichiers (max 5, 10 MB total) | ❌ |
**Après soumission** : **Après soumission** :
- Génération numéro de ticket unique (ex: `#MOD-2026-00142`) - Génération numéro de ticket unique (ex: `#MOD-2026-00142`)
- Email confirmation : "Votre appel sera traité sous 72h" - Email confirmation : "Votre appel sera traité sous 72h"
- Statut visible dans l'app : "En cours d'examen" - Statut visible dans l'app : "En cours d'examen"
**Délai de soumission** : **Délai de soumission** :
- Maximum **7 jours** après notification de sanction - Maximum **7 jours** après notification de sanction
- Après 7 jours : appel automatiquement refusé - Après 7 jours : appel automatiquement refusé
**Justification** : **Justification** :
- Professionnel et traçable - Professionnel et traçable
- Intégration complète avec système modération - Intégration complète avec système modération
- Coût : 0€ (formulaire custom backend) - Coût : 0€ (formulaire custom backend)
@@ -284,6 +304,7 @@ L'équipe RoadWave
| **Critique** | 24h (cas suspension longue/ban) | Admin modération | | **Critique** | 24h (cas suspension longue/ban) | Admin modération |
**Notification intermédiaire** (si délai >72h) : **Notification intermédiaire** (si délai >72h) :
- Email J+3 : "Votre appel #MOD-XXX est en cours d'examen approfondi. Réponse sous 2 jours." - Email J+3 : "Votre appel #MOD-XXX est en cours d'examen approfondi. Réponse sous 2 jours."
**Réponse finale** : **Réponse finale** :
@@ -295,10 +316,12 @@ Email détaillé avec :
4. **Définitif** : mention "Cette décision est définitive" (pas de second appel) 4. **Définitif** : mention "Cette décision est définitive" (pas de second appel)
**Suivi in-app** : **Suivi in-app** :
- Mise à jour statut : "Appel accepté ✓" ou "Appel rejeté ✗" - Mise à jour statut : "Appel accepté ✓" ou "Appel rejeté ✗"
- Badge notification - Badge notification
**Justification** : **Justification** :
- Équilibre entre rapidité et qualité de traitement - Équilibre entre rapidité et qualité de traitement
- Conforme pratiques industrie (YouTube, TikTok : 5-7 jours) - Conforme pratiques industrie (YouTube, TikTok : 5-7 jours)
- Ressources humaines réalistes - Ressources humaines réalistes
@@ -329,6 +352,7 @@ Email détaillé avec :
5. **Fil d'activité** : actions récentes équipe (temps réel) 5. **Fil d'activité** : actions récentes équipe (temps réel)
**Coût infrastructure** : **Coût infrastructure** :
- MVP : 0-50€/mois (serveur CPU) - MVP : 0-50€/mois (serveur CPU)
- Scale : 50-200€/mois (GPU + Redis Cluster) - Scale : 50-200€/mois (GPU + Redis Cluster)
@@ -337,20 +361,24 @@ Email détaillé avec :
### 14.5 Modération préventive (rappel) ### 14.5 Modération préventive (rappel)
**Nouveaux créateurs** : **Nouveaux créateurs** :
- Validation manuelle des **3 premiers contenus** - Validation manuelle des **3 premiers contenus**
- Délai : 24-48h (jours ouvrés) - Délai : 24-48h (jours ouvrés)
- Transcription automatique pour aide modérateur - Transcription automatique pour aide modérateur
**Score de confiance** : **Score de confiance** :
- Évolution dynamique selon historique - Évolution dynamique selon historique
- Créateur fiable (0 strike depuis 6 mois) → validation automatique - Créateur fiable (0 strike depuis 6 mois) → validation automatique
- Créateur suspect (strikes récents) → validation manuelle systématique - Créateur suspect (strikes récents) → validation manuelle systématique
**Publicités** : **Publicités** :
- Validation manuelle obligatoire 24-48h (responsabilité juridique) - Validation manuelle obligatoire 24-48h (responsabilité juridique)
- Transcription + analyse métadonnées (ciblage, durée, volume) - Transcription + analyse métadonnées (ciblage, durée, volume)
**Justification** : **Justification** :
- Prévention > réaction (économie modération) - Prévention > réaction (économie modération)
- Qualité plateforme préservée dès le début - Qualité plateforme préservée dès le début
@@ -375,11 +403,13 @@ Email détaillé avec :
**Coût total MVP** : **0-200€/mois** (infrastructure IA optionnelle) **Coût total MVP** : **0-200€/mois** (infrastructure IA optionnelle)
**Conformité** : **Conformité** :
- ✅ DSA (Digital Services Act) : transparence, traçabilité, délais - ✅ DSA (Digital Services Act) : transparence, traçabilité, délais
- ✅ RGPD : données modération anonymisées après 3 ans - ✅ RGPD : données modération anonymisées après 3 ans
- ✅ Logs audit : toutes actions tracées (obligation légale plateforme) - ✅ Logs audit : toutes actions tracées (obligation légale plateforme)
**Scalabilité** : **Scalabilité** :
- 0-1000 signalements/mois : équipe 1-2 modérateurs junior + 1 senior - 0-1000 signalements/mois : équipe 1-2 modérateurs junior + 1 senior
- 1000-10K signalements/mois : équipe 5-10 modérateurs + IA GPU - 1000-10K signalements/mois : équipe 5-10 modérateurs + IA GPU
- 10K+ signalements/mois : équipe dédiée + IA optimisée + modération communautaire - 10K+ signalements/mois : équipe dédiée + IA optimisée + modération communautaire

View File

@@ -64,6 +64,7 @@ stateDiagram-v2
## Légende ## Légende
**États principaux** : **États principaux** :
- **Reçu** : Signalement initial (<1s) - **Reçu** : Signalement initial (<1s)
- **EnTranscription** : Whisper large-v3 (1-20 min) - **EnTranscription** : Whisper large-v3 (1-20 min)
- **EnAnalyseIA** : Score confiance 0-100% (<1 min) - **EnAnalyseIA** : Score confiance 0-100% (<1 min)

View File

@@ -22,6 +22,7 @@ Le domaine **Monetization** gère la monétisation des créateurs de contenu via
## Ubiquitous Language ## Ubiquitous Language
**Termes métier du domaine** : **Termes métier du domaine** :
- **Creator Monetization** : Activation de la monétisation pour un créateur - **Creator Monetization** : Activation de la monétisation pour un créateur
- **KYC Verification** : Vérification d'identité requise pour versements - **KYC Verification** : Vérification d'identité requise pour versements
- **Revenue Share** : Partage de revenus (70% créateur / 30% plateforme) - **Revenue Share** : Partage de revenus (70% créateur / 30% plateforme)

View File

@@ -5,6 +5,7 @@
**Décision** : ❌ Fonctionnalité abandonnée pour le MVP **Décision** : ❌ Fonctionnalité abandonnée pour le MVP
**Raisons** : **Raisons** :
- Complexité juridique (collecte pour compte de tiers, TVA variable) - Complexité juridique (collecte pour compte de tiers, TVA variable)
- Frais de transaction élevés sur petits montants (Mangopay ~1.8% + 0.18€) - Frais de transaction élevés sur petits montants (Mangopay ~1.8% + 0.18€)
- UX additionnelle à développer (wallet, transactions, confirmations) - UX additionnelle à développer (wallet, transactions, confirmations)
@@ -29,11 +30,13 @@
**Vérification** : Automatique via requêtes SQL lors de la demande d'activation **Vérification** : Automatique via requêtes SQL lors de la demande d'activation
**Affichage** : **Affichage** :
- Bouton "Demander la monétisation" dans profil créateur - Bouton "Demander la monétisation" dans profil créateur
- Si critères non remplis → affichage progression vers objectifs - Si critères non remplis → affichage progression vers objectifs
- Si critères remplis → redirection vers KYC Mangopay - Si critères remplis → redirection vers KYC Mangopay
**Justification** : **Justification** :
- **Anti-fraude** : Le délai de 3 mois permet de détecter les comptes suspects - **Anti-fraude** : Le délai de 3 mois permet de détecter les comptes suspects
- **Qualité** : Seuls les créateurs sérieux avec audience réelle sont monétisés - **Qualité** : Seuls les créateurs sérieux avec audience réelle sont monétisés
- **Coût administratif** : Réduit le nombre de comptes à gérer (KYC, comptabilité, virements) - **Coût administratif** : Réduit le nombre de comptes à gérer (KYC, comptabilité, virements)
@@ -46,6 +49,7 @@
**Décision** : Statut juridique professionnel obligatoire **Décision** : Statut juridique professionnel obligatoire
**Statuts acceptés** : **Statuts acceptés** :
- Auto-entrepreneur (micro-BNC pour artistes/créateurs de contenu) - Auto-entrepreneur (micro-BNC pour artistes/créateurs de contenu)
- SARL/SAS/SASU (sociétés) - SARL/SAS/SASU (sociétés)
@@ -64,17 +68,20 @@
**Délai** : 24-72h si documents conformes **Délai** : 24-72h si documents conformes
**Rejet possible si** : **Rejet possible si** :
- Documents invalides/illisibles - Documents invalides/illisibles
- Identité ne correspond pas au compte RoadWave - Identité ne correspond pas au compte RoadWave
- Liste noire anti-blanchiment (vérification automatique Mangopay) - Liste noire anti-blanchiment (vérification automatique Mangopay)
- RIB non professionnel (particulier) - RIB non professionnel (particulier)
**Base légale** : **Base légale** :
- **Conformité fiscale** : L'État français impose déclaration revenus >1200€/an (DAS2) - **Conformité fiscale** : L'État français impose déclaration revenus >1200€/an (DAS2)
- **Anti-blanchiment** : Directive EU 2018/843 (5ème directive LCB-FT) - **Anti-blanchiment** : Directive EU 2018/843 (5ème directive LCB-FT)
- **RGPD** : Données hébergées EU via Mangopay (conforme) - **RGPD** : Données hébergées EU via Mangopay (conforme)
**Justification** : **Justification** :
- **Responsabilité légale** : RoadWave doit pouvoir prouver identité réelle créateurs monétisés - **Responsabilité légale** : RoadWave doit pouvoir prouver identité réelle créateurs monétisés
- **Automatisation** : Mangopay gère tout (KYC, vérifications, conformité, e-wallets) - **Automatisation** : Mangopay gère tout (KYC, vérifications, conformité, e-wallets)
- **KYC gratuit** : inclus dans l'offre Mangopay (vs 1.20€ chez Stripe) - **KYC gratuit** : inclus dans l'offre Mangopay (vs 1.20€ chez Stripe)
@@ -101,16 +108,19 @@ Publicité facturée par RoadWave : 0.05€/écoute complète = 50€ CPM
``` ```
**Exemple concret** : **Exemple concret** :
- 10 000 écoutes/mois → créateur touche **30€** - 10 000 écoutes/mois → créateur touche **30€**
- 50 000 écoutes/mois → créateur touche **150€** - 50 000 écoutes/mois → créateur touche **150€**
- 100 000 écoutes/mois → créateur touche **300€** - 100 000 écoutes/mois → créateur touche **300€**
**Comparaison industrie** : **Comparaison industrie** :
- YouTube : 3-5€/1000 vues - YouTube : 3-5€/1000 vues
- Spotify : 3-4€/1000 écoutes - Spotify : 3-4€/1000 écoutes
- RoadWave : 3€/1000 écoutes (aligné) - RoadWave : 3€/1000 écoutes (aligné)
**Règles comptabilisation** : **Règles comptabilisation** :
- ✅ Écoute complète = ≥80% du contenu écouté - ✅ Écoute complète = ≥80% du contenu écouté
- ✅ Utilisateur gratuit uniquement - ✅ Utilisateur gratuit uniquement
- ❌ Écoutes Premium ne comptent pas ici (autre système) - ❌ Écoutes Premium ne comptent pas ici (autre système)
@@ -130,6 +140,7 @@ Utilisateur Premium = 4.99€/mois
└─ 1.50€ gardés par plateforme (30%) └─ 1.50€ gardés par plateforme (30%)
Si l'utilisateur écoute 3 créateurs ce mois : Si l'utilisateur écoute 3 créateurs ce mois :
- Créateur A : 10h d'écoute (50%) → 1.75€ - Créateur A : 10h d'écoute (50%) → 1.75€
- Créateur B : 6h d'écoute (30%) → 1.05€ - Créateur B : 6h d'écoute (30%) → 1.05€
- Créateur C : 4h d'écoute (20%) → 0.70€ - Créateur C : 4h d'écoute (20%) → 0.70€
@@ -151,12 +162,14 @@ GROUP BY creator_id;
``` ```
**Comparaison industrie** : **Comparaison industrie** :
- YouTube Premium : 70/30 - YouTube Premium : 70/30
- Spotify : 70/30 - Spotify : 70/30
- Apple Music : 52/48 (moins avantageux) - Apple Music : 52/48 (moins avantageux)
- RoadWave : 70/30 (standard) - RoadWave : 70/30 (standard)
**Justification** : **Justification** :
- **Standard industrie** : ratio équitable éprouvé - **Standard industrie** : ratio équitable éprouvé
- **Incitation qualité** : créateurs les plus écoutés gagnent plus - **Incitation qualité** : créateurs les plus écoutés gagnent plus
- **Équité** : pas de "winner takes all", chaque créateur écouté reçoit sa part - **Équité** : pas de "winner takes all", chaque créateur écouté reçoit sa part
@@ -178,6 +191,7 @@ GROUP BY creator_id;
- Solde conservé **indéfiniment** SI créateur actif - Solde conservé **indéfiniment** SI créateur actif
- Critère activité : >0 écoute/mois OU connexion dashboard/mois - Critère activité : >0 écoute/mois OU connexion dashboard/mois
- Solde visible en temps réel dans dashboard créateur - Solde visible en temps réel dans dashboard créateur
**Créateur inactif** (0 écoute/mois + 0 connexion dashboard) : **Créateur inactif** (0 écoute/mois + 0 connexion dashboard) :
@@ -191,11 +205,13 @@ GROUP BY creator_id;
| **18 mois + 37j** | Purge données comptables | (Conservation logs 10 ans RGPD) | | **18 mois + 37j** | Purge données comptables | (Conservation logs 10 ans RGPD) |
**Exception soldes <10€** : **Exception soldes <10€** :
- Si solde <10€ après 18 mois → Frais bancaires (0.36€) > 3.6% du montant - Si solde <10€ après 18 mois → Frais bancaires (0.36€) > 3.6% du montant
- Proposition email : "Don association ou conservation jusqu'à 50€" - Proposition email : "Don association ou conservation jusqu'à 50€"
- Si don refusé + inactivité continue → versement forcé quand même (équité) - Si don refusé + inactivité continue → versement forcé quand même (équité)
**Frais bancaires assumés par créateur** : **Frais bancaires assumés par créateur** :
- Mangopay SEPA : 1.8% + 0.18€ - Mangopay SEPA : 1.8% + 0.18€
- Exemple : 45€ → versement **44.64€** net - Exemple : 45€ → versement **44.64€** net
- Transparence totale dans email préavis - Transparence totale dans email préavis
@@ -215,6 +231,7 @@ Votre solde actuel : XX.XX€
→ Montant net estimé : XX.XX€ → Montant net estimé : XX.XX€
💡 Pour éviter le versement anticipé : 💡 Pour éviter le versement anticipé :
- Publiez un nouveau contenu, OU - Publiez un nouveau contenu, OU
- Connectez-vous à votre dashboard créateur - Connectez-vous à votre dashboard créateur
@@ -234,6 +251,7 @@ L'équipe RoadWave
| **Frais bancaires** | ❓ Non documenté | Déduits + annoncés | ✅ RoadWave transparent | | **Frais bancaires** | ❓ Non documenté | Déduits + annoncés | ✅ RoadWave transparent |
**Justification** : **Justification** :
- **Plus équitable que Twitch** : versement forcé au lieu de forfeiture (créateur récupère son argent) - **Plus équitable que Twitch** : versement forcé au lieu de forfeiture (créateur récupère son argent)
- **Emails préventifs** : 3 relances (12 mois, 18 mois, 18 mois + 30j) avant action - **Emails préventifs** : 3 relances (12 mois, 18 mois, 18 mois + 30j) avant action
- **Transparence** : frais bancaires annoncés clairement dans emails - **Transparence** : frais bancaires annoncés clairement dans emails
@@ -253,6 +271,7 @@ L'équipe RoadWave
| **16-18 du mois suivant** | Réception virement (1-3 jours ouvrés SEPA) | | **16-18 du mois suivant** | Réception virement (1-3 jours ouvrés SEPA) |
**Virement via Mangopay** : **Virement via Mangopay** :
- SEPA pour comptes EU (gratuit, 1-3 jours) - SEPA pour comptes EU (gratuit, 1-3 jours)
- Virement international hors EU (frais variables selon pays, rare en pratique) - Virement international hors EU (frais variables selon pays, rare en pratique)
- **E-wallets automatiques** : chaque créateur possède un wallet Mangopay où ses revenus sont transférés automatiquement - **E-wallets automatiques** : chaque créateur possède un wallet Mangopay où ses revenus sont transférés automatiquement
@@ -281,27 +300,32 @@ L'équipe RoadWave
**Décision** : Créateur décide individuellement pour chaque contenu **Décision** : Créateur décide individuellement pour chaque contenu
**Fonctionnement** : **Fonctionnement** :
- Toggle "Réservé Premium" lors création/édition contenu - Toggle "Réservé Premium" lors création/édition contenu
- **Aucune limite imposée** : créateur peut mettre 0%, 50% ou 100% en premium - **Aucune limite imposée** : créateur peut mettre 0%, 50% ou 100% en premium
- Badge 👑 visible sur interface utilisateur - Badge 👑 visible sur interface utilisateur
**Comportement utilisateurs gratuits** : **Comportement utilisateurs gratuits** :
- Contenu premium visible dans liste/algo - Contenu premium visible dans liste/algo
- Tentative lecture → overlay bloquant - Tentative lecture → overlay bloquant
- Message : "Ce contenu est réservé aux abonnés Premium" - Message : "Ce contenu est réservé aux abonnés Premium"
- CTA : "Passez Premium pour 4.99€/mois" - CTA : "Passez Premium pour 4.99€/mois"
**Comportement algorithme** : **Comportement algorithme** :
- Contenus premium inclus dans recommandations - Contenus premium inclus dans recommandations
- Si user gratuit → contenu skippé automatiquement (ne consomme pas de slot) - Si user gratuit → contenu skippé automatiquement (ne consomme pas de slot)
- Si user premium → diffusé normalement - Si user premium → diffusé normalement
**Métadonnées** : **Métadonnées** :
- Champ `is_premium` (boolean) en base - Champ `is_premium` (boolean) en base
- Index sur ce champ pour requêtes rapides - Index sur ce champ pour requêtes rapides
- Cache Redis : `content:{id}:premium` (TTL 1h) - Cache Redis : `content:{id}:premium` (TTL 1h)
**Justification** : **Justification** :
- **Liberté créateur** : chaque créateur choisit sa stratégie (freemium, tout gratuit, tout premium) - **Liberté créateur** : chaque créateur choisit sa stratégie (freemium, tout gratuit, tout premium)
- **Incitation Premium** : contenu exclusif = argument fort pour s'abonner - **Incitation Premium** : contenu exclusif = argument fort pour s'abonner
- **Équité** : un petit créateur peut tout mettre en premium, un gros peut tout offrir gratuitement - **Équité** : un petit créateur peut tout mettre en premium, un gros peut tout offrir gratuitement
@@ -330,6 +354,7 @@ L'équipe RoadWave
> Bien que le seuil légal DAS2 soit 1200€/an, rien n'interdit de déclarer les montants inférieurs. Au contraire, cela renforce la transparence et protège RoadWave en cas de contrôle fiscal. > Bien que le seuil légal DAS2 soit 1200€/an, rien n'interdit de déclarer les montants inférieurs. Au contraire, cela renforce la transparence et protège RoadWave en cas de contrôle fiscal.
**Avantages** : **Avantages** :
-**Conformité maximale** : aucune zone grise -**Conformité maximale** : aucune zone grise
-**Protection juridique RoadWave** : traçabilité totale -**Protection juridique RoadWave** : traçabilité totale
-**Simplicité technique** : même processus pour tous -**Simplicité technique** : même processus pour tous
@@ -344,6 +369,7 @@ Objet : Votre déclaration fiscale 2026 RoadWave
Bonjour [Créateur], Bonjour [Créateur],
Vos revenus RoadWave 2026 ont été déclarés aux impôts (DAS2) : Vos revenus RoadWave 2026 ont été déclarés aux impôts (DAS2) :
- Revenus publicité : XXX.XX€ - Revenus publicité : XXX.XX€
- Revenus Premium : XXX.XX€ - Revenus Premium : XXX.XX€
- Total déclaré : XXX.XX€ - Total déclaré : XXX.XX€
@@ -358,12 +384,14 @@ L'équipe RoadWave
``` ```
**Créateur responsable de** : **Créateur responsable de** :
- Déclarer ses revenus à l'URSSAF (cotisations sociales auto-entrepreneur ou IS/IR) - Déclarer ses revenus à l'URSSAF (cotisations sociales auto-entrepreneur ou IS/IR)
- Déclarer ses revenus aux impôts (IR ou IS selon statut) - Déclarer ses revenus aux impôts (IR ou IS selon statut)
- Gérer sa TVA si applicable (franchise en base jusqu'à ~37K€/an en micro-BNC) - Gérer sa TVA si applicable (franchise en base jusqu'à ~37K€/an en micro-BNC)
- Conserver justificatifs **10 ans** (obligation légale comptable) - Conserver justificatifs **10 ans** (obligation légale comptable)
**Mangopay transmet automatiquement** : **Mangopay transmet automatiquement** :
- Données aux autorités fiscales EU via **DAC7** (directive 2021/514) - Données aux autorités fiscales EU via **DAC7** (directive 2021/514)
- Justificatif de chaque virement (preuve bancaire pour comptabilité créateur) - Justificatif de chaque virement (preuve bancaire pour comptabilité créateur)
@@ -376,6 +404,7 @@ Si créateur a touché 2500€ en 2026 :
``` ```
**Justification** : **Justification** :
- **Conformité légale** : RoadWave doit déclarer revenus versés (DAS2, DAC7) - **Conformité légale** : RoadWave doit déclarer revenus versés (DAS2, DAC7)
- **Responsabilité fiscale** : Le créateur reste responsable de sa déclaration (impossible de gérer pour lui) - **Responsabilité fiscale** : Le créateur reste responsable de sa déclaration (impossible de gérer pour lui)
- **Automatisation** : Minimise charge administrative côtés créateur et plateforme - **Automatisation** : Minimise charge administrative côtés créateur et plateforme
@@ -385,6 +414,7 @@ Si créateur a touché 2500€ en 2026 :
### 9.8 Désactivation et suspension monétisation ### 9.8 Désactivation et suspension monétisation
**Créateur peut** : **Créateur peut** :
- Désactiver temporairement (vacances, pause création) - Désactiver temporairement (vacances, pause création)
- Réactiver sans refaire KYC si données à jour (<2 ans) - Réactiver sans refaire KYC si données à jour (<2 ans)
- Solde conservé pendant désactivation - Solde conservé pendant désactivation
@@ -399,16 +429,19 @@ Si créateur a touché 2500€ en 2026 :
| **Fraude détectée** | Suspension immédiate + enquête | Cas par cas | | **Fraude détectée** | Suspension immédiate + enquête | Cas par cas |
**Suppression définitive si** : **Suppression définitive si** :
- Demande du créateur (solde versé sous 30 jours) - Demande du créateur (solde versé sous 30 jours)
- Inactivité 24 mois + solde <50€ (purge RGPD) - Inactivité 24 mois + solde <50€ (purge RGPD)
- Ban définitif compte (Strike 4) - Ban définitif compte (Strike 4)
**Notification** : **Notification** :
- Email + in-app pour toute suspension - Email + in-app pour toute suspension
- Raison explicite fournie - Raison explicite fournie
- Procédure de réactivation indiquée - Procédure de réactivation indiquée
**Justification** : **Justification** :
- **Flexibilité** : créateur peut faire pause sans perdre statut - **Flexibilité** : créateur peut faire pause sans perdre statut
- **Sécurité** : plateforme doit pouvoir suspendre en cas problème légal/technique - **Sécurité** : plateforme doit pouvoir suspendre en cas problème légal/technique
- **RGPD** : suppression auto données inactives après délai raisonnable - **RGPD** : suppression auto données inactives après délai raisonnable

View File

@@ -24,6 +24,7 @@ Le domaine **Premium** gère les abonnements payants et les fonctionnalités exc
## Ubiquitous Language ## Ubiquitous Language
**Termes métier du domaine** : **Termes métier du domaine** :
- **Premium Subscription** : Abonnement payant mensuel ou annuel - **Premium Subscription** : Abonnement payant mensuel ou annuel
- **Offline Download** : Téléchargement pour écoute hors-ligne - **Offline Download** : Téléchargement pour écoute hors-ligne
- **Sync Queue** : File d'attente de synchronisation offline - **Sync Queue** : File d'attente de synchronisation offline

View File

@@ -5,6 +5,7 @@
**Décision** : Boost +30% au score + reste dans le mix **Décision** : Boost +30% au score + reste dans le mix
**Boost de score abonnements** : **Boost de score abonnements** :
- **+30% au score final** pour contenus d'un créateur suivi - **+30% au score final** pour contenus d'un créateur suivi
- Application : multiplicateur sur le score calculé - Application : multiplicateur sur le score calculé
@@ -13,6 +14,7 @@ score_final_avec_boost = score_final × 1.3
``` ```
**Reste dans le mix** : **Reste dans le mix** :
-**Pas de priorité absolue** (pas de file dédiée abonnements) -**Pas de priorité absolue** (pas de file dédiée abonnements)
- ✅ Contenu suivi entre en **compétition avec autres contenus** - ✅ Contenu suivi entre en **compétition avec autres contenus**
- ✅ Si créateur suivi publie contenu faible engagement → peut être battu par contenu viral non-suivi - ✅ Si créateur suivi publie contenu faible engagement → peut être battu par contenu viral non-suivi
@@ -22,12 +24,14 @@ score_final_avec_boost = score_final × 1.3
Utilisateur à Paris, 2 contenus disponibles : Utilisateur à Paris, 2 contenus disponibles :
Contenu A (créateur NON suivi) : Contenu A (créateur NON suivi) :
- Score géo : 0.9 (très proche) - Score géo : 0.9 (très proche)
- Score intérêts : 0.8 - Score intérêts : 0.8
- Score engagement : 0.7 - Score engagement : 0.7
→ Score final : 0.80 → Score final : 0.80
Contenu B (créateur suivi) : Contenu B (créateur suivi) :
- Score géo : 0.5 (moyennement proche) - Score géo : 0.5 (moyennement proche)
- Score intérêts : 0.6 - Score intérêts : 0.6
- Score engagement : 0.5 - Score engagement : 0.5
@@ -45,6 +49,7 @@ Contenu B (suivi) : score 0.60 → avec boost 0.78
``` ```
**Justification** : **Justification** :
- **Équilibre** : valorise abonnements sans enfermer utilisateur - **Équilibre** : valorise abonnements sans enfermer utilisateur
- **Découverte** : contenus viraux/locaux peuvent toujours émerger - **Découverte** : contenus viraux/locaux peuvent toujours émerger
- **Prévisible** : boost fixe, pas de logique opaque - **Prévisible** : boost fixe, pas de logique opaque
@@ -104,16 +109,19 @@ Tap pour explorer
``` ```
**Filtrage géographique** : **Filtrage géographique** :
- Si contenu/live hors zone utilisateur → **pas de notification** - Si contenu/live hors zone utilisateur → **pas de notification**
- Évite frustration : "notification pour contenu que je ne peux pas écouter" - Évite frustration : "notification pour contenu que je ne peux pas écouter"
- Exception : contenu national → notifie tous les abonnés - Exception : contenu national → notifie tous les abonnés
**Fréquence maximale** : **Fréquence maximale** :
- **Maximum 10 notifications push/jour** par utilisateur (tous types confondus) - **Maximum 10 notifications push/jour** par utilisateur (tous types confondus)
- Si dépassement : notifications regroupées - Si dépassement : notifications regroupées
- Message groupé : "🎧 3 nouveaux contenus de créateurs suivis" - Message groupé : "🎧 3 nouveaux contenus de créateurs suivis"
**Plages horaires** : **Plages horaires** :
- **Mode silencieux** : 22h-8h (pas de push, sauf live) - **Mode silencieux** : 22h-8h (pas de push, sauf live)
- Paramétrable utilisateur (désactivation totale possible) - Paramétrable utilisateur (désactivation totale possible)
- Option "Notifications importantes uniquement" (lives uniquement) - Option "Notifications importantes uniquement" (lives uniquement)
@@ -129,6 +137,7 @@ Tap pour explorer
| **Limite quotidienne** | 10 | Modifiable 5-20 | | **Limite quotidienne** | 10 | Modifiable 5-20 |
**Justification** : **Justification** :
- **Sécurité routière** : pas de push en conduite (distraction) - **Sécurité routière** : pas de push en conduite (distraction)
- **Engagement piéton** : push actifs pour audio-guides (valeur ajoutée tourisme) - **Engagement piéton** : push actifs pour audio-guides (valeur ajoutée tourisme)
- **Pas de spam** : limite 10/jour + mode silencieux - **Pas de spam** : limite 10/jour + mode silencieux
@@ -207,10 +216,12 @@ Liste des séquences :
| **Quitter** | Tap "×" | Sauvegarde progression, sortie guide | | **Quitter** | Tap "×" | Sauvegarde progression, sortie guide |
**Guidage vocal automatique** : **Guidage vocal automatique** :
- Entre 2 séquences : "Vous avez terminé la séquence 2. Dirigez-vous vers la Vénus de Milo pour la séquence 3." - Entre 2 séquences : "Vous avez terminé la séquence 2. Dirigez-vous vers la Vénus de Milo pour la séquence 3."
- Si utilisateur s'éloigne (>50m de la prochaine pièce) : "Vous vous éloignez de la prochaine étape. Consultez le plan." - Si utilisateur s'éloigne (>50m de la prochaine pièce) : "Vous vous éloignez de la prochaine étape. Consultez le plan."
**Sauvegarde progression** : **Sauvegarde progression** :
- Position dans guide sauvegardée automatiquement - Position dans guide sauvegardée automatiquement
- Retour ultérieur : "Reprendre à la séquence 5 ?" ou "Recommencer depuis le début" - Retour ultérieur : "Reprendre à la séquence 5 ?" ou "Recommencer depuis le début"
- Historique : guide marqué "Terminé" si toutes séquences écoutées - Historique : guide marqué "Terminé" si toutes séquences écoutées
@@ -251,6 +262,7 @@ Liste des séquences :
``` ```
**Justification** : **Justification** :
- **UX piéton** : navigation tactile adaptée (pas de commandes volant) - **UX piéton** : navigation tactile adaptée (pas de commandes volant)
- **Autonomie** : utilisateur maître de son rythme (pas d'enchaînement forcé) - **Autonomie** : utilisateur maître de son rythme (pas d'enchaînement forcé)
- **Choix** : plusieurs guides = diversité styles (famille, expert, rapide) - **Choix** : plusieurs guides = diversité styles (famille, expert, rapide)
@@ -264,6 +276,7 @@ Liste des séquences :
**Décision** : 200 abonnements max + désabonnement -5% jauges **Décision** : 200 abonnements max + désabonnement -5% jauges
**Nombre maximum d'abonnements** : **Nombre maximum d'abonnements** :
- **200 créateurs maximum** par utilisateur - **200 créateurs maximum** par utilisateur
- Raisons : - Raisons :
- **Évite spam** : au-delà de 200, notifications ingérables - **Évite spam** : au-delà de 200, notifications ingérables
@@ -271,16 +284,19 @@ Liste des séquences :
- **Performance** : requêtes SQL optimisées (index sur 200 max) - **Performance** : requêtes SQL optimisées (index sur 200 max)
**Si limite atteinte** : **Si limite atteinte** :
- Message : "Vous suivez déjà 200 créateurs. Désabonnez-vous d'un créateur pour en suivre un nouveau." - Message : "Vous suivez déjà 200 créateurs. Désabonnez-vous d'un créateur pour en suivre un nouveau."
- Liste triable : par date abonnement, nb contenus écoutés, dernière activité - Liste triable : par date abonnement, nb contenus écoutés, dernière activité
- Suggestion : "Vous n'avez pas écouté [Créateur X] depuis 6 mois, le désabonner ?" - Suggestion : "Vous n'avez pas écouté [Créateur X] depuis 6 mois, le désabonner ?"
**Abonnement initial** : **Abonnement initial** :
- Impact : **+5% toutes jauges tags du créateur** (voir [Règle 05 - Section 5.3](../../recommendation/rules/interactions-navigation.md#actions-complémentaires-mode-piéton-uniquement)) - Impact : **+5% toutes jauges tags du créateur** (voir [Règle 05 - Section 5.3](../../recommendation/rules/interactions-navigation.md#actions-complémentaires-mode-piéton-uniquement))
- Action : Bouton "S'abonner" dans profil créateur (interface mobile) - Action : Bouton "S'abonner" dans profil créateur (interface mobile)
- Immédiat à l'action - Immédiat à l'action
**Désabonnement** : **Désabonnement** :
- Impact : **-5% toutes jauges tags du créateur** (symétrique) - Impact : **-5% toutes jauges tags du créateur** (symétrique)
- Action : Bouton "Se désabonner" dans profil créateur - Action : Bouton "Se désabonner" dans profil créateur
- Immédiat à l'action - Immédiat à l'action
@@ -300,15 +316,18 @@ Abonnement :
``` ```
**Gestion multi-tags** : **Gestion multi-tags** :
- Si créateur a 3 tags → **+5% sur chacun des 3 tags** - Si créateur a 3 tags → **+5% sur chacun des 3 tags**
- Logique : abonnement = signal fort d'affinité à TOUS les sujets du créateur - Logique : abonnement = signal fort d'affinité à TOUS les sujets du créateur
**Abonnements réciproques** : **Abonnements réciproques** :
-**Pas d'abonnement mutuel visible** -**Pas d'abonnement mutuel visible**
- Créateur ne voit pas qui est abonné (privacy) - Créateur ne voit pas qui est abonné (privacy)
- Créateur voit uniquement : nombre total abonnés (métrique globale) - Créateur voit uniquement : nombre total abonnés (métrique globale)
**Justification** : **Justification** :
- **Limite 200** : équilibre entre liberté et gestion spam - **Limite 200** : équilibre entre liberté et gestion spam
- **Symétrie +5%/-5%** : cohérence mathématique, prévisibilité - **Symétrie +5%/-5%** : cohérence mathématique, prévisibilité
- **Privacy** : pas de liste publique abonnés (évite stalking) - **Privacy** : pas de liste publique abonnés (évite stalking)

View File

@@ -5,6 +5,7 @@
**Zone géographique** : Choix manuel utilisateur **Zone géographique** : Choix manuel utilisateur
**Options prédéfinies** : **Options prédéfinies** :
- "Autour de moi" (rayon 50 km position actuelle) - "Autour de moi" (rayon 50 km position actuelle)
- "Ma ville" (limite administrative détectée) - "Ma ville" (limite administrative détectée)
- "Mon département" (sélection liste) - "Mon département" (sélection liste)
@@ -19,6 +20,7 @@
| **Premium** | Illimité | "245 contenus (3.2 GB)" | | **Premium** | Illimité | "245 contenus (3.2 GB)" |
**Calcul temps disponible** : **Calcul temps disponible** :
- 50 contenus × 5 min moyenne = 250 min = **4h d'écoute** (suffisant pour gratuits) - 50 contenus × 5 min moyenne = 250 min = **4h d'écoute** (suffisant pour gratuits)
- Premium illimité = limité uniquement par espace disque device - Premium illimité = limité uniquement par espace disque device
@@ -47,6 +49,7 @@ Exemple : 20 contenus × 5 min × 48 kbps = ~72 MB
| **Haute** | 64 kbps | ~30 MB/h | **Premium uniquement** | | **Haute** | 64 kbps | ~30 MB/h | **Premium uniquement** |
**Justification** : **Justification** :
- Standard = bon compromis qualité/taille (Opus 48 kbps = très correct pour voix) - Standard = bon compromis qualité/taille (Opus 48 kbps = très correct pour voix)
- Haute réservée Premium = incitation upgrade - Haute réservée Premium = incitation upgrade
- User peut réduire à "basse" si espace limité - User peut réduire à "basse" si espace limité
@@ -58,6 +61,7 @@ Exemple : 20 contenus × 5 min × 48 kbps = ~72 MB
**Durée de validité** : 30 jours après téléchargement **Durée de validité** : 30 jours après téléchargement
**Standard industrie** : **Standard industrie** :
- Spotify : 30 jours - Spotify : 30 jours
- YouTube Music : 30 jours - YouTube Music : 30 jours
- Deezer : 30 jours - Deezer : 30 jours
@@ -77,11 +81,13 @@ App détecte WiFi + contenus >25 jours
``` ```
**Notification avant expiration** : **Notification avant expiration** :
- **J-3** : "X contenus expirent dans 3 jours. Connectez-vous en WiFi pour les renouveler" - **J-3** : "X contenus expirent dans 3 jours. Connectez-vous en WiFi pour les renouveler"
- **J-0** : Suppression automatique - **J-0** : Suppression automatique
- **J+0** : Toast "15 contenus expirés ont été supprimés" - **J+0** : Toast "15 contenus expirés ont été supprimés"
**Justification** : **Justification** :
- **Force reconnexion** : vérifier abonnement actif, contenus légaux - **Force reconnexion** : vérifier abonnement actif, contenus légaux
- **Évite stockage obsolète** : contenus supprimés/modérés ne restent pas - **Évite stockage obsolète** : contenus supprimés/modérés ne restent pas
- **UX transparente** : renouvellement silencieux si WiFi régulier - **UX transparente** : renouvellement silencieux si WiFi régulier
@@ -91,6 +97,7 @@ App détecte WiFi + contenus >25 jours
### 11.3 Synchronisation actions offline ### 11.3 Synchronisation actions offline
**Actions stockées localement (SQLite)** : **Actions stockées localement (SQLite)** :
- Likes/unlikes - Likes/unlikes
- Abonnements/désabonnements - Abonnements/désabonnements
- Signalements - Signalements
@@ -108,11 +115,13 @@ App détecte WiFi + contenus >25 jours
``` ```
**Gestion erreurs sync** : **Gestion erreurs sync** :
- Si échec après 3 tentatives → notification : "Impossible de synchroniser. Réessayez plus tard" - Si échec après 3 tentatives → notification : "Impossible de synchroniser. Réessayez plus tard"
- Actions conservées jusqu'à sync réussie (pas de perte) - Actions conservées jusqu'à sync réussie (pas de perte)
- **Rétention max 7 jours** : après = purge (évite queue infinie) - **Rétention max 7 jours** : après = purge (évite queue infinie)
**Justification** : **Justification** :
- **Pas de conflit possible** : actions unilatérales user (likes/abonnements) - **Pas de conflit possible** : actions unilatérales user (likes/abonnements)
- **UX fluide** : pas de blocage offline - **UX fluide** : pas de blocage offline
- **Batch = économie** : requêtes HTTP groupées - **Batch = économie** : requêtes HTTP groupées
@@ -187,17 +196,20 @@ User se reconnecte (WiFi détecté)
``` ```
**Bouton "Voir la liste"** : **Bouton "Voir la liste"** :
- Affiche titres + créateurs des contenus supprimés - Affiche titres + créateurs des contenus supprimés
- Permet comprendre ce qui a disparu - Permet comprendre ce qui a disparu
- Historique conservé 7 jours (puis purge) - Historique conservé 7 jours (puis purge)
**Justification KISS** : **Justification KISS** :
-**Simplicité technique** : pas de grace period complexe, pas de gestion d'états intermédiaires -**Simplicité technique** : pas de grace period complexe, pas de gestion d'états intermédiaires
-**Respect créateur** : si créateur supprime = volonté claire immédiate, pas de diffusion prolongée -**Respect créateur** : si créateur supprime = volonté claire immédiate, pas de diffusion prolongée
-**Conformité légale** : contenu modéré (illégal, violation CGU) retiré immédiatement, pas de risque juridique -**Conformité légale** : contenu modéré (illégal, violation CGU) retiré immédiatement, pas de risque juridique
-**Cas rare** : peu de créateurs suppriment contenus après publication, impact user limité -**Cas rare** : peu de créateurs suppriment contenus après publication, impact user limité
**Post-MVP** : Si feedback négatifs users ("J'étais en train d'écouter et ça s'est coupé brutalement !"), ajouter grace period UNIQUEMENT pour suppression créateur volontaire : **Post-MVP** : Si feedback négatifs users ("J'étais en train d'écouter et ça s'est coupé brutalement !"), ajouter grace period UNIQUEMENT pour suppression créateur volontaire :
- Motif suppression = "modération RoadWave" → Suppression immédiate (sécurité/légalité) - Motif suppression = "modération RoadWave" → Suppression immédiate (sécurité/légalité)
- Motif suppression = "créateur volontaire" → Grace period 7 jours + badge "Bientôt retiré" - Motif suppression = "créateur volontaire" → Grace period 7 jours + badge "Bientôt retiré"
- Motif suppression = "passage Premium" → Si user Premium : conserve accès, si gratuit : grace period 7j - Motif suppression = "passage Premium" → Si user Premium : conserve accès, si gratuit : grace period 7j

View File

@@ -12,6 +12,7 @@
**❌ Pas d'essai gratuit** **❌ Pas d'essai gratuit**
**Raisons** : **Raisons** :
- **Anti-abus vacances** : évite inscriptions opportunistes (essai 14j avant road trip vacances, puis annulation) - **Anti-abus vacances** : évite inscriptions opportunistes (essai 14j avant road trip vacances, puis annulation)
- **Protection revenus créateurs** : les écoutes Premium rémunèrent créateurs dès jour 1 - **Protection revenus créateurs** : les écoutes Premium rémunèrent créateurs dès jour 1
- **Simplicité** : pas de gestion période trial + conversion - **Simplicité** : pas de gestion période trial + conversion
@@ -20,6 +21,7 @@
**❌ Pas de partage familial (MVP)** **❌ Pas de partage familial (MVP)**
**Raisons** : **Raisons** :
- Complexité technique (gestion invitations, validation liens, limite devices) - Complexité technique (gestion invitations, validation liens, limite devices)
- Risque abus ("familles" de 6 inconnus) - Risque abus ("familles" de 6 inconnus)
- Coût dev/support élevé pour ROI incertain - Coût dev/support élevé pour ROI incertain
@@ -27,6 +29,7 @@
- **Post-MVP** : Si forte demande, offre "Famille" à 9.99€/mois pour 5 comptes - **Post-MVP** : Si forte demande, offre "Famille" à 9.99€/mois pour 5 comptes
**Justification tarif** : **Justification tarif** :
- **Aligné marché bas** : Spotify = 10.99€, YouTube Premium = 11.99€, Apple Music = 10.99€ - **Aligné marché bas** : Spotify = 10.99€, YouTube Premium = 11.99€, Apple Music = 10.99€
- **Prix accessible** : cible conducteurs quotidiens (budget raisonnable) - **Prix accessible** : cible conducteurs quotidiens (budget raisonnable)
- **Incitation annuel** : 2 mois offerts = engagement long terme + réduction churn - **Incitation annuel** : 2 mois offerts = engagement long terme + réduction churn
@@ -100,6 +103,7 @@ Device 1 vraiment offline (mode avion, tunnel)
``` ```
**Boutons** : **Boutons** :
- **Reprendre ici** : Coupe l'autre device, reprend lecture sur ce device - **Reprendre ici** : Coupe l'autre device, reprend lecture sur ce device
- **Sécuriser mon compte** : Lien vers changement mot de passe + déconnexion tous devices - **Sécuriser mon compte** : Lien vers changement mot de passe + déconnexion tous devices
@@ -119,6 +123,7 @@ Contenus téléchargés valides 30 jours
#### Détection abus (post-MVP) #### Détection abus (post-MVP)
Monitoring patterns suspects (backend analytics) : Monitoring patterns suspects (backend analytics) :
- >10 changements devices/jour (suspect) - >10 changements devices/jour (suspect)
- Connexions alternées 2 villes éloignées répétées - Connexions alternées 2 villes éloignées répétées
- Signalements users : "je n'ai jamais été à Marseille" - Signalements users : "je n'ai jamais été à Marseille"
@@ -131,6 +136,7 @@ Action :
**Pas d'action automatique** (évite faux positifs), juste flag modération manuelle. **Pas d'action automatique** (évite faux positifs), juste flag modération manuelle.
**Justification KISS** : **Justification KISS** :
-**Simplicité technique** : pas de tracking GPS précis, pas de calcul distances, pas de faux positifs (TGV Paris→Lyon = légitime) -**Simplicité technique** : pas de tracking GPS précis, pas de calcul distances, pas de faux positifs (TGV Paris→Lyon = légitime)
-**Assume bonne foi** : majorité users honnêtes, partage compte = minorité, gestion réactive suffit -**Assume bonne foi** : majorité users honnêtes, partage compte = minorité, gestion réactive suffit
-**Message dissuasif clair** : avertissement CGU dans message coupure, possibilité "Sécuriser compte" si suspicion piratage -**Message dissuasif clair** : avertissement CGU dans message coupure, possibilité "Sécuriser compte" si suspicion piratage
@@ -144,12 +150,14 @@ Action :
**Décision** : Créateur décide (déjà couvert section 9.6) **Décision** : Créateur décide (déjà couvert section 9.6)
**Rappel règles** : **Rappel règles** :
- Toggle "Réservé Premium" par contenu - Toggle "Réservé Premium" par contenu
- Aucune limite de ratio gratuit/premium - Aucune limite de ratio gratuit/premium
- Badge 👑 visible - Badge 👑 visible
- Users gratuits : lecture bloquée avec CTA "Passez Premium" - Users gratuits : lecture bloquée avec CTA "Passez Premium"
**Impact algorithme** : **Impact algorithme** :
- Contenus premium inclus dans recommandations - Contenus premium inclus dans recommandations
- Si user gratuit → skip automatique (ne consomme pas slot) - Si user gratuit → skip automatique (ne consomme pas slot)
- Si user premium → diffusé normalement selon score - Si user premium → diffusé normalement selon score
@@ -169,10 +177,12 @@ Action :
| **Historique écoute** | 100 derniers | Illimité | | **Historique écoute** | 100 derniers | Illimité |
**Qualité audio** : **Qualité audio** :
- Gratuit : 48 kbps Opus (~20 MB/h) = très correct pour voix - Gratuit : 48 kbps Opus (~20 MB/h) = très correct pour voix
- Premium : 64 kbps Opus (~30 MB/h) = excellente qualité - Premium : 64 kbps Opus (~30 MB/h) = excellente qualité
**Justification différences** : **Justification différences** :
- **0 pub** = argument principal (confort écoute) - **0 pub** = argument principal (confort écoute)
- **Qualité audio** = avantage tangible audiophiles - **Qualité audio** = avantage tangible audiophiles
- **Offline illimité** = use case road trips longs - **Offline illimité** = use case road trips longs
@@ -191,23 +201,27 @@ Action :
| **Android App** | Google Play Billing | 5.99€ | 30% (Google) | | **Android App** | Google Play Billing | 5.99€ | 30% (Google) |
**Majoration mobile (5.99€)** : **Majoration mobile (5.99€)** :
- Apple/Google prennent 30% de commission - Apple/Google prennent 30% de commission
- RoadWave majore prix de 20% pour compenser - RoadWave majore prix de 20% pour compenser
- **Incitation web** : Email aux users "Abonnez-vous sur roadwave.com pour 4.99€/mois" (38% moins cher en frais !) - **Incitation web** : Email aux users "Abonnez-vous sur roadwave.com pour 4.99€/mois" (38% moins cher en frais !)
**Renouvellement automatique** : **Renouvellement automatique** :
- Email rappel **7 jours avant** renouvellement - Email rappel **7 jours avant** renouvellement
- Email confirmation **après** renouvellement réussi - Email confirmation **après** renouvellement réussi
- Retry automatique si échec paiement (3 tentatives sur 7 jours) - Retry automatique si échec paiement (3 tentatives sur 7 jours)
- Annulation automatique après 3 échecs - Annulation automatique après 3 échecs
**Annulation** : **Annulation** :
- Self-service dans Settings app : "Abonnement > Annuler" - Self-service dans Settings app : "Abonnement > Annuler"
- Accès Premium maintenu jusqu'à **fin période payée** - Accès Premium maintenu jusqu'à **fin période payée**
- Pas de remboursement prorata (standard industrie) - Pas de remboursement prorata (standard industrie)
- Email confirmation annulation avec date fin d'accès - Email confirmation annulation avec date fin d'accès
**Réabonnement** : **Réabonnement** :
- Possibilité immédiate - Possibilité immédiate
- ❌ Pas de nouvelle période d'essai (pas d'essai du tout) - ❌ Pas de nouvelle période d'essai (pas d'essai du tout)
@@ -235,6 +249,7 @@ CREATE TABLE subscriptions (
``` ```
Cache Redis : premium:{user_id} → boolean (TTL 1h) Cache Redis : premium:{user_id} → boolean (TTL 1h)
Refresh via webhooks : Refresh via webhooks :
- Mangopay : PAYIN_NORMAL_SUCCEEDED, PAYIN_NORMAL_FAILED - Mangopay : PAYIN_NORMAL_SUCCEEDED, PAYIN_NORMAL_FAILED
- Apple : App Store Server Notifications - Apple : App Store Server Notifications
- Google : Real-time Developer Notifications - Google : Real-time Developer Notifications

View File

@@ -31,6 +31,7 @@ Le domaine **Recommendation** gère le système de recommandation de contenus ba
## Ubiquitous Language ## Ubiquitous Language
**Termes métier du domaine** : **Termes métier du domaine** :
- **Interest Gauge** : Jauge de centre d'intérêt (score de 0 à 100) - **Interest Gauge** : Jauge de centre d'intérêt (score de 0 à 100)
- **Interest Category** : Catégorie d'intérêt (automobile, voyage, musique, etc.) - **Interest Category** : Catégorie d'intérêt (automobile, voyage, musique, etc.)
- **Recommendation Score** : Score combinant distance géographique et affinité d'intérêt - **Recommendation Score** : Score combinant distance géographique et affinité d'intérêt

View File

@@ -204,6 +204,7 @@ godog run features/recommendation/scoring-recommandation.feature --tags=@calcul
## CI/CD ## CI/CD
Ces tests sont exécutés : Ces tests sont exécutés :
- ✅ Avant chaque release - ✅ Avant chaque release
- ✅ Sur les PRs modifiant l'algorithme de recommandation - ✅ Sur les PRs modifiant l'algorithme de recommandation
- ✅ Nightly builds (tous les tests) - ✅ Nightly builds (tous les tests)

View File

@@ -11,11 +11,13 @@
| **Géo-neutre** | Universel, pas de lien géo | Podcast philosophie, musique | 20% | | **Géo-neutre** | Universel, pas de lien géo | Podcast philosophie, musique | 20% |
**Qui décide** : **Qui décide** :
- ✅ Créateur choisit le type à la publication - ✅ Créateur choisit le type à la publication
- ✅ Modération peut reclassifier après validation - ✅ Modération peut reclassifier après validation
- ✅ Modification possible après publication (tout le monde a le droit de se tromper) - ✅ Modification possible après publication (tout le monde a le droit de se tromper)
**Justification** : **Justification** :
- Différencie audio-guide (hyper-local) des podcasts génériques - Différencie audio-guide (hyper-local) des podcasts génériques
- Algorithme adapte automatiquement la pondération - Algorithme adapte automatiquement la pondération
- Coût : champ supplémentaire en DB + règle algo - Coût : champ supplémentaire en DB + règle algo
@@ -33,6 +35,7 @@ score_final = (score_geo * poids_geo_type)
+ (bonus_aleatoire) + (bonus_aleatoire)
où : où :
- score_geo = 1 - (distance_km / distance_max_km) - score_geo = 1 - (distance_km / distance_max_km)
- score_interets = moyenne des jauges utilisateur pour les tags du contenu - score_interets = moyenne des jauges utilisateur pour les tags du contenu
- score_engagement = (taux_completion * 0.5) + (ratio_likes * 0.3) + (ratio_abonnements * 0.2) - score_engagement = (taux_completion * 0.5) + (ratio_likes * 0.3) + (ratio_abonnements * 0.2)
@@ -42,6 +45,7 @@ où :
#### Calcul détaillé du score_interets #### Calcul détaillé du score_interets
**Domaine des données** : **Domaine des données** :
- Jauges utilisateur : stockées en pourcentage [0-100] - Jauges utilisateur : stockées en pourcentage [0-100]
- score_interets : normalisé dans l'intervalle [0.0-1.0] pour pondération - score_interets : normalisé dans l'intervalle [0.0-1.0] pour pondération
@@ -50,6 +54,7 @@ où :
score_interets = (SUM(gauge_values_for_tags) / NB_TAGS) / 100 score_interets = (SUM(gauge_values_for_tags) / NB_TAGS) / 100
où : où :
- gauge_values_for_tags = valeurs des jauges correspondant aux tags du contenu - gauge_values_for_tags = valeurs des jauges correspondant aux tags du contenu
- NB_TAGS = nombre de tags du contenu (minimum 1, maximum 3) - NB_TAGS = nombre de tags du contenu (minimum 1, maximum 3)
- Division par 100 pour normaliser [0-100] → [0.0-1.0] - Division par 100 pour normaliser [0-100] → [0.0-1.0]
@@ -61,6 +66,7 @@ Contenu : "Visite du Louvre"
Tags : ["Musique", "Tourisme"] Tags : ["Musique", "Tourisme"]
Utilisateur : Utilisateur :
- Jauge "Musique" = 75% - Jauge "Musique" = 75%
- Jauge "Tourisme" = 60% - Jauge "Tourisme" = 60%
- Jauge "Automobile" = 40% (non pertinente, ignorée) - Jauge "Automobile" = 40% (non pertinente, ignorée)
@@ -79,6 +85,7 @@ score_final = (score_geo * 0.5) + (score_interets * 0.3) + (score_engagement * 0
``` ```
**Cas limites** : **Cas limites** :
- Utilisateur n'a aucune jauge pour les tags du contenu → score_interets = 0.5 (valeur neutre par défaut) - Utilisateur n'a aucune jauge pour les tags du contenu → score_interets = 0.5 (valeur neutre par défaut)
- Contenu avec 1 seul tag → score_interets = gauge_value / 100 - Contenu avec 1 seul tag → score_interets = gauge_value / 100
- Jauges multiples → moyenne arithmétique simple (pas de pondération différente par tag) - Jauges multiples → moyenne arithmétique simple (pas de pondération différente par tag)
@@ -93,6 +100,7 @@ score_final = (score_geo * 0.5) + (score_interets * 0.3) + (score_engagement * 0
| Géo-neutre | 0.2 | 0.6 | | Géo-neutre | 0.2 | 0.6 |
**Paramètres** : **Paramètres** :
- Distance max recommandée : **200 km** - Distance max recommandée : **200 km**
- Dégradation : **linéaire** (1 - distance/200km) - Dégradation : **linéaire** (1 - distance/200km)
- Rayon point GPS : **500m** (adapté au volume de contenu local) - Rayon point GPS : **500m** (adapté au volume de contenu local)
@@ -100,6 +108,7 @@ score_final = (score_geo * 0.5) + (score_interets * 0.3) + (score_engagement * 0
**Tous ces paramètres sont configurables à chaud via interface admin.** **Tous ces paramètres sont configurables à chaud via interface admin.**
**Justification** : **Justification** :
- Flexibilité totale selon type de contenu - Flexibilité totale selon type de contenu
- Linéaire = rattrapage naturel du contenu viral ancien - Linéaire = rattrapage naturel du contenu viral ancien
- Auditable via métriques engagement (moyenne/médiane) - Auditable via métriques engagement (moyenne/médiane)
@@ -111,6 +120,7 @@ score_final = (score_geo * 0.5) + (score_interets * 0.3) + (score_engagement * 0
**Décision** : Intégration popularité avec poids 0.2 **Décision** : Intégration popularité avec poids 0.2
**Métriques** : **Métriques** :
- **Taux de complétion** : écoutes >80% / total écoutes pertinentes (poids 0.5) - **Taux de complétion** : écoutes >80% / total écoutes pertinentes (poids 0.5)
- **Ratio likes** : likes / écoutes (poids 0.3) - **Ratio likes** : likes / écoutes (poids 0.3)
- **Ratio abonnements** : nouveaux abonnés après écoute / écoutes (poids 0.2) - **Ratio abonnements** : nouveaux abonnés après écoute / écoutes (poids 0.2)
@@ -145,19 +155,23 @@ GROUP BY content_id;
``` ```
**Seuil minimum** : **Seuil minimum** :
- Minimum **50 écoutes pertinentes** avant de considérer l'engagement - Minimum **50 écoutes pertinentes** avant de considérer l'engagement
- Contenu <50 écoutes : score engagement = 0.5 (neutre) - Contenu <50 écoutes : score engagement = 0.5 (neutre)
**Contenu viral** : **Contenu viral** :
- Un contenu viral à Paris **peut** être proposé à Marseille - Un contenu viral à Paris **peut** être proposé à Marseille
- Score géo faible compensé par score engagement élevé - Score géo faible compensé par score engagement élevé
- Paramétrable admin - Paramétrable admin
**Dépréciation temporelle** : **Dépréciation temporelle** :
- Pas de dépréciation automatique - Pas de dépréciation automatique
- Ratio linéaire = contenu ancien mais toujours apprécié reste pertinent - Ratio linéaire = contenu ancien mais toujours apprécié reste pertinent
**Justification** : **Justification** :
- Équilibre découverte / qualité - Équilibre découverte / qualité
- **Protection créateur** : abonnés fidèles ne pénalisent pas les métriques - **Protection créateur** : abonnés fidèles ne pénalisent pas les métriques
- **Anti-raid naturel** : skips via search/direct_link ne comptent pas (raid inefficace) - **Anti-raid naturel** : skips via search/direct_link ne comptent pas (raid inefficace)
@@ -172,16 +186,19 @@ GROUP BY content_id;
**Décision** : 10% par défaut, paramétrable utilisateur **Décision** : 10% par défaut, paramétrable utilisateur
**Fonctionnement** : **Fonctionnement** :
- 1 contenu sur 10 = tirage aléatoire (hors historique déjà écouté) - 1 contenu sur 10 = tirage aléatoire (hors historique déjà écouté)
- Utilisateur peut ajuster : curseur 0% (aucun aléatoire) à 50% (exploration max) - Utilisateur peut ajuster : curseur 0% (aucun aléatoire) à 50% (exploration max)
**Curseur utilisateur** : **Curseur utilisateur** :
- 🎯 **0%** : Personnalisé max (recommandations strictes) - 🎯 **0%** : Personnalisé max (recommandations strictes)
- ⚖️ **10%** : Équilibré (défaut) - ⚖️ **10%** : Équilibré (défaut)
- 🎲 **30%** : Découverte élevée - 🎲 **30%** : Découverte élevée
- 🌍 **50%** : Découverte max (équivaut à national = découverte) - 🌍 **50%** : Découverte max (équivaut à national = découverte)
**Justification** : **Justification** :
- Évite la bulle de filtre - Évite la bulle de filtre
- Laisse l'utilisateur maître de son expérience - Laisse l'utilisateur maître de son expérience
- Coût : variable aléatoire en algo - Coût : variable aléatoire en algo
@@ -195,23 +212,27 @@ GROUP BY content_id;
**Décision MVP** : Tag simple "Politique" sans classification idéologique **Décision MVP** : Tag simple "Politique" sans classification idéologique
**Tagging** : **Tagging** :
- Créateur peut taguer son contenu comme "Politique" (optionnel) - Créateur peut taguer son contenu comme "Politique" (optionnel)
- Tag "Politique" au même niveau que "Économie", "Sport", "Culture", etc. - Tag "Politique" au même niveau que "Économie", "Sport", "Culture", etc.
- **Pas de classification gauche/droite** - **Pas de classification gauche/droite**
- **Pas d'équilibrage imposé** - **Pas d'équilibrage imposé**
**Filtrage utilisateur** : **Filtrage utilisateur** :
- Option paramètres : **"Masquer contenu politique"** - Option paramètres : **"Masquer contenu politique"**
- Si activé → 0% de contenus tagués "Politique" dans le feed - Si activé → 0% de contenus tagués "Politique" dans le feed
- Par défaut : désactivé (tous contenus visibles) - Par défaut : désactivé (tous contenus visibles)
**Justification MVP** : **Justification MVP** :
- **Simplicité** : Pas de modération politique coûteuse (~2000€/mois économisés) - **Simplicité** : Pas de modération politique coûteuse (~2000€/mois économisés)
- **Neutralité technique** : Aucun jugement éditorial sur orientation - **Neutralité technique** : Aucun jugement éditorial sur orientation
- **Risque minimal** : Évite controverses et contentieux DSA au lancement - **Risque minimal** : Évite controverses et contentieux DSA au lancement
- **Fonctionnel** : Utilisateurs peuvent filtrer si souhaité - **Fonctionnel** : Utilisateurs peuvent filtrer si souhaité
**Post-MVP** : **Post-MVP** :
- Classification avancée possible si forte demande utilisateurs - Classification avancée possible si forte demande utilisateurs
- Nécessite ressources modération dédiées et audit DSA - Nécessite ressources modération dédiées et audit DSA
@@ -230,22 +251,26 @@ GROUP BY content_id;
| **13-15 ans** | Collège | Contenus "Tous publics" uniquement | Filtrage 16+ et 18+ | | **13-15 ans** | Collège | Contenus "Tous publics" uniquement | Filtrage 16+ et 18+ |
**Activation** : **Activation** :
-**Pas d'activation automatique** (tous les utilisateurs ont ≥13 ans) -**Pas d'activation automatique** (tous les utilisateurs ont ≥13 ans)
-**Activation manuelle** via toggle paramètres -**Activation manuelle** via toggle paramètres
- ✅ Parents peuvent activer pour leurs enfants 13-15 ans - ✅ Parents peuvent activer pour leurs enfants 13-15 ans
- ✅ Utilisateur peut désactiver à tout moment - ✅ Utilisateur peut désactiver à tout moment
**Filtrage quand Mode Kids activé** : **Filtrage quand Mode Kids activé** :
- ✅ Contenus "Tous publics" uniquement - ✅ Contenus "Tous publics" uniquement
- ❌ Exclusion contenus 16+ et 18+ - ❌ Exclusion contenus 16+ et 18+
- ❌ Pas de contenu politique (automatiquement filtré) - ❌ Pas de contenu politique (automatiquement filtré)
- ❌ Pas de publicité (ou uniquement pub validée manuellement) - ❌ Pas de publicité (ou uniquement pub validée manuellement)
**Interface** : **Interface** :
- Interface standard (pas d'interface dédiée enfants pour MVP) - Interface standard (pas d'interface dédiée enfants pour MVP)
- Filtrage algorithmique des contenus inappropriés - Filtrage algorithmique des contenus inappropriés
**Justification** : **Justification** :
- **Conformité légale** : Âge minimum 13 ans (RGPD, DSA) - **Conformité légale** : Âge minimum 13 ans (RGPD, DSA)
- **Simplicité MVP** : Un seul mode optionnel vs 4 tranches d'âge - **Simplicité MVP** : Un seul mode optionnel vs 4 tranches d'âge
- **Protection mineurs** : Filtrage contenus adultes pour 13-15 ans - **Protection mineurs** : Filtrage contenus adultes pour 13-15 ans
@@ -266,15 +291,18 @@ GROUP BY content_id;
6. Si ignoré → contenu proposé normalement en file d'attente 6. Si ignoré → contenu proposé normalement en file d'attente
**Publicités** : **Publicités** :
- ⚠️ **Jamais d'interruption** de contenu en cours - ⚠️ **Jamais d'interruption** de contenu en cours
- Pub s'intercale **entre deux séquences** uniquement - Pub s'intercale **entre deux séquences** uniquement
- Notification pub : son différent (facultatif selon paramètres) - Notification pub : son différent (facultatif selon paramètres)
**Gestion demi-tour** : **Gestion demi-tour** :
- Si utilisateur repart du point après notification → pas de nouvelle notification (déjà proposé) - Si utilisateur repart du point après notification → pas de nouvelle notification (déjà proposé)
- Réinitialisation après 24h - Réinitialisation après 24h
**Justification** : **Justification** :
- Respect écoute en cours (pas de coupure brutale) - Respect écoute en cours (pas de coupure brutale)
- UX fluide (utilisateur garde contrôle) - UX fluide (utilisateur garde contrôle)
- Simplicité technique (pas de prédiction trajectoire) - Simplicité technique (pas de prédiction trajectoire)
@@ -295,17 +323,20 @@ GROUP BY content_id;
| **Partiellement écouté** | 10-80% | Peu importe | ✅ Reproposer avec reprise position (`last_position_seconds`) | | **Partiellement écouté** | 10-80% | Peu importe | ✅ Reproposer avec reprise position (`last_position_seconds`) |
**Stockage historique** : **Stockage historique** :
- Table `user_content_history` (user_id, content_id, creator_id, **is_subscribed**, completion_rate, last_position, listened_at) - Table `user_content_history` (user_id, content_id, creator_id, **is_subscribed**, completion_rate, last_position, listened_at)
- Historique **illimité** (PostgreSQL) - Historique **illimité** (PostgreSQL)
- Algorithme considère les **100 derniers** pour optimisation requêtes - Algorithme considère les **100 derniers** pour optimisation requêtes
- Export complet disponible (RGPD) - Export complet disponible (RGPD)
**Colonne `is_subscribed`** : **Colonne `is_subscribed`** :
- Booléen stockant si l'utilisateur était abonné au créateur **au moment de l'écoute** - Booléen stockant si l'utilisateur était abonné au créateur **au moment de l'écoute**
- Permet de distinguer les skips d'abonnés (contextuels) des skips de non-abonnés (désintérêt) - Permet de distinguer les skips d'abonnés (contextuels) des skips de non-abonnés (désintérêt)
- Utilisé pour décisions de reproposition et calculs d'engagement - Utilisé pour décisions de reproposition et calculs d'engagement
**Justification** : **Justification** :
- Découverte maximale (pas de redites) - Découverte maximale (pas de redites)
- **Cohérence abonnement** : un skip ponctuel d'un abonné ≠ rejet du créateur (peut être contextuel : "pas maintenant", "pas ce sujet", "mauvais timing") - **Cohérence abonnement** : un skip ponctuel d'un abonné ≠ rejet du créateur (peut être contextuel : "pas maintenant", "pas ce sujet", "mauvais timing")
- Respect erreurs de clic (contenu partiel = 2nde chance) - Respect erreurs de clic (contenu partiel = 2nde chance)
@@ -331,23 +362,27 @@ GROUP BY content_id;
| `seuil_min_ecoutes_engagement` | 10 - 200 | 50 | nb | | `seuil_min_ecoutes_engagement` | 10 - 200 | 50 | nb |
**Application changements** : **Application changements** :
- Immédiat : nouveaux calculs utilisent nouvelle config - Immédiat : nouveaux calculs utilisent nouvelle config
- Aucun recalcul batch (coût CPU) - Aucun recalcul batch (coût CPU)
- Version config trackée (git-like) - Version config trackée (git-like)
- Rollback 1 clic - Rollback 1 clic
**A/B Testing** : **A/B Testing** :
- Création variantes (Config A vs Config B) - Création variantes (Config A vs Config B)
- Split utilisateurs 50/50 aléatoire - Split utilisateurs 50/50 aléatoire
- Métriques comparatives : taux complétion, engagement, session duration - Métriques comparatives : taux complétion, engagement, session duration
- Dashboard graphique temps réel - Dashboard graphique temps réel
**Audit engagement** : **Audit engagement** :
- Métriques clés : moyenne/médiane temps d'écoute par session - Métriques clés : moyenne/médiane temps d'écoute par session
- Graphiques : évolution engagement selon config - Graphiques : évolution engagement selon config
- Export CSV pour analyse externe - Export CSV pour analyse externe
**Justification** : **Justification** :
- Optimisation continue sans redéploiement - Optimisation continue sans redéploiement
- Data-driven decisions (métriques objectives) - Data-driven decisions (métriques objectives)
- Coût : dashboard admin à développer (one-time) - Coût : dashboard admin à développer (one-time)
@@ -361,26 +396,31 @@ GROUP BY content_id;
**Niveaux de personnalisation** : **Niveaux de personnalisation** :
**Curseurs disponibles** : **Curseurs disponibles** :
- 📍 **Géolocalisation** : Local ← slider → National (découverte = national) - 📍 **Géolocalisation** : Local ← slider → National (découverte = national)
- 🎲 **Découverte** : 0% ← slider → 50% (part aléatoire) - 🎲 **Découverte** : 0% ← slider → 50% (part aléatoire)
- ⚖️ **Politique** : Masquer / Équilibré / Mes préférences - ⚖️ **Politique** : Masquer / Équilibré / Mes préférences
**Profils sauvegardables** : **Profils sauvegardables** :
- 🚗 Trajet quotidien (boulot) : géo local, découverte 5%, politique masqué - 🚗 Trajet quotidien (boulot) : géo local, découverte 5%, politique masqué
- 🛣️ Road trip : géo régional, découverte 30%, politique équilibré - 🛣️ Road trip : géo régional, découverte 30%, politique équilibré
- 👶 Enfants : Mode Kids activé - 👶 Enfants : Mode Kids activé
**Synchronisation** : **Synchronisation** :
- ✅ Sync profils entre devices (cloud PostgreSQL) - ✅ Sync profils entre devices (cloud PostgreSQL)
- ❌ Pas de partage profils entre utilisateurs (famille) - ❌ Pas de partage profils entre utilisateurs (famille)
- Auto-switch selon context (détection trajet récurrent via GPS) - Auto-switch selon context (détection trajet récurrent via GPS)
**Sécurité conduite** : **Sécurité conduite** :
- ⚠️ **Blocage modification si vitesse GPS >10 km/h** - ⚠️ **Blocage modification si vitesse GPS >10 km/h**
- Warning au lancement app : "Configurez avant de prendre la route" - Warning au lancement app : "Configurez avant de prendre la route"
- Modifications uniquement app arrêtée/passager - Modifications uniquement app arrêtée/passager
**Justification** : **Justification** :
- Utilisateur maître de son expérience - Utilisateur maître de son expérience
- Contextes d'usage différents (quotidien vs voyage) - Contextes d'usage différents (quotidien vs voyage)
- Sécurité routière (pas de distraction) - Sécurité routière (pas de distraction)
@@ -392,25 +432,30 @@ GROUP BY content_id;
**Décision** : Ouverture aux médias établis **Décision** : Ouverture aux médias établis
**Médias autorisés** : **Médias autorisés** :
- Presse nationale : Le Monde, Le Parisien, Libération, Le Figaro, etc. - Presse nationale : Le Monde, Le Parisien, Libération, Le Figaro, etc.
- Radios : France Inter, RTL, Europe 1, etc. - Radios : France Inter, RTL, Europe 1, etc.
- Médias régionaux : Ouest-France, Sud-Ouest, etc. - Médias régionaux : Ouest-France, Sud-Ouest, etc.
**Format contenus** : **Format contenus** :
- Flashs info géolocalisés (actualité régionale) - Flashs info géolocalisés (actualité régionale)
- Chroniques thématiques (culture, économie, sport) - Chroniques thématiques (culture, économie, sport)
- Éditos et débats (classification politique appliquée) - Éditos et débats (classification politique appliquée)
**Validation** : **Validation** :
- Compte média vérifié (badge ✓) - Compte média vérifié (badge ✓)
- Pas de validation 3 premiers contenus (confiance établie) - Pas de validation 3 premiers contenus (confiance établie)
- Modération a posteriori uniquement - Modération a posteriori uniquement
**Monétisation** : **Monétisation** :
- Partage revenus pub standard (même conditions créateurs) - Partage revenus pub standard (même conditions créateurs)
- Possibilité sponsoring direct (pas via plateforme) - Possibilité sponsoring direct (pas via plateforme)
**Justification** : **Justification** :
- Crédibilité plateforme (contenus professionnels) - Crédibilité plateforme (contenus professionnels)
- Diversité éditoriale - Diversité éditoriale
- Attractivité grand public (noms reconnus) - Attractivité grand public (noms reconnus)

View File

@@ -17,6 +17,7 @@
**Note importante** : Les pourcentages indiqués sont des **points de pourcentage absolus**, **PAS des pourcentages relatifs**. **Note importante** : Les pourcentages indiqués sont des **points de pourcentage absolus**, **PAS des pourcentages relatifs**.
**Calcul** : **Calcul** :
- Si jauge "Automobile" = 45% - Si jauge "Automobile" = 45%
- Like renforcé (+2%) → 45 + 2 = **47%** - Like renforcé (+2%) → 45 + 2 = **47%**
- **NOT** 45 × 1.02 = 45.9% ❌ - **NOT** 45 × 1.02 = 45.9% ❌
@@ -24,6 +25,7 @@
Cette approche garantit une **progression linéaire** et **équitable** pour tous les utilisateurs, indépendamment de leur niveau actuel dans une jauge. Cette approche garantit une **progression linéaire** et **équitable** pour tous les utilisateurs, indépendamment de leur niveau actuel dans une jauge.
**Paramètres techniques** : **Paramètres techniques** :
- Les jauges sont bornées strictement entre **0% et 100%** - Les jauges sont bornées strictement entre **0% et 100%**
- Calcul immédiat à chaque action (pas de batch différé) - Calcul immédiat à chaque action (pas de batch différé)
- Les tags du contenu sont définis par le créateur à la publication - Les tags du contenu sont définis par le créateur à la publication
@@ -61,6 +63,7 @@ Scénario 5 : Skip après 5s (ABONNÉ au créateur)
``` ```
**Justification** : **Justification** :
- **Like automatique** : Reflète l'engagement réel (voir [Règle 05 - Section 5.3](interactions-navigation.md#53-interactions-au-volant--like-automatique-et-engagement)) - **Like automatique** : Reflète l'engagement réel (voir [Règle 05 - Section 5.3](interactions-navigation.md#53-interactions-au-volant--like-automatique-et-engagement))
- **Sécurité routière** : Pas d'action complexe en conduite - **Sécurité routière** : Pas d'action complexe en conduite
- **Prévisibilité** : Règles claires et déterministes - **Prévisibilité** : Règles claires et déterministes
@@ -78,11 +81,13 @@ Scénario 5 : Skip après 5s (ABONNÉ au créateur)
**Décision** : Démarrage neutre à 50%, pas de questionnaire **Décision** : Démarrage neutre à 50%, pas de questionnaire
**À l'inscription** : **À l'inscription** :
- Toutes les jauges d'intérêt sont initialisées à **50%** - Toutes les jauges d'intérêt sont initialisées à **50%**
- Pas de questionnaire onboarding (friction zéro) - Pas de questionnaire onboarding (friction zéro)
- L'algorithme apprend naturellement via les premières écoutes - L'algorithme apprend naturellement via les premières écoutes
**Catégories disponibles** : **Catégories disponibles** :
- Automobile - Automobile
- Voyage - Voyage
- Famille - Famille
@@ -104,12 +109,14 @@ Scénario 5 : Skip après 5s (ABONNÉ au créateur)
4. Après 10-15 écoutes, profil commence à se dessiner clairement 4. Après 10-15 écoutes, profil commence à se dessiner clairement
**Alternative optionnelle (post-MVP)** : **Alternative optionnelle (post-MVP)** :
- Questionnaire **optionnel** proposé après 3 écoutes (in-app) - Questionnaire **optionnel** proposé après 3 écoutes (in-app)
- Message : "Améliorez vos recommandations en sélectionnant vos centres d'intérêt" - Message : "Améliorez vos recommandations en sélectionnant vos centres d'intérêt"
- Si rempli : jauges sélectionnées passent à 70%, non sélectionnées à 30% - Si rempli : jauges sélectionnées passent à 70%, non sélectionnées à 30%
- Si skip : conserve 50% partout - Si skip : conserve 50% partout
**Justification** : **Justification** :
- **Inscription ultra-rapide** : pas de questionnaire = moins de churn - **Inscription ultra-rapide** : pas de questionnaire = moins de churn
- **Découverte naturelle** : l'algorithme apprend en quelques écoutes - **Découverte naturelle** : l'algorithme apprend en quelques écoutes
- **Équitable** : pas de biais initial vers certains créateurs - **Équitable** : pas de biais initial vers certains créateurs
@@ -125,6 +132,7 @@ Scénario 5 : Skip après 5s (ABONNÉ au créateur)
Les jauges **ne diminuent jamais** avec le temps de manière automatique. Les jauges **ne diminuent jamais** avec le temps de manière automatique.
**Règle** : **Règle** :
- Une jauge ne change **que par les actions utilisateur** (like, écoute, skip) - Une jauge ne change **que par les actions utilisateur** (like, écoute, skip)
- Pas de cron job de dégradation périodique - Pas de cron job de dégradation périodique
- Pas de "rafraîchissement" artificiel - Pas de "rafraîchissement" artificiel
@@ -138,16 +146,19 @@ Utilisateur aimait "Économie" (jauge 80%) il y a 1 an
``` ```
**Si utilisateur inactif longtemps** : **Si utilisateur inactif longtemps** :
- Utilisateur part en vacances 6 mois → jauges conservées - Utilisateur part en vacances 6 mois → jauges conservées
- Au retour : ses jauges reflètent toujours ses goûts d'avant - Au retour : ses jauges reflètent toujours ses goûts d'avant
- Comportement cohérent et prévisible - Comportement cohérent et prévisible
**Alternative utilisateur (contrôle explicite)** : **Alternative utilisateur (contrôle explicite)** :
- Bouton "Réinitialiser mes centres d'intérêt" dans paramètres - Bouton "Réinitialiser mes centres d'intérêt" dans paramètres
- Action manuelle : remet toutes les jauges à 50% - Action manuelle : remet toutes les jauges à 50%
- Permet nouveau départ si souhaité (changement de vie, etc.) - Permet nouveau départ si souhaité (changement de vie, etc.)
**Justification** : **Justification** :
- **Principe KISS** (Keep It Simple, Stupid) - **Principe KISS** (Keep It Simple, Stupid)
- **Coût 0** : pas de batch nocturne, pas de calculs temporels - **Coût 0** : pas de batch nocturne, pas de calculs temporels
- **Fiabilité maximale** : pas de bugs de fuseaux horaires, dates, etc. - **Fiabilité maximale** : pas de bugs de fuseaux horaires, dates, etc.

View File

@@ -5,6 +5,7 @@
**Décision** : Pré-calcul 5 contenus avec insertion prioritaire pour points géographiques **Décision** : Pré-calcul 5 contenus avec insertion prioritaire pour points géographiques
**File d'attente** : **File d'attente** :
- **5 contenus pré-calculés** en cache (Redis) - **5 contenus pré-calculés** en cache (Redis)
- Recalcul automatique si : - Recalcul automatique si :
- Déplacement >10km - Déplacement >10km
@@ -14,12 +15,14 @@
**Insertion prioritaire géo-ancrée (mode voiture uniquement)** : **Insertion prioritaire géo-ancrée (mode voiture uniquement)** :
**Détection** : **Détection** :
- Calcul ETA (Estimated Time of Arrival) via API GPS native iOS/Android - Calcul ETA (Estimated Time of Arrival) via API GPS native iOS/Android
- Notification déclenchée **7 secondes avant** d'arriver au point GPS - Notification déclenchée **7 secondes avant** d'arriver au point GPS
- Si vitesse < 5 km/h ET distance < 50m → notification immédiate - Si vitesse < 5 km/h ET distance < 50m → notification immédiate
- ⚠️ **App doit être ouverte** (pas de détection en arrière-plan en mode voiture) - ⚠️ **App doit être ouverte** (pas de détection en arrière-plan en mode voiture)
**Notification** : **Notification** :
- **Sonore uniquement** : bip court ou son personnalisé RoadWave - **Sonore uniquement** : bip court ou son personnalisé RoadWave
- **Visuelle minimale** : icône selon type de contenu (🏛️ culture, 👨‍👩‍👧 famille, 🎵 musique, etc.) - **Visuelle minimale** : icône selon type de contenu (🏛️ culture, 👨‍👩‍👧 famille, 🎵 musique, etc.)
- **Compteur visible** : 7...6...5...4...3...2...1 (décompte des secondes) - **Compteur visible** : 7...6...5...4...3...2...1 (décompte des secondes)
@@ -34,19 +37,23 @@
5. À la fin du décompte → contenu géolocalisé démarre (fade out/in 0.3s) 5. À la fin du décompte → contenu géolocalisé démarre (fade out/in 0.3s)
**Si user n'appuie pas sur "Suivant"** : **Si user n'appuie pas sur "Suivant"** :
- Notification disparaît après 7 secondes - Notification disparaît après 7 secondes
- Contenu géolocalisé est perdu (pas d'insertion dans file) - Contenu géolocalisé est perdu (pas d'insertion dans file)
- Pas de nouveau contenu géolocalisé pendant **10 minutes** (éviter spam) - Pas de nouveau contenu géolocalisé pendant **10 minutes** (éviter spam)
**Limitation anti-spam** : **Limitation anti-spam** :
- Maximum **6 contenus géolocalisés par heure** - Maximum **6 contenus géolocalisés par heure**
- Timer reset toutes les heures (rolling window) - Timer reset toutes les heures (rolling window)
- Exception : séquences d'un même audio-guide multi-séquences (comptent comme 1) - Exception : séquences d'un même audio-guide multi-séquences (comptent comme 1)
- Si quota atteint : notifications suivantes ignorées jusqu'à libération du quota - Si quota atteint : notifications suivantes ignorées jusqu'à libération du quota
**Invalidation immédiate** : **Invalidation immédiate** :
- Utilisateur change ses préférences (curseurs géo/découverte/politique) - Utilisateur change ses préférences (curseurs géo/découverte/politique)
- ⚠️ **Modification bloquée si vitesse GPS >10 km/h** (sécurité routière) - ⚠️ **Modification bloquée si vitesse GPS >10 km/h** (sécurité routière)
- Live démarre d'un créateur suivi dans la zone - Live démarre d'un créateur suivi dans la zone
**Implémentation** : **Implémentation** :
@@ -76,6 +83,7 @@ Cooldown après ignorance (Redis) :
``` ```
**Justification** : **Justification** :
- **Expérience fluide** : pas de latence au clic "Suivant" - **Expérience fluide** : pas de latence au clic "Suivant"
- **Réactivité géo** : contenu local inséré immédiatement - **Réactivité géo** : contenu local inséré immédiatement
- **Coût optimisé** : recalcul uniquement si nécessaire - **Coût optimisé** : recalcul uniquement si nécessaire
@@ -88,12 +96,14 @@ Cooldown après ignorance (Redis) :
**Décision** : Notifications push en arrière-plan avec rayon large **Décision** : Notifications push en arrière-plan avec rayon large
**Contexte** : **Contexte** :
- Mode piéton détecté automatiquement si vitesse moyenne < 5 km/h - Mode piéton détecté automatiquement si vitesse moyenne < 5 km/h
- Cas d'usage : visites à pied, musées, monuments, quartiers historiques - Cas d'usage : visites à pied, musées, monuments, quartiers historiques
- User n'a pas besoin d'avoir l'app ouverte - User n'a pas besoin d'avoir l'app ouverte
- ⚠️ **Fonctionnalité optionnelle** : requiert permission "localisation en arrière-plan" (activée par user) - ⚠️ **Fonctionnalité optionnelle** : requiert permission "localisation en arrière-plan" (activée par user)
**Détection** : **Détection** :
- App peut être en arrière-plan (si permission accordée) - App peut être en arrière-plan (si permission accordée)
- Rayon de détection : **200 mètres** autour du point GPS - Rayon de détection : **200 mètres** autour du point GPS
- Geofencing iOS/Android pour minimiser consommation batterie - Geofencing iOS/Android pour minimiser consommation batterie
@@ -119,12 +129,14 @@ Musée du Louvre : La Joconde - @paris_museum
⚠️ **Important** : RoadWave utilise une **stratégie de permissions progressive** pour maximiser l'acceptation utilisateur et la validation stores. ⚠️ **Important** : RoadWave utilise une **stratégie de permissions progressive** pour maximiser l'acceptation utilisateur et la validation stores.
**Étape 1 - Permission de base (tous utilisateurs)** : **Étape 1 - Permission de base (tous utilisateurs)** :
- iOS : "Allow While Using App" (`locationWhenInUse`) - iOS : "Allow While Using App" (`locationWhenInUse`)
- Android : `ACCESS_FINE_LOCATION` - Android : `ACCESS_FINE_LOCATION`
- **Demandée** : Au premier lancement (onboarding) - **Demandée** : Au premier lancement (onboarding)
- **Permet** : Mode voiture complet ✅ - **Permet** : Mode voiture complet ✅
**Étape 2 - Permission arrière-plan (optionnelle, mode piéton uniquement)** : **Étape 2 - Permission arrière-plan (optionnelle, mode piéton uniquement)** :
- iOS : "Allow Always" (`locationAlways`) - iOS : "Allow Always" (`locationAlways`)
- Android : `ACCESS_BACKGROUND_LOCATION` - Android : `ACCESS_BACKGROUND_LOCATION`
- **Demandée** : Uniquement si user active "Notifications audio-guides piéton" dans settings - **Demandée** : Uniquement si user active "Notifications audio-guides piéton" dans settings
@@ -132,6 +144,7 @@ Musée du Louvre : La Joconde - @paris_museum
- **Permet** : Mode piéton avec notifications push en arrière-plan ✅ - **Permet** : Mode piéton avec notifications push en arrière-plan ✅
**Si permission arrière-plan refusée** : **Si permission arrière-plan refusée** :
- Mode piéton **désactivé** (toggle grisé dans settings) - Mode piéton **désactivé** (toggle grisé dans settings)
- Mode voiture reste **pleinement fonctionnel** - Mode voiture reste **pleinement fonctionnel**
- Audio-guides accessibles en mode **manuel** (user ouvre app, lance contenu) - Audio-guides accessibles en mode **manuel** (user ouvre app, lance contenu)
@@ -188,6 +201,7 @@ Android (`AndroidManifest.xml`) :
``` ```
**Si user refuse** : **Si user refuse** :
- Mode piéton désactivé (uniquement mode voiture disponible) - Mode piéton désactivé (uniquement mode voiture disponible)
- App fonctionne normalement avec permission "When In Use" - App fonctionne normalement avec permission "When In Use"
- Audio-guides accessibles en mode manuel (user ouvre app, sélectionne contenu) - Audio-guides accessibles en mode manuel (user ouvre app, sélectionne contenu)
@@ -201,6 +215,7 @@ Android (`AndroidManifest.xml`) :
**Basculement automatique voiture ↔ piéton** : **Basculement automatique voiture ↔ piéton** :
Détection par vitesse GPS moyenne sur 30 secondes : Détection par vitesse GPS moyenne sur 30 secondes :
- Vitesse < 5 km/h (stable 10s) → mode piéton - Vitesse < 5 km/h (stable 10s) → mode piéton
- Vitesse ≥ 5 km/h (stable 10s) → mode voiture - Vitesse ≥ 5 km/h (stable 10s) → mode voiture
@@ -212,15 +227,18 @@ Changements de mode :
| Voiture | < 5 km/h | Piéton | Notifications sonores → push arrière-plan | | Voiture | < 5 km/h | Piéton | Notifications sonores → push arrière-plan |
**Pas de popup confirmation** : **Pas de popup confirmation** :
- Basculement transparent et automatique - Basculement transparent et automatique
- User n'a rien à faire - User n'a rien à faire
- Hysteresis (10s) pour éviter basculements intempestifs - Hysteresis (10s) pour éviter basculements intempestifs
**Quota anti-spam mode piéton** : **Quota anti-spam mode piéton** :
- Même limitation que mode voiture : **6 contenus/heure** - Même limitation que mode voiture : **6 contenus/heure**
- Cooldown 10 min si notification ignorée (app pas ouverte après tap) - Cooldown 10 min si notification ignorée (app pas ouverte après tap)
**Justification** : **Justification** :
- ✅ Expérience adaptée aux visites à pied (rayon large, pas de timing précis) - ✅ Expérience adaptée aux visites à pied (rayon large, pas de timing précis)
- ✅ Économie batterie (geofencing natif iOS/Android) - ✅ Économie batterie (geofencing natif iOS/Android)
- ✅ User peut garder téléphone en poche - ✅ User peut garder téléphone en poche
@@ -241,6 +259,7 @@ Changements de mode :
| **Premier de session** | N/A | Replay depuis début (rien avant) | | **Premier de session** | N/A | Replay depuis début (rien avant) |
**Historique de navigation** : **Historique de navigation** :
- **10 contenus maximum** en mémoire (Redis List) - **10 contenus maximum** en mémoire (Redis List)
- Structure : `[{content_id, position_seconds, listened_at}, ...]` - Structure : `[{content_id, position_seconds, listened_at}, ...]`
- FIFO : au-delà de 10, suppression du plus ancien - FIFO : au-delà de 10, suppression du plus ancien
@@ -257,11 +276,13 @@ Utilisateur écoute :
``` ```
**Interface (responsabilité front)** : **Interface (responsabilité front)** :
- ❌ Pas de message UI - ❌ Pas de message UI
- ✅ Progress bar revient au début ou à position exacte - ✅ Progress bar revient au début ou à position exacte
- ✅ Animation fluide (transition 0.3s) - ✅ Animation fluide (transition 0.3s)
**Justification** : **Justification** :
- **UX intuitive** : comportement standard Spotify/YouTube - **UX intuitive** : comportement standard Spotify/YouTube
- **Pas de frustration** : si début, vraiment revenir en arrière - **Pas de frustration** : si début, vraiment revenir en arrière
- **Simplicité** : règle unique (seuil 10s) - **Simplicité** : règle unique (seuil 10s)
@@ -273,6 +294,7 @@ Utilisateur écoute :
**Décision** : Like automatique basé sur le temps d'écoute **Décision** : Like automatique basé sur le temps d'écoute
**Problème technique identifié** : **Problème technique identifié** :
- iOS et Android ne supportent **pas nativement** les appuis longs ou doubles-appuis sur les commandes média - iOS et Android ne supportent **pas nativement** les appuis longs ou doubles-appuis sur les commandes média
- Les commandes physiques au volant varient selon les véhicules (pas de bouton "Pause" dédié sur beaucoup de modèles) - Les commandes physiques au volant varient selon les véhicules (pas de bouton "Pause" dédié sur beaucoup de modèles)
- Système de double-appui/appui long = **non-intuitif** et **risques sécurité** (regarder écran pour feedback) - Système de double-appui/appui long = **non-intuitif** et **risques sécurité** (regarder écran pour feedback)
@@ -309,12 +331,14 @@ Utilisateur écoute :
**Exemples concrets** : **Exemples concrets** :
``` ```
Contenu de 3 minutes (180s) : Contenu de 3 minutes (180s) :
- Écoute 2min30 (83%) → Like renforcé (+2 points) - Écoute 2min30 (83%) → Like renforcé (+2 points)
- Écoute 1min15 (42%) → Like standard (+1 point) - Écoute 1min15 (42%) → Like standard (+1 point)
- Écoute 30s (17%) puis skip → Pas de like - Écoute 30s (17%) puis skip → Pas de like
- Skip après 5s → Signal négatif (-0.5 point) - Skip après 5s → Signal négatif (-0.5 point)
Contenu de 15 minutes (900s) : Contenu de 15 minutes (900s) :
- Écoute 13min (87%) → Like renforcé (+2 points) - Écoute 13min (87%) → Like renforcé (+2 points)
- Écoute 6min (40%) → Like standard (+1 point) - Écoute 6min (40%) → Like standard (+1 point)
``` ```
@@ -334,11 +358,13 @@ Contenu de 15 minutes (900s) :
| **Signalement** | Menu contextuel "⋮" | Ouverture flux modération | | **Signalement** | Menu contextuel "⋮" | Ouverture flux modération |
**Feedback visuel** : **Feedback visuel** :
- **Like automatique** : Badge discret "♥ Ajouté à vos favoris" (2s, bas de l'écran) - **Like automatique** : Badge discret "♥ Ajouté à vos favoris" (2s, bas de l'écran)
- **Like explicite** : Animation cœur rouge + vibration courte - **Like explicite** : Animation cœur rouge + vibration courte
- **Abonnement** : Animation étoile dorée + badge "Abonné ✓" - **Abonnement** : Animation étoile dorée + badge "Abonné ✓"
**Disponibilité** : **Disponibilité** :
- ✅ Mode piéton (vitesse < 5 km/h) : toutes les actions disponibles - ✅ Mode piéton (vitesse < 5 km/h) : toutes les actions disponibles
- ❌ Mode voiture (vitesse ≥ 5 km/h) : aucune de ces actions (sauf like automatique) - ❌ Mode voiture (vitesse ≥ 5 km/h) : aucune de ces actions (sauf like automatique)
@@ -347,17 +373,20 @@ Contenu de 15 minutes (900s) :
#### Gestion impacts jauges (algorithme) #### Gestion impacts jauges (algorithme)
**Like automatique** : **Like automatique** :
- Like renforcé (≥80%) → **+2% jauges** de tous les tags du contenu - Like renforcé (≥80%) → **+2% jauges** de tous les tags du contenu
- Like standard (30-79%) → **+1% jauges** des tags du contenu - Like standard (30-79%) → **+1% jauges** des tags du contenu
- Signal négatif (skip <10s) → **-0.5% jauges** des tags du contenu - Signal négatif (skip <10s) → **-0.5% jauges** des tags du contenu
**Actions explicites** : **Actions explicites** :
- Like manuel → **+2% jauges** (cumulable avec like auto) - Like manuel → **+2% jauges** (cumulable avec like auto)
- Unlike → **-2% jauges** - Unlike → **-2% jauges**
- Abonnement → **+5% toutes jauges** tags créateur - Abonnement → **+5% toutes jauges** tags créateur
- Désabonnement → **-5% toutes jauges** - Désabonnement → **-5% toutes jauges**
**Persistance** : **Persistance** :
- Événements stockés en base (table `listen_events`) - Événements stockés en base (table `listen_events`)
- Mise à jour jauges : **immédiate** (Redis) + **async batch** (PostgreSQL) - Mise à jour jauges : **immédiate** (Redis) + **async batch** (PostgreSQL)
@@ -431,6 +460,7 @@ class AudioPlayerManager {
#### Justification #### Justification
**Avantages** : **Avantages** :
-**Sécurité routière maximale** : aucune action complexe au volant -**Sécurité routière maximale** : aucune action complexe au volant
-**UX intuitive** : comportement standard industrie (Spotify, YouTube Music, Deezer) -**UX intuitive** : comportement standard industrie (Spotify, YouTube Music, Deezer)
-**Compatibilité 100%** : fonctionne sur tous véhicules, tous OS -**Compatibilité 100%** : fonctionne sur tous véhicules, tous OS
@@ -439,6 +469,7 @@ class AudioPlayerManager {
-**Simplicité développement** : pas de workarounds complexes iOS/Android -**Simplicité développement** : pas de workarounds complexes iOS/Android
**Inconvénients mitigés** : **Inconvénients mitigés** :
- ⚠️ Pas de like explicite en conduite → **Mitigation** : like automatique + vocal (CarPlay/Android Auto) - ⚠️ Pas de like explicite en conduite → **Mitigation** : like automatique + vocal (CarPlay/Android Auto)
- ⚠️ Pas d'abonnement en conduite → **Mitigation** : liste "Créateurs à découvrir" dans app - ⚠️ Pas d'abonnement en conduite → **Mitigation** : liste "Créateurs à découvrir" dans app
- ⚠️ Like automatique peut surprendre → **Mitigation** : onboarding clair + unlike possible - ⚠️ Like automatique peut surprendre → **Mitigation** : onboarding clair + unlike possible
@@ -502,6 +533,7 @@ Utilisez les boutons au volant :
- Persiste : Redis (immédiat) + PostgreSQL (batch async) - Persiste : Redis (immédiat) + PostgreSQL (batch async)
**Séparation des responsabilités** : **Séparation des responsabilités** :
-**Calculation** : Logique métier pure (réutilisable pour auto-like, skip, actions manuelles) -**Calculation** : Logique métier pure (réutilisable pour auto-like, skip, actions manuelles)
-**Update** : Persistance et contraintes techniques -**Update** : Persistance et contraintes techniques
@@ -516,6 +548,7 @@ newValue := currentValue * (1 + adjustment/100) // NE PAS FAIRE
``` ```
**Persistance** : **Persistance** :
- **Redis** : Mise à jour immédiate (latence <10ms) - **Redis** : Mise à jour immédiate (latence <10ms)
- **PostgreSQL** : Batch async toutes les 5 minutes (cohérence finale) - **PostgreSQL** : Batch async toutes les 5 minutes (cohérence finale)
- Raison : Jauges consultées fréquemment (recommandations temps réel) - Raison : Jauges consultées fréquemment (recommandations temps réel)
@@ -541,12 +574,14 @@ newValue := currentValue * (1 + adjustment/100) // NE PAS FAIRE
| **Live** | 0 seconde | Enchaînement immédiat | | **Live** | 0 seconde | Enchaînement immédiat |
**Insertion publicité** : **Insertion publicité** :
- Pub s'insère **pendant le délai de 2s** (transition naturelle) - Pub s'insère **pendant le délai de 2s** (transition naturelle)
- Fréquence : **paramétrable admin** (défaut : 1 pub / 5 contenus) - Fréquence : **paramétrable admin** (défaut : 1 pub / 5 contenus)
- Message : "Publicité (15s)" puis lecture pub - Message : "Publicité (15s)" puis lecture pub
- ⚠️ **Jamais d'interruption** d'un contenu en cours - ⚠️ **Jamais d'interruption** d'un contenu en cours
**Publicité skippable** : **Publicité skippable** :
- Durée minimale visionnage : **paramétrable** (défaut : 5 secondes) - Durée minimale visionnage : **paramétrable** (défaut : 5 secondes)
- Bouton "Passer" apparaît après délai - Bouton "Passer" apparaît après délai
- Métriques engagement : taux skip, durée écoute moyenne - Métriques engagement : taux skip, durée écoute moyenne
@@ -559,11 +594,13 @@ newValue := currentValue * (1 + adjustment/100) // NE PAS FAIRE
4. Sinon → lecture en pause, attente action utilisateur 4. Sinon → lecture en pause, attente action utilisateur
**Gestion erreurs** : **Gestion erreurs** :
- Échec chargement contenu suivant → **retry 3× avec backoff exponentiel** - Échec chargement contenu suivant → **retry 3× avec backoff exponentiel**
- Si 3 échecs → message "Connexion instable, basculement mode offline" - Si 3 échecs → message "Connexion instable, basculement mode offline"
- Mode offline → lecture contenus téléchargés uniquement - Mode offline → lecture contenus téléchargés uniquement
**Justification** : **Justification** :
- **Fluidité** : enchaînement naturel sans action utilisateur - **Fluidité** : enchaînement naturel sans action utilisateur
- **Contrôle** : possibilité annuler pendant délai - **Contrôle** : possibilité annuler pendant délai
- **Paramétrabilité pub** : évite frustration excès publicité - **Paramétrabilité pub** : évite frustration excès publicité

View File

@@ -23,6 +23,7 @@
Les présentes Conditions Générales d'Utilisation (CGU) régissent l'utilisation de la plateforme RoadWave, réseau social audio géolocalisé. Les présentes Conditions Générales d'Utilisation (CGU) régissent l'utilisation de la plateforme RoadWave, réseau social audio géolocalisé.
RoadWave permet aux utilisateurs : RoadWave permet aux utilisateurs :
- **Auditeurs** : écouter du contenu audio contextuel géolocalisé - **Auditeurs** : écouter du contenu audio contextuel géolocalisé
- **Créateurs** : publier du contenu audio géolocalisé - **Créateurs** : publier du contenu audio géolocalisé
@@ -39,11 +40,13 @@ L'utilisation de la Plateforme implique l'acceptation pleine et entière des pr
RoadWave se réserve le droit de modifier les CGU à tout moment. RoadWave se réserve le droit de modifier les CGU à tout moment.
**Notification** : **Notification** :
- Email à tous les utilisateurs **14 jours avant** l'entrée en vigueur - Email à tous les utilisateurs **14 jours avant** l'entrée en vigueur
- Notification in-app au lancement suivant la modification - Notification in-app au lancement suivant la modification
- Version mise à jour disponible sur roadwave.fr/cgu - Version mise à jour disponible sur roadwave.fr/cgu
**Refus des nouvelles CGU** : **Refus des nouvelles CGU** :
- Utilisateur peut supprimer son compte dans les 14 jours - Utilisateur peut supprimer son compte dans les 14 jours
- Utilisation continue = acceptation tacite - Utilisation continue = acceptation tacite
@@ -67,6 +70,7 @@ RoadWave se réserve le droit de modifier les CGU à tout moment.
### 4.3 Responsabilité du compte ### 4.3 Responsabilité du compte
L'utilisateur est responsable de : L'utilisateur est responsable de :
- La confidentialité de ses identifiants - La confidentialité de ses identifiants
- Toutes actions effectuées depuis son compte - Toutes actions effectuées depuis son compte
- Signalement immédiat en cas d'accès non autorisé - Signalement immédiat en cas d'accès non autorisé
@@ -74,6 +78,7 @@ L'utilisateur est responsable de :
### 4.4 Un compte par personne ### 4.4 Un compte par personne
Création de comptes multiples interdite, sauf : Création de comptes multiples interdite, sauf :
- Compte test (développeurs autorisés) - Compte test (développeurs autorisés)
- Demande explicite auprès de RoadWave - Demande explicite auprès de RoadWave
@@ -84,6 +89,7 @@ Création de comptes multiples interdite, sauf :
### 5.1 Licence d'utilisation ### 5.1 Licence d'utilisation
RoadWave accorde une licence **non exclusive, révocable, non transférable** pour : RoadWave accorde une licence **non exclusive, révocable, non transférable** pour :
- Accéder à la Plateforme - Accéder à la Plateforme
- Écouter du contenu - Écouter du contenu
- Publier du contenu (créateurs) - Publier du contenu (créateurs)
@@ -91,6 +97,7 @@ RoadWave accorde une licence **non exclusive, révocable, non transférable** po
### 5.2 Interdictions générales ### 5.2 Interdictions générales
Il est interdit de : Il est interdit de :
- Utiliser la Plateforme à des fins illégales - Utiliser la Plateforme à des fins illégales
- Tenter de contourner les mesures de sécurité - Tenter de contourner les mesures de sécurité
- Utiliser des bots, scripts ou outils automatisés - Utiliser des bots, scripts ou outils automatisés
@@ -113,6 +120,7 @@ Il est interdit de :
Voir **[Charte Créateur](charte-createur.md)** pour règles détaillées. Voir **[Charte Créateur](charte-createur.md)** pour règles détaillées.
**Résumé** : **Résumé** :
- Contenus originaux ou droits acquis - Contenus originaux ou droits acquis
- Pas de contenu haineux, violent, illégal - Pas de contenu haineux, violent, illégal
- Pas de musique protégée >30 secondes sans licence - Pas de musique protégée >30 secondes sans licence
@@ -132,6 +140,7 @@ Voir **[Charte Créateur](charte-createur.md)** pour règles détaillées.
### 6.4 Responsabilité du créateur ### 6.4 Responsabilité du créateur
Le créateur garantit : Le créateur garantit :
- Détenir tous les droits nécessaires - Détenir tous les droits nécessaires
- Ne pas violer de droits tiers (musique, marques, image) - Ne pas violer de droits tiers (musique, marques, image)
- Respecter les classifications d'âge - Respecter les classifications d'âge
@@ -146,44 +155,52 @@ Le créateur garantit :
Sont strictement interdits : Sont strictement interdits :
#### **Haine et violence** (Article 7.1.1) #### **Haine et violence** (Article 7.1.1)
- Incitation à la haine raciale, ethnique, religieuse - Incitation à la haine raciale, ethnique, religieuse
- Discrimination sexiste, homophobe, transphobe - Discrimination sexiste, homophobe, transphobe
- Apologie de crimes contre l'humanité - Apologie de crimes contre l'humanité
- Menaces de violence physique - Menaces de violence physique
#### **Contenu sexuel** (Article 7.1.2) #### **Contenu sexuel** (Article 7.1.2)
- Pornographie ou contenu sexuellement explicite - Pornographie ou contenu sexuellement explicite
- Contenu impliquant des mineurs (strictement interdit) - Contenu impliquant des mineurs (strictement interdit)
- Sollicitation sexuelle - Sollicitation sexuelle
#### **Illégalité** (Article 7.1.3) #### **Illégalité** (Article 7.1.3)
- Apologie du terrorisme - Apologie du terrorisme
- Incitation aux actes criminels - Incitation aux actes criminels
- Vente de produits illégaux (drogues, armes) - Vente de produits illégaux (drogues, armes)
- Pédopornographie → **ban immédiat + signalement autorités** - Pédopornographie → **ban immédiat + signalement autorités**
#### **Droits d'auteur** (Article 7.1.4) #### **Droits d'auteur** (Article 7.1.4)
- Musique protégée en intégrale ou extraits >30 secondes - Musique protégée en intégrale ou extraits >30 secondes
- Films, séries, livres audio protégés - Films, séries, livres audio protégés
- Diffusion de concerts, événements sportifs payants (lives) - Diffusion de concerts, événements sportifs payants (lives)
- **Exception** : extraits ≤30s pour critique/analyse (fair use) - **Exception** : extraits ≤30s pour critique/analyse (fair use)
#### **Désinformation dangereuse** (Article 7.1.5) #### **Désinformation dangereuse** (Article 7.1.5)
- Fausses informations sur la santé (COVID, vaccins, traitements) - Fausses informations sur la santé (COVID, vaccins, traitements)
- Fausses informations sur la sécurité routière - Fausses informations sur la sécurité routière
- Manipulation électorale - Manipulation électorale
#### **Harcèlement** (Article 7.1.6) #### **Harcèlement** (Article 7.1.6)
- Menaces répétées envers une personne - Menaces répétées envers une personne
- Doxxing (publication informations privées) - Doxxing (publication informations privées)
- Intimidation, chantage - Intimidation, chantage
#### **Fraude** (Article 7.1.7) #### **Fraude** (Article 7.1.7)
- Arnaques, escroqueries - Arnaques, escroqueries
- Pyramides de Ponzi, MLM illégaux - Pyramides de Ponzi, MLM illégaux
- Phishing, vol d'identité - Phishing, vol d'identité
#### **Spam** (Article 7.1.8) #### **Spam** (Article 7.1.8)
- Publicité non autorisée (hors système pub RoadWave) - Publicité non autorisée (hors système pub RoadWave)
- Répétition de contenus identiques - Répétition de contenus identiques
- Liens vers sites externes de spam - Liens vers sites externes de spam
@@ -191,6 +208,7 @@ Sont strictement interdits :
### 7.2 Modération ### 7.2 Modération
**Délais de traitement** : **Délais de traitement** :
- CRITIQUE (violence, suicide) : <2h (24/7) - CRITIQUE (violence, suicide) : <2h (24/7)
- HAUTE (haine, harcèlement) : <24h - HAUTE (haine, harcèlement) : <24h
- MOYENNE (spam) : <48h - MOYENNE (spam) : <48h
@@ -212,10 +230,12 @@ Sont strictement interdits :
### 8.2 Exceptions ### 8.2 Exceptions
**Tolérance 1ère fois (droits d'auteur uniquement)** : **Tolérance 1ère fois (droits d'auteur uniquement)** :
- Avertissement sans strike si première violation musique protégée - Avertissement sans strike si première violation musique protégée
- Explication pédagogique + lien vers règles - Explication pédagogique + lien vers règles
**Violations graves (pas de tolérance)** : **Violations graves (pas de tolérance)** :
- Haine, violence → Strike 1 immédiat - Haine, violence → Strike 1 immédiat
- Contenu illégal (terrorisme, pédopornographie) → Strike 4 (ban) + signalement autorités - Contenu illégal (terrorisme, pédopornographie) → Strike 4 (ban) + signalement autorités
@@ -243,6 +263,7 @@ Créateur a Strike 2
### 8.5 Notification des sanctions ### 8.5 Notification des sanctions
**Multi-canal** (email + push + in-app) : **Multi-canal** (email + push + in-app) :
- Catégorie violée (référence article CGU) - Catégorie violée (référence article CGU)
- Raison détaillée (langage clair) - Raison détaillée (langage clair)
- Extrait audio concerné (timestamp) - Extrait audio concerné (timestamp)
@@ -297,6 +318,7 @@ Tout utilisateur sanctionné peut contester la décision.
Voir **[CGV Publicités](cgv-publicites.md)** Voir **[CGV Publicités](cgv-publicites.md)**
**Résumé** : **Résumé** :
- Interface self-service - Interface self-service
- Budget minimum : 50€ - Budget minimum : 50€
- Validation manuelle obligatoire (24-48h) - Validation manuelle obligatoire (24-48h)
@@ -309,6 +331,7 @@ Voir **[CGV Publicités](cgv-publicites.md)**
Voir **[CGV Premium](cgv-premium.md)** Voir **[CGV Premium](cgv-premium.md)**
**Résumé** : **Résumé** :
- Prix : 4.99€/mois OU 49.99€/an - Prix : 4.99€/mois OU 49.99€/an
- Avantages : 0 pub, contenus exclusifs 👑, qualité 64 kbps, offline illimité - Avantages : 0 pub, contenus exclusifs 👑, qualité 64 kbps, offline illimité
- Résiliation : à tout moment (effet fin période en cours) - Résiliation : à tout moment (effet fin période en cours)
@@ -328,6 +351,7 @@ Voir **[CGV Premium](cgv-premium.md)**
### 12.2 KYC (Know Your Customer) ### 12.2 KYC (Know Your Customer)
Vérification obligatoire via Mangopay : Vérification obligatoire via Mangopay :
- SIRET, numéro TVA, RIB professionnel - SIRET, numéro TVA, RIB professionnel
- Pièce d'identité - Pièce d'identité
- Kbis <3 mois (entreprises) - Kbis <3 mois (entreprises)
@@ -335,10 +359,12 @@ Vérification obligatoire via Mangopay :
### 12.3 Revenus ### 12.3 Revenus
**Publicités** : **Publicités** :
- 3€ / 1000 écoutes complètes - 3€ / 1000 écoutes complètes
- Représente ~6% du CA publicitaire - Représente ~6% du CA publicitaire
**Premium** : **Premium** :
- 70% créateur, 30% plateforme - 70% créateur, 30% plateforme
- Proportionnel au temps d'écoute - Proportionnel au temps d'écoute
@@ -381,6 +407,7 @@ Voir **[Politique de confidentialité](politique-confidentialite.md)** pour dét
### 14.1 Propriété de la Plateforme ### 14.1 Propriété de la Plateforme
RoadWave et tous ses éléments (code, design, logo, marque) sont protégés par : RoadWave et tous ses éléments (code, design, logo, marque) sont protégés par :
- Droit d'auteur - Droit d'auteur
- Droit des marques - Droit des marques
- Droit sui generis des bases de données - Droit sui generis des bases de données
@@ -398,12 +425,14 @@ RoadWave et tous ses éléments (code, design, logo, marque) sont protégés par
### 14.3 Utilisation des contenus par RoadWave ### 14.3 Utilisation des contenus par RoadWave
RoadWave peut : RoadWave peut :
- Diffuser les contenus aux auditeurs - Diffuser les contenus aux auditeurs
- Transcrire automatiquement (modération IA) - Transcrire automatiquement (modération IA)
- Générer segments HLS (streaming) - Générer segments HLS (streaming)
- Promouvoir la Plateforme (captures d'écran, extraits marketing) - Promouvoir la Plateforme (captures d'écran, extraits marketing)
RoadWave **ne peut pas** : RoadWave **ne peut pas** :
- Revendre les contenus à des tiers - Revendre les contenus à des tiers
- Modifier substantiellement les contenus (hors transcoding technique) - Modifier substantiellement les contenus (hors transcoding technique)
@@ -420,6 +449,7 @@ RoadWave **ne peut pas** :
### 15.2 Résiliation par RoadWave ### 15.2 Résiliation par RoadWave
RoadWave peut suspendre ou supprimer un compte en cas de : RoadWave peut suspendre ou supprimer un compte en cas de :
- Violation grave des CGU - Violation grave des CGU
- Strike 4 (ban définitif) - Strike 4 (ban définitif)
- Activité frauduleuse - Activité frauduleuse
@@ -428,15 +458,18 @@ RoadWave peut suspendre ou supprimer un compte en cas de :
### 15.3 Conséquences de la résiliation ### 15.3 Conséquences de la résiliation
**Contenus créateurs** : **Contenus créateurs** :
- Dépubliés immédiatement - Dépubliés immédiatement
- Marqués "Utilisateur supprimé" (anonymisation) - Marqués "Utilisateur supprimé" (anonymisation)
- Fichiers audio supprimés sous 48h - Fichiers audio supprimés sous 48h
**Abonnement Premium** : **Abonnement Premium** :
- Pas de remboursement au prorata - Pas de remboursement au prorata
- Accès jusqu'à fin période payée - Accès jusqu'à fin période payée
**Revenus créateurs** : **Revenus créateurs** :
- Solde <50€ → perdu - Solde <50€ → perdu
- Solde ≥50€ → virement final sous 30 jours - Solde ≥50€ → virement final sous 30 jours
@@ -447,6 +480,7 @@ RoadWave peut suspendre ou supprimer un compte en cas de :
### 16.1 Disponibilité de la Plateforme ### 16.1 Disponibilité de la Plateforme
RoadWave s'efforce d'assurer une disponibilité 24/7 mais : RoadWave s'efforce d'assurer une disponibilité 24/7 mais :
- **Aucune garantie** de disponibilité continue - **Aucune garantie** de disponibilité continue
- Maintenances programmées notifiées 48h avant - Maintenances programmées notifiées 48h avant
- Interruptions d'urgence possibles sans préavis - Interruptions d'urgence possibles sans préavis
@@ -456,6 +490,7 @@ RoadWave s'efforce d'assurer une disponibilité 24/7 mais :
RoadWave n'est **pas responsable** des contenus publiés par les créateurs. RoadWave n'est **pas responsable** des contenus publiés par les créateurs.
**Modération** : **Modération** :
- Validation 3 premiers contenus (nouveaux créateurs) - Validation 3 premiers contenus (nouveaux créateurs)
- Modération a posteriori (créateurs vérifiés) - Modération a posteriori (créateurs vérifiés)
- Réactivité <24-48h après signalement - Réactivité <24-48h après signalement
@@ -463,11 +498,13 @@ RoadWave n'est **pas responsable** des contenus publiés par les créateurs.
### 16.3 Limitation de dommages ### 16.3 Limitation de dommages
RoadWave ne peut être tenu responsable de : RoadWave ne peut être tenu responsable de :
- Perte de données (sauvegardes régulières recommandées) - Perte de données (sauvegardes régulières recommandées)
- Perte de revenus créateurs (indisponibilité temporaire) - Perte de revenus créateurs (indisponibilité temporaire)
- Dommages indirects ou consécutifs - Dommages indirects ou consécutifs
**Plafond** : **Plafond** :
- Responsabilité limitée aux **12 derniers mois d'abonnement Premium** (auditeurs) - Responsabilité limitée aux **12 derniers mois d'abonnement Premium** (auditeurs)
- Responsabilité limitée aux **revenus perçus sur 12 derniers mois** (créateurs) - Responsabilité limitée aux **revenus perçus sur 12 derniers mois** (créateurs)
@@ -482,6 +519,7 @@ Les présentes CGU sont régies par le **droit français**.
### 17.2 Médiation ### 17.2 Médiation
Avant toute action judiciaire, l'utilisateur doit tenter une **médiation** : Avant toute action judiciaire, l'utilisateur doit tenter une **médiation** :
- Médiateur de la consommation : [NOM MÉDIATEUR] - Médiateur de la consommation : [NOM MÉDIATEUR]
- Plateforme européenne ODR : https://ec.europa.eu/consumers/odr - Plateforme européenne ODR : https://ec.europa.eu/consumers/odr
@@ -508,6 +546,7 @@ L'absence d'exercice d'un droit par RoadWave ne constitue pas une renonciation.
--- ---
**Contact** : **Contact** :
- Email : support@roadwave.fr - Email : support@roadwave.fr
- Adresse : [ADRESSE SIÈGE SOCIAL] - Adresse : [ADRESSE SIÈGE SOCIAL]
- SIRET : [SIRET] - SIRET : [SIRET]

View File

@@ -23,6 +23,7 @@ Complète les **[CGU](cgu.md)** (Article 11).
| **Annuel** | 49.99€/an | ~17% (4.16€/mois effectif) | | **Annuel** | 49.99€/an | ~17% (4.16€/mois effectif) |
**Tarif IAP (In-App Purchase iOS/Android)** : **Tarif IAP (In-App Purchase iOS/Android)** :
- Mensuel : 5.99€/mois (+20% commission Apple/Google) - Mensuel : 5.99€/mois (+20% commission Apple/Google)
- Annuel : 59.99€/an - Annuel : 59.99€/an
@@ -50,11 +51,13 @@ Complète les **[CGU](cgu.md)** (Article 11).
### 3.1 Modalités ### 3.1 Modalités
**Via web (Mangopay)** : **Via web (Mangopay)** :
- Carte bancaire (Visa, Mastercard, Amex) - Carte bancaire (Visa, Mastercard, Amex)
- Prélèvement SEPA (si mensuel) - Prélèvement SEPA (si mensuel)
- Paiement sécurisé 3D Secure - Paiement sécurisé 3D Secure
**Via mobile (IAP)** : **Via mobile (IAP)** :
- App Store (iOS) : Apple Pay, carte bancaire - App Store (iOS) : Apple Pay, carte bancaire
- Google Play (Android) : Google Pay, carte bancaire - Google Play (Android) : Google Pay, carte bancaire
@@ -64,6 +67,7 @@ Complète les **[CGU](cgu.md)** (Article 11).
- **Annuel** : renouvellement 1 an après souscription - **Annuel** : renouvellement 1 an après souscription
**Notification avant renouvellement** : **Notification avant renouvellement** :
- Email **7 jours avant** renouvellement - Email **7 jours avant** renouvellement
- Rappel : résiliation possible à tout moment - Rappel : résiliation possible à tout moment
@@ -88,17 +92,20 @@ Résiliation : 15 janvier
### 4.2 Par RoadWave ### 4.2 Par RoadWave
RoadWave peut résilier si : RoadWave peut résilier si :
- Échec paiement (3 tentatives) - Échec paiement (3 tentatives)
- Violation grave CGU (Strike 4 = ban) - Violation grave CGU (Strike 4 = ban)
- Fraude détectée (carte volée, etc.) - Fraude détectée (carte volée, etc.)
**Notification** : **Notification** :
- Email **48h avant** résiliation - Email **48h avant** résiliation
- Possibilité mise à jour moyen paiement - Possibilité mise à jour moyen paiement
### 4.3 Remboursement ### 4.3 Remboursement
**Aucun remboursement** sauf : **Aucun remboursement** sauf :
- Bug empêchant utilisation service >7 jours consécutifs - Bug empêchant utilisation service >7 jours consécutifs
- Résiliation par RoadWave (erreur de notre part) - Résiliation par RoadWave (erreur de notre part)
@@ -133,6 +140,7 @@ RoadWave peut résilier si :
- **Droit de résiliation** sans frais pendant ces 30 jours - **Droit de résiliation** sans frais pendant ces 30 jours
**Protection abonnés annuels** : **Protection abonnés annuels** :
- Tarif gelé jusqu'à fin période annuelle - Tarif gelé jusqu'à fin période annuelle
- Nouveau tarif appliqué au prochain renouvellement annuel - Nouveau tarif appliqué au prochain renouvellement annuel
@@ -156,6 +164,7 @@ RoadWave peut résilier si :
5. Si échec final → **suspension Premium** 5. Si échec final → **suspension Premium**
**Suspension** : **Suspension** :
- Accès Premium désactivé - Accès Premium désactivé
- Passage compte gratuit (avec pubs) - Passage compte gratuit (avec pubs)
- Réactivation possible sous 30 jours (mise à jour carte) - Réactivation possible sous 30 jours (mise à jour carte)
@@ -165,11 +174,13 @@ RoadWave peut résilier si :
## 8. Rétractation (14 jours) ## 8. Rétractation (14 jours)
**Droit de rétractation UE** : **Droit de rétractation UE** :
- **14 jours** après souscription - **14 jours** après souscription
- Demande via : support@roadwave.fr - Demande via : support@roadwave.fr
- Remboursement intégral sous 14 jours - Remboursement intégral sous 14 jours
**Exception** : **Exception** :
- Si utilisation service pendant 14 jours = renonciation au droit de rétractation - Si utilisation service pendant 14 jours = renonciation au droit de rétractation
- Acceptation explicite à la souscription - Acceptation explicite à la souscription

View File

@@ -51,6 +51,7 @@ Complète les **[CGU](cgu.md)** (Article 10).
- **Critères** : conformité CGU, pas de contenu trompeur, respect ARPP - **Critères** : conformité CGU, pas de contenu trompeur, respect ARPP
**Refus si** : **Refus si** :
- Contenu trompeur, illégal - Contenu trompeur, illégal
- Alcool, tabac (interdits) - Alcool, tabac (interdits)
- Produits santé non autorisés - Produits santé non autorisés
@@ -106,6 +107,7 @@ Complète les **[CGU](cgu.md)** (Article 10).
Accessible 24/7 : roadwave.fr/pub/dashboard Accessible 24/7 : roadwave.fr/pub/dashboard
**Métriques** : **Métriques** :
- Impressions totales (nombre diffusions) - Impressions totales (nombre diffusions)
- Taux d'écoute complète (%) - Taux d'écoute complète (%)
- Taux de skip (%) - Taux de skip (%)
@@ -128,6 +130,7 @@ Accessible 24/7 : roadwave.fr/pub/dashboard
### 7.2 Budget non consommé ### 7.2 Budget non consommé
**Si campagne terminée avec budget restant** : **Si campagne terminée avec budget restant** :
- <10€ : crédit conservé pour prochaine campagne - <10€ : crédit conservé pour prochaine campagne
- ≥10€ : remboursement automatique sous 14 jours - ≥10€ : remboursement automatique sous 14 jours
@@ -154,6 +157,7 @@ Accessible 24/7 : roadwave.fr/pub/dashboard
### 9.1 Contenus prohibés ### 9.1 Contenus prohibés
Strictement interdits : Strictement interdits :
- Alcool, tabac, cannabis - Alcool, tabac, cannabis
- Jeux d'argent (casinos, paris sportifs) - Jeux d'argent (casinos, paris sportifs)
- Produits pharmaceutiques sans autorisation - Produits pharmaceutiques sans autorisation
@@ -174,6 +178,7 @@ Strictement interdits :
### 10.1 Annonceur ### 10.1 Annonceur
L'annonceur garantit : L'annonceur garantit :
- Détenir droits sur contenu publicitaire (musique, voix, marques) - Détenir droits sur contenu publicitaire (musique, voix, marques)
- Conformité légale (ARPP, DGCCRF) - Conformité légale (ARPP, DGCCRF)
- Véracité des informations (pas de publicité mensongère) - Véracité des informations (pas de publicité mensongère)
@@ -181,6 +186,7 @@ L'annonceur garantit :
### 10.2 RoadWave ### 10.2 RoadWave
RoadWave n'est pas responsable de : RoadWave n'est pas responsable de :
- Performance commerciale de la pub (pas de garantie ventes) - Performance commerciale de la pub (pas de garantie ventes)
- Avis négatifs utilisateurs sur la pub - Avis négatifs utilisateurs sur la pub

View File

@@ -25,11 +25,13 @@ Cette Charte complète les **[CGU](cgu.md)** (Articles 6 et 7) et détaille les
### 1.2 Critères de validation ### 1.2 Critères de validation
**Accepté si** : **Accepté si** :
- Qualité audio compréhensible - Qualité audio compréhensible
- Métadonnées cohérentes (zone géo, tags, classification âge) - Métadonnées cohérentes (zone géo, tags, classification âge)
- Pas de contenu prohibé évident - Pas de contenu prohibé évident
**Refusé si** : **Refusé si** :
- Audio incompréhensible (grésillement excessif) - Audio incompréhensible (grésillement excessif)
- Musique protégée évidente en intégrale - Musique protégée évidente en intégrale
- Contenu haineux, violent, illégal - Contenu haineux, violent, illégal
@@ -62,16 +64,19 @@ Cette Charte complète les **[CGU](cgu.md)** (Articles 6 et 7) et détaille les
| **Classification âge** | Tout public / 13+ / 16+ / 18+ | Obligatoire | | **Classification âge** | Tout public / 13+ / 16+ / 18+ | Obligatoire |
**Tags disponibles** : **Tags disponibles** :
- Automobile, Voyage, Famille, Amour, Musique, Économie, Cryptomonnaie, Politique, Culture générale, Sport, Technologie, Santé - Automobile, Voyage, Famille, Amour, Musique, Économie, Cryptomonnaie, Politique, Culture générale, Sport, Technologie, Santé
### 2.3 Cohérence métadonnées ### 2.3 Cohérence métadonnées
**Exemples incohérents** : **Exemples incohérents** :
- "Histoire Tour Eiffel" en zone "National" (devrait être "Point GPS Paris") - "Histoire Tour Eiffel" en zone "National" (devrait être "Point GPS Paris")
- Podcast enfants 3-6 ans classé "18+" (incohérent) - Podcast enfants 3-6 ans classé "18+" (incohérent)
- Contenu politique non tagué "Politique" - Contenu politique non tagué "Politique"
**Exemples cohérents** : **Exemples cohérents** :
- "Visite château Versailles" → Type Ancré, Point GPS Versailles, Tags Voyage + Culture - "Visite château Versailles" → Type Ancré, Point GPS Versailles, Tags Voyage + Culture
- "Podcast auto route A7" → Type Contextuel, Zone Région Auvergne-Rhône-Alpes, Tag Automobile - "Podcast auto route A7" → Type Contextuel, Zone Région Auvergne-Rhône-Alpes, Tag Automobile
@@ -82,6 +87,7 @@ Cette Charte complète les **[CGU](cgu.md)** (Articles 6 et 7) et détaille les
### 3.1 Musique autorisée ### 3.1 Musique autorisée
**Vous pouvez utiliser** : **Vous pouvez utiliser** :
- Votre propre musique originale (vous êtes compositeur/interprète) - Votre propre musique originale (vous êtes compositeur/interprète)
- Musique libre de droits (Epidemic Sound, Artlist, YouTube Audio Library, Creative Commons CC0) - Musique libre de droits (Epidemic Sound, Artlist, YouTube Audio Library, Creative Commons CC0)
- Musique domaine public (>70 ans après mort auteur, ex: classique pré-1950) - Musique domaine public (>70 ans après mort auteur, ex: classique pré-1950)
@@ -90,6 +96,7 @@ Cette Charte complète les **[CGU](cgu.md)** (Articles 6 et 7) et détaille les
### 3.2 Musique interdite ### 3.2 Musique interdite
**Strictement interdit** : **Strictement interdit** :
- Musique protégée en intégrale (titre complet) - Musique protégée en intégrale (titre complet)
- Musique protégée en fond >30 secondes - Musique protégée en fond >30 secondes
- Compilation DJ sans droits - Compilation DJ sans droits
@@ -104,16 +111,19 @@ Cette Charte complète les **[CGU](cgu.md)** (Articles 6 et 7) et détaille les
4. Mention titre + artiste recommandée 4. Mention titre + artiste recommandée
**Exemples OK** : **Exemples OK** :
- Review album : extrait 20s + commentaire analyse musicale - Review album : extrait 20s + commentaire analyse musicale
- Podcast histoire musique : extrait 25s + contexte historique - Podcast histoire musique : extrait 25s + contexte historique
**Exemples KO** : **Exemples KO** :
- Fond musical hit radio 2 minutes (>30s) - Fond musical hit radio 2 minutes (>30s)
- Extrait 15s sans commentaire (pas d'usage transformatif) - Extrait 15s sans commentaire (pas d'usage transformatif)
### 3.4 Preuves licence ### 3.4 Preuves licence
Si vous utilisez musique payante (Epidemic Sound, Artlist) : Si vous utilisez musique payante (Epidemic Sound, Artlist) :
- Conservez factures/contrats - Conservez factures/contrats
- En cas de signalement, upload preuve via processus d'appel - En cas de signalement, upload preuve via processus d'appel
- Musique sera ajoutée à whitelist interne (évite futures erreurs) - Musique sera ajoutée à whitelist interne (évite futures erreurs)
@@ -125,6 +135,7 @@ Si vous utilisez musique payante (Epidemic Sound, Artlist) :
### 4.1 Règles spécifiques ### 4.1 Règles spécifiques
**Interdictions strictes en live** : **Interdictions strictes en live** :
- Diffusion concert/spectacle depuis la salle → Strike 2 immédiat (7 jours) - Diffusion concert/spectacle depuis la salle → Strike 2 immédiat (7 jours)
- Événement sportif payant (match, compétition droits TV) → Strike 2 immédiat - Événement sportif payant (match, compétition droits TV) → Strike 2 immédiat
- Film, série, musique fond sans droits → Strike 1 (3 jours) - Film, série, musique fond sans droits → Strike 1 (3 jours)
@@ -177,6 +188,7 @@ Si vous utilisez musique payante (Epidemic Sound, Artlist) :
### 6.2 Si besoin de changer audio/zone/classification ### 6.2 Si besoin de changer audio/zone/classification
**Supprimer contenu + republier** **Supprimer contenu + republier**
- Si <3 contenus validés : retourne en file validation - Si <3 contenus validés : retourne en file validation
- Si ≥3 contenus validés : publication immédiate - Si ≥3 contenus validés : publication immédiate
@@ -201,11 +213,13 @@ Si vous utilisez musique payante (Epidemic Sound, Artlist) :
### 7.2 Suspension monétisation ### 7.2 Suspension monétisation
**Suspension immédiate si** : **Suspension immédiate si** :
- Strike 3+ actif - Strike 3+ actif
- Inactivité (aucun contenu publié depuis 6 mois) - Inactivité (aucun contenu publié depuis 6 mois)
- Échec virement (RIB invalide, 3 tentatives) - Échec virement (RIB invalide, 3 tentatives)
**Réactivation** : **Réactivation** :
- Après résolution strikes (réhabilitation 6 mois) - Après résolution strikes (réhabilitation 6 mois)
- Après mise à jour RIB - Après mise à jour RIB
- Après publication nouveau contenu - Après publication nouveau contenu
@@ -213,11 +227,13 @@ Si vous utilisez musique payante (Epidemic Sound, Artlist) :
### 7.3 Fermeture compte monétisé ### 7.3 Fermeture compte monétisé
**Solde perdu si** : **Solde perdu si** :
- <50€ au moment de la fermeture - <50€ au moment de la fermeture
- Ban définitif (Strike 4) - Ban définitif (Strike 4)
- Inactivité 24 mois + solde <50€ - Inactivité 24 mois + solde <50€
**Virement final si** : **Virement final si** :
- ≥50€ → virement sous 30 jours après fermeture - ≥50€ → virement sous 30 jours après fermeture
--- ---
@@ -227,6 +243,7 @@ Si vous utilisez musique payante (Epidemic Sound, Artlist) :
### 8.1 Spam ### 8.1 Spam
**Interdit** : **Interdit** :
- Publier 10+ contenus identiques/similaires - Publier 10+ contenus identiques/similaires
- Répéter contenu dans zones différentes (ex: même podcast publié 50 fois dans 50 villes) - Répéter contenu dans zones différentes (ex: même podcast publié 50 fois dans 50 villes)
- Auto-promotion excessive (ex: "Abonnez-vous !" répété 20 fois) - Auto-promotion excessive (ex: "Abonnez-vous !" répété 20 fois)
@@ -234,6 +251,7 @@ Si vous utilisez musique payante (Epidemic Sound, Artlist) :
### 8.2 Manipulation ### 8.2 Manipulation
**Interdit** : **Interdit** :
- Acheter des abonnés, likes, écoutes - Acheter des abonnés, likes, écoutes
- Utiliser bots pour gonfler métriques - Utiliser bots pour gonfler métriques
- S'abonner massivement puis se désabonner (follow/unfollow spam) - S'abonner massivement puis se désabonner (follow/unfollow spam)
@@ -241,6 +259,7 @@ Si vous utilisez musique payante (Epidemic Sound, Artlist) :
### 8.3 Harcèlement ### 8.3 Harcèlement
**Interdit** : **Interdit** :
- Créer contenu ciblant nommément une personne (harcèlement) - Créer contenu ciblant nommément une personne (harcèlement)
- Publier informations privées d'un tiers (doxxing) - Publier informations privées d'un tiers (doxxing)
- Menaces répétées - Menaces répétées
@@ -262,12 +281,14 @@ Si vous utilisez musique payante (Epidemic Sound, Artlist) :
### 9.2 Conséquences strike ### 9.2 Conséquences strike
**Suspension upload** : **Suspension upload** :
- Strike 1 : **3 jours** sans possibilité de publier - Strike 1 : **3 jours** sans possibilité de publier
- Strike 2 : **7 jours** - Strike 2 : **7 jours**
- Strike 3 : **30 jours** - Strike 3 : **30 jours**
- Strike 4 : **Permanent** (ban définitif) - Strike 4 : **Permanent** (ban définitif)
**Pas d'impact sur** : **Pas d'impact sur** :
- Contenus déjà publiés (restent en ligne sauf si violents/illégaux) - Contenus déjà publiés (restent en ligne sauf si violents/illégaux)
- Revenus en cours (virement mensuel maintenu) - Revenus en cours (virement mensuel maintenu)
- Radio live (suspension upload = suspension live aussi) - Radio live (suspension upload = suspension live aussi)
@@ -295,5 +316,6 @@ Si vous utilisez musique payante (Epidemic Sound, Artlist) :
--- ---
**Contact** : **Contact** :
- Email créateurs : createurs@roadwave.fr - Email créateurs : createurs@roadwave.fr
- Email général : support@roadwave.fr - Email général : support@roadwave.fr

View File

@@ -40,10 +40,12 @@ Email : dpo@roadwave.fr
| **Geohash 5 (~5km²)** | Auto | Recommandations après 24h | Intérêt légitime | | **Geohash 5 (~5km²)** | Auto | Recommandations après 24h | Intérêt légitime |
**Durée conservation GPS précis** : **Durée conservation GPS précis** :
- Historique personnel : **24h** puis agrégé en geohash 5 - Historique personnel : **24h** puis agrégé en geohash 5
- Geohash : **conservé** pour analytics (anonymisé) - Geohash : **conservé** pour analytics (anonymisé)
**Révocation consentement** : **Révocation consentement** :
- Désactivation GPS dans paramètres → effet immédiat - Désactivation GPS dans paramètres → effet immédiat
- Mode dégradé : contenus nationaux + neutres uniquement - Mode dégradé : contenus nationaux + neutres uniquement
@@ -57,6 +59,7 @@ Email : dpo@roadwave.fr
| **Logs techniques** (IP, user-agent) | Sécurité, anti-fraude | Intérêt légitime | | **Logs techniques** (IP, user-agent) | Sécurité, anti-fraude | Intérêt légitime |
**IP anonymisée** : **IP anonymisée** :
- Dernier octet masqué (ex: 192.168.1.XXX) - Dernier octet masqué (ex: 192.168.1.XXX)
- Conservation : 7 jours (sécurité) puis suppression - Conservation : 7 jours (sécurité) puis suppression
@@ -122,6 +125,7 @@ RoadWave **ne vend jamais** vos données à des tiers.
### 4.4 Autorités ### 4.4 Autorités
Données transmises uniquement si : Données transmises uniquement si :
- **Obligation légale** (réquisition judiciaire) - **Obligation légale** (réquisition judiciaire)
- **Signalement contenu illégal** (terrorisme, pédopornographie) → autorités compétentes - **Signalement contenu illégal** (terrorisme, pédopornographie) → autorités compétentes
@@ -163,6 +167,7 @@ Données transmises uniquement si :
- Après 30 jours : suppression définitive - Après 30 jours : suppression définitive
**Exceptions** (conservation nécessaire) : **Exceptions** (conservation nécessaire) :
- Logs modération : 3 ans (obligation DSA) - Logs modération : 3 ans (obligation DSA)
- KYC créateurs : 5 ans (obligation fiscale) - KYC créateurs : 5 ans (obligation fiscale)
- Analytics agrégés (anonymisés) - Analytics agrégés (anonymisés)
@@ -174,6 +179,7 @@ Données transmises uniquement si :
- Lien téléchargement expire après **7 jours** - Lien téléchargement expire après **7 jours**
**Contenu export** : **Contenu export** :
- Profil (pseudo, bio, stats) - Profil (pseudo, bio, stats)
- Historique écoute complet - Historique écoute complet
- Centres d'intérêt (jauges) - Centres d'intérêt (jauges)
@@ -194,6 +200,7 @@ Données transmises uniquement si :
### 6.7 Réclamation CNIL ### 6.7 Réclamation CNIL
Si désaccord avec RoadWave : Si désaccord avec RoadWave :
- **CNIL** (Commission Nationale de l'Informatique et des Libertés) - **CNIL** (Commission Nationale de l'Informatique et des Libertés)
- Site : https://www.cnil.fr/fr/plaintes - Site : https://www.cnil.fr/fr/plaintes
- Adresse : 3 Place de Fontenoy, 75007 Paris - Adresse : 3 Place de Fontenoy, 75007 Paris
@@ -218,6 +225,7 @@ Si désaccord avec RoadWave :
### 7.3 Violation de données ### 7.3 Violation de données
En cas de fuite de données : En cas de fuite de données :
- Notification CNIL sous **72h** - Notification CNIL sous **72h**
- Notification utilisateurs concernés (email) si risque élevé - Notification utilisateurs concernés (email) si risque élevé
- Mesures correctives immédiates - Mesures correctives immédiates
@@ -273,6 +281,7 @@ En cas de fuite de données :
### 10.1 Principe ### 10.1 Principe
Données hébergées **exclusivement UE** : Données hébergées **exclusivement UE** :
- Serveurs : Hetzner (Allemagne) ou OVH (France) - Serveurs : Hetzner (Allemagne) ou OVH (France)
- Storage : OVH Object Storage (France) - Storage : OVH Object Storage (France)
- Paiements : Mangopay (Luxembourg) - Paiements : Mangopay (Luxembourg)
@@ -280,6 +289,7 @@ Données hébergées **exclusivement UE** :
### 10.2 Exceptions ### 10.2 Exceptions
**API tierces potentielles** (post-MVP) : **API tierces potentielles** (post-MVP) :
- Si transfert hors UE → clauses contractuelles types (CCT) - Si transfert hors UE → clauses contractuelles types (CCT)
- Notification utilisateurs avant activation - Notification utilisateurs avant activation
@@ -296,6 +306,7 @@ Données hébergées **exclusivement UE** :
## 12. Contact DPO ## 12. Contact DPO
**Délégué à la Protection des Données** : **Délégué à la Protection des Données** :
- Email : dpo@roadwave.fr - Email : dpo@roadwave.fr
- Délai réponse : **1 mois** (RGPD) - Délai réponse : **1 mois** (RGPD)

View File

@@ -14,18 +14,21 @@ La géolocalisation est **critique** pour RoadWave, mais les permissions arrièr
### Problématiques Identifiées ### Problématiques Identifiées
#### iOS App Store #### iOS App Store
- **Taux de rejet ~70%** si permission "Always Location" mal justifiée - **Taux de rejet ~70%** si permission "Always Location" mal justifiée
- Apple exige que l'app soit **pleinement utilisable** sans "Always Location" - Apple exige que l'app soit **pleinement utilisable** sans "Always Location"
- Textes `Info.plist` scrutés manuellement par reviewers humains - Textes `Info.plist` scrutés manuellement par reviewers humains
- Rejection si suspicion de tracking publicitaire ou vente de données - Rejection si suspicion de tracking publicitaire ou vente de données
#### Android Play Store #### Android Play Store
- Depuis Android 10 : `ACCESS_BACKGROUND_LOCATION` nécessite **déclaration justifiée** - Depuis Android 10 : `ACCESS_BACKGROUND_LOCATION` nécessite **déclaration justifiée**
- Vidéo démo **obligatoire** montrant le flow de demande (< 30s) - Vidéo démo **obligatoire** montrant le flow de demande (< 30s)
- Google vérifie que la permission est **réellement optionnelle** - Google vérifie que la permission est **réellement optionnelle**
- Foreground service notification **obligatoire** en arrière-plan (Android 12+) - Foreground service notification **obligatoire** en arrière-plan (Android 12+)
#### RGPD (Règle 02) #### RGPD (Règle 02)
- Permissions doivent être **optionnelles** - Permissions doivent être **optionnelles**
- Utilisateur doit pouvoir **refuser sans pénalité** - Utilisateur doit pouvoir **refuser sans pénalité**
- App doit fonctionner en **mode dégradé acceptable** - App doit fonctionner en **mode dégradé acceptable**
@@ -62,6 +65,7 @@ La géolocalisation est **critique** pour RoadWave, mais les permissions arrièr
## Étape 1 : Permission de Base (Onboarding) ## Étape 1 : Permission de Base (Onboarding)
### Quand ### Quand
- **Premier lancement** de l'app - **Premier lancement** de l'app
- Avant de pouvoir utiliser les fonctionnalités principales - Avant de pouvoir utiliser les fonctionnalités principales
@@ -109,6 +113,7 @@ La géolocalisation est **critique** pour RoadWave, mais les permissions arrièr
### Si Permission Refusée ### Si Permission Refusée
**Mode dégradé (IP2Location)** : **Mode dégradé (IP2Location)** :
- Détection pays/ville via adresse IP (IP2Location Lite, voir [ADR-019](../adr/019-geolocalisation-ip.md)) - Détection pays/ville via adresse IP (IP2Location Lite, voir [ADR-019](../adr/019-geolocalisation-ip.md))
- Contenus nationaux et régionaux disponibles - Contenus nationaux et régionaux disponibles
- Pas de contenus hyperlocaux (< 10km) - Pas de contenus hyperlocaux (< 10km)
@@ -246,6 +251,7 @@ class LocationOnboardingScreen extends StatelessWidget {
## Étape 2 : Permission Arrière-Plan (Optionnelle) ## Étape 2 : Permission Arrière-Plan (Optionnelle)
### Quand ### Quand
- User **active explicitement** "Notifications audio-guides piéton" dans Settings - User **active explicitement** "Notifications audio-guides piéton" dans Settings
- **Jamais au premier lancement** - **Jamais au premier lancement**
@@ -547,6 +553,7 @@ class _NotificationsSettingsScreenState extends State<NotificationsSettingsScree
| **Denied** | ⚠️ IP2Location (ville) | ❌ Désactivé | ❌ Aucun | Aucune | | **Denied** | ⚠️ IP2Location (ville) | ❌ Désactivé | ❌ Aucun | Aucune |
**Garanties** : **Garanties** :
- App **utilisable** à tous niveaux de permission ✅ - App **utilisable** à tous niveaux de permission ✅
- Pas de fonctionnalité **bloquante** sans permission ✅ - Pas de fonctionnalité **bloquante** sans permission ✅
- Mode dégradé **acceptable** (contenus régionaux) ✅ - Mode dégradé **acceptable** (contenus régionaux) ✅
@@ -632,6 +639,7 @@ class _NotificationsSettingsScreenState extends State<NotificationsSettingsScree
- [ ] Fonctionnalité précise ("audio-guides piéton") - [ ] Fonctionnalité précise ("audio-guides piéton")
- [ ] **Optionnalité** ("Cette fonctionnalité est optionnelle") - [ ] **Optionnalité** ("Cette fonctionnalité est optionnelle")
- [ ] Pas de mention tracking/publicité - [ ] Pas de mention tracking/publicité
- [ ] App fonctionne **complètement** avec permission "When In Use" uniquement - [ ] App fonctionne **complètement** avec permission "When In Use" uniquement
- [ ] App fonctionne en **mode dégradé** sans aucune permission (IP2Location) - [ ] App fonctionne en **mode dégradé** sans aucune permission (IP2Location)
- [ ] Screenshots montrant app fonctionnelle sans permission "Always" - [ ] Screenshots montrant app fonctionnelle sans permission "Always"
@@ -642,11 +650,13 @@ class _NotificationsSettingsScreenState extends State<NotificationsSettingsScree
- [ ] Déclaration `ACCESS_BACKGROUND_LOCATION` avec justification dans Play Console : - [ ] Déclaration `ACCESS_BACKGROUND_LOCATION` avec justification dans Play Console :
- [ ] "Notifications géolocalisées pour audio-guides touristiques en arrière-plan" - [ ] "Notifications géolocalisées pour audio-guides touristiques en arrière-plan"
- [ ] "Permet aux utilisateurs de recevoir des alertes lorsqu'ils passent près de monuments" - [ ] "Permet aux utilisateurs de recevoir des alertes lorsqu'ils passent près de monuments"
- [ ] **Vidéo démo obligatoire** (< 30s) montrant : - [ ] **Vidéo démo obligatoire** (< 30s) montrant :
- [ ] Activation toggle "Mode piéton" dans Settings - [ ] Activation toggle "Mode piéton" dans Settings
- [ ] Écran d'éducation pré-permission - [ ] Écran d'éducation pré-permission
- [ ] Demande permission système Android - [ ] Demande permission système Android
- [ ] App fonctionnelle si permission refusée - [ ] App fonctionnelle si permission refusée
- [ ] Foreground service notification visible en mode piéton (Android 12+) - [ ] Foreground service notification visible en mode piéton (Android 12+)
- [ ] App fonctionne **complètement** avec `ACCESS_FINE_LOCATION` uniquement - [ ] App fonctionne **complètement** avec `ACCESS_FINE_LOCATION` uniquement
- [ ] App fonctionne en **mode dégradé** sans permissions - [ ] App fonctionne en **mode dégradé** sans permissions
@@ -729,6 +739,7 @@ void main() {
### Tests Manuels (Devices Réels) ### Tests Manuels (Devices Réels)
**iOS** : **iOS** :
- [ ] iPhone avec iOS 14, 15, 16, 17, 18 - [ ] iPhone avec iOS 14, 15, 16, 17, 18
- [ ] Tester flow onboarding permission "When In Use" - [ ] Tester flow onboarding permission "When In Use"
- [ ] Tester activation mode piéton avec permission "Always" - [ ] Tester activation mode piéton avec permission "Always"
@@ -736,6 +747,7 @@ void main() {
- [ ] Tester changement permission dans Settings iOS → app réagit correctement - [ ] Tester changement permission dans Settings iOS → app réagit correctement
**Android** : **Android** :
- [ ] Android 10, 11, 12, 13, 14, 15 - [ ] Android 10, 11, 12, 13, 14, 15
- [ ] Tester flow onboarding permission `FINE_LOCATION` - [ ] Tester flow onboarding permission `FINE_LOCATION`
- [ ] Tester activation mode piéton avec `BACKGROUND_LOCATION` - [ ] Tester activation mode piéton avec `BACKGROUND_LOCATION`
@@ -755,11 +767,13 @@ void main() {
**Durée** : 2 semaines **Durée** : 2 semaines
**Checklist** : **Checklist** :
- [ ] Upload build vers TestFlight - [ ] Upload build vers TestFlight
- [ ] Compléter questionnaire App Store Connect : - [ ] Compléter questionnaire App Store Connect :
- [ ] "Why does your app use background location?" - [ ] "Why does your app use background location?"
→ "To send push notifications when users walk near tourist audio-guides, even when app is closed. This feature is optional and can be disabled in settings." → "To send push notifications when users walk near tourist audio-guides, even when app is closed. This feature is optional and can be disabled in settings."
- [ ] Screenshots montrant app fonctionnelle sans permission "Always" - [ ] Screenshots montrant app fonctionnelle sans permission "Always"
- [ ] Attendre review Apple (24-48h) - [ ] Attendre review Apple (24-48h)
- [ ] Si rejet : analyser feedback, ajuster textes/flow, re-soumettre - [ ] Si rejet : analyser feedback, ajuster textes/flow, re-soumettre
- [ ] Si accepté : lancer beta test avec testeurs - [ ] Si accepté : lancer beta test avec testeurs
@@ -772,6 +786,7 @@ void main() {
5. Désactiver mode piéton → vérifier app toujours fonctionnelle 5. Désactiver mode piéton → vérifier app toujours fonctionnelle
**Métriques collectées** : **Métriques collectées** :
- Taux acceptation permission "When In Use" : cible >85% - Taux acceptation permission "When In Use" : cible >85%
- Taux acceptation permission "Always" : cible >40% - Taux acceptation permission "Always" : cible >40%
- Taux rejet App Review : cible 0% - Taux rejet App Review : cible 0%
@@ -785,10 +800,12 @@ void main() {
**Durée** : 1 semaine **Durée** : 1 semaine
**Checklist** : **Checklist** :
- [ ] Upload build vers Play Console (Internal Testing) - [ ] Upload build vers Play Console (Internal Testing)
- [ ] Compléter déclaration permissions : - [ ] Compléter déclaration permissions :
- [ ] `ACCESS_BACKGROUND_LOCATION` justification - [ ] `ACCESS_BACKGROUND_LOCATION` justification
- [ ] Upload vidéo démo (< 30s) - [ ] Upload vidéo démo (< 30s)
- [ ] Tester sur Android 10, 11, 12, 13, 14, 15 - [ ] Tester sur Android 10, 11, 12, 13, 14, 15
- [ ] Vérifier foreground notification visible (Android 12+) - [ ] Vérifier foreground notification visible (Android 12+)
@@ -800,6 +817,7 @@ void main() {
5. Vérifier notification foreground service visible dans panneau notifications 5. Vérifier notification foreground service visible dans panneau notifications
**Métriques collectées** : **Métriques collectées** :
- Consommation batterie mode piéton : cible <5% par heure - Consommation batterie mode piéton : cible <5% par heure
- Taux crash background service : cible <0.1% - Taux crash background service : cible <0.1%
@@ -843,6 +861,7 @@ void main() {
### Q4 : Combien de temps pour validation TestFlight/Play Store ? ### Q4 : Combien de temps pour validation TestFlight/Play Store ?
**R** : **R** :
- TestFlight : 24-48h (review Apple) - TestFlight : 24-48h (review Apple)
- Play Console Internal Testing : Immédiat (pas de review) - Play Console Internal Testing : Immédiat (pas de review)
- Play Console Production : 3-7 jours (review Google) - Play Console Production : 3-7 jours (review Google)

View File

@@ -39,11 +39,13 @@ Semaine 6 : Validation finale + go/no-go production
- [ ] `NSLocationAlwaysAndWhenInUseUsageDescription` ≤ 200 caractères - [ ] `NSLocationAlwaysAndWhenInUseUsageDescription` ≤ 200 caractères
- [ ] Pas de mention tracking/publicité - [ ] Pas de mention tracking/publicité
- [ ] Mention explicite "optionnel" - [ ] Mention explicite "optionnel"
- [ ] Vérifier `UIBackgroundModes` contient `location` - [ ] Vérifier `UIBackgroundModes` contient `location`
- [ ] Build & Archive (Xcode) - [ ] Build & Archive (Xcode)
- [ ] Version : `1.0.0 (1)` (beta) - [ ] Version : `1.0.0 (1)` (beta)
- [ ] Bundle ID : `com.roadwave.app` - [ ] Bundle ID : `com.roadwave.app`
- [ ] Signing : Distribution certificate - [ ] Signing : Distribution certificate
- [ ] Upload vers App Store Connect - [ ] Upload vers App Store Connect
- [ ] Attendre processing (15-30 min) - [ ] Attendre processing (15-30 min)
@@ -55,11 +57,13 @@ Semaine 6 : Validation finale + go/no-go production
- [ ] `ACCESS_BACKGROUND_LOCATION` - [ ] `ACCESS_BACKGROUND_LOCATION`
- [ ] `FOREGROUND_SERVICE` - [ ] `FOREGROUND_SERVICE`
- [ ] `FOREGROUND_SERVICE_LOCATION` - [ ] `FOREGROUND_SERVICE_LOCATION`
- [ ] Vérifier foreground service déclaration - [ ] Vérifier foreground service déclaration
- [ ] Build AAB (Android App Bundle) - [ ] Build AAB (Android App Bundle)
- [ ] Version : `1.0.0 (1)` - [ ] Version : `1.0.0 (1)`
- [ ] Package : `com.roadwave.app` - [ ] Package : `com.roadwave.app`
- [ ] Signing : Release keystore - [ ] Signing : Release keystore
- [ ] Upload vers Play Console (Internal Testing) - [ ] Upload vers Play Console (Internal Testing)
### Documentation App Store Connect ### Documentation App Store Connect
@@ -79,10 +83,12 @@ Users can use RoadWave fully without enabling background location - they
will simply use the "car mode" which only requires location "while using". will simply use the "car mode" which only requires location "while using".
Background location is ONLY used for: Background location is ONLY used for:
- Detecting proximity to audio-guide points of interest (200m radius) - Detecting proximity to audio-guide points of interest (200m radius)
- Sending a single push notification to alert the user - Sending a single push notification to alert the user
Background location is NEVER used for: Background location is NEVER used for:
- Advertising or tracking - Advertising or tracking
- Selling data to third parties - Selling data to third parties
- Analytics beyond core functionality - Analytics beyond core functionality
@@ -116,11 +122,13 @@ notifications push géolocalisées aux utilisateurs en mode piéton (touristes
à pied). à pied).
Usage précis : Usage précis :
- Geofencing radius 200m autour des points d'intérêt (monuments, musées) - Geofencing radius 200m autour des points d'intérêt (monuments, musées)
- Notification push unique lorsque l'utilisateur entre dans la zone - Notification push unique lorsque l'utilisateur entre dans la zone
- Permet découverte de contenus audio-guides sans ouvrir l'app - Permet découverte de contenus audio-guides sans ouvrir l'app
Cette fonctionnalité est OPTIONNELLE : Cette fonctionnalité est OPTIONNELLE :
- Demandée uniquement si utilisateur active "Mode piéton" dans Settings - Demandée uniquement si utilisateur active "Mode piéton" dans Settings
- Écran explicatif affiché AVANT demande permission système - Écran explicatif affiché AVANT demande permission système
- L'app fonctionne pleinement sans cette permission (mode voiture disponible) - L'app fonctionne pleinement sans cette permission (mode voiture disponible)
@@ -128,12 +136,14 @@ Cette fonctionnalité est OPTIONNELLE :
Foreground service notification visible (Android 12+) lorsque geofencing actif. Foreground service notification visible (Android 12+) lorsque geofencing actif.
Données de localisation : Données de localisation :
- JAMAIS vendues ou partagées avec tiers - JAMAIS vendues ou partagées avec tiers
- JAMAIS utilisées pour publicité ciblée - JAMAIS utilisées pour publicité ciblée
- Anonymisées après 24h (conformité RGPD) - Anonymisées après 24h (conformité RGPD)
``` ```
**Vidéo démo** (requis) : **Vidéo démo** (requis) :
- [ ] Enregistrer screen recording (25-30s) - [ ] Enregistrer screen recording (25-30s)
- [ ] Montrer activation mode piéton depuis Settings - [ ] Montrer activation mode piéton depuis Settings
- [ ] Montrer écran d'éducation - [ ] Montrer écran d'éducation
@@ -157,6 +167,7 @@ Données de localisation :
| **External 2** | 20-30 | Grand public varié | Tests UX/acceptation réelle | | **External 2** | 20-30 | Grand public varié | Tests UX/acceptation réelle |
**Configuration** : **Configuration** :
- [ ] Créer groupe "Internal Testers" (accès immédiat) - [ ] Créer groupe "Internal Testers" (accès immédiat)
- [ ] Créer groupe "External Beta 1" (review Apple requise, 24-48h) - [ ] Créer groupe "External Beta 1" (review Apple requise, 24-48h)
- [ ] Créer groupe "External Beta 2" (après succès Beta 1) - [ ] Créer groupe "External Beta 2" (après succès Beta 1)
@@ -168,6 +179,7 @@ Données de localisation :
**Durée** : 2-3 jours **Durée** : 2-3 jours
**Devices** : **Devices** :
- iPhone 12 (iOS 15) - iPhone 12 (iOS 15)
- iPhone 13 Pro (iOS 16) - iPhone 13 Pro (iOS 16)
- iPhone 14 (iOS 17) - iPhone 14 (iOS 17)
@@ -325,10 +337,13 @@ analytics.logEvent(
- Taux acceptation "When In Use" : `granted / requested` - Taux acceptation "When In Use" : `granted / requested`
- Cible : >85% - Cible : >85%
- Taux activation mode piéton : `toggle_attempted / total_users` - Taux activation mode piéton : `toggle_attempted / total_users`
- Cible : >30% - Cible : >30%
- Taux acceptation "Always" : `always_granted / education_continued` - Taux acceptation "Always" : `always_granted / education_continued`
- Cible : >40% - Cible : >40%
- Taux abandon education : `education_dismissed / education_shown` - Taux abandon education : `education_dismissed / education_shown`
- Cible : <60% - Cible : <60%
@@ -355,11 +370,13 @@ Si Apple **rejette** External Beta :
### Configuration Play Console Internal Testing ### Configuration Play Console Internal Testing
**Testeurs** : **Testeurs** :
- [ ] Ajouter emails testeurs (max 100 pour Internal Testing) - [ ] Ajouter emails testeurs (max 100 pour Internal Testing)
- [ ] Créer "testers list" dans Play Console - [ ] Créer "testers list" dans Play Console
- [ ] Share lien installation (pas de review Google pour Internal) - [ ] Share lien installation (pas de review Google pour Internal)
**Devices** : **Devices** :
- Google Pixel 5 (Android 12) - Google Pixel 5 (Android 12)
- Samsung Galaxy S21 (Android 13) - Samsung Galaxy S21 (Android 13)
- OnePlus 9 (Android 14) - OnePlus 9 (Android 14)
@@ -415,6 +432,7 @@ Then:
### Vidéo Démo Play Store ### Vidéo Démo Play Store
**Enregistrement** : **Enregistrement** :
- [ ] Device : Pixel 8 (Android 15, UI stock) - [ ] Device : Pixel 8 (Android 15, UI stock)
- [ ] Screen recorder : Android natif (Game Toolbar) - [ ] Screen recorder : Android natif (Game Toolbar)
- [ ] Durée : 25-30s - [ ] Durée : 25-30s
@@ -430,6 +448,7 @@ Then:
6. (22-25s) Retour Settings, toggle ON confirmé 6. (22-25s) Retour Settings, toggle ON confirmé
**Post-production** : **Post-production** :
- [ ] Ajouter text overlays : "Utilisateur active mode piéton", "Écran explicatif affiché", etc. - [ ] Ajouter text overlays : "Utilisateur active mode piéton", "Écran explicatif affiché", etc.
- [ ] Exporter MP4 < 50MB - [ ] Exporter MP4 < 50MB
- [ ] Upload Play Console > Permissions > Background Location > Video demo - [ ] Upload Play Console > Permissions > Background Location > Video demo
@@ -462,6 +481,7 @@ Then:
### Décision Go/No-Go Production ### Décision Go/No-Go Production
**Critères GO** (tous doivent être ✅) : **Critères GO** (tous doivent être ✅) :
- [ ] Apple a approuvé External Beta TestFlight - [ ] Apple a approuvé External Beta TestFlight
- [ ] Taux acceptation permission base iOS ≥ 80% - [ ] Taux acceptation permission base iOS ≥ 80%
- [ ] Taux acceptation permission base Android ≥ 80% - [ ] Taux acceptation permission base Android ≥ 80%
@@ -488,6 +508,7 @@ Then:
### iOS App Store ### iOS App Store
**Checklist soumission** : **Checklist soumission** :
- [ ] Build production uploadé (même code que TestFlight validé) - [ ] Build production uploadé (même code que TestFlight validé)
- [ ] Version : `1.0.0 (1)` - [ ] Version : `1.0.0 (1)`
- [ ] Screenshots stores (5 minimum, incluant permissions flow) - [ ] Screenshots stores (5 minimum, incluant permissions flow)
@@ -500,6 +521,7 @@ Then:
**App Privacy (obligatoire iOS 14+)** : **App Privacy (obligatoire iOS 14+)** :
Location Data Collection : Location Data Collection :
- [ ] "Precise Location" : Yes - [ ] "Precise Location" : Yes
- [ ] Purpose : "App Functionality" + "Product Personalization" - [ ] Purpose : "App Functionality" + "Product Personalization"
- [ ] Linked to user : Yes - [ ] Linked to user : Yes
@@ -507,6 +529,7 @@ Location Data Collection :
- [ ] "Coarse Location" : No - [ ] "Coarse Location" : No
**Timing** : **Timing** :
- Review Apple : 24-48h (généralement) - Review Apple : 24-48h (généralement)
- Si rejet : corrections + re-soumission (24h) - Si rejet : corrections + re-soumission (24h)
- **Total prévu** : 3-7 jours - **Total prévu** : 3-7 jours
@@ -514,6 +537,7 @@ Location Data Collection :
### Android Play Store ### Android Play Store
**Checklist soumission** : **Checklist soumission** :
- [ ] Build production (Release AAB) - [ ] Build production (Release AAB)
- [ ] Version : `1.0.0 (1)` - [ ] Version : `1.0.0 (1)`
- [ ] Screenshots (8 minimum) - [ ] Screenshots (8 minimum)
@@ -527,6 +551,7 @@ Location Data Collection :
**Data Safety Form** : **Data Safety Form** :
Location Data : Location Data :
- [ ] "Approximate location" : No - [ ] "Approximate location" : No
- [ ] "Precise location" : Yes - [ ] "Precise location" : Yes
- [ ] Purpose : "App functionality" + "Personalization" - [ ] Purpose : "App functionality" + "Personalization"
@@ -535,6 +560,7 @@ Location Data :
- [ ] User can request deletion : Yes - [ ] User can request deletion : Yes
**Timing** : **Timing** :
- Review Google : 3-7 jours - Review Google : 3-7 jours
- Si rejet : corrections + re-soumission (1-2 jours) - Si rejet : corrections + re-soumission (1-2 jours)
- **Total prévu** : 5-10 jours - **Total prévu** : 5-10 jours

View File

@@ -96,89 +96,90 @@ nav:
- Domaines DDD: - Domaines DDD:
- 'Context Map': domains/README.md - 'Context Map': domains/README.md
- 'Core Domain': - 'Core Domain':
- '🔐 Shared': domains/_shared/README.md - '🔐 Shared':
- Règles: - Vue d'ensemble: domains/_shared/README.md
- Authentification: domains/_shared/rules/authentification.md - Règles:
- RGPD: domains/_shared/rules/rgpd.md - Authentification: domains/_shared/rules/authentification.md
- Gestion Erreurs: domains/_shared/rules/gestion-erreurs.md - RGPD: domains/_shared/rules/rgpd.md
- 'Annexe Post-MVP': domains/_shared/rules/ANNEXE-POST-MVP.md - Gestion Erreurs: domains/_shared/rules/gestion-erreurs.md
- Features BDD: - 'Annexe Post-MVP': domains/_shared/rules/ANNEXE-POST-MVP.md
- 'Authentication': - Features BDD:
- Appareil de confiance et 2FA: generated/bdd/_shared/features/authentication/appareil-confiance-2fa.md - 'Authentication':
- Classification par âge: generated/bdd/_shared/features/authentication/classification-age.md - Appareil de confiance et 2FA: generated/bdd/_shared/features/authentication/appareil-confiance-2fa.md
- Connexion: generated/bdd/_shared/features/authentication/connexion.md - Classification par âge: generated/bdd/_shared/features/authentication/classification-age.md
- Gestion de compte: generated/bdd/_shared/features/authentication/gestion-compte.md - Connexion: generated/bdd/_shared/features/authentication/connexion.md
- Inscription: generated/bdd/_shared/features/authentication/inscription.md - Gestion de compte: generated/bdd/_shared/features/authentication/gestion-compte.md
- Limite de tentatives de connexion: generated/bdd/_shared/features/authentication/limite-tentatives-connexion.md - Inscription: generated/bdd/_shared/features/authentication/inscription.md
- Sessions multi-devices: generated/bdd/_shared/features/authentication/multi-device-sessions.md - Limite de tentatives de connexion: generated/bdd/_shared/features/authentication/limite-tentatives-connexion.md
- Récupération de compte: generated/bdd/_shared/features/authentication/recuperation-compte.md - Sessions multi-devices: generated/bdd/_shared/features/authentication/multi-device-sessions.md
- Récupération de mot de passe avancée: generated/bdd/_shared/features/authentication/recuperation-mot-passe-avancee.md - Récupération de compte: generated/bdd/_shared/features/authentication/recuperation-compte.md
- Sessions et tokens: generated/bdd/_shared/features/authentication/sessions-tokens.md - Récupération de mot de passe avancée: generated/bdd/_shared/features/authentication/recuperation-mot-passe-avancee.md
- Authentification à deux facteurs: generated/bdd/_shared/features/authentication/two-factor-authentication.md - Sessions et tokens: generated/bdd/_shared/features/authentication/sessions-tokens.md
- Validation mot de passe: generated/bdd/_shared/features/authentication/validation-mot-passe.md - Authentification à deux facteurs: generated/bdd/_shared/features/authentication/two-factor-authentication.md
- Vérification email: generated/bdd/_shared/features/authentication/verification-email.md - Validation mot de passe: generated/bdd/_shared/features/authentication/validation-mot-passe.md
- 'Profil': - Vérification email: generated/bdd/_shared/features/authentication/verification-email.md
- Badge vérifié: generated/bdd/_shared/features/profil/badge-verifie.md - 'Profil':
- Profil créateur: generated/bdd/_shared/features/profil/profil-createur.md - Badge vérifié: generated/bdd/_shared/features/profil/badge-verifie.md
- Statistiques arrondies: generated/bdd/_shared/features/profil/statistiques-arrondies.md - Profil créateur: generated/bdd/_shared/features/profil/profil-createur.md
- 'Partage': - Statistiques arrondies: generated/bdd/_shared/features/profil/statistiques-arrondies.md
- Partage de contenu: generated/bdd/_shared/features/partage/partage-contenu.md - 'Partage':
- Partage de contenu Premium: generated/bdd/_shared/features/partage/partage-contenu-premium.md - Partage de contenu: generated/bdd/_shared/features/partage/partage-contenu.md
- 'Error Handling': - Partage de contenu Premium: generated/bdd/_shared/features/partage/partage-contenu-premium.md
- Aucun contenu disponible: generated/bdd/_shared/features/error-handling/aucun-contenu-disponible.md - 'Error Handling':
- Contenu supprimé pendant écoute: generated/bdd/_shared/features/error-handling/contenu-supprime-pendant-ecoute.md - Aucun contenu disponible: generated/bdd/_shared/features/error-handling/aucun-contenu-disponible.md
- Géolocalisation désactivée: generated/bdd/_shared/features/error-handling/geolocalisation-desactivee.md - Contenu supprimé pendant écoute: generated/bdd/_shared/features/error-handling/contenu-supprime-pendant-ecoute.md
- Perte réseau: generated/bdd/_shared/features/error-handling/perte-reseau.md - Géolocalisation désactivée: generated/bdd/_shared/features/error-handling/geolocalisation-desactivee.md
- 'RGPD & Conformité': - Perte réseau: generated/bdd/_shared/features/error-handling/perte-reseau.md
- Consentement: generated/bdd/_shared/features/rgpd-compliance/consentement.md - 'RGPD & Conformité':
- Anonymisation GPS: generated/bdd/_shared/features/rgpd-compliance/anonymisation-gps.md - Consentement: generated/bdd/_shared/features/rgpd-compliance/consentement.md
- Portabilité Données: generated/bdd/_shared/features/rgpd-compliance/portabilite-donnees.md - Anonymisation GPS: generated/bdd/_shared/features/rgpd-compliance/anonymisation-gps.md
- Suppression Compte: generated/bdd/_shared/features/rgpd-compliance/suppression-compte.md - Portabilité Données: generated/bdd/_shared/features/rgpd-compliance/portabilite-donnees.md
- Conservation Données: generated/bdd/_shared/features/rgpd-compliance/conservation-donnees.md - Suppression Compte: generated/bdd/_shared/features/rgpd-compliance/suppression-compte.md
- Cookies & Analytics: generated/bdd/_shared/features/rgpd-compliance/cookies-analytics.md - Conservation Données: generated/bdd/_shared/features/rgpd-compliance/conservation-donnees.md
- Mode Dégradé GeoIP: generated/bdd/_shared/features/rgpd-compliance/mode-degrade-geoip.md - Cookies & Analytics: generated/bdd/_shared/features/rgpd-compliance/cookies-analytics.md
- Compliance Administrative: generated/bdd/_shared/features/rgpd-compliance/compliance-administrative.md - Mode Dégradé GeoIP: generated/bdd/_shared/features/rgpd-compliance/mode-degrade-geoip.md
- Protection Mineurs: generated/bdd/_shared/features/rgpd-compliance/minors-protection.md - Compliance Administrative: generated/bdd/_shared/features/rgpd-compliance/compliance-administrative.md
- Sécurité Données: generated/bdd/_shared/features/rgpd-compliance/data-security.md - Protection Mineurs: generated/bdd/_shared/features/rgpd-compliance/minors-protection.md
- Politique Confidentialité: generated/bdd/_shared/features/rgpd-compliance/privacy-policy.md - Sécurité Données: generated/bdd/_shared/features/rgpd-compliance/data-security.md
- Droits Utilisateurs: generated/bdd/_shared/features/rgpd-compliance/user-rights.md - Politique Confidentiali: generated/bdd/_shared/features/rgpd-compliance/privacy-policy.md
- Entités: - Droits Utilisateurs: generated/bdd/_shared/features/rgpd-compliance/user-rights.md
- "Vue d'ensemble": domains/_shared/entities/vue-ensemble.md - Entités:
- 'Auth & Sécurité': - "Vue d'ensemble": domains/_shared/entities/vue-ensemble.md
- Sessions: domains/_shared/entities/sessions.md - 'Auth & Sécurité':
- Devices: domains/_shared/entities/devices.md - Sessions: domains/_shared/entities/sessions.md
- 'RGPD & Conformité': - Devices: domains/_shared/entities/devices.md
- Consentements: domains/_shared/entities/consents.md - 'RGPD & Conformité':
- Historique GPS: domains/_shared/entities/location-history.md - Consentements: domains/_shared/entities/consents.md
- Exports Données: domains/_shared/entities/exports.md - Historique GPS: domains/_shared/entities/location-history.md
- Consentements Parentaux: domains/_shared/entities/parental-consents.md - Exports Données: domains/_shared/entities/exports.md
- Politique Confidentialité: domains/_shared/entities/privacy-policy-versions.md - Consentements Parentaux: domains/_shared/entities/parental-consents.md
- Suppressions Compte: domains/_shared/entities/account-deletions.md - Politique Confidentialité: domains/_shared/entities/privacy-policy-versions.md
- Incidents Breach: domains/_shared/entities/breach-incidents.md - Suppressions Compte: domains/_shared/entities/account-deletions.md
- Historique Profil: domains/_shared/entities/user-profile-history.md - Incidents Breach: domains/_shared/entities/breach-incidents.md
- Logs Rétention Données: domains/_shared/entities/data-retention-logs.md - Historique Profil: domains/_shared/entities/user-profile-history.md
- 'Recommandation & Modération': - Logs Rétention Données: domains/_shared/entities/data-retention-logs.md
- Jauges Intérêt: domains/_shared/entities/interest-gauges.md - 'Recommandation & Modération':
- Signalements: domains/_shared/entities/reports.md - Jauges Intérêt: domains/_shared/entities/interest-gauges.md
- 'États (Lifecycles)': - Signalements: domains/_shared/entities/reports.md
- Compte Utilisateur: domains/_shared/states/compte-utilisateur.md - 'États (Lifecycles)':
- Contenu: domains/_shared/states/contenu.md - Compte Utilisateur: domains/_shared/states/compte-utilisateur.md
- Session: domains/_shared/states/session.md - Contenu: domains/_shared/states/contenu.md
- Signalement: domains/_shared/states/signalement.md - Session: domains/_shared/states/session.md
- Export Données: domains/_shared/states/export-donnees.md - Signalement: domains/_shared/states/signalement.md
- Consentement Parental: domains/_shared/states/consentement-parental.md - Export Données: domains/_shared/states/export-donnees.md
- Suppression Compte: domains/_shared/states/suppression-compte.md - Consentement Parental: domains/_shared/states/consentement-parental.md
- Incident Breach: domains/_shared/states/incident-breach.md - Suppression Compte: domains/_shared/states/suppression-compte.md
- Séquences: - Incident Breach: domains/_shared/states/incident-breach.md
- Authentification: domains/_shared/sequences/authentification.md - Séquences:
- Refresh Token: domains/_shared/sequences/refresh-token.md - Authentification: domains/_shared/sequences/authentification.md
- Modération Contenu: domains/_shared/sequences/moderation-contenu.md - Refresh Token: domains/_shared/sequences/refresh-token.md
- Signalement: domains/_shared/sequences/signalement.md - Modération Contenu: domains/_shared/sequences/moderation-contenu.md
- Export Données: domains/_shared/sequences/export-donnees.md - Signalement: domains/_shared/sequences/signalement.md
- Suppression Compte: domains/_shared/sequences/suppression-compte.md - Export Données: domains/_shared/sequences/export-donnees.md
- Consentement Parental: domains/_shared/sequences/consentement-parental.md - Suppression Compte: domains/_shared/sequences/suppression-compte.md
- Anonymisation GPS: domains/_shared/sequences/anonymisation-gps.md - Consentement Parental: domains/_shared/sequences/consentement-parental.md
- Notification Breach: domains/_shared/sequences/notification-breach.md - Anonymisation GPS: domains/_shared/sequences/anonymisation-gps.md
- Notification Breach: domains/_shared/sequences/notification-breach.md
- 'Supporting Subdomains': - 'Supporting Subdomains':
- '🎯 Recommendation': - '🎯 Recommendation':
- Vue d'ensemble: domains/recommendation/README.md - Vue d'ensemble: domains/recommendation/README.md

58
scripts/fix-markdown-lists.sh Executable file
View File

@@ -0,0 +1,58 @@
#!/bin/bash
# Script pour ajouter des lignes vides avant les listes markdown
# qui n'en ont pas, pour un rendu correct dans mkdocs
set -e
echo "🔍 Recherche des fichiers markdown dans docs/..."
# Compteur de fichiers modifiés
modified=0
# Trouver tous les fichiers .md dans docs/
find docs -name "*.md" -type f | while read -r file; do
echo " Traitement de $file..."
# Utiliser awk pour ajouter une ligne vide avant les listes si nécessaire
awk '
BEGIN {
prev = ""
prev_empty = 1
}
{
current = $0
# Si la ligne courante commence par "- " et que la ligne précédente n'\''est pas vide
# et ne commence pas déjà par "- " (déjà dans une liste)
if (current ~ /^- / && prev !~ /^$/ && prev !~ /^- /) {
print prev
print "" # Ajouter une ligne vide
prev = current
}
# Sinon, imprimer la ligne précédente normalement
else if (NR > 1) {
print prev
prev = current
}
else {
prev = current
}
}
END {
# Imprimer la dernière ligne
if (prev != "") print prev
}
' "$file" > "$file.tmp"
# Vérifier si le fichier a changé
if ! cmp -s "$file" "$file.tmp"; then
mv "$file.tmp" "$file"
echo "$file modifié"
modified=$((modified + 1))
else
rm "$file.tmp"
fi
done
echo ""
echo "✨ Terminé ! $modified fichier(s) modifié(s)"

View File

@@ -195,7 +195,8 @@ def get_keyword_color(keyword: str) -> str:
def format_step(step: Step, indent: str = "") -> str: def format_step(step: Step, indent: str = "") -> str:
"""Formate une étape Gherkin avec couleur""" """Formate une étape Gherkin avec couleur"""
color = get_keyword_color(step.keyword) color = get_keyword_color(step.keyword)
result = f'{indent}<span style="color: {color}">**{step.keyword}**</span> {step.text}' # Ajouter deux espaces à la fin pour forcer un line break en markdown
result = f'{indent}<span style="color: {color}">**{step.keyword}**</span> {step.text} '
if step.table: if step.table:
result += "\n\n" result += "\n\n"