feat(bdd): réorganiser features en catégories api/ui/e2e et créer ADR-024

Résolution des incohérences #10, #11, et #12 de l'analyse d'architecture.

## Phase 1 : Réorganisation Features BDD (Point #10 - RÉSOLU)

- Créer structure features/{api,ui,e2e}
- Déplacer 83 features en 3 catégories via git mv (historique préservé)
  - features/api/ : 53 features (tests API backend)
  - features/ui/ : 22 features (tests UI mobile)
  - features/e2e/ : 8 features (tests end-to-end)

Domaines déplacés :
- API : authentication, recommendation, rgpd-compliance, content-creation,
  moderation, monetisation, premium, radio-live, publicites
- UI : audio-guides, navigation, interest-gauges, mode-offline,
  partage, profil, recherche
- E2E : abonnements, error-handling

## Phase 2 : Mise à jour Documentation

### ADR-007 - Tests BDD
- Ajouter section "Convention de Catégorisation des Features"
- Documenter règles api/ui/e2e avec exemples concrets
- Spécifier step definitions (backend Go, mobile Dart)

### ADR-024 - Stratégie CI/CD Monorepo (NOUVEAU)
- Créer ADR dédié pour stratégie CI/CD avec path filters
- Architecture workflows séparés (backend.yml, mobile.yml, shared.yml)
- Configuration path filters détaillée avec exemples YAML
- Matrice de déclenchement et optimisations (~70% gain temps CI)
- Plan d'implémentation (~2h, reporté jusqu'au développement)

### ADR-016 - Organisation Monorepo
- Simplifier en retirant section CI/CD détaillée
- Ajouter référence vers ADR-024 pour stratégie CI/CD

### INCONSISTENCIES-ANALYSIS.md
- Point #10 (Tests BDD synchronisés) :  RÉSOLU
  - Catégorisation features implémentée
  - ADR-007 mis à jour avec convention complète
- Point #11 (70/30 Split paiements) :  ANNULÉ (faux problème)
  - ADR-009 et Règle 18 parfaitement cohérents
  - Documentation exhaustive existante (formule, SQL, comparaisons)
- Point #12 (Monorepo path filters) : ⏸️ DOCUMENTÉ
  - Architecture CI/CD complète dans ADR-024
  - Implémentation reportée (projet en phase documentation)
- Métriques mises à jour :
  - MODERATE : 6/9 traités (4 résolus + 1 annulé + 1 documenté)
  - ADR à jour : 100% (19/19 avec ADR-024)

## Phase 3 : Validation

- Structure features validée (api/ui/e2e, aucun répertoire restant)
- Historique Git préservé (git mv, renommages détectés)
- 83 features total (API: 53, UI: 22, E2E: 8)

Closes: Point #10 (résolu), Point #11 (annulé), Point #12 (documenté)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
jpgiannetti
2026-02-01 11:31:41 +01:00
parent 841028d1b2
commit 37c62206ad
88 changed files with 625 additions and 67 deletions

View File

@@ -0,0 +1,206 @@
# language: fr
Fonctionnalité: Partage de contenu
En tant qu'utilisateur de RoadWave
Je veux pouvoir partager du contenu audio
Afin de faire découvrir l'application à d'autres personnes
Contexte:
Étant donné que l'application RoadWave est démarrée
Et que l'utilisateur "jean@example.com" est connecté
# 15.1.1 - Bouton "Partager"
Scénario: Bouton partager disponible dans le player en lecture
Étant donné que le contenu "Balade à Paris" est en cours de lecture
Quand l'utilisateur consulte les contrôles du player
Alors le bouton "Partager" est visible
Scénario: Bouton partager disponible sur la page profil créateur
Étant donné que l'utilisateur consulte le profil de "@paris_stories"
Quand l'utilisateur consulte un contenu dans la liste
Alors le bouton "Partager" est disponible pour chaque contenu
Scénario: Bouton partager dans la liste de recherche
Étant donné que l'utilisateur effectue une recherche "voyage paris"
Quand l'utilisateur ouvre le menu contextuel d'un résultat
Alors l'option "Partager" est disponible
Scénario: Bouton partager dans l'historique personnel
Étant donné que l'utilisateur consulte son historique d'écoute
Quand l'utilisateur sélectionne un contenu de l'historique
Alors le bouton "Partager" est accessible
Plan du Scénario: Menu de partage avec options multiples
Étant donné que le contenu "<contenu>" est disponible
Quand l'utilisateur clique sur le bouton "Partager"
Alors le menu natif OS s'ouvre
Et les options suivantes sont disponibles:
| option |
| Copier le lien |
| WhatsApp |
| Email |
| SMS |
| Plus... |
Exemples:
| contenu |
| Balade à Paris |
| Secrets de Montmartre |
# 15.1.2 - Comportement du lien partagé
Scénario: Génération du lien de partage
Étant donné un contenu avec l'ID "content_12345"
Quand l'utilisateur copie le lien de partage
Alors le lien généré est "https://roadwave.fr/share/c/content_12345"
Scénario: Ouverture du lien partagé avec l'application installée (Deep link)
Étant donné que l'application RoadWave est installée sur l'appareil
Et qu'un lien "https://roadwave.fr/share/c/content_12345" est partagé
Quand l'utilisateur clique sur le lien
Alors l'application RoadWave s'ouvre automatiquement
Et le contenu "content_12345" commence à jouer
Scénario: Ouverture du lien partagé sans l'application installée (Web player)
Étant donné que l'application RoadWave n'est pas installée
Et qu'un lien "https://roadwave.fr/share/c/content_12345" est partagé
Quand l'utilisateur clique sur le lien
Alors une page web responsive s'affiche
Et le web player HTML5 est visible
Et les boutons de téléchargement App Store et Google Play sont affichés
Scénario: Contenu de la page web de partage
Étant donné un contenu public avec les métadonnées suivantes:
| champ | valeur |
| titre | Balade à Paris |
| créateur | @paris_stories |
| durée | 12 min |
| écoutes | 2300 |
| localisation | Paris 5e |
| type_geo | Ancré |
| tags | Voyage, Histoire |
Quand la page de partage est affichée
Alors la page contient:
| élément |
| Cover image 16:9 |
| Titre "Balade à Paris" |
| "@paris_stories" |
| "12 min · 🎧 2.3K" |
| "📍 Paris 5e · Ancré" |
| "🏷 #Voyage #Histoire" |
| Description |
| Player HTML5 |
| Bouton App Store |
| Bouton Google Play |
Scénario: Métadonnées Open Graph pour partage social
Étant donné un contenu "Balade à Paris" par "@paris_stories"
Quand la page de partage est générée
Alors les métadonnées Open Graph incluent:
| propriété | valeur |
| og:title | Balade à Paris - RoadWave |
| og:description | Écoutez ce contenu par @paris_stories |
| og:type | music.song |
| og:site_name | RoadWave |
| twitter:card | player |
Et l'aperçu s'affiche correctement sur WhatsApp
Et l'aperçu s'affiche correctement sur Facebook
Et l'aperçu s'affiche correctement sur Twitter
Plan du Scénario: Deep linking par plateforme
Étant donné que l'application RoadWave est installée sur <plateforme>
Et qu'un lien de partage est ouvert
Quand le système détecte l'application
Alors l'application s'ouvre via <mécanisme>
Exemples:
| plateforme | mécanisme |
| iOS | Universal Links |
| Android | App Links |
Scénario: Fallback URL scheme pour deep linking
Étant donné que les App Links ne fonctionnent pas
Quand le système tente d'ouvrir le contenu
Alors l'URL scheme "roadwave://content/content_12345" est utilisé
# 15.1.3 - Contenus Premium partagés
Scénario: Badge Premium visible sur le lien partagé
Étant donné un contenu Premium "Visite VIP Louvre"
Quand l'utilisateur non-premium clique sur le lien partagé
Alors la page web affiche le badge "👑 Contenu Premium"
Scénario: Preview 30 secondes d'un contenu Premium partagé
Étant donné un contenu Premium "Visite VIP Louvre" de 15 minutes
Et qu'un utilisateur non-premium ouvre le lien partagé
Quand le player démarre automatiquement
Alors l'audio joue pendant 30 secondes exactement
Et un fade out de 2 secondes est appliqué
Et un overlay "Contenu réservé Premium" s'affiche après 32 secondes
Scénario: Contenu de l'overlay paywall Premium
Étant donné qu'un contenu Premium a atteint la limite de 30 secondes
Quand l'overlay paywall s'affiche
Alors le texte suivant est visible:
"""
👑 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]
"""
Scénario: Actions disponibles sur l'overlay Premium
Étant donné que l'overlay paywall Premium est affiché
Quand l'utilisateur consulte les options
Alors les actions suivantes sont disponibles:
| action | comportement |
| Passer Premium | Redirection vers paiement Mangopay web |
| Télécharger l'app | Redirection vers App Store/Google Play |
| Rejouer les 30 premières sec | Relecture illimitée du preview |
Scénario: Relecture illimitée du preview Premium
Étant donné un contenu Premium partagé
Et que l'utilisateur a écouté les 30 premières secondes
Quand l'utilisateur clique sur "Rejouer"
Alors les 30 premières secondes sont rejouées
Et cette action est possible de manière illimitée
Scénario: Tracking des partages Premium
Étant donné un créateur "@guide_louvre" avec un contenu Premium
Quand son contenu est partagé
Alors les métriques suivantes sont enregistrées:
| métrique | valeur |
| Partages Premium | +1 |
| Ouvertures lien | compteur |
| Conversions Premium | si souscription |
Scénario: Rémunération créateur sur conversion Premium via partage
Étant donné un contenu Premium partagé par "@guide_louvre"
Quand un utilisateur s'abonne via le lien partagé
Alors le créateur reçoit 70% des revenus de cet abonnement
Et la conversion est trackée dans son dashboard
# Cas d'erreur
Scénario: Partage d'un contenu supprimé
Étant donné qu'un lien de partage "https://roadwave.fr/share/c/deleted_content" est ouvert
Et que le contenu n'existe plus
Quand la page web se charge
Alors un message "Ce contenu n'est plus disponible" s'affiche
Et les boutons de téléchargement de l'app sont affichés
Scénario: Partage d'un contenu en attente de modération
Étant donné un contenu en cours de validation modération
Quand un lien de partage est ouvert
Alors le message "Ce contenu est en cours de validation" s'affiche
Scénario: Génération du lien hors connexion
Étant donné que l'utilisateur n'a pas de connexion réseau
Quand l'utilisateur tente de partager un contenu
Alors le lien est copié dans le presse-papiers
Et un message "Lien copié (nécessite connexion pour ouvrir)" s'affiche