StreakFit: exercices planifiés dans la séance + filtre matériel + config matos profil
Build & Deploy / build (push) Successful in 25s

- BUG: une séance issue d'une routine était vide -> WorkoutSessionResource expose planned_exercises (eager-load routine.routineExercises.exercise), pre-rempli cote front
- profil: champ users.available_equipment (json), PATCH /api/me (UpdateProfileRequest), expose dans /api/me
- exercises: filtre equipment accepte une liste CSV (whereIn) -> filtre 'mon matos'

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-21 13:27:44 +02:00
co-authored by Claude Opus 4.8
parent d629d60cba
commit 29bda37948
8 changed files with 127 additions and 5 deletions
@@ -34,10 +34,12 @@ class SessionsController
->setStatusCode(Response::HTTP_CREATED);
}
/** GET /api/sessions/{session} — séance + setLogs. */
/** GET /api/sessions/{session} — séance + setLogs + exercices planifiés de la routine. */
public function show(int $session): WorkoutSessionResource
{
return new WorkoutSessionResource($this->findForUser($session)->load('setLogs'));
return new WorkoutSessionResource(
$this->findForUser($session)->load(['setLogs', 'routine.routineExercises.exercise'])
);
}
/** POST /api/sessions/{session}/sets — log un set. */
@@ -2,11 +2,14 @@
namespace Functional\Tracking\Http\Resources;
use Functional\Exercises\Models\Exercise;
use Functional\Routines\Models\RoutineExercise;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/**
* Une séance d'entraînement, avec ses séries (setLogs) quand elles sont chargées.
* Une séance d'entraînement, avec ses séries (setLogs) quand elles sont chargées, et pour une
* séance issue d'une routine les exercices planifiés (prêts-à-logger, avec séries/reps cibles).
*/
class WorkoutSessionResource extends JsonResource
{
@@ -23,6 +26,42 @@ class WorkoutSessionResource extends JsonResource
'notes' => $this->notes,
'set_count' => $this->when($this->set_logs_count !== null, $this->set_logs_count),
'set_logs' => SetLogResource::collection($this->whenLoaded('setLogs')),
'planned_exercises' => $this->plannedExercises($request),
];
}
/**
* Exercices prévus par la routine (dans l'ordre), pour pré-remplir la séance dès son démarrage.
* Vide pour une séance ad hoc (sans routine).
*/
private function plannedExercises(Request $request): array
{
if (! $this->relationLoaded('routine') || $this->routine === null) {
return [];
}
$locale = (string) ($request->query('locale') ?: 'fr');
return $this->routine->routineExercises
->map(function (RoutineExercise $routineExercise) use ($locale) {
$exercise = $routineExercise->exercise;
return [
'exercise_id' => $routineExercise->exercise_id,
'position' => $routineExercise->position,
'sets' => $routineExercise->sets,
'target_reps' => $routineExercise->target_reps,
'target_weight' => $routineExercise->target_weight,
'rest_seconds' => $routineExercise->rest_seconds,
'exercise' => $exercise ? [
'id' => $exercise->id,
'name' => $exercise->localizedName($locale),
'image_url' => $exercise->image_url,
'target' => Exercise::localizeTerm($exercise->target, $locale),
] : null,
];
})
->values()
->all();
}
}