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:
jpgiannetti
2026-02-07 17:15:02 +01:00
parent 78422bb2c0
commit 5e5fcf4714
227 changed files with 1413 additions and 1967 deletions

View File

@@ -0,0 +1,226 @@
# language: fr
@api @navigation @anti-spam @mvp
Fonctionnalité: Quota et cooldown pour contenus géolocalisés
En tant que système de navigation
Je veux limiter les notifications géolocalisées à 6 par heure
Et appliquer un cooldown de 10 minutes après refus
Afin d'éviter le spam et préserver l'expérience utilisateur
Contexte:
Étant donné un utilisateur authentifié en mode voiture
Et la géolocalisation est activée
# ============================================================================
# QUOTA 6 NOTIFICATIONS / HEURE (fenêtre glissante)
# ============================================================================
Scénario: Première notification de l'heure sans quota atteint
Étant donné l'utilisateur n'a reçu aucune notification géolocalisée dans les 60 dernières minutes
Et un contenu géolocalisé déclenche une notification (ETA = 7s)
Quand la notification est envoyée
Alors le compteur de quota doit être incrémenté à 1/6
Et un timestamp doit être enregistré pour cette notification
Et la notification doit être affichée normalement
Scénario: Notifications multiples sous le quota
Étant donné l'utilisateur a reçu 3 notifications dans les 60 dernières minutes :
| timestamp | contenu_id |
| 2026-02-03 14:10:00 | content-1 |
| 2026-02-03 14:25:00 | content-2 |
| 2026-02-03 14:40:00 | content-3 |
Et il est maintenant 14:50:00
Et un nouveau contenu géolocalisé déclenche une notification
Quand la notification est évaluée
Alors le compteur doit afficher 4/6
Et la notification doit être envoyée normalement
Scénario: 6ème notification - dernière autorisée
Étant donné l'utilisateur a reçu 5 notifications dans l'heure
Et un nouveau contenu géolocalisé déclenche une notification
Quand la notification est envoyée
Alors le compteur doit afficher 6/6
Et la notification doit être affichée normalement
Et un flag "quota_limit_reached" doit être ajouté aux métriques
Scénario: 7ème notification - quota dépassé
Étant donné l'utilisateur a reçu 6 notifications dans les 60 dernières minutes
Et un nouveau contenu géolocalisé déclenche une notification
Quand le système évalue le quota
Alors la notification ne doit PAS être envoyée
Et le contenu doit être ajouté silencieusement à la file d'attente
Et un événement "notification_blocked_quota" doit être loggé
Et l'utilisateur ne doit voir aucun indicateur visuel de blocage
Scénario: Fenêtre glissante - libération progressive du quota
Étant donné l'utilisateur a reçu 6 notifications :
| timestamp | contenu_id |
| 2026-02-03 13:00:00 | content-1 |
| 2026-02-03 13:15:00 | content-2 |
| 2026-02-03 13:30:00 | content-3 |
| 2026-02-03 13:45:00 | content-4 |
| 2026-02-03 14:00:00 | content-5 |
| 2026-02-03 14:10:00 | content-6 |
Et il est maintenant 14:05:00 (la 1ère notification a >60 min)
Et un nouveau contenu déclenche une notification
Quand le système calcule le quota sur les 60 dernières minutes
Alors seules 5 notifications doivent être comptées (13:15 à 14:10)
Et le compteur doit afficher 6/6 (5 + nouvelle = 6)
Et la notification doit être envoyée
Scénario: Reset complet après 60 minutes sans notification
Étant donné l'utilisateur a reçu 6 notifications entre 12:00 et 12:50
Et il est maintenant 13:55 (>60 min après la dernière)
Quand un nouveau contenu déclenche une notification
Alors le compteur doit être reset à 1/6
Et la notification doit être envoyée normalement
# ============================================================================
# EXCEPTION AUDIO-GUIDES (1 quota = toutes les séquences)
# ============================================================================
Scénario: Audio-guide multi-séquences compte pour 1 seul quota
Étant donné l'utilisateur a reçu 5 notifications normales dans l'heure
Et l'utilisateur démarre un audio-guide avec 8 séquences géolocalisées
Quand la 1ère séquence de l'audio-guide déclenche une notification
Alors le quota doit être incrémenté à 6/6
Quand les 7 séquences suivantes déclenchent des notifications
Alors le quota doit rester à 6/6
Et toutes les notifications d'audio-guide doivent être envoyées
Et un flag "audio_guide_exception" doit être loggé
Scénario: Audio-guide suivi de contenus normaux bloqués
Étant donné l'utilisateur a reçu 5 notifications normales
Et l'utilisateur a terminé un audio-guide de 6 séquences (compte pour 1 quota)
Et le quota est maintenant 6/6
Quand un contenu normal déclenche une notification
Alors la notification doit être bloquée (quota dépassé)
Et le contenu doit être ajouté à la file d'attente
Scénario: Plusieurs audio-guides dans l'heure
Étant donné l'utilisateur a démarré 3 audio-guides dans l'heure :
| timestamp | audio_guide_id | sequences |
| 2026-02-03 13:00:00 | guide-1 | 5 |
| 2026-02-03 13:30:00 | guide-2 | 8 |
| 2026-02-03 14:00:00 | guide-3 | 4 |
Quand le système calcule le quota
Alors chaque audio-guide doit compter pour 1 quota
Et le compteur doit afficher 3/6
Et 3 contenus normaux supplémentaires peuvent être notifiés
# ============================================================================
# COOLDOWN 10 MINUTES APRÈS REFUS
# ============================================================================
Scénario: Notification ignorée déclenche cooldown de 10 minutes
Étant donné une notification géolocalisée est affichée à 14:00:00
Et le compteur de 7 secondes se termine sans action utilisateur
Quand le délai de 7 secondes expire
Alors un cooldown de 10 minutes doit être activé
Et un timestamp "cooldown_until: 14:10:00" doit être enregistré
Et la notification doit disparaître
Scénario: Notifications bloquées pendant le cooldown
Étant donné un cooldown est actif jusqu'à 14:10:00
Et il est maintenant 14:05:00
Et 3 contenus géolocalisés déclenchent des notifications
Quand le système évalue les conditions
Alors aucune notification ne doit être affichée
Et les 3 contenus doivent être ajoutés silencieusement à la file d'attente
Et un événement "notification_blocked_cooldown" doit être loggé pour chacun
Scénario: Fin du cooldown - reprise normale
Étant donné un cooldown actif jusqu'à 14:10:00
Et il est maintenant 14:10:05 (cooldown expiré)
Et un contenu géolocalisé déclenche une notification
Quand le système évalue les conditions
Alors le cooldown doit être considéré comme expiré
Et la notification doit être envoyée normalement
Et le flag "post_cooldown" doit être ajouté aux métriques
Scénario: Validation notification pendant le countdown annule le cooldown
Étant donné une notification affichée avec compteur à 4 secondes restantes
Quand l'utilisateur appuie sur "Écouter maintenant"
Alors le contenu doit démarrer
Et aucun cooldown ne doit être appliqué
Et la prochaine notification peut être envoyée normalement (sous réserve du quota)
Scénario: Cooldown + Quota simultanés
Étant donné l'utilisateur a reçu 6 notifications dans l'heure (quota atteint)
Et la dernière notification a été ignorée (cooldown actif pour 10 min)
Et il est maintenant 5 minutes plus tard
Quand un nouveau contenu déclenche une notification
Alors la notification doit être bloquée pour les 2 raisons :
| raison | statut |
| quota_exceeded | true |
| cooldown_active | true |
Et le contenu doit être ajouté à la file d'attente
Et les deux raisons doivent être loggées
# ============================================================================
# CAS LIMITES & EDGE CASES
# ============================================================================
Scénario: Cooldown ne s'applique pas en mode piéton
Étant donné l'utilisateur est en mode piéton
Et une notification push géolocalisée est ignorée
Quand la notification expire
Alors aucun cooldown ne doit être appliqué
Car en mode piéton les notifications sont opt-in et moins intrusives
Scénario: Changement de mode pendant cooldown (voiture → piéton)
Étant donné un cooldown actif en mode voiture jusqu'à 14:20:00
Et il est maintenant 14:12:00 (cooldown encore actif)
Quand l'utilisateur bascule en mode piéton
Alors le cooldown doit être immédiatement annulé
Et les notifications piéton doivent être activées normalement
Scénario: Déconnexion/reconnexion pendant cooldown
Étant donné un cooldown actif jusqu'à 15:30:00
Quand l'utilisateur se déconnecte puis se reconnecte à 15:20:00
Alors le cooldown doit être persisté (Redis ou DB)
Et le cooldown doit toujours être actif jusqu'à 15:30:00
Et les notifications doivent rester bloquées
Scénario: Quota reset à minuit vs fenêtre glissante
Étant donné le système utilise une fenêtre glissante de 60 minutes
Et l'utilisateur a reçu 6 notifications entre 23:30 et 23:55
Quand minuit passe et il est 00:05
Alors le quota doit toujours être calculé sur les 60 dernières minutes
Et les 6 notifications doivent encore être comptées
Et aucune notification supplémentaire ne peut être envoyée avant 00:30
# ============================================================================
# MÉTRIQUES & ANALYTICS
# ============================================================================
Scénario: Logging des blocages quota pour optimisation
Étant donné le quota est atteint (6/6)
Et 5 contenus tentent de déclencher une notification dans l'heure suivante
Quand ces notifications sont bloquées
Alors un événement analytics doit être loggé pour chacune :
| event_type | notification_blocked_quota |
| content_id | content-xyz |
| user_quota_current | 6 |
| user_quota_max | 6 |
| timestamp_blocked | 2026-02-03 14:30:00 |
| added_to_queue | true |
Et ces métriques doivent alimenter le dashboard de monitoring
Scénario: Métriques de cooldown par utilisateur
Étant donné un utilisateur ignore 3 notifications dans la journée
Quand le système analyse le comportement
Alors les métriques suivantes doivent être calculées :
| cooldowns_triggered_today | 3 |
| avg_cooldown_per_user | 2.1 |
| ignore_rate | 50% |
Et ces données doivent être utilisées pour ajuster l'algorithme de recommandation
Scénario: A/B testing - quota 6 vs 8 vs 10 par heure
Étant donné l'utilisateur est dans le groupe de test "quota_8"
Et le système teste différentes valeurs de quota
Quand le système évalue les notifications
Alors le quota max doit être de 8 au lieu de 6
Et le groupe de test doit être loggé dans les événements
Et les métriques d'engagement doivent être comparées entre groupes