diff --git a/docs/regles-metier/17-premium.md b/docs/regles-metier/17-premium.md index 9c2aa13..2c23233 100644 --- a/docs/regles-metier/17-premium.md +++ b/docs/regles-metier/17-premium.md @@ -35,38 +35,107 @@ ### 10.2 Multi-devices et détection simultanée -**Décision** : 1 seul stream actif par compte à tout moment +**Décision** : 1 seul stream actif par compte à tout moment - Priorité au dernier device (KISS) -**Détection connexion simultanée** : +**Règle simple** : Le dernier device à démarrer prend toujours la priorité, sans exception temporelle ni géolocalisation. +#### Comportement multi-devices + +| Scénario | Device 1 | Device 2 | Résultat | Message Device 1 | +|----------|----------|----------|----------|------------------| +| **Transition normale** | Écoute online | Démarre 5s après | Device 1 coupé, Device 2 actif | "Lecture interrompue : compte utilisé sur autre appareil" | +| **Offline connecté internet** | Écoute offline (avec WiFi) | Démarre online | Device 1 coupé, Device 2 actif | Même message | +| **Offline déconnecté internet** | Écoute offline (mode avion) | Démarre online | Device 1 continue, Device 2 actif | Pas de détection possible (exception technique) | + +#### Implémentation technique détaillée + +**1. Stream online** : ``` -User A écoute sur iPhone -→ User A lance sur iPad -→ Détection : session active iPhone existe -→ Action : Arrêt lecture iPhone (WebSocket close) -→ Message iPhone : "Lecture interrompue : votre compte est utilisé sur un autre appareil" -→ Lecture démarre iPad +Device 1 écoute online +→ Heartbeat 30s vers serveur +→ Redis : active_streams:{user_id} = {device_id: "iPhone_123", started_at: timestamp} +→ TTL : 5 minutes + +Device 2 démarre +→ Détection : active_stream existe +→ Action : Envoi WebSocket close à Device 1 +→ Redis : mise à jour active_streams:{user_id} = {device_id: "iPad_456", started_at: timestamp} +→ Device 2 lecture démarre ``` -**Implémentation technique** : - +**2. Offline connecté internet** : ``` -Redis : active_streams:{user_id} → {device_id, started_at} -TTL : 5 minutes (refresh à chaque heartbeat) - -Heartbeat toutes les 30s depuis app : -→ Si autre device détecté : kill session actuelle -→ Si pas de heartbeat pendant 5 min : considérer session morte +Device 1 écoute offline MAIS connecté WiFi/4G +→ Heartbeat 30s envoyé quand même +→ Redis : active_streams:{user_id} = {device_id: "iPhone_123", started_at: timestamp, mode: "offline"} +→ Même mécanique que online : Device 2 coupe Device 1 ``` -**Exceptions** : -- Contenus téléchargés (offline) ne comptent pas comme stream actif -- Transition rapide device (<10s) tolérée (changement voiture → maison) +**3. Offline déconnecté internet** : +``` +Device 1 vraiment offline (mode avion, tunnel) +→ Pas de heartbeat possible +→ Redis : aucune entrée OU expiration TTL après 5 min +→ Device 2 démarre : pas de détection Device 1 +→ "Tant pis" (exception technique acceptable) +``` -**Justification** : -- **Anti-partage compte** : empêche 2 personnes d'utiliser même compte Premium -- **Protection revenus créateurs** : 1 abonnement = 1 personne = 1 écoute -- **UX claire** : message explicite, pas de coupure brutale +#### Message utilisateur (device coupé) + +``` +┌────────────────────────────────────────┐ +│ ⚠️ Lecture interrompue │ +├────────────────────────────────────────┤ +│ Votre compte est utilisé sur un │ +│ autre appareil. │ +│ │ +│ Un seul appareil peut écouter à la │ +│ fois avec votre compte Premium. │ +│ │ +│ Le partage de compte viole nos CGU │ +│ et peut entraîner une suspension. │ +│ │ +│ [Reprendre ici] [Sécuriser mon compte] │ +└────────────────────────────────────────┘ +``` + +**Boutons** : +- **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 + +#### Limite offline 30 jours + +**Référence** : [08-mode-offline.md](08-mode-offline.md) section 11.2 + +``` +Contenus téléchargés valides 30 jours +→ Après 30j sans connexion : contenus bloqués +→ Reconnexion WiFi : renouvellement auto si <30j +→ Notification J-3 : "X contenus expirent dans 3 jours" +``` + +**Cohérence** : User offline déconnecté >30j ne peut plus écouter → force reconnexion → détection multi-devices redevient possible. + +#### Détection abus (post-MVP) + +Monitoring patterns suspects (backend analytics) : +- >10 changements devices/jour (suspect) +- Connexions alternées 2 villes éloignées répétées +- Signalements users : "je n'ai jamais été à Marseille" + +Action : +→ Email investigation : "Activité suspecte, sécurisez votre compte" +→ Si confirmé partage : suspension 7j + warning +→ Récidive : ban définitif + +**Pas d'action automatique** (évite faux positifs), juste flag modération manuelle. + +**Justification KISS** : +- ✅ **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 +- ✅ **Message dissuasif clair** : avertissement CGU dans message coupure, possibilité "Sécuriser compte" si suspicion piratage +- ✅ **Protection revenus créateurs** : 1 abonnement = 1 personne = 1 écoute active +- ✅ **UX claire** : message explicite, user comprend immédiatement ---