Complete quiz attempt service with result and history queries

This commit is contained in:
jieun committed 2026-10-20 20:56:30 +09:00
1 parent b539a9a99a
commit aaa051c7f7
1 file changed
+56 -1
@@ -3,6 +3,13 @@ package com.example.questionbank.web.rest;
import com.example.questionbank.repository.ExamAttemptRepository; import com.example.questionbank.repository.ExamAttemptRepository;
import com.example.questionbank.service.ExamAttemptService; import com.example.questionbank.service.ExamAttemptService;
import com.example.questionbank.service.dto.ExamAttemptDTO; import com.example.questionbank.service.dto.ExamAttemptDTO;
import com.example.questionbank.service.quiz.QuizAttemptService;
import com.example.questionbank.web.rest.dto.ExamAttemptStartResult;
import com.example.questionbank.web.rest.dto.ExamAttemptSummary;
import com.example.questionbank.web.rest.dto.ExamQuestionView;
import com.example.questionbank.web.rest.dto.ExamResult;
import com.example.questionbank.web.rest.dto.StartExamRequest;
import com.example.questionbank.web.rest.dto.SubmitExamRequest;
import com.example.questionbank.web.rest.errors.BadRequestAlertException; import com.example.questionbank.web.rest.errors.BadRequestAlertException;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@@ -17,7 +24,9 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import tech.jhipster.web.util.HeaderUtil; import tech.jhipster.web.util.HeaderUtil;
@@ -31,6 +40,8 @@ import tech.jhipster.web.util.ResponseUtil;
@RequestMapping("/api/exam-attempts") @RequestMapping("/api/exam-attempts")
public class ExamAttemptResource { public class ExamAttemptResource {
private final QuizAttemptService quizAttemptService;
private static final Logger LOG = LoggerFactory.getLogger(ExamAttemptResource.class); private static final Logger LOG = LoggerFactory.getLogger(ExamAttemptResource.class);
private static final String ENTITY_NAME = "examAttempt"; private static final String ENTITY_NAME = "examAttempt";
@@ -42,9 +53,14 @@ public class ExamAttemptResource {
private final ExamAttemptRepository examAttemptRepository; private final ExamAttemptRepository examAttemptRepository;
public ExamAttemptResource(ExamAttemptService examAttemptService, ExamAttemptRepository examAttemptRepository) { public ExamAttemptResource(
ExamAttemptService examAttemptService,
ExamAttemptRepository examAttemptRepository,
QuizAttemptService quizAttemptService
) {
this.examAttemptService = examAttemptService; this.examAttemptService = examAttemptService;
this.examAttemptRepository = examAttemptRepository; this.examAttemptRepository = examAttemptRepository;
this.quizAttemptService = quizAttemptService;
} }
/** /**
@@ -185,4 +201,43 @@ public class ExamAttemptResource {
.headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString())) .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString()))
.build(); .build();
} }
// 1. 시험 응시 시작
@PostMapping("/start")
public ResponseEntity<ExamAttemptStartResult> startExam(@Valid @RequestBody StartExamRequest request, Authentication authentication) {
ExamAttemptStartResult result = quizAttemptService.start(request.subjectId(), authentication.getName());
return ResponseEntity.status(HttpStatus.CREATED).body(result);
}
// 2. 시험 문제 조회
@GetMapping("/{attemptId}/questions")
public ResponseEntity<List<ExamQuestionView>> getExamQuestions(
@PathVariable("attemptId") Long attemptId,
Authentication authentication
) {
return ResponseEntity.ok(quizAttemptService.getQuestions(attemptId, authentication.getName()));
}
// 3. 답안 제출 및 자동 채점
@PostMapping("/{attemptId}/submit")
public ResponseEntity<ExamResult> submitExam(
@PathVariable("attemptId") Long attemptId,
@Valid @RequestBody SubmitExamRequest request,
Authentication authentication
) {
return ResponseEntity.ok(quizAttemptService.submit(attemptId, authentication.getName(), request));
}
// 4. 제출된 시험 결과 조회
@GetMapping("/{attemptId}/result")
public ResponseEntity<ExamResult> getExamResult(@PathVariable("attemptId") Long attemptId, Authentication authentication) {
return ResponseEntity.ok(quizAttemptService.getResult(attemptId, authentication.getName()));
}
// 5. 내 응시 이력 조회
@GetMapping("/my")
public ResponseEntity<List<ExamAttemptSummary>> getMyExamAttempts(Authentication authentication) {
return ResponseEntity.ok(quizAttemptService.getMyAttempts(authentication.getName()));
}
} }