248 lines
5.3 KiB
Markdown
248 lines
5.3 KiB
Markdown
# Contrats API REST — Budget Tracker
|
|
|
|
**Version** : 1.0.0 | **Base URL** : `/api/v1` | **Format** : JSON
|
|
|
|
## Conventions
|
|
|
|
- Tous les montants sont en **centimes** (integer)
|
|
- Authentification : `Authorization: Bearer <access_token>`
|
|
- Dates : ISO 8601 (`YYYY-MM-DD`)
|
|
- Mois : `YYYY-MM`
|
|
- Soft-delete : les ressources supprimées retournent 404
|
|
- Erreurs : `{"detail": "message d'erreur"}`
|
|
|
|
---
|
|
|
|
## Authentification
|
|
|
|
### POST /auth/register
|
|
Créer un compte utilisateur.
|
|
|
|
**Body** :
|
|
```json
|
|
{"email": "user@example.com", "password": "...", "full_name": "Jean Dupont"}
|
|
```
|
|
**Réponse 201** :
|
|
```json
|
|
{"id": "uuid", "email": "user@example.com", "full_name": "Jean Dupont"}
|
|
```
|
|
|
|
### POST /auth/login
|
|
Obtenir les tokens JWT.
|
|
|
|
**Body** : `application/x-www-form-urlencoded` : `username=email&password=...`
|
|
|
|
**Réponse 200** :
|
|
```json
|
|
{"access_token": "...", "refresh_token": "...", "token_type": "bearer"}
|
|
```
|
|
|
|
### POST /auth/refresh
|
|
Renouveler l'access token.
|
|
|
|
**Body** : `{"refresh_token": "..."}`
|
|
**Réponse 200** : `{"access_token": "...", "token_type": "bearer"}`
|
|
|
|
### POST /auth/logout
|
|
Invalider le refresh token.
|
|
**Réponse 204** : no content
|
|
|
|
---
|
|
|
|
## Transactions
|
|
|
|
### GET /transactions
|
|
Lister les transactions (paginées, filtrables).
|
|
|
|
**Query params** : `?month=2026-03&category_id=uuid&type=expense&page=1&per_page=20`
|
|
|
|
**Réponse 200** :
|
|
```json
|
|
{
|
|
"items": [
|
|
{
|
|
"id": "uuid",
|
|
"amount_cents": 4500,
|
|
"type": "expense",
|
|
"description": "Courses Leclerc",
|
|
"category": {"id": "uuid", "name": "Alimentation", "color": "#4CAF50"},
|
|
"transaction_date": "2026-03-15",
|
|
"created_at": "2026-03-15T10:30:00Z"
|
|
}
|
|
],
|
|
"total": 42,
|
|
"page": 1,
|
|
"per_page": 20
|
|
}
|
|
```
|
|
|
|
### POST /transactions
|
|
Créer une transaction.
|
|
|
|
**Body** :
|
|
```json
|
|
{
|
|
"amount_cents": 4500,
|
|
"type": "expense",
|
|
"category_id": "uuid",
|
|
"description": "Courses Leclerc",
|
|
"transaction_date": "2026-03-15"
|
|
}
|
|
```
|
|
**Réponse 201** : transaction complète
|
|
|
|
### GET /transactions/{id}
|
|
Détail d'une transaction. **Réponse 200** : transaction complète
|
|
|
|
### PUT /transactions/{id}
|
|
Modifier une transaction. **Body** : mêmes champs que POST. **Réponse 200** : transaction mise à jour
|
|
|
|
### DELETE /transactions/{id}
|
|
Soft-delete. **Réponse 204** : no content
|
|
|
|
---
|
|
|
|
## Catégories
|
|
|
|
### GET /categories
|
|
Lister les catégories de l'utilisateur (y compris les défauts système).
|
|
|
|
**Query** : `?type=expense`
|
|
|
|
**Réponse 200** :
|
|
```json
|
|
[
|
|
{"id": "uuid", "name": "Alimentation", "type": "expense", "color": "#4CAF50", "icon": "shopping-cart", "is_default": true}
|
|
]
|
|
```
|
|
|
|
### POST /categories
|
|
Créer une catégorie personnalisée.
|
|
|
|
**Body** : `{"name": "Loisirs", "type": "expense", "color": "#9C27B0", "icon": "gamepad"}`
|
|
**Réponse 201** : catégorie créée
|
|
|
|
### PUT /categories/{id}
|
|
Modifier une catégorie. **Réponse 200** : catégorie mise à jour
|
|
|
|
### DELETE /categories/{id}
|
|
Soft-delete. Erreur 409 si des transactions y sont liées.
|
|
|
|
---
|
|
|
|
## Budgets (Enveloppes)
|
|
|
|
### GET /budgets
|
|
Lister les budgets du mois courant ou d'un mois donné.
|
|
|
|
**Query** : `?month=2026-03`
|
|
|
|
**Réponse 200** :
|
|
```json
|
|
[
|
|
{
|
|
"id": "uuid",
|
|
"category": {"id": "uuid", "name": "Alimentation"},
|
|
"month": "2026-03",
|
|
"limit_cents": 30000,
|
|
"spent_cents": 12500,
|
|
"remaining_cents": 17500,
|
|
"percentage_used": 41.7
|
|
}
|
|
]
|
|
```
|
|
|
|
### POST /budgets
|
|
Définir un budget pour une catégorie/mois.
|
|
|
|
**Body** : `{"category_id": "uuid", "month": "2026-03", "limit_cents": 30000}`
|
|
**Réponse 201** : budget créé
|
|
|
|
### PUT /budgets/{id}
|
|
Modifier la limite d'un budget. **Réponse 200** : budget mis à jour
|
|
|
|
### DELETE /budgets/{id}
|
|
Supprimer un budget. **Réponse 204**
|
|
|
|
---
|
|
|
|
## Dashboard
|
|
|
|
### GET /dashboard
|
|
KPIs du mois courant ou d'un mois donné.
|
|
|
|
**Query** : `?month=2026-03`
|
|
|
|
**Réponse 200** :
|
|
```json
|
|
{
|
|
"month": "2026-03",
|
|
"balance_cents": 150000,
|
|
"total_income_cents": 250000,
|
|
"total_expense_cents": 100000,
|
|
"by_category": [
|
|
{"category_id": "uuid", "name": "Alimentation", "total_cents": 45000, "percentage": 45.0}
|
|
],
|
|
"monthly_trend": [
|
|
{"month": "2026-01", "income_cents": 240000, "expense_cents": 110000},
|
|
{"month": "2026-02", "income_cents": 245000, "expense_cents": 95000},
|
|
{"month": "2026-03", "income_cents": 250000, "expense_cents": 100000}
|
|
],
|
|
"budget_alerts": [
|
|
{"category_id": "uuid", "name": "Loisirs", "percentage_used": 92.0, "status": "warning"}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Historique
|
|
|
|
### GET /history
|
|
Résumé mensuel navigable.
|
|
|
|
**Query** : `?year=2026`
|
|
|
|
**Réponse 200** :
|
|
```json
|
|
[
|
|
{
|
|
"month": "2026-03",
|
|
"income_cents": 250000,
|
|
"expense_cents": 100000,
|
|
"balance_cents": 150000,
|
|
"transaction_count": 42
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
## Export
|
|
|
|
### GET /export/csv
|
|
Exporter les transactions en CSV.
|
|
|
|
**Query** : `?month=2026-03` (optionnel — tout exporter si absent)
|
|
**Réponse 200** : `Content-Type: text/csv`, fichier `transactions_2026-03.csv`
|
|
|
|
### GET /export/pdf
|
|
Exporter le rapport mensuel en PDF.
|
|
|
|
**Query** : `?month=2026-03`
|
|
**Réponse 200** : `Content-Type: application/pdf`, fichier `rapport_2026-03.pdf`
|
|
|
|
---
|
|
|
|
## Codes d'erreur
|
|
|
|
| Code | Signification |
|
|
|------|--------------|
|
|
| 400 | Données invalides (validation Pydantic) |
|
|
| 401 | Token manquant ou expiré |
|
|
| 403 | Ressource appartenant à un autre utilisateur |
|
|
| 404 | Ressource introuvable (ou soft-deleted) |
|
|
| 409 | Conflit (doublon, contrainte métier) |
|
|
| 422 | Erreur de validation (détail par champ) |
|
|
| 500 | Erreur serveur |
|