Files
roadwave/docs/regles-metier/19-autres-comportements.md
2026-01-31 11:45:11 +01:00

23 KiB
Raw Blame History

15. Autres comportements

15.1 Partage de contenu

Décision : Système de partage complet avec web player

15.1.1 Bouton "Partager"

Disponibilité : Partout dans l'application

Emplacements :

  • Player en lecture (bouton dans contrôles)
  • Page profil créateur (sur chaque contenu)
  • Liste de recherche (menu contextuel)
  • Historique personnel

Icône : ⬆️ (universelle iOS/Android)

Menu options :

  • Copier le lien
  • WhatsApp
  • Email
  • SMS
  • Plus... (sheet natif OS)

Justification :

  • Viralité = croissance organique gratuite
  • Aucune friction, partage universel

15.1.2 Comportement du lien partagé

Format URL : https://roadwave.fr/share/c/[content_id]

Comportement multi-plateforme :

User clique lien partagé
    ↓
Page web responsive
    ↓
┌─────────────────────────────────┐
│ Si app installée                │
│ → Deep link (ouverture directe) │
└─────────────────────────────────┘
    ↓
┌─────────────────────────────────┐
│ Si app non installée             │
│ → Web player + CTA téléchargement│
└─────────────────────────────────┘

Contenu de la page web :

┌───────────────────────────────────────┐
│ RoadWave                              │
├───────────────────────────────────────┤
│ [Image cover 16:9]                    │
│                                       │
│ 📻 Titre du contenu                   │
│ Par @créateur · 12 min · 🎧 2.3K      │
│                                       │
│ 📍 Paris 5e · Ancré                   │
│ 🏷️ #Voyage #Histoire                  │
│                                       │
│ Description : Lorem ipsum...          │
│                                       │
│ [▶️ Écouter maintenant]               │
│ (Player HTML5 si contenu public)      │
│                                       │
│ ──────────────────────────────────    │
│                                       │
│ 📱 Télécharger l'app RoadWave         │
│ [App Store] [Google Play]             │
│                                       │
│ [Voir le profil de @créateur]         │
└───────────────────────────────────────┘

Métadonnées Open Graph (SEO) :

<meta property="og:title" content="[Titre contenu] - RoadWave">
<meta property="og:description" content="[Description ou extrait]">
<meta property="og:image" content="[URL cover image]">
<meta property="og:audio" content="[URL audio si public]">
<meta property="og:type" content="music.song">
<meta property="og:site_name" content="RoadWave">
<meta name="twitter:card" content="player">
<meta name="twitter:player" content="https://roadwave.fr/player/[content_id]">

Deep linking :

  • iOS : Universal Links (configuration apple-app-site-association)
  • Android : App Links (configuration assetlinks.json)
  • URL scheme : roadwave://content/[content_id]

Justification :

  • Meilleure viralité (partage social optimisé)
  • SEO (contenus indexés Google)
  • UX optimale (web + app)
  • Coût : 0€ (backend simple + CDN existant)

15.1.3 Contenus Premium partagés

Décision : Preview 30 secondes + paywall

Comportement :

  1. User clique lien contenu Premium partagé
  2. Page web affiche badge "👑 Contenu Premium"
  3. Player démarre automatiquement
  4. Après 30 secondes exactement :
    • Fade out audio (2 secondes)
    • Overlay apparaît :
┌─────────────────────────────────┐
│ 👑 Contenu réservé Premium      │
│                                 │
│ Profitez de ce contenu complet  │
│ et de milliers d'autres         │
│ sans publicité                  │
│                                 │
│ [Passer Premium - 4.99€/mois]   │
│ [Télécharger l'app]             │
└─────────────────────────────────┘
  1. Utilisateur peut :
    • S'abonner Premium (redirection web Mangopay)
    • Télécharger l'app (redirection stores)
    • Rejouer les 30 premières secondes (illimité)

Tracking :

  • Métriques créateur : "Partages Premium" + "Conversions Premium"
  • Créateur touche sa part si conversion (70%)

Justification :

  • Équilibre viralité / monétisation
  • 30s = assez pour donner envie, pas assez pour satisfaire
  • Protège revenus créateurs

15.2 Profil créateur

Décision : Profil public complet et transparent

15.2.1 Structure de la page profil

URL : https://roadwave.fr/@[pseudo]

Layout :

┌────────────────────────────────────────┐
│ [Photo profil 120×120]                 │
│ @pseudo ✓                              │
│ [Badge vérifié si applicable]          │
│                                        │
│ Bio : Lorem ipsum dolor sit amet...    │
│ (300 caractères max)                   │
│                                        │
│ 🎧 1.2K abonnés                        │
│ 📻 42 contenus                         │
│ ⏱️ 18h de contenu créé                 │
│ 🔊 54K écoutes totales                 │
│                                        │
│ [S'abonner] [Partager profil] [•••]   │
│                                        │
│ ────────────────────────────────────   │
│                                        │
│ Contenus ▼ [Plus récents ▼]           │
│                                        │
│ ┌──────────────────────────────────┐  │
│ │ [Cover] Titre contenu 1           │  │
│ │ 12 min · 🎧 2.3K · 📍 Paris       │  │
│ │ [▶️]                              │  │
│ └──────────────────────────────────┘  │
│                                        │
│ ┌──────────────────────────────────┐  │
│ │ [Cover] Titre contenu 2           │  │
│ │ 8 min · 🎧 5.1K · 📍 Lyon         │  │
│ │ [▶️]                              │  │
│ └──────────────────────────────────┘  │
│                                        │
│ [Charger plus]                         │
└────────────────────────────────────────┘

Informations affichées :

Élément Visibilité Détails
Photo + pseudo Public Identité visuelle
Badge vérifié ✓ Public (si applicable) Compte authentique
Bio Public 0-300 caractères, markdown basique (gras, italique, liens)
Nombre abonnés Public Arrondi si >1000 (ex: 1.2K, 54K)
Nombre contenus Public Exact
Durée totale créée Public Arrondi en heures (ex: 18h, 142h)
Écoutes totales Public Arrondi (ex: 54K, 1.2M)
Liste abonnés Privé Protection vie privée (RGPD)
Revenus Privé Confidentialité financière
Localisation précise Privé Sécurité
Email Privé Anti-spam

Tri des contenus :

Option Comportement
Plus récents Date publication DESC (défaut)
Plus populaires Écoutes complètes × (1 + (date_publication - now) / 90 jours)
Plus anciens Date publication ASC
Par tag Filtre multi-sélection tags

Recherche locale :

  • Barre recherche dans profil : "Rechercher dans les contenus de @pseudo"
  • Recherche full-text sur titres + descriptions

Actions menu [•••] :

  • Partager profil
  • Signaler profil (spam, usurpation)
  • Bloquer créateur (masque tous ses contenus)

15.2.2 Statistiques publiques

Décision : Stats arrondies et motivantes

Affichage public :

Métrique Format affichage Exemple
Abonnés Exact si <1000, arrondi sinon 342 / 1.2K / 54K / 1.2M
Écoutes totales Arrondi dès 1000 842 / 5.4K / 142K / 2.1M
Contenus publiés Exact 42 contenus
Durée totale Arrondi en heures 18h / 142h de contenu

Métriques PRIVÉES (créateur uniquement) :

Métrique Disponible dans dashboard créateur
Taux complétion moyen 78% (écoutes >80% / écoutes totales)
Évolution abonnés Graphique 30j / 90j / 1 an
Écoutes par contenu Tableau détaillé
Revenus Dashboard monétisation dédié
Taux conversion Premium Partages → conversions
Démographie Âge / zone géo (agrégée, anonymisée)

Justification :

  • Arrondi = évite comparaisons anxiogènes
  • Preuve sociale pour nouveaux auditeurs (trust)
  • Gamification douce (motivation créateurs)
  • Privacy by design

15.2.3 Badge vérifié

Décision : Badge unique ✓ (vérifié officiel)

Critères d'attribution (au moins UN des critères) :

  1. KYC monétisation validé : identité vérifiée via Mangopay KYC
  2. Célébrité / Média officiel : validation manuelle équipe RoadWave
  3. Communauté significative : ≥10K abonnés + compte actif >6 mois

Affichage :

  • Badge bleu accolé au pseudo (partout : profil, player, recherche)
  • Tooltip au survol/appui long : "Compte vérifié"

Processus d'obtention :

Type Processus
Automatique (KYC) Badge attribué dès validation documents Mangopay
Manuel (célébrité) Formulaire demande → équipe vérifie identité → validation 48-72h
Automatique (10K) Badge attribué automatiquement à 10K abonnés si compte >6 mois

Retrait du badge :

  • Suspension monétisation → badge retiré temporairement
  • Strikes multiples → badge retiré définitivement
  • Usurpation identité détectée → ban + retrait

Justification :

  • Combat usurpations d'identité
  • Trust auditeurs (surtout pour médias/personnalités)
  • Simplicité (1 seul badge, pas de gamification excessive)
  • Coût : 0€ (champ boolean verified en DB)

15.3 Recherche

Décision : Recherche full-text + géo + filtres avancés

15.3.1 Recherche par mot-clé

Implémentation : PostgreSQL full-text search (français)

Configuration technique :

-- Index full-text optimisé français
CREATE INDEX idx_content_search ON contents
USING GIN(
    to_tsvector('french',
        coalesce(title, '') || ' ' ||
        coalesce(description, '') || ' ' ||
        coalesce(creator_pseudo, '')
    )
);

-- Recherche avec ranking
SELECT
    c.*,
    ts_rank(
        to_tsvector('french', c.title || ' ' || c.description),
        plainto_tsquery('french', $search_query)
    ) AS rank
FROM contents c
WHERE to_tsvector('french', c.title || ' ' || c.description)
      @@ plainto_tsquery('french', $search_query)
ORDER BY rank DESC, listen_count DESC
LIMIT 20;

Champs indexés :

  • Titre du contenu (poids × 3)
  • Description (poids × 1)
  • Pseudo créateur (poids × 2)
  • Tags (poids × 1.5)

Fonctionnalités :

Feature Description
Stemming français "voyages" trouve "voyage", "voyager", etc.
Correction auto Suggestion si 0 résultat
Recherches populaires "Essayez plutôt : balade paris, audio-guide louvre"
Historique personnel 10 dernières recherches sauvegardées
Autocomplete Suggestions pendant frappe (top 5)

Coût : 0€ (PostgreSQL natif)

Migration future :

  • Si >100K contenus : Meilisearch (typo-tolerance avancée, ~20-50€/mois)
  • Si >1M contenus : Elasticsearch cluster

Justification :

  • PostgreSQL full-text = performant jusqu'à 500K contenus
  • Stemming français natif
  • 0€, aucune dépendance externe

15.3.2 Recherche géographique

Décision : Recherche lieu + rayon paramétrable

Interface utilisateur :

┌─────────────────────────────────────┐
│ 🔍 Recherche contenu...             │
├─────────────────────────────────────┤
│ <20><> Lieu                             │
│ [Paris, France              ▼]     │
│ · Autour de moi (GPS actuel)       │
│ · Entrer une adresse/ville         │
│                                     │
│ 📏 Rayon de recherche               │
│ [●─────────────────] 50 km         │
│ (curseur 5 km → 500 km)            │
│                                     │
│ 🗺️ [Afficher sur carte]            │
└─────────────────────────────────────┘

Géocodage :

Service Usage Coût
Nominatim (OSM) MVP (API publique) 0€ (rate limit 1 req/s)
Nominatim self-hosted Scale (Docker) 20-50€/mois VPS
Mapbox Geocoding Fallback premium 0.50€ / 1000 requêtes

Processus de recherche géo :

  1. User tape "Louvre" ou "Paris"
  2. Autocomplete via Nominatim → liste suggestions
  3. User sélectionne → récupération coordonnées (lat, lon)
  4. Requête PostGIS :
SELECT c.*,
       ST_Distance(c.location::geography, ST_Point($lon, $lat)::geography) AS distance
FROM contents c
WHERE ST_DWithin(
    c.location::geography,
    ST_Point($lon, $lat)::geography,
    $radius_meters
)
ORDER BY distance ASC;

Affichage résultats :

  • Tri par défaut : distance croissante
  • Indication distance : "À 2.3 km" / "À 15 km" / "À 142 km"
  • Option carte : markers cliquables (clustering si >50 résultats)

Coût :

  • MVP : 0€ (Nominatim public)
  • Scale : 20-50€/mois (Nominatim self-hosted Docker)

Justification :

  • Essentiel pour tourisme / planification trajet
  • OpenStreetMap = pas de dépendance Google
  • PostGIS = performant (index GIST natif)

15.3.3 Filtres avancés

Décision : 7 catégories de filtres combinables

Interface filtres :

┌─────────────────────────────────────┐
│ Filtres                        [×]  │
├─────────────────────────────────────┤
│ Type de contenu                     │
│ ☐ Contenu court (<5 min)            │
│ ☐ Podcast (>5 min)                  │
│ ☐ Radio live                        │
│ ☐ Audio-guide                       │
│                                     │
│ Durée                               │
│ ○ Toutes durées                     │
│ ○ <5 min                            │
│ ○ 5-15 min                          │
│ ○ 15-30 min                         │
│ ○ >30 min                           │
│                                     │
│ Classification âge                  │
│ ☐ Tout public                       │
│ ☐ 13+                               │
│ ☐ 16+                               │
│ ☐ 18+                               │
│                                     │
│ Géo-pertinence                      │
│ ☐ Ancré (lieu précis)               │
│ ☐ Contextuel (zone large)           │
│ ☐ Neutre (national)                 │
│                                     │
│ Tags (multi-sélection)              │
│ ☐ Automobile   ☐ Voyage             │
│ ☐ Famille      ☐ Histoire           │
│ ☐ Économie     ☐ Sciences           │
│ ... (liste complète tags)           │
│                                     │
│ Date de publication                 │
│ ○ Toutes dates                      │
│ ○ Dernières 24h                     │
│ ○ Cette semaine                     │
│ ○ Ce mois                           │
│ ○ Cette année                       │
│                                     │
│ Abonnement                          │
│ ○ Tous les contenus                 │
│ ○ Gratuits uniquement               │
│ ○ Premium uniquement 👑             │
│                                     │
│ ──────────────────────────────      │
│ [Réinitialiser] [Appliquer]         │
└─────────────────────────────────────┘

Options de tri :

Tri Algorithme
Pertinence Score recherche × (1 + log(listen_count + 1))
Popularité Écoutes complètes derniers 30j DESC
Récent Date publication DESC
Proximité Distance GPS ASC (si recherche géo active)
Durée Durée audio ASC ou DESC

Sauvegarde de recherches :

  • Bouton "💾 Sauvegarder cette recherche"
  • Nom personnalisable : "Podcasts voyage Paris"
  • Maximum 5 recherches sauvegardées
  • Accès rapide : onglet "Recherches sauvegardées" dans page recherche
  • Notifications optionnelles : "3 nouveaux contenus dans 'Podcasts voyage Paris'"

Performances :

-- Index composites pour filtres
CREATE INDEX idx_content_filters ON contents (
    content_type,
    duration,
    age_rating,
    geo_type,
    published_at
);

-- Index GIN pour tags
CREATE INDEX idx_content_tags ON contents USING GIN(tags);

Coût : 0€ (PostgreSQL + index standards)

Justification :

  • Filtres essentiels pour découvrabilité
  • Combinables = puissance maximale
  • Sauvegarde = gain temps utilisateurs réguliers

15.3.4 Page de résultats

Décision : Liste avec previews enrichies

Layout résultats :

┌─────────────────────────────────────────┐
│ 🔍 "voyage paris"                       │
│ 42 résultats · Tri : Pertinence ▼       │
│ [Filtres] [Carte]                       │
├─────────────────────────────────────────┤
│ ┌─────────────────────────────────────┐ │
│ │ [Cover     ] Balade à Paris          │ │
│ │ [16:9      ] @paris_stories ✓        │ │
│ │ [Image     ] 12 min · 🎧 2.3K        │ │
│ │              📍 Paris 5e · Ancré     │ │
│ │              🏷️ #Voyage #Histoire    │ │
│ │              [▶️ Écouter] [⋮]        │ │
│ └─────────────────────────────────────┘ │
│                                         │
│ ┌─────────────────────────────────────┐ │
│ │ [Cover     ] Secrets Montmartre      │ │
│ │ [16:9      ] @explore_paris          │ │
│ │ [Image     ] 8 min · 🎧 5.1K         │ │
│ │              📍 Paris 18e · Guide    │ │
│ │              🏷️ #Voyage #Art         │ │
│ │              [▶️ Écouter] [⋮]        │ │
│ └─────────────────────────────────────┘ │
│                                         │
│ [Charger plus] (20 suivants)            │
└─────────────────────────────────────────┘

Informations par résultat :

Élément Affichage
Cover image 16:9, 120×68 px, lazy loading
Titre Tronqué 2 lignes max
Créateur @pseudo + badge ✓ si vérifié, cliquable → profil
Durée Format : "3 min" / "12 min" / "1h 24 min"
Écoutes Arrondi : "2.3K" / "54K" / "1.2M"
Localisation Ville + type géo (Ancré/Contextuel/Neutre)
Tags Maximum 3 premiers tags
Badge Premium 👑 si contenu premium
Distance Si recherche géo : "À 2.3 km"

Actions contextuelles [⋮] :

  • Partager
  • Ajouter à une playlist (future feature)
  • Télécharger (offline)
  • Signaler

Pagination :

  • 20 résultats par page
  • Infinite scroll (charger automatiquement si scroll >80%)
  • Bouton "Charger 20 suivants" en bas (fallback si scroll auto désactivé)

Vue carte (alternative) :

  • Bouton toggle "Liste / Carte"
  • Map Leaflet (OpenStreetMap)
  • Markers cliquables → popup avec preview
  • Clustering si >50 résultats proches

Coût : 0€ (Leaflet open source + OSM tiles gratuit)

Justification :

  • Équilibre information / compacité
  • Lazy loading = performances
  • Infinite scroll = UX moderne

Récapitulatif Section 15

Point Décision Coût Complexité
15.1.1 Bouton partager Disponible partout (⬆️), menu natif OS 0€ Faible
15.1.2 Lien partagé Web player + deep link + Open Graph SEO 0€ Moyenne
15.1.3 Premium partagé Preview 30s + paywall overlay 0€ Faible
15.2.1 Page profil Profil public complet (stats + bio + contenus + tri) 0€ Faible
15.2.2 Stats publiques Arrondies (abonnés, écoutes, durée totale) 0€ Faible
15.2.3 Badge vérifié ✓ si KYC/célébrité/>10K abonnés 0€ Faible
15.3.1 Recherche texte PostgreSQL full-text french + stemming 0€ Moyenne
15.3.2 Recherche géo Lieu + rayon (Nominatim OSM) 0-50€/mois Moyenne
15.3.3 Filtres 7 catégories combinables + sauvegarde recherches 0€ Moyenne
15.3.4 Page résultats Liste enrichie + vue carte Leaflet + infinite scroll 0€ Moyenne

Coût total MVP : 0-50€/mois (Nominatim self-hosted optionnel)


Points d'attention pour Gherkin

  • Tester partage contenu public vs Premium (preview 30s)
  • Tester deep linking iOS/Android (ouverture app si installée)
  • Tester Open Graph (aperçu correct sur WhatsApp, Twitter, Facebook)
  • Tester profil public (stats arrondies, badge vérifié)
  • Tester recherche full-text français (stemming, accents)
  • Tester recherche géo + rayon (PostGIS distance)
  • Tester combinaison filtres multiples (AND logic)
  • Tester sauvegarde recherches (max 5)
  • Tester pagination infinite scroll + fallback bouton
  • Tester vue carte Leaflet (clustering, markers cliquables)