Files
roadwave/docs/domains/premium/rules/mode-offline.md
jpgiannetti 5e5fcf4714 refactor(docs): réorganiser la documentation selon principes DDD
Réorganise la documentation du projet selon les principes du Domain-Driven Design (DDD) pour améliorer la cohésion, la maintenabilité et l'alignement avec l'architecture modulaire du backend.

**Structure cible:**
```
docs/domains/
├── README.md (Context Map)
├── _shared/ (Core Domain)
├── recommendation/ (Supporting Subdomain)
├── content/ (Supporting Subdomain)
├── moderation/ (Supporting Subdomain)
├── advertising/ (Generic Subdomain)
├── premium/ (Generic Subdomain)
└── monetization/ (Generic Subdomain)
```

**Changements effectués:**

Phase 1: Création de l'arborescence des 7 bounded contexts
Phase 2: Déplacement des règles métier (01-19) vers domains/*/rules/
Phase 3: Déplacement des diagrammes d'entités vers domains/*/entities/
Phase 4: Déplacement des diagrammes flux/états/séquences vers domains/*/
Phase 5: Création des README.md pour chaque domaine
Phase 6: Déplacement des features Gherkin vers domains/*/features/
Phase 7: Création du Context Map (domains/README.md)
Phase 8: Mise à jour de mkdocs.yml pour la nouvelle navigation
Phase 9: Correction automatique des liens internes (script fix-markdown-links.sh)
Phase 10: Nettoyage de l'ancienne structure (regles-metier/, diagrammes/, features/)

**Configuration des tests:**
- Makefile: godog run docs/domains/*/features/
- scripts/generate-bdd-docs.py: features_dir → docs/domains

**Avantages:**
 Cohésion forte: toute la doc d'un domaine au même endroit
 Couplage faible: domaines indépendants, dépendances explicites
 Navigabilité améliorée: README par domaine = entrée claire
 Alignement code/docs: miroir de backend/internal/
 Onboarding facilité: exploration domaine par domaine
 Tests BDD intégrés: features au plus près des règles métier

Voir docs/REFACTOR-DDD.md pour le plan complet.
2026-02-07 17:15:02 +01:00

226 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 11. Mode offline
### 11.1 Téléchargement
**Zone géographique** : Choix manuel utilisateur
**Options prédéfinies** :
- "Autour de moi" (rayon 50 km position actuelle)
- "Ma ville" (limite administrative détectée)
- "Mon département" (sélection liste)
- "Ma région" (sélection liste)
- Recherche manuelle : "Paris", "Lyon", "Marseille", etc.
**Nombre de contenus téléchargeables** :
| Statut | Limite | Affichage |
|--------|--------|-----------|
| **Gratuit** | 50 contenus max | "12/50 contenus téléchargés" |
| **Premium** | Illimité | "245 contenus (3.2 GB)" |
**Calcul temps disponible** :
- 50 contenus × 5 min moyenne = 250 min = **4h d'écoute** (suffisant pour gratuits)
- Premium illimité = limité uniquement par espace disque device
**Connexion WiFi/Mobile** :
**Par défaut** : WiFi uniquement
**Sur données mobiles** :
1. User clique "Télécharger"
2. Détection : pas de WiFi
3. Popup : "Vous n'êtes pas connecté en WiFi. Télécharger via données mobiles consommera environ **X MB**. Continuer ?"
4. Boutons : "Attendre WiFi" / "Continuer"
**Calcul estimation** :
```
Nombre contenus × durée moyenne × bitrate qualité
Exemple : 20 contenus × 5 min × 48 kbps = ~72 MB
```
**Qualité audio téléchargement** :
| Qualité | Bitrate | Taille | Disponibilité |
|---------|---------|--------|---------------|
| **Basse** | 24 kbps | ~10 MB/h | Gratuit + Premium |
| **Standard** | 48 kbps | ~20 MB/h | Gratuit + Premium (défaut) |
| **Haute** | 64 kbps | ~30 MB/h | **Premium uniquement** |
**Justification** :
- Standard = bon compromis qualité/taille (Opus 48 kbps = très correct pour voix)
- Haute réservée Premium = incitation upgrade
- User peut réduire à "basse" si espace limité
---
### 11.2 Validité et renouvellement
**Durée de validité** : 30 jours après téléchargement
**Standard industrie** :
- Spotify : 30 jours
- YouTube Music : 30 jours
- Deezer : 30 jours
**Renouvellement automatique** :
```
App détecte WiFi + contenus >25 jours
→ Requête API : GET /offline/contents/refresh
→ Backend vérifie pour chaque contenu :
- Abonnement Premium toujours actif ?
- Contenu pas modéré/supprimé ?
- Métadonnées à jour ?
→ Renouvelle validité à 30 jours supplémentaires
→ Mise à jour métadonnées (titre, créateur, statut)
→ Pas de re-téléchargement audio (sauf si fichier corrompu)
```
**Notification avant expiration** :
- **J-3** : "X contenus expirent dans 3 jours. Connectez-vous en WiFi pour les renouveler"
- **J-0** : Suppression automatique
- **J+0** : Toast "15 contenus expirés ont été supprimés"
**Justification** :
- **Force reconnexion** : vérifier abonnement actif, contenus légaux
- **Évite stockage obsolète** : contenus supprimés/modérés ne restent pas
- **UX transparente** : renouvellement silencieux si WiFi régulier
---
### 11.3 Synchronisation actions offline
**Actions stockées localement (SQLite)** :
- Likes/unlikes
- Abonnements/désabonnements
- Signalements
- Progression audio-guides
**Sync automatique à la reconnexion** :
```
1. App détecte reconnexion Internet
2. Récupération queue locale : SELECT * FROM pending_actions ORDER BY created_at
3. Envoi batch API : POST /sync/actions
4. Backend traite chaque action
5. Confirmation réception : DELETE FROM pending_actions WHERE id IN (...)
6. Toast : "3 likes et 1 abonnement synchronisés"
```
**Gestion erreurs sync** :
- Si échec après 3 tentatives → notification : "Impossible de synchroniser. Réessayez plus tard"
- Actions conservées jusqu'à sync réussie (pas de perte)
- **Rétention max 7 jours** : après = purge (évite queue infinie)
**Justification** :
- **Pas de conflit possible** : actions unilatérales user (likes/abonnements)
- **UX fluide** : pas de blocage offline
- **Batch = économie** : requêtes HTTP groupées
---
### 11.4 Contenus supprimés pendant offline
**Problème** : Que se passe-t-il si un utilisateur télécharge des contenus, part offline plusieurs jours, et pendant ce temps certains contenus sont supprimés par les créateurs ou la modération ?
**Décision** : Suppression immédiate à la reconnexion (Option A - KISS)
#### Processus de synchronisation
```
User se reconnecte (WiFi détecté)
1. API sync : GET /offline/validate
Backend retourne :
{
"valid_ids": [id1, id2, id3, ...],
"deleted_ids": [id10, id12, id15],
"metadata_updates": [{id: id5, new_title: "..."}]
}
2. App mobile compare avec contenus locaux :
- valid_ids : renouvelle validité 30j
- deleted_ids : suppression immédiate fichiers locaux
- metadata_updates : mise à jour titre/créateur/tags
3. Notification user :
Toast : "3 contenus supprimés ont été retirés"
```
#### Gestion contenu en cours d'écoute
**Si contenu supprimé en cours de lecture** :
```
┌────────────────────────────────────────┐
│ Contenu supprimé │
├────────────────────────────────────────┤
│ Ce contenu n'est plus disponible │
│ et a été retiré par le créateur. │
│ │
│ Passage au contenu suivant... │
│ │
│ [OK] │
└────────────────────────────────────────┘
→ Lecture s'arrête
→ Fichier supprimé localement
→ Passage automatique au contenu suivant (après 2s)
```
#### Message récapitulatif
**Si plusieurs contenus supprimés** :
```
┌────────────────────────────────────────┐
│ Contenus supprimés │
├────────────────────────────────────────┤
│ 3 contenus téléchargés ne sont plus │
│ disponibles et ont été retirés. │
│ │
│ Les créateurs peuvent supprimer ou │
│ modifier leurs contenus à tout moment. │
│ │
│ [Voir la liste] [OK] │
└────────────────────────────────────────┘
```
**Bouton "Voir la liste"** :
- Affiche titres + créateurs des contenus supprimés
- Permet comprendre ce qui a disparu
- Historique conservé 7 jours (puis purge)
**Justification KISS** :
-**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
-**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é
**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 = "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
**Mais attendre feedback réel avant d'ajouter cette complexité.**
---
## Récapitulatif Section 11
| Aspect | Décision | Valeur |
|--------|----------|--------|
| **Zone téléchargement** | Choix | Manuel (autour/ville/département/région/recherche) |
| **Limite gratuit** | Contenus | 50 max |
| **Limite Premium** | Contenus | Illimité (espace disque) |
| **Connexion** | Par défaut | WiFi (mobile avec confirmation) |
| **Qualité Standard** | Bitrate | 48 kbps Opus |
| **Qualité Haute** | Bitrate | 64 kbps (Premium uniquement) |
| **Validité** | Durée | 30 jours |
| **Renouvellement** | Mode | Automatique si WiFi |
| **Notification expiration** | Délai | J-3 |
| **Sync actions** | Mode | Batch automatique reconnexion |
| **Rétention queue** | Durée | 7 jours max |
---