chartbastan/_bmad-output/implementation-artifacts/3-4-créer-l-endpoint-api-pour-récupérer-les-prédictions.md
2026-02-01 09:31:38 +01:00

163 lines
5.6 KiB
Markdown

# 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é)