user(); $session = SessionQuiz::query() ->whereIn('statut', [SessionQuiz::EN_ATTENTE, SessionQuiz::EN_COURS]) ->whereHas('quiz', fn ($q) => $q->where('classe_id', $eleve->classe_id)) ->with('questionCourante.choix') ->latest('demarree_a') ->first(); if (! $session) { return response()->json(['session' => null]); } $dejaRepondu = $session->question_quiz_courante_id ? ReponseQuiz::where('session_quiz_id', $session->id) ->where('question_quiz_id', $session->question_quiz_courante_id) ->where('eleve_id', $eleve->id) ->exists() : false; $question = $session->questionCourante; return response()->json([ 'session' => [ 'id' => $session->id, 'statut' => $session->statut, 'deja_repondu' => $dejaRepondu, 'question' => $question ? [ 'id' => $question->id, 'enonce' => $question->enonce, 'type' => $question->type, 'choix' => $question->type === QuestionQuiz::QCM ? $question->choix->map(fn ($c) => ['id' => $c->id, 'texte' => $c->texte])->values() : [], ] : null, ], ]); } public function repondre(Request $request, SessionQuiz $session): JsonResponse { $eleve = Auth::guard('eleve')->user(); abort_if($session->quiz->classe_id !== $eleve->classe_id, 403); abort_if($session->statut !== SessionQuiz::EN_COURS || ! $session->question_quiz_courante_id, 409, 'Aucune question en cours.'); $question = $session->questionCourante; abort_if( ReponseQuiz::where('session_quiz_id', $session->id) ->where('question_quiz_id', $question->id) ->where('eleve_id', $eleve->id) ->exists(), 409, 'Déjà répondu.' ); $donnees = $request->validate([ 'choix_id' => ['nullable', 'integer'], 'reponse_vrai_faux' => ['nullable', 'boolean'], ]); $correcte = $question->estCorrecte($donnees['choix_id'] ?? null, $donnees['reponse_vrai_faux'] ?? null); try { ReponseQuiz::create([ 'session_quiz_id' => $session->id, 'question_quiz_id' => $question->id, 'eleve_id' => $eleve->id, 'choix_question_quiz_id' => $donnees['choix_id'] ?? null, 'reponse_vrai_faux' => $donnees['reponse_vrai_faux'] ?? null, 'correcte' => $correcte, 'repondu_a' => now(), ]); } catch (QueryException $e) { // Double clic : la contrainte d'unicité (session, question, élève) // a bloqué un second envoi arrivé en même temps que le premier. abort(409, 'Déjà répondu.'); } return response()->json(['correcte' => $correcte]); } }