Skip to content

Commit 080b5cc

Browse files
authored
๐Ÿ”– release: v0.0.11
2 parents dbf4617 + faa344f commit 080b5cc

File tree

13 files changed

+94
-121
lines changed

13 files changed

+94
-121
lines changed

โ€Žbackend/src/main/java/io/f1/backend/domain/game/app/GameService.javaโ€Ž

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public void gameStart(Long roomId, UserPrincipal principal) {
9696
public void onCorrectAnswer(GameCorrectAnswerEvent event) {
9797

9898
Room room = event.room();
99+
log.debug(room.getId() + "๋ฒˆ ๋ฐฉ ์ฑ„ํŒ…์œผ๋กœ ์ •๋‹ต! ํ˜„์žฌ ๋ผ์šด๋“œ : " + room.getCurrentRound());
99100
String sessionId = event.sessionId();
100101
ChatMessage chatMessage = event.chatMessage();
101102
String answer = event.answer();
@@ -135,6 +136,8 @@ public void onCorrectAnswer(GameCorrectAnswerEvent event) {
135136
@EventListener
136137
public void onTimeout(GameTimeoutEvent event) {
137138
Room room = event.room();
139+
log.debug(room.getId() + "๋ฒˆ ๋ฐฉ ํƒ€์ž„์•„์›ƒ! ํ˜„์žฌ ๋ผ์šด๋“œ : " + room.getCurrentRound());
140+
138141
String destination = getDestination(room.getId());
139142

140143
messageSender.sendBroadcast(

โ€Žbackend/src/main/java/io/f1/backend/domain/game/app/TimerService.javaโ€Ž

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,23 @@
44
import io.f1.backend.domain.game.model.Room;
55

66
import lombok.RequiredArgsConstructor;
7+
import lombok.extern.slf4j.Slf4j;
78

89
import org.springframework.context.ApplicationEventPublisher;
910
import org.springframework.stereotype.Service;
1011

1112
import java.util.concurrent.ScheduledFuture;
1213
import java.util.concurrent.TimeUnit;
1314

15+
@Slf4j
1416
@Service
1517
@RequiredArgsConstructor
1618
public class TimerService {
1719

1820
private final ApplicationEventPublisher eventPublisher;
1921

2022
public void startTimer(Room room, int delaySec) {
23+
log.debug(room.getId() + "๋ฒˆ ๋ฐฉ ํƒ€์ด๋จธ ์‹œ์ž‘ ! ํ˜„์žฌ ๋ผ์šด๋“œ : " + room.getCurrentRound());
2124
cancelTimer(room);
2225

2326
ScheduledFuture<?> timer =
@@ -43,6 +46,7 @@ public boolean validateCurrentRound(Room room) {
4346

4447
public boolean cancelTimer(Room room) {
4548
// ์ •๋‹ต ๋งžํ˜”์–ด์š” ~ ํƒ€์ด๋จธ ์บ”์Šฌ ๋ถ€ํƒ
49+
log.debug(room.getId() + "๋ฒˆ ๋ฐฉ ํƒ€์ด๋จธ ์ทจ์†Œ ! ํ˜„์žฌ ๋ผ์šด๋“œ : " + room.getCurrentRound());
4650
ScheduledFuture<?> timer = room.getTimer();
4751
if (timer != null && !timer.isDone()) {
4852
return timer.cancel(false);

โ€Žbackend/src/main/java/io/f1/backend/domain/question/api/QuestionController.javaโ€Ž

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
package io.f1.backend.domain.question.api;
22

33
import io.f1.backend.domain.question.app.QuestionService;
4-
import io.f1.backend.domain.question.dto.QuestionUpdateRequest;
54

65
import lombok.RequiredArgsConstructor;
76

87
import org.springframework.http.ResponseEntity;
98
import org.springframework.web.bind.annotation.DeleteMapping;
109
import org.springframework.web.bind.annotation.PathVariable;
11-
import org.springframework.web.bind.annotation.PutMapping;
12-
import org.springframework.web.bind.annotation.RequestBody;
1310
import org.springframework.web.bind.annotation.RequestMapping;
1411
import org.springframework.web.bind.annotation.RestController;
1512

@@ -20,21 +17,6 @@ public class QuestionController {
2017

2118
private final QuestionService questionService;
2219

23-
@PutMapping("/{questionId}")
24-
public ResponseEntity<Void> updateQuestion(
25-
@PathVariable Long questionId, @RequestBody QuestionUpdateRequest request) {
26-
27-
if (request.content() != null) {
28-
questionService.updateQuestionContent(questionId, request.content());
29-
}
30-
31-
if (request.content() != null) {
32-
questionService.updateQuestionAnswer(questionId, request.answer());
33-
}
34-
35-
return ResponseEntity.noContent().build();
36-
}
37-
3820
@DeleteMapping("/{questionId}")
3921
public ResponseEntity<Void> deleteQuestion(@PathVariable Long questionId) {
4022
questionService.deleteQuestion(questionId);

โ€Žbackend/src/main/java/io/f1/backend/domain/question/app/QuestionService.javaโ€Ž

Lines changed: 9 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,23 @@
22

33
import static io.f1.backend.domain.question.mapper.QuestionMapper.questionRequestToQuestion;
44
import static io.f1.backend.domain.question.mapper.TextQuestionMapper.questionRequestToTextQuestion;
5+
import static io.f1.backend.domain.quiz.app.QuizService.verifyUserAuthority;
56

67
import io.f1.backend.domain.question.dao.QuestionRepository;
78
import io.f1.backend.domain.question.dao.TextQuestionRepository;
89
import io.f1.backend.domain.question.dto.QuestionRequest;
10+
import io.f1.backend.domain.question.dto.QuestionUpdateRequest;
911
import io.f1.backend.domain.question.entity.Question;
1012
import io.f1.backend.domain.question.entity.TextQuestion;
1113
import io.f1.backend.domain.quiz.entity.Quiz;
1214
import io.f1.backend.global.exception.CustomException;
13-
import io.f1.backend.global.exception.errorcode.AuthErrorCode;
1415
import io.f1.backend.global.exception.errorcode.QuestionErrorCode;
15-
import io.f1.backend.global.security.enums.Role;
16-
import io.f1.backend.global.util.SecurityUtils;
1716

1817
import lombok.RequiredArgsConstructor;
1918

2019
import org.springframework.stereotype.Service;
2120
import org.springframework.transaction.annotation.Transactional;
2221

23-
import java.util.Objects;
24-
2522
@Service
2623
@RequiredArgsConstructor
2724
public class QuestionService {
@@ -41,46 +38,22 @@ public void saveQuestion(Quiz quiz, QuestionRequest request) {
4138
question.addTextQuestion(textQuestion);
4239
}
4340

44-
@Transactional
45-
public void updateQuestionContent(Long questionId, String content) {
46-
47-
validateContent(content);
41+
public void updateQuestions(Quiz quiz, QuestionUpdateRequest request) {
4842

49-
Question question =
50-
questionRepository
51-
.findById(questionId)
52-
.orElseThrow(
53-
() -> new CustomException(QuestionErrorCode.QUESTION_NOT_FOUND));
54-
55-
verifyUserAuthority(question.getQuiz());
56-
57-
TextQuestion textQuestion = question.getTextQuestion();
58-
textQuestion.changeContent(content);
59-
}
60-
61-
private static void verifyUserAuthority(Quiz quiz) {
62-
if (SecurityUtils.getCurrentUserRole() == Role.ADMIN) {
43+
if (request.getId() == null) {
44+
saveQuestion(quiz, QuestionRequest.of(request));
6345
return;
6446
}
65-
if (!Objects.equals(SecurityUtils.getCurrentUserId(), quiz.getCreator().getId())) {
66-
throw new CustomException(AuthErrorCode.FORBIDDEN);
67-
}
68-
}
69-
70-
@Transactional
71-
public void updateQuestionAnswer(Long questionId, String answer) {
72-
73-
validateAnswer(answer);
7447

7548
Question question =
7649
questionRepository
77-
.findById(questionId)
50+
.findById(request.getId())
7851
.orElseThrow(
7952
() -> new CustomException(QuestionErrorCode.QUESTION_NOT_FOUND));
8053

81-
verifyUserAuthority(question.getQuiz());
82-
83-
question.changeAnswer(answer);
54+
TextQuestion textQuestion = question.getTextQuestion();
55+
textQuestion.changeContent(request.getContent());
56+
question.changeAnswer(request.getAnswer());
8457
}
8558

8659
@Transactional
@@ -96,16 +69,4 @@ public void deleteQuestion(Long questionId) {
9669

9770
questionRepository.delete(question);
9871
}
99-
100-
private void validateAnswer(String answer) {
101-
if (answer.trim().length() < 5 || answer.trim().length() > 30) {
102-
throw new CustomException(QuestionErrorCode.INVALID_ANSWER_LENGTH);
103-
}
104-
}
105-
106-
private void validateContent(String content) {
107-
if (content.trim().length() < 5 || content.trim().length() > 30) {
108-
throw new CustomException(QuestionErrorCode.INVALID_CONTENT_LENGTH);
109-
}
110-
}
11172
}

โ€Žbackend/src/main/java/io/f1/backend/domain/question/dto/QuestionRequest.javaโ€Ž

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,12 @@ public class QuestionRequest {
1919
@TrimmedSize(min = 1, max = 30)
2020
@NotBlank(message = "์ •๋‹ต์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.")
2121
private String answer;
22+
23+
public static QuestionRequest of(QuestionUpdateRequest request) {
24+
QuestionRequest questionRequest = new QuestionRequest();
25+
questionRequest.content = request.getContent();
26+
questionRequest.answer = request.getAnswer();
27+
28+
return questionRequest;
29+
}
2230
}
Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
11
package io.f1.backend.domain.question.dto;
22

3-
public record QuestionUpdateRequest(String content, String answer) {}
3+
import io.f1.backend.global.validation.TrimmedSize;
4+
5+
import jakarta.validation.constraints.NotBlank;
6+
7+
import lombok.AccessLevel;
8+
import lombok.Getter;
9+
import lombok.NoArgsConstructor;
10+
11+
@Getter
12+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
13+
public class QuestionUpdateRequest {
14+
15+
private Long id;
16+
17+
@TrimmedSize(min = 5, max = 30)
18+
@NotBlank(message = "๋ฌธ์ œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.")
19+
private String content;
20+
21+
@TrimmedSize(min = 1, max = 30)
22+
@NotBlank(message = "์ •๋‹ต์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.")
23+
private String answer;
24+
}

โ€Žbackend/src/main/java/io/f1/backend/domain/quiz/api/QuizController.javaโ€Ž

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,9 @@ public ResponseEntity<Void> deleteQuiz(@PathVariable Long quizId) {
5757
public ResponseEntity<Void> updateQuiz(
5858
@PathVariable Long quizId,
5959
@RequestPart(required = false) MultipartFile thumbnailFile,
60-
@RequestPart QuizUpdateRequest request) {
60+
@Valid @RequestPart QuizUpdateRequest request) {
6161

62-
if (request.title() != null) {
63-
quizService.updateQuizTitle(quizId, request.title());
64-
}
65-
66-
if (request.description() != null) {
67-
quizService.updateQuizDesc(quizId, request.description());
68-
}
62+
quizService.updateQuizAndQuestions(quizId, request);
6963

7064
if (thumbnailFile != null && !thumbnailFile.isEmpty()) {
7165
quizService.updateThumbnail(quizId, thumbnailFile);

โ€Žbackend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.javaโ€Ž

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import io.f1.backend.domain.question.app.QuestionService;
88
import io.f1.backend.domain.question.dto.QuestionRequest;
9+
import io.f1.backend.domain.question.dto.QuestionUpdateRequest;
910
import io.f1.backend.domain.question.entity.Question;
1011
import io.f1.backend.domain.quiz.dao.QuizRepository;
1112
import io.f1.backend.domain.quiz.dto.QuizCreateRequest;
@@ -14,6 +15,7 @@
1415
import io.f1.backend.domain.quiz.dto.QuizListResponse;
1516
import io.f1.backend.domain.quiz.dto.QuizMinData;
1617
import io.f1.backend.domain.quiz.dto.QuizQuestionListResponse;
18+
import io.f1.backend.domain.quiz.dto.QuizUpdateRequest;
1719
import io.f1.backend.domain.quiz.entity.Quiz;
1820
import io.f1.backend.domain.user.dao.UserRepository;
1921
import io.f1.backend.domain.user.entity.User;
@@ -138,7 +140,7 @@ public void deleteQuiz(Long quizId) {
138140
quizRepository.deleteById(quizId);
139141
}
140142

141-
private static void verifyUserAuthority(Quiz quiz) {
143+
public static void verifyUserAuthority(Quiz quiz) {
142144
if (SecurityUtils.getCurrentUserRole() == Role.ADMIN) {
143145
return;
144146
}
@@ -148,30 +150,22 @@ private static void verifyUserAuthority(Quiz quiz) {
148150
}
149151

150152
@Transactional
151-
public void updateQuizTitle(Long quizId, String title) {
153+
public void updateQuizAndQuestions(Long quizId, QuizUpdateRequest request) {
152154
Quiz quiz =
153155
quizRepository
154156
.findById(quizId)
155157
.orElseThrow(() -> new CustomException(QuizErrorCode.QUIZ_NOT_FOUND));
156158

157159
verifyUserAuthority(quiz);
158160

159-
validateTitle(title);
160-
quiz.changeTitle(title);
161-
}
162-
163-
@Transactional
164-
public void updateQuizDesc(Long quizId, String description) {
165-
166-
Quiz quiz =
167-
quizRepository
168-
.findById(quizId)
169-
.orElseThrow(() -> new CustomException(QuizErrorCode.QUIZ_NOT_FOUND));
161+
quiz.changeTitle(request.getTitle());
162+
quiz.changeDescription(request.getDescription());
170163

171-
verifyUserAuthority(quiz);
164+
List<QuestionUpdateRequest> questionReqList = request.getQuestions();
172165

173-
validateDesc(description);
174-
quiz.changeDescription(description);
166+
for (QuestionUpdateRequest questionReq : questionReqList) {
167+
questionService.updateQuestions(quiz, questionReq);
168+
}
175169
}
176170

177171
@Transactional
@@ -191,18 +185,6 @@ public void updateThumbnail(Long quizId, MultipartFile thumbnailFile) {
191185
quiz.changeThumbnailUrl(newThumbnailPath);
192186
}
193187

194-
private void validateDesc(String desc) {
195-
if (desc.trim().length() < 10 || desc.trim().length() > 50) {
196-
throw new CustomException(QuizErrorCode.INVALID_DESC_LENGTH);
197-
}
198-
}
199-
200-
private void validateTitle(String title) {
201-
if (title.trim().length() < 2 || title.trim().length() > 30) {
202-
throw new CustomException(QuizErrorCode.INVALID_TITLE_LENGTH);
203-
}
204-
}
205-
206188
private void deleteThumbnailFile(String oldFilename) {
207189
if (oldFilename.contains(DEFAULT)) {
208190
return;
Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
11
package io.f1.backend.domain.quiz.dto;
22

3-
public record QuizUpdateRequest(String title, String description) {}
3+
import io.f1.backend.domain.question.dto.QuestionUpdateRequest;
4+
import io.f1.backend.global.validation.TrimmedSize;
5+
6+
import jakarta.validation.constraints.NotBlank;
7+
import jakarta.validation.constraints.Size;
8+
9+
import lombok.AccessLevel;
10+
import lombok.Getter;
11+
import lombok.NoArgsConstructor;
12+
13+
import java.util.List;
14+
15+
@Getter
16+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
17+
public class QuizUpdateRequest {
18+
19+
@TrimmedSize(min = 2, max = 30)
20+
@NotBlank(message = "ํ€ด์ฆˆ ์ œ๋ชฉ์„ ์„ค์ •ํ•ด์ฃผ์„ธ์š”.")
21+
private String title;
22+
23+
@TrimmedSize(min = 10, max = 50)
24+
@NotBlank(message = "ํ€ด์ฆˆ ์„ค๋ช…์„ ์ ์–ด์ฃผ์„ธ์š”.")
25+
private String description;
26+
27+
@Size(min = 10, max = 80, message = "๋ฌธ์ œ๋Š” ์ตœ์†Œ 10๊ฐœ, ์ตœ๋Œ€ 80๊ฐœ๋กœ ์ •ํ•ด์ฃผ์„ธ์š”.")
28+
private List<QuestionUpdateRequest> questions;
29+
}

โ€Žbackend/src/main/java/io/f1/backend/domain/stat/dao/StatRepositoryAdapter.javaโ€Ž

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
import io.f1.backend.global.exception.errorcode.RoomErrorCode;
1111
import io.f1.backend.global.exception.errorcode.UserErrorCode;
1212

13-
import jakarta.annotation.PostConstruct;
14-
1513
import lombok.RequiredArgsConstructor;
1614
import lombok.extern.slf4j.Slf4j;
1715

@@ -30,7 +28,6 @@ public class StatRepositoryAdapter implements StatRepository {
3028
private final StatJpaRepository jpaRepository;
3129
private final StatRedisRepository redisRepository;
3230

33-
@PostConstruct
3431
public void setup() {
3532
redisRepository.setup();
3633
warmingRedis();

0 commit comments

Comments
ย (0)