# 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": "", "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": "", "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