Files
roadwave/features/api/interest-gauges/jauge-initiale.feature
jpgiannetti 718581b954 feat(gherkin): ajouter features API pour jauges d'intérêt
Création de 3 features Gherkin pour les tests backend des jauges d'intérêt:

- evolution-jauges.feature: Tests API pour calculs de jauges (likes auto/manuels,
  abonnements créateurs, skips), persistence PostgreSQL, bornes 0-100%, cache Redis

- jauge-initiale.feature: Tests API pour initialisation à 50% lors inscription,
  questionnaire optionnel post-MVP, recommandations cold start

- degradation-temporelle.feature: Tests API confirmant absence de dégradation
  automatique, réinitialisation manuelle avec snapshot et audit log

Complète les features UI existantes avec les aspects techniques backend.
2026-02-02 22:32:29 +01:00

338 lines
12 KiB
Gherkin

# language: fr
Fonctionnalité: API - Jauge initiale et cold start
En tant qu'API backend
Je veux initialiser toutes les jauges à 50% lors de l'inscription
Afin de garantir un démarrage neutre et équitable
Contexte:
Étant donné que l'API RoadWave est disponible
Et que la base de données PostgreSQL est accessible
Scénario: API initialise toutes les jauges à 50% lors inscription
Quand je POST /api/v1/auth/register
"""json
{
"email": "nouveau@example.com",
"password": "SecureP@ss123",
"birth_date": "1990-01-15",
"username": "nouveau_user"
}
"""
Alors le statut de réponse est 201
Et la réponse contient:
"""json
{
"user_id": "<uuid>",
"email": "nouveau@example.com",
"username": "nouveau_user"
}
"""
Et en base de données, la table interest_gauges contient 12 lignes pour ce user_id:
| category | level |
| Automobile | 50 |
| Voyage | 50 |
| Famille | 50 |
| Amour | 50 |
| Musique | 50 |
| Économie | 50 |
| Cryptomonnaie | 50 |
| Politique | 50 |
| Culture générale | 50 |
| Sport | 50 |
| Technologie | 50 |
| Santé | 50 |
Scénario: API retourne les 12 catégories disponibles
Quand je GET /api/v1/interest-gauges/categories
Alors le statut de réponse est 200
Et la réponse contient:
"""json
{
"categories": [
{"id": "automobile", "name": "Automobile", "icon": "car"},
{"id": "voyage", "name": "Voyage", "icon": "plane"},
{"id": "famille", "name": "Famille", "icon": "users"},
{"id": "amour", "name": "Amour", "icon": "heart"},
{"id": "musique", "name": "Musique", "icon": "music"},
{"id": "economie", "name": "Économie", "icon": "chart"},
{"id": "cryptomonnaie", "name": "Cryptomonnaie", "icon": "bitcoin"},
{"id": "politique", "name": "Politique", "icon": "landmark"},
{"id": "culture-generale", "name": "Culture générale", "icon": "book"},
{"id": "sport", "name": "Sport", "icon": "running"},
{"id": "technologie", "name": "Technologie", "icon": "cpu"},
{"id": "sante", "name": "Santé", "icon": "heart-pulse"}
]
}
"""
Scénario: API GET retourne jauges utilisateur nouvellement inscrit
Étant donné qu'un utilisateur "user_new" vient de s'inscrire
Quand je GET /api/v1/users/user_new/interest-gauges
Alors le statut de réponse est 200
Et la réponse contient 12 jauges toutes à 50%:
"""json
{
"user_id": "user_new",
"gauges": [
{"category": "Automobile", "level": 50, "evolution_since_signup": 0},
{"category": "Voyage", "level": 50, "evolution_since_signup": 0},
{"category": "Famille", "level": 50, "evolution_since_signup": 0},
{"category": "Amour", "level": 50, "evolution_since_signup": 0},
{"category": "Musique", "level": 50, "evolution_since_signup": 0},
{"category": "Économie", "level": 50, "evolution_since_signup": 0},
{"category": "Cryptomonnaie", "level": 50, "evolution_since_signup": 0},
{"category": "Politique", "level": 50, "evolution_since_signup": 0},
{"category": "Culture générale", "level": 50, "evolution_since_signup": 0},
{"category": "Sport", "level": 50, "evolution_since_signup": 0},
{"category": "Technologie", "level": 50, "evolution_since_signup": 0},
{"category": "Santé", "level": 50, "evolution_since_signup": 0}
]
}
"""
Scénario: API calcule recommandations avec jauges à 50% - pas de biais
Étant donné qu'un utilisateur "user_new" vient de s'inscrire
Et que toutes ses jauges sont à 50%
Et qu'il est à la position GPS (48.8566, 2.3522) - Paris
Quand je POST /api/v1/recommendations
"""json
{
"user_id": "user_new",
"latitude": 48.8566,
"longitude": 2.3522,
"limit": 10
}
"""
Alors le statut de réponse est 200
Et la réponse contient 10 contenus
Et le scoring est basé uniquement sur:
| critère | poids |
| Distance géographique| 100% |
| Intérêts (50% égal) | 0% |
Et aucune catégorie n'a d'avantage initial
Scénario: API permet ajout de nouvelles catégories
Étant donné qu'un admin ajoute une nouvelle catégorie "Gastronomie"
Quand je POST /api/v1/admin/interest-gauges/categories
"""json
{
"id": "gastronomie",
"name": "Gastronomie",
"icon": "utensils"
}
"""
Alors le statut de réponse est 201
Et pour tous les utilisateurs existants:
| action |
| Une ligne est créée dans interest_gauges |
| category = "Gastronomie" |
| level = 50 |
Et les nouveaux utilisateurs auront aussi cette catégorie à 50%
Scénario: API calcule évolution depuis inscription
Étant donné qu'un utilisateur "user123" s'est inscrit il y a 30 jours
Et qu'il a les jauges suivantes en base:
| catégorie | niveau | initial |
| Automobile | 67% | 50% |
| Voyage | 82% | 50% |
| Économie | 34% | 50% |
| Sport | 50% | 50% |
Quand je GET /api/v1/users/user123/interest-gauges
Alors le statut de réponse est 200
Et la réponse contient:
"""json
{
"user_id": "user123",
"signup_date": "2026-01-03T10:00:00Z",
"gauges": [
{
"category": "Automobile",
"level": 67,
"evolution_since_signup": 17
},
{
"category": "Voyage",
"level": 82,
"evolution_since_signup": 32
},
{
"category": "Économie",
"level": 34,
"evolution_since_signup": -16
},
{
"category": "Sport",
"level": 50,
"evolution_since_signup": 0
}
]
}
"""
Scénario: API transaction atomique lors inscription
Quand je POST /api/v1/auth/register
"""json
{
"email": "test@example.com",
"password": "SecureP@ss123",
"birth_date": "1995-03-20",
"username": "test_user"
}
"""
Alors l'insertion en base de données est atomique:
| action |
| INSERT INTO users |
| INSERT INTO interest_gauges (12 lignes) |
| Tout ou rien (transaction) |
Et si une erreur survient, aucune donnée partielle n'est créée
Scénario: API rollback si initialisation jauges échoue
Étant donné que la table interest_gauges a une contrainte violée
Quand je POST /api/v1/auth/register avec données valides
Alors le statut de réponse est 500
Et aucune ligne n'est créée dans la table users
Et aucune ligne n'est créée dans la table interest_gauges
Et la transaction est rollback complètement
Scénario: API POST questionnaire optionnel post-MVP
Étant donné qu'un utilisateur "user123" a écouté 3 contenus
Et qu'il décide de remplir le questionnaire optionnel
Quand je POST /api/v1/users/user123/interest-gauges/quick-setup
"""json
{
"selected_categories": ["Automobile", "Voyage", "Sport"]
}
"""
Alors le statut de réponse est 200
Et en base de données:
| catégorie | niveau |
| Automobile | 70 |
| Voyage | 70 |
| Sport | 70 |
| Musique | 30 |
| Économie | 30 |
| Cryptomonnaie | 30 |
| Politique | 30 |
| Culture générale | 30 |
| Technologie | 30 |
| Santé | 30 |
| Famille | 30 |
| Amour | 30 |
Et un flag quick_setup_completed = true est enregistré
Scénario: API rejette questionnaire optionnel si déjà rempli
Étant donné qu'un utilisateur "user123" a déjà rempli le questionnaire optionnel
Quand je POST /api/v1/users/user123/interest-gauges/quick-setup
"""json
{
"selected_categories": ["Musique", "Technologie"]
}
"""
Alors le statut de réponse est 409
Et la réponse contient:
"""json
{
"error": "QUICK_SETUP_ALREADY_COMPLETED",
"message": "Le questionnaire a déjà été rempli"
}
"""
Scénario: API valide nombre de catégories sélectionnées
Quand je POST /api/v1/users/user123/interest-gauges/quick-setup
"""json
{
"selected_categories": ["Automobile"]
}
"""
Alors le statut de réponse est 400
Et la réponse contient:
"""json
{
"error": "VALIDATION_ERROR",
"message": "Vous devez sélectionner entre 2 et 5 catégories"
}
"""
Scénario: API déterministe - deux users identiques
Étant donné que l'utilisateur "userA" s'inscrit à 10:00:00
Et que l'utilisateur "userB" s'inscrit à 10:00:01
Quand je GET /api/v1/users/userA/interest-gauges
Et je GET /api/v1/users/userB/interest-gauges
Alors les deux réponses ont des jauges identiques (toutes à 50%)
Et le comportement est déterministe
Scénario: API retourne statistiques cold start
Étant donné qu'un utilisateur "user_new" vient de s'inscrire
Quand je GET /api/v1/users/user_new/stats
Alors le statut de réponse est 200
Et la réponse contient:
"""json
{
"user_id": "user_new",
"signup_date": "2026-02-02T14:00:00Z",
"total_listened_content": 0,
"gauges_summary": {
"all_at_default": true,
"default_value": 50,
"total_categories": 12,
"personalization_level": "none"
}
}
"""
Scénario: API recommandations cold start priorité géo
Étant donné qu'un utilisateur "user_new" vient de s'inscrire
Et qu'il est à Paris avec 100 contenus disponibles dans un rayon de 5km
Et que ces contenus ont des catégories variées
Quand je POST /api/v1/recommendations
"""json
{
"user_id": "user_new",
"latitude": 48.8566,
"longitude": 2.3522,
"limit": 10
}
"""
Alors le statut de réponse est 200
Et les 10 contenus retournés sont les plus proches géographiquement
Et les catégories sont variées (pas de biais intérêts)
Et la réponse contient:
"""json
{
"recommendations": [
{
"content_id": "<uuid>",
"distance_meters": 150,
"interest_match": 50,
"final_score": 0.95
}
],
"cold_start": true,
"personalization_level": "none"
}
"""
Scénario: API index optimisé pour lecture jauges
Étant donné que la table interest_gauges a 1 million de lignes
Quand je GET /api/v1/users/user123/interest-gauges
Alors la requête SQL utilise l'index (user_id, category)
Et le temps de réponse est < 50ms
Et le plan d'exécution confirme l'utilisation de l'index
Scénario: API cache jauges utilisateur en Redis
Étant donné qu'un utilisateur "user123" a ses jauges en base
Quand je GET /api/v1/users/user123/interest-gauges
Alors le backend vérifie d'abord Redis avec clé "user:user123:gauges"
Et si absent, lit depuis PostgreSQL
Et met en cache dans Redis avec TTL = 300 secondes
Quand je GET à nouveau dans les 5 minutes
Alors la réponse vient directement de Redis
Et aucune requête PostgreSQL n'est faite
Scénario: API invalide cache Redis lors mise à jour jauge
Étant donné que les jauges de "user123" sont en cache Redis
Quand je POST /api/v1/listening-events qui modifie une jauge
Alors le cache Redis "user:user123:gauges" est supprimé
Et le prochain GET recharge depuis PostgreSQL
Et remet en cache avec nouvelles valeurs