> ⚠️ **MODE DEV STRICT (pas PROD)**  
> - **Aucune transition**, **aucun fallback**, **aucune rétro-compat**.  
> - Soit on règle un point proprement soit on n'y touche pas. pas de zone de : "transition ou entre deux".  
> - Toute contribution qui introduit une zone grise, un compromis ou un retour au legacy est **refusée**.

# Sécurité V4 — Auth, CSRF, Rate‑limit

## Authentification
- Session obligatoire pour accéder aux endpoints protégés (via `AuthMiddleware`).
- 401 `UNAUTHORIZED` → `{ ok:false, code: UNAUTHORIZED, message: ... }`.

## CSRF
- Obligatoire pour toute requête mutante (POST/PUT/PATCH/DELETE) hors `/api/auth/{login,register}`.
- Requis: header `X-CSRF-Token` correspondant au token de session.
- Erreurs:
  - 401 `{ ok:false, code: CSRF_SESSION_REQUIRED, message: ... }` (pas de session)
  - 403 `{ ok:false, code: CSRF_TOKEN_INVALID, message: ... }` (token invalide)

## Rate‑limit (auth)
- Appliqué aux endpoints `/api/auth/login` et `/api/auth/register` (anti brute‑force).
- Trop d’échecs récents → 429 `{ ok:false, code: RATE_LIMITED, message: ... }`.
- Succès login → remise à zéro de l’IP côté limiteur.

## Erreurs canoniques
- Toujours `Response::error(code, message, details?, status)`.
- Codes symboliques stables (UPPER_SNAKE), message lisible, `details` optionnel.
- Jamais de corps HTML ou de texte brut en erreur.

## Bonnes pratiques
- Front: vérifier `Content-Type` JSON côté client avant parse; un seul retry CSRF si 403.
- Back: ne pas `echo`/`print` hors réponse; centraliser via helpers de réponse.
