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.
This commit is contained in:
225
docs/domains/premium/rules/mode-offline.md
Normal file
225
docs/domains/premium/rules/mode-offline.md
Normal file
@@ -0,0 +1,225 @@
|
||||
## 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 |
|
||||
|
||||
---
|
||||
Reference in New Issue
Block a user