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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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) |
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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`)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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é
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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** :
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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é"`)
|
||||||
|
|||||||
@@ -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"]`
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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€
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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]`
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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é)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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é
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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é
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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é
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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é
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
167
mkdocs.yml
167
mkdocs.yml
@@ -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 Confidentialité: 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
58
scripts/fix-markdown-lists.sh
Executable 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)"
|
||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user