# API Auth JWT — Documentation
## Sprint 2-3 (HRT-28)

Base URL: `http://localhost:8792`

---

## Endpoints d'authentification

### `POST /api/v1/auth/register`
Inscription d'un nouvel utilisateur (plan free par défaut).

**Body JSON:**
```json
{ "email": "user@example.com", "password": "motdepasse123" }
```
**Réponse 201:**
```json
{ "message": "Compte créé avec succès", "user_id": 1 }
```
**Erreurs:** `400` (email invalide / mot de passe < 8 car.), `409` (email déjà utilisé)

---

### `POST /api/v1/auth/login`
Connexion — retourne access_token (15min) + refresh_token (30j).

**Body JSON:**
```json
{ "email": "user@example.com", "password": "motdepasse123" }
```
**Réponse 200:**
```json
{
  "access_token": "<JWT>",
  "refresh_token": "<refresh_JWT>",
  "token_type": "Bearer",
  "plan": "free"
}
```

---

### `POST /api/v1/auth/refresh`
Rotation du refresh token — invalide l'ancien, émet un nouveau.

**Body JSON:**
```json
{ "refresh_token": "<refresh_JWT>" }
```
**Réponse 200:** identique à `/login`

---

### `POST /api/v1/auth/logout`
Révocation du refresh token.

**Body JSON:**
```json
{ "refresh_token": "<refresh_JWT>" }
```
**Réponse 200:**
```json
{ "message": "Déconnexion réussie" }
```

---

## Routes protégées

Toutes les routes protégées nécessitent le header:
```
Authorization: Bearer <access_token>
```

### `GET /api/v1/predictions`
| Plan    | Accès                                      |
|---------|---------------------------------------------|
| free    | Top 3 uniquement, 1 course/jour             |
| premium | Toutes les courses + alertes Telegram       |
| pro     | API complète + lien export CSV              |

### `GET /api/v1/predictions/export`
Export CSV — **plan pro uniquement** (`403` pour free/premium).

### `GET /api/v1/subscription/upgrade`
Infos sur les plans disponibles et plan courant de l'utilisateur.

### `GET /api/v1/health`
Vérification d'état du service (pas d'auth requise).

---

## Sécurité

- **Passwords:** hashés avec bcrypt (saltRounds=12)
- **JWT access:** expiration 15 minutes (HS256)
- **JWT refresh:** expiration 30 jours, stocké hashé (SHA-256) en DB, rotation à chaque usage
- **Rate limiting:** 100 requêtes/min par IP — header `X-RateLimit-Remaining`
- **CORS:** configuré pour `https://turf-ia.h3r7.tech` + localhost dev
- **Logs d'accès:** horodatés ISO 8601 dans `logs/saas_api.log`

---

## Lancement

```bash
JWT_SECRET_KEY="votre_cle_secrete" \
CORS_ORIGINS="https://turf-ia.h3r7.tech" \
./venv/bin/python saas_api.py
```

---

## Tests

```bash
./venv/bin/pytest tests/test_auth.py -v
# Avec couverture:
./venv/bin/pytest tests/test_auth.py --cov=auth --cov=auth_db --cov=middleware --cov=saas_api --cov-report=term-missing
# Résultat: 27 tests OK, couverture globale 83%
```

---

## Structure des tables DB

```sql
-- users: id, email, password_hash, plan(free/premium/pro), created_at, is_active, daily_usage, last_usage_date
-- subscriptions: id, user_id, plan, start_date, end_date, stripe_customer_id
-- refresh_tokens: id, user_id, token_hash, created_at, expires_at, revoked
```
