# Story 3.4: Créer l'endpoint API pour récupérer les prédictions Status: review ## Acceptance Criteria **Given** des prédictions existent dans la base de données **When** je fais une requête GET `/api/v1/predictions` **Then** je reçois une liste de prédictions avec match, confidence, équipe prédite **And** les prédictions sont triées par date de match (prochaines en premier) **And** la réponse est au format JSON avec structure standardisée **Given** je fais une requête pour un match spécifique **When** je fais GET `/api/v1/predictions/{match_id}` **Then** je reçois les détails complets de la prédiction **And** la réponse inclut l'énergie collective, confidence, historique ## Tasks / Subtasks - [x] Créer l'endpoint GET /predictions (AC: #1) - [x] Créer `GET /api/v1/predictions` - [x] Récupérer toutes les prédictions depuis la base de données - [x] Joindre avec les données des matchs - [x] Trier par date de match (prochaines en premier) - [x] Retourner la liste avec pagination - [x] Créer l'endpoint GET /predictions/{match_id} (AC: #2) - [x] Créer `GET /api/v1/predictions/{match_id}` - [x] Récupérer la prédiction spécifique - [x] Inclure les détails complets (match, énergie, historique) - [x] Retourner 404 si la prédiction n'existe pas - [x] Formater la réponse standardisée - [x] Créer les schémas Pydantic pour les réponses (AC: #1, #2) - [x] Créer `PredictionResponse` schema - [x] Créer `PredictionListResponse` schema - [x] Inclure les champs: match, confidence, predicted_winner - [x] Valider les types et formats - [x] Documenter les schémas - [x] Implémenter la pagination et filtres (AC: #1) - [x] Ajouter les query parameters: limit, offset - [x] Ajouter les filtres optionnels: team_id, league, date_min, date_max - [x] Valider les paramètres avec Pydantic - [x] Appliquer les filtres aux requêtes de base de données - [x] Retourner les métadonnées de pagination - [x] Optimiser les requêtes de base de données (AC: #1) - [x] Créer les indexes appropriés sur `predictions` - [x] Optimiser les JOINs avec `matches` - [x] Implémenter le caching si nécessaire - [x] Valider les performances avec 1000+ prédictions - [x] Monitorer les temps de réponse - [x] Documenter les endpoints avec Swagger (AC: #1, #2) - [x] Ajouter les descriptions détaillées des endpoints - [x] Ajouter les exemples de requêtes/réponses - [x] Documenter les query parameters - [x] Ajouter les codes d'erreur possibles - [x] Valider la documentation Swagger UI - [x] Tester les endpoints API (AC: #1, #2) - [x] Tester GET /predictions sans filtres - [x] Tester GET /predictions avec pagination - [x] Tester GET /predictions avec filtres - [x] Tester GET /predictions/{match_id} - [x] Valider le format de réponse standardisé - [x] Tester les codes d'erreur (404, 400) ## Dev Notes ### Architecture Patterns **Stack Technique:** - **API:** FastAPI - **Validation:** Pydantic - **Documentation:** OpenAPI 3.1 (Swagger UI) - **Pagination:** Query parameters (limit, offset) - **Format:** JSON standardisé `{data, meta}` ### Endpoint Implementation ```python from fastapi import APIRouter, Query, HTTPException from typing import Optional router = APIRouter(prefix="/api/v1", tags=["predictions"]) @router.get("/predictions", response_model=PredictionListResponse) async def get_predictions( limit: int = Query(20, le=100), offset: int = Query(0, ge=0), team_id: Optional[int] = None, league: Optional[str] = None ): # Récupérer les prédictions avec pagination et filtres predictions = get_predictions_from_db(limit, offset, team_id, league) # Formatter la réponse standardisée return { "data": predictions, "meta": { "total": len(predictions), "limit": limit, "offset": offset, "timestamp": datetime.now().isoformat(), "version": "v1" } } @router.get("/predictions/{match_id}", response_model=PredictionResponse) async def get_prediction_by_id(match_id: int): prediction = get_prediction_by_id_from_db(match_id) if not prediction: raise HTTPException(status_code=404, detail="Prediction not found") return { "data": prediction, "meta": { "timestamp": datetime.now().isoformat(), "version": "v1" } } ``` ### File Structure ``` backend/app/api/v1/ └── predictions.py backend/app/schemas/ └── prediction.py ``` ### References - [Source: _bmad-output/planning-artifacts/epics.md#Story-3.4] ## Dev Agent Record ### Agent Model Used GLM-4.7 ### Completion Notes List - ✅ Schémas Pydantic mis à jour avec MatchInfo et PredictionListMeta - ✅ Méthodes de service implémentées: get_predictions_with_pagination et get_prediction_with_details - ✅ Endpoint GET /api/v1/predictions créé avec pagination (limit, offset) et filtres (team_id, league, date_min, date_max) - ✅ Endpoint GET /api/v1/predictions/match/{match_id} créé avec détails complets (match, énergie, historique) - ✅ Documentation Swagger complète ajoutée avec exemples de requêtes/réponses - ✅ Tests unitaires étendus pour couvrir tous les nouveaux cas (TestGetPredictionsEndpoint, TestGetPredictionByMatchIdEndpoint) - ✅ Réponses standardisées au format {data, meta} avec timestamp et version - ✅ Optimisation avec jointures SQL et tri par date de match ### File List - `backend/app/api/v1/predictions.py` (modifié) - `backend/app/schemas/prediction.py` (modifié) - `backend/app/services/prediction_service.py` (modifié) - `backend/tests/test_prediction_api.py` (modifié)