# StreakFit — Contrat d'API (v1)

Base API : `https://api.streakfit.nfteam.ovh`. Front : `https://streakfit.nfteam.ovh`.
**Auth = Sanctum SPA par COOKIE de session** (pas de token exposé au front). Cookie de session sur `.streakfit.nfteam.ovh`.
`SANCTUM_STATEFUL_DOMAINS=streakfit.nfteam.ovh`, `SESSION_DOMAIN=.streakfit.nfteam.ovh`, CORS `supports_credentials=true`, origine autorisée = le front.
**Toute la logique est back.** Le front ne fait que : GET `/sanctum/csrf-cookie`, envoyer le cookie XSRF, afficher.

## Auth (couche functional/users)
- `GET /sanctum/csrf-cookie` — pose le cookie XSRF (Sanctum).
- `POST /register` `{name,email,password}` → 201, ouvre la session. Crée User (locale/units par défaut) + Streak vide.
- `POST /login` `{email,password}` → 200 `{user}`, ouvre la session.
- `POST /logout` → 204.
- `GET /auth/oidc/redirect` → 302 vers pocket-id (authorization code + PKCE). État en session.
- `GET /auth/oidc/callback?code&state` → échange le code (OIDC_ISSUER=https://pocket.nfteam.ovh, client via env OIDC_CLIENT_ID/SECRET,
  redirect OIDC_REDIRECT_URI), lie/crée le user par `oidc_sub` puis `email`, ouvre la session, **302 vers APP_FRONT_URL**.
- `GET /api/me` (auth) → `{ user:{id,name,email,locale,units,timezone,avatar_url}, streak:{current,longest,freezes} }`.

## Exercices (public, lecture seule — couche exercises)
- `GET /api/exercises?search=&body_part=&equipment=&target=&category=&per_page=` → pagination
  `{ data:[{id,name,slug,body_part,equipment,target,image_url,gif_url}], meta:{current_page,last_page,total} }`.
- `GET /api/exercises/{id}?locale=fr|pt-BR|en` → `{id,name,slug,body_part,category,equipment,target,muscle_group,
  secondary_muscles[], instructions:[...étapes dans la locale (pt-BR→fallback en/fr)], image_url, gif_url, attribution}`.
- `GET /api/exercises/facets` → valeurs distinctes pour filtres `{body_parts[],equipments[],targets[],categories[]}`.

## Routines (auth, scopées user — couche routines)
CRUD REST : `GET/POST /api/routines`, `GET/PUT/DELETE /api/routines/{id}`.
Routine = `{id,name,description,is_public,estimated_minutes, exercises:[{exercise_id,position,sets,target_reps,rest_seconds,tempo,target_weight,notes, exercise:{id,name,image_url,target}}]}`.
POST/PUT accepte `exercises[]` (sync du pivot routine_exercises).

## Programmes (auth — couche programs)
CRUD REST : `/api/programs`. Program = `{id,name,description,duration_weeks,days_per_week, slots:[{week,weekday,routine_id,label}]}`.

## Séances / tracking (auth — couche tracking)
- `POST /api/sessions` `{routine_id?,title?}` → démarre une séance (status=active) → `{session}`.
- `GET /api/sessions/{id}` → séance + setLogs.
- `POST /api/sessions/{id}/sets` `{exercise_id,set_number,reps?,weight?,rpe?,duration_seconds?,distance_meters?,is_warmup?}` → log un set → `{set_log}`.
- `POST /api/sessions/{id}/complete` `{ended_at?}` → passe status=completed (déclenche WorkoutCompleted → streak). → `{session, streak, unlocked_achievements[]}`.
- `GET /api/history?per_page=` → séances completed paginées.
- `GET /api/metrics` / `POST /api/metrics` `{measured_on,weight?,body_fat?,notes?}` — mensurations.

## Dashboard (LE cœur — couche streaks, controller view-model)
- `GET /api/dashboard` (auth) → objet prêt-à-afficher :
```
{
  streak: { current, longest, freezes_available, last_active_date, flame_level (0..5 selon current), active_today (bool) },
  week:   { goal_sessions, done_sessions, days:[{date,done,source}] },   // 7 derniers jours
  recent_sessions: [ {id,title,started_at,total_volume,set_count} ],
  achievements: [ {key,earned_at,label} ],
  suggestion: { type:'routine'|'rest', routine_id?, label }              // proposition prochaine séance
}
```
- `GET /api/achievements` → liste complète des badges de l'user.

## Conventions
- Tout scopé par `auth()->id()` (access-control lomkit ou policies) sauf exercices (public).
- Réponses JSON camelCase OU snake_case — rester COHÉRENT (snake_case, comme ci-dessus).
- Erreurs : 401 non authentifié, 403 non autorisé, 422 validation (format Laravel `{message,errors}`).
- Pagination Laravel standard (`meta`, `links`).
