Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package hello.cluebackend.application.quizbattle.dto;

import lombok.Builder;
import lombok.Getter;

import java.util.Map;

@Getter
@Builder
public class RevealAnswerResponse {
private final int correctAnswer;
private final String explanation;
private final Map<Integer, Integer> statistics;
private final int totalAnswers;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package hello.cluebackend.application.quizbattle.dto;

import hello.cluebackend.domain.quizbattle.model.QuizAnswer;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class SubmitAnswerResponse {
private final QuizAnswer answer;
private final int totalAnswers;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class QuizParticipant implements Serializable {
private Integer correctAnswers;
private Boolean isReady;
private Long joinedAt;
private String profileImage;

public void addScore(int points) {
this.score = (this.score != null ? this.score : 0) + points;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package hello.cluebackend.domain.quizbattle.service;

import hello.cluebackend.application.agent.dto.response.AgentResponse;
import hello.cluebackend.application.quizbattle.dto.SubmitAnswerResponse;
import hello.cluebackend.application.quizbattle.dto.RevealAnswerResponse;
import hello.cluebackend.application.quizbattle.dto.QuizGenerationRequest;
import hello.cluebackend.application.quizbattle.dto.QuizGenerationResponse;
import hello.cluebackend.domain.classroom.model.ClassRoom;
Expand Down Expand Up @@ -93,7 +95,7 @@ public QuizRoom createRoom(
return savedRoom;
}

public QuizParticipant joinRoom(String roomCode, UUID userId, String sessionId) {
public QuizParticipant joinRoom(String roomCode, UUID userId, String sessionId, String profileImage) {
QuizRoom room = quizRoomRepository.findByRoomCode(roomCode)
.orElseThrow(() -> new IllegalArgumentException("Room not found: " + roomCode));

Expand All @@ -117,6 +119,7 @@ public QuizParticipant joinRoom(String roomCode, UUID userId, String sessionId)
.correctAnswers(0)
.isReady(false)
.joinedAt(System.currentTimeMillis())
.profileImage(profileImage)
.build();

redisService.addParticipant(roomCode, participant);
Expand Down Expand Up @@ -205,7 +208,7 @@ private List<QuizQuestion> generateQuestions(int count, UUID documentId, int tim
}
}

public QuizAnswer submitAnswer(
public SubmitAnswerResponse submitAnswer(
String roomCode, UUID userId, int questionNumber,
int answerIndex, long submittedAt, int timeSpent) {
QuizRoom room = quizRoomRepository.findByRoomCode(roomCode)
Expand Down Expand Up @@ -263,7 +266,13 @@ public QuizAnswer submitAnswer(
log.info("User {} submitted answer for question {} in room {}, correct: {}, points: {}",
userId, questionNumber, roomCode, isCorrect, answer.getPoints());

return answer;
Map<Integer, Integer> statistics = redisService.getAnswerStatistics(roomCode, questionNumber);
int totalAnswers = statistics.values().stream().mapToInt(Integer::intValue).sum();

return SubmitAnswerResponse.builder()
.answer(answer)
.totalAnswers(totalAnswers)
.build();
}

public List<QuizRanking> getRankings(String roomCode) {
Expand Down Expand Up @@ -378,7 +387,7 @@ public void setQuestionActive(String roomCode, int questionNumber) {
log.info("Set question {} to ACTIVE in room {}", questionNumber, roomCode);
}

public Map<String, Object> revealAnswer(String roomCode, int questionNumber) {
public RevealAnswerResponse revealAnswer(String roomCode, int questionNumber) {
QuizQuestion question = redisService.getQuestion(roomCode, questionNumber);
if (question == null) {
throw new IllegalArgumentException("Question not found: " + questionNumber);
Expand All @@ -394,15 +403,14 @@ public Map<String, Object> revealAnswer(String roomCode, int questionNumber) {
Map<Integer, Integer> statistics = redisService.getAnswerStatistics(roomCode, questionNumber);
int totalAnswers = statistics.values().stream().mapToInt(Integer::intValue).sum();

Map<String, Object> result = new HashMap<>();
result.put("correctAnswer", question.getCorrectAnswer());
result.put("explanation", question.getExplanation());
result.put("statistics", statistics);
result.put("totalAnswers", totalAnswers);

log.info("Revealed answer for question {} in room {}", questionNumber, roomCode);

return result;
return RevealAnswerResponse.builder()
.correctAnswer(question.getCorrectAnswer())
.explanation(question.getExplanation())
.statistics(statistics)
.totalAnswers(totalAnswers)
.build();
}

public void nextQuestion(String roomCode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import hello.cluebackend.common.utils.JWTUtil;
import hello.cluebackend.domain.quizbattle.model.*;
import hello.cluebackend.application.quizbattle.dto.SubmitAnswerResponse;
import hello.cluebackend.domain.quizbattle.service.QuizBattleService;
import hello.cluebackend.application.quizbattle.dto.RevealAnswerResponse;
import hello.cluebackend.domain.quizbattle.service.QuizTimerService;
import hello.cluebackend.presentation.websocket.quizbattle.dto.*;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -122,13 +124,14 @@ public RoomCreatedMessage createRoom(
@MessageMapping("/quiz/join/{roomCode}")
public void joinRoom(
@DestinationVariable String roomCode,
@Payload JoinRoomRequest request,
SimpMessageHeaderAccessor headerAccessor
) {
try {
UUID userId = getUserIdFromHeader(headerAccessor);
String sessionId = headerAccessor.getSessionId();

QuizParticipant participant = quizBattleService.joinRoom(roomCode, userId, sessionId);
QuizParticipant participant = quizBattleService.joinRoom(roomCode, userId, sessionId, request.getProfileImage());
List<QuizParticipant> allParticipants = quizBattleService.getParticipants(roomCode);

ParticipantJoinedMessage message = ParticipantJoinedMessage.builder()
Expand Down Expand Up @@ -225,7 +228,7 @@ public void submitAnswer(
) {
try {
UUID userId = getUserIdFromHeader(headerAccessor);
QuizAnswer answer = quizBattleService.submitAnswer(
SubmitAnswerResponse resultData = quizBattleService.submitAnswer(
roomCode,
userId,
request.getQuestionNumber(),
Expand All @@ -234,6 +237,9 @@ public void submitAnswer(
request.getTimeSpent()
);

QuizAnswer answer = resultData.getAnswer();
int totalAnswers = resultData.getTotalAnswers();

AnswerResultMessage result = AnswerResultMessage.builder()
.questionNumber(answer.getQuestionNumber())
.isCorrect(answer.getIsCorrect())
Expand All @@ -247,8 +253,19 @@ public void submitAnswer(
result
);

log.info("User {} submitted answer for question {} in room {}",
userId, request.getQuestionNumber(), roomCode);
// Notify everyone in the room about the new answer count
int totalParticipants = quizBattleService.getParticipants(roomCode).size();
AnswerCountMessage countMessage = AnswerCountMessage.builder()
.status("ANSWER_SUBMITTED")
.message("An answer was submitted.")
.questionNumber(request.getQuestionNumber())
.totalAnswers(totalAnswers)
.totalParticipants(totalParticipants)
.build();
messagingTemplate.convertAndSend("/topic/quiz/" + roomCode + "/game", countMessage);

log.info("User {} submitted answer for question {} in room {}, total answers now {}",
userId, request.getQuestionNumber(), roomCode, totalAnswers);

} catch (Exception e) {
log.error("Error submitting answer", e);
Expand Down Expand Up @@ -284,14 +301,14 @@ public void revealAnswer(

quizTimerService.cancelQuestionTimer(roomCode, currentQuestionNum);

Map<String, Object> result = quizBattleService.revealAnswer(roomCode, currentQuestionNum);
RevealAnswerResponse result = quizBattleService.revealAnswer(roomCode, currentQuestionNum);

AnswerRevealMessage message = AnswerRevealMessage.builder()
.questionNumber(currentQuestionNum)
.correctAnswer((Integer) result.get("correctAnswer"))
.explanation((String) result.get("explanation"))
.statistics((Map<Integer, Integer>) result.get("statistics"))
.totalAnswers((Integer) result.get("totalAnswers"))
.correctAnswer(result.getCorrectAnswer())
.explanation(result.getExplanation())
.statistics(result.getStatistics())
.totalAnswers(result.getTotalAnswers())
.status("success")
.message("Answer revealed")
.build();
Expand Down Expand Up @@ -478,14 +495,14 @@ private void sendQuestionToRoom(String roomCode, QuizQuestion question) {
// 시간이 끝나면 정답만 공개하고, 다음 문제로는 넘어가지 않음
Integer currentQuestionNum = quizBattleService.getCurrentQuestionNumber(roomCode);
if (currentQuestionNum != null) {
Map<String, Object> result = quizBattleService.revealAnswer(roomCode, currentQuestionNum);
RevealAnswerResponse result = quizBattleService.revealAnswer(roomCode, currentQuestionNum);

AnswerRevealMessage message = AnswerRevealMessage.builder()
.questionNumber(currentQuestionNum)
.correctAnswer((Integer) result.get("correctAnswer"))
.explanation((String) result.get("explanation"))
.statistics((Map<Integer, Integer>) result.get("statistics"))
.totalAnswers((Integer) result.get("totalAnswers"))
.correctAnswer(result.getCorrectAnswer())
.explanation(result.getExplanation())
.statistics(result.getStatistics())
.totalAnswers(result.getTotalAnswers())
.status("success")
.message("Time's up! Answer revealed")
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package hello.cluebackend.presentation.websocket.quizbattle.dto;

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class AnswerCountMessage {
private String status;
private String message;
private int questionNumber;
private int totalAnswers;
private int totalParticipants;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package hello.cluebackend.presentation.websocket.quizbattle.dto;

import lombok.Data;

@Data
public class JoinRoomRequest {
private String profileImage;
}