feat: Sprint 3-4 — Refacto API /v1/ (HRT-29)
- Blueprint Flask api_v1 avec prefix /api/v1/
- GET /api/v1/health — healthcheck public
- GET /api/v1/courses/today — courses du jour (paginé, filtré)
- GET /api/v1/courses/{id}/predictions — prédictions ML pour une course
- GET /api/v1/predictions/top3 — top 3 global (free tier)
- GET /api/v1/predictions/all — toutes prédictions (premium+)
- GET /api/v1/valuebets — value bets du jour (premium+)
- GET /api/v1/backtest — résultats backtest historiques (pro)
- GET /api/v1/export/csv — export CSV prédictions/paris (pro)
- GET /api/v1/metrics — métriques perf ML (premium+)
- Swagger/OpenAPI via flasgger à /api/v1/docs
- Erreurs uniformes {status, message, code}
- Pagination limit/offset sur toutes les listes
- 42 tests d'intégration passants
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
156
README_API_V1.md
Normal file
156
README_API_V1.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# Turf SaaS — API v1 Reference
|
||||
|
||||
Sprint 3-4 · HRT-29 — Refacto API /v1/
|
||||
|
||||
## Base URL
|
||||
|
||||
```
|
||||
http://<host>:8792
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
All endpoints (except `/api/v1/health` and `/api/v1/auth/*`) require a **Bearer JWT** token.
|
||||
|
||||
```
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
### Get a token
|
||||
|
||||
```bash
|
||||
# Register
|
||||
curl -X POST http://localhost:8792/api/v1/auth/register \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email": "user@example.com", "password": "mypassword"}'
|
||||
|
||||
# Login → returns access_token + refresh_token
|
||||
curl -X POST http://localhost:8792/api/v1/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email": "user@example.com", "password": "mypassword"}'
|
||||
```
|
||||
|
||||
## Plans & Access Control
|
||||
|
||||
| Plan | Inclus |
|
||||
|-----------|----------------------------------------------------|
|
||||
| `free` | health, auth, courses/today, predictions/top3 (1/j)|
|
||||
| `premium` | + predictions/all, valuebets, metrics |
|
||||
| `pro` | + backtest, export/csv |
|
||||
|
||||
## Endpoints
|
||||
|
||||
### System
|
||||
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------------------|------|----------------------|
|
||||
| GET | `/api/v1/health` | Non | Healthcheck public |
|
||||
| GET | `/api/v1/docs` | Non | Swagger UI |
|
||||
|
||||
### Auth
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|---------------------------|--------------------------------|
|
||||
| POST | `/api/v1/auth/register` | Créer un compte (plan=free) |
|
||||
| POST | `/api/v1/auth/login` | Login → JWT tokens |
|
||||
| POST | `/api/v1/auth/refresh` | Renouveler l'access token |
|
||||
| POST | `/api/v1/auth/logout` | Révoquer le refresh token |
|
||||
|
||||
### Courses
|
||||
|
||||
| Method | Path | Plan | Description |
|
||||
|--------|---------------------------------------|---------|------------------------------------|
|
||||
| GET | `/api/v1/courses/today` | free+ | Courses du jour (paginé) |
|
||||
| GET | `/api/v1/courses/{id}/predictions` | free+ | Prédictions ML pour une course |
|
||||
|
||||
Query params `courses/today`: `filter=[all|quinte|trot|plat]`, `limit`, `offset`
|
||||
|
||||
`{id}` format: `{num_reunion}-{num_course}` ex: `1-3`
|
||||
|
||||
### Prédictions
|
||||
|
||||
| Method | Path | Plan | Description |
|
||||
|--------|---------------------------|-----------|------------------------------|
|
||||
| GET | `/api/v1/predictions/top3`| free+ | Top 3 chevaux du jour |
|
||||
| GET | `/api/v1/predictions/all` | premium+ | Toutes les prédictions ML |
|
||||
|
||||
Query params: `date=YYYY-MM-DD`, `limit`, `offset`
|
||||
|
||||
### Value Bets
|
||||
|
||||
| Method | Path | Plan | Description |
|
||||
|--------|---------------------|-----------|--------------------------|
|
||||
| GET | `/api/v1/valuebets` | premium+ | Value bets du jour |
|
||||
|
||||
Query params: `date`, `min_odds` (défaut 2.0), `limit`, `offset`
|
||||
|
||||
### Backtest
|
||||
|
||||
| Method | Path | Plan | Description |
|
||||
|--------|---------------------|------|----------------------------------|
|
||||
| GET | `/api/v1/backtest` | pro | Résultats historiques des paris |
|
||||
|
||||
Query params: `start`, `end` (YYYY-MM-DD), `limit`, `offset`
|
||||
|
||||
### Export
|
||||
|
||||
| Method | Path | Plan | Description |
|
||||
|--------|-------------------------|------|----------------------|
|
||||
| GET | `/api/v1/export/csv` | pro | Export CSV |
|
||||
|
||||
Query params: `type=[predictions|bets]`, `date`, `start`, `end`
|
||||
|
||||
### Métriques
|
||||
|
||||
| Method | Path | Plan | Description |
|
||||
|--------|---------------------|----------|-----------------------|
|
||||
| GET | `/api/v1/metrics` | premium+ | Métriques ML et paris |
|
||||
|
||||
Query params: `days` (int, défaut 30)
|
||||
|
||||
## Réponse uniforme
|
||||
|
||||
Toutes les erreurs retournent :
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"message": "Description de l'erreur",
|
||||
"code": 400
|
||||
}
|
||||
```
|
||||
|
||||
Les listes paginées incluent :
|
||||
|
||||
```json
|
||||
{
|
||||
"pagination": {
|
||||
"total": 150,
|
||||
"limit": 20,
|
||||
"offset": 0,
|
||||
"has_more": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Démarrage
|
||||
|
||||
```bash
|
||||
cd /home/h3r7/turf_saas
|
||||
source venv/bin/activate
|
||||
python app_v1.py
|
||||
# ou
|
||||
gunicorn -w 2 -b 0.0.0.0:8792 app_v1:app
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
cd /home/h3r7/turf_saas
|
||||
source venv/bin/activate
|
||||
python -m pytest tests/test_api_v1.py -v
|
||||
```
|
||||
|
||||
## Documentation Swagger
|
||||
|
||||
Accessible sur : `http://localhost:8792/api/v1/docs`
|
||||
Reference in New Issue
Block a user