From d98947ca1ea19dffcb5ceb4f79dbd2bbcc40925b Mon Sep 17 00:00:00 2001 From: 1Seob Date: Sun, 3 May 2026 21:11:01 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20user=5Fdaily=5Fquestions=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=EC=97=90=20reroll=5Fleft=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=20=EB=B0=8F=20=EC=97=94=ED=8B=B0=ED=8B=B0=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 데이터 reroll_left = 0 백필, 신규 데이터 기본값 5, NOT NULL 적용, UserDailyQuestion 엔티티에 rerollLeft 필드 및 초기값 반영 --- .../question/core/entity/UserDailyQuestion.java | 5 +++++ ...3__IS_add_reroll_left_to_user_daily_questions.sql | 12 ++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/main/resources/db/migration/V20260503_1953__IS_add_reroll_left_to_user_daily_questions.sql diff --git a/src/main/java/com/devkor/ifive/nadab/domain/question/core/entity/UserDailyQuestion.java b/src/main/java/com/devkor/ifive/nadab/domain/question/core/entity/UserDailyQuestion.java index c130083c..80405611 100644 --- a/src/main/java/com/devkor/ifive/nadab/domain/question/core/entity/UserDailyQuestion.java +++ b/src/main/java/com/devkor/ifive/nadab/domain/question/core/entity/UserDailyQuestion.java @@ -38,12 +38,16 @@ public class UserDailyQuestion extends AuditableEntity { @Column(name = "reroll_used", nullable = false) private boolean rerollUsed = false; + @Column(name = "reroll_left", nullable = false) + private int rerollLeft = 5; + public static UserDailyQuestion create(User user, LocalDate date, DailyQuestion dailyQuestion) { UserDailyQuestion udq = new UserDailyQuestion(); udq.user = user; udq.date = date; udq.dailyQuestion = dailyQuestion; udq.rerollUsed = false; + udq.rerollLeft = 5; return udq; } @@ -51,5 +55,6 @@ public static UserDailyQuestion create(User user, LocalDate date, DailyQuestion public void rerollTo(DailyQuestion newQuestion) { this.dailyQuestion = newQuestion; this.rerollUsed = true; + this.rerollLeft = Math.max(0, this.rerollLeft - 1); } } \ No newline at end of file diff --git a/src/main/resources/db/migration/V20260503_1953__IS_add_reroll_left_to_user_daily_questions.sql b/src/main/resources/db/migration/V20260503_1953__IS_add_reroll_left_to_user_daily_questions.sql new file mode 100644 index 00000000..1bde9cef --- /dev/null +++ b/src/main/resources/db/migration/V20260503_1953__IS_add_reroll_left_to_user_daily_questions.sql @@ -0,0 +1,12 @@ +ALTER TABLE user_daily_questions +ADD COLUMN reroll_left INT; + +UPDATE user_daily_questions +SET reroll_left = 0 +WHERE reroll_left IS NULL; + +ALTER TABLE user_daily_questions +ALTER COLUMN reroll_left SET DEFAULT 5; + +ALTER TABLE user_daily_questions +ALTER COLUMN reroll_left SET NOT NULL; From 19a44a84d6101018c81a9a80e3bb6f6f22254ede Mon Sep 17 00:00:00 2001 From: 1Seob Date: Mon, 4 May 2026 11:10:34 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=EC=98=A4=EB=8A=98=EC=9D=98=20?= =?UTF-8?q?=EC=A7=88=EB=AC=B8=20=EC=A1=B0=ED=9A=8C=20V2=20API=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../question/api/QuestionControllerV2.java | 64 ++++++++++++++ .../dto/response/DailyQuestionResponseV2.java | 31 +++++++ .../application/QuestionCommandServiceV2.java | 86 +++++++++++++++++++ .../helper/QuestionLevelPolicy.java | 4 + .../UserDailyQuestionRepository.java | 2 + src/main/resources/application-local.yml | 1 + 6 files changed, 188 insertions(+) create mode 100644 src/main/java/com/devkor/ifive/nadab/domain/question/api/QuestionControllerV2.java create mode 100644 src/main/java/com/devkor/ifive/nadab/domain/question/api/dto/response/DailyQuestionResponseV2.java create mode 100644 src/main/java/com/devkor/ifive/nadab/domain/question/application/QuestionCommandServiceV2.java diff --git a/src/main/java/com/devkor/ifive/nadab/domain/question/api/QuestionControllerV2.java b/src/main/java/com/devkor/ifive/nadab/domain/question/api/QuestionControllerV2.java new file mode 100644 index 00000000..0b57d4ab --- /dev/null +++ b/src/main/java/com/devkor/ifive/nadab/domain/question/api/QuestionControllerV2.java @@ -0,0 +1,64 @@ +package com.devkor.ifive.nadab.domain.question.api; + +import com.devkor.ifive.nadab.domain.question.api.dto.response.DailyQuestionResponseV2; +import com.devkor.ifive.nadab.domain.question.application.QuestionCommandServiceV2; +import com.devkor.ifive.nadab.global.core.response.ApiResponseDto; +import com.devkor.ifive.nadab.global.core.response.ApiResponseEntity; +import com.devkor.ifive.nadab.global.security.principal.UserPrincipal; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "질문 API V2", description = "오늘의 질문 관련 API V2") +@RestController +@RequestMapping("/api/v2/question") +@RequiredArgsConstructor +public class QuestionControllerV2 { + + private final QuestionCommandServiceV2 questionCommandService; + + @GetMapping + @PreAuthorize("isAuthenticated()") + @Operation( + summary = "오늘의 질문 조회", + description = "오늘의 질문을 조회합니다.", + security = @SecurityRequirement(name = "bearerAuth"), + responses = { + @ApiResponse( + responseCode = "200", + description = "성공", + content = @Content(schema = @Schema(implementation = DailyQuestionResponseV2.class), mediaType = "application/json") + ), + @ApiResponse( + responseCode = "401", + description = "인증 실패 (JWT 토큰 관련)", + content = @Content + ), + @ApiResponse( + responseCode = "404", + description = """ + - ErrorCode: USER_NOT_FOUND - 사용자를 찾을 수 없습니다. + - ErrorCode: USER_INTEREST_NOT_FOUND - 관심 주제를 찾을 수 없습니다. + - ErrorCode: QUESTION_NOT_FOUND_FOR_CONDITION - 조건에 맞는 질문을 찾을 수 없습니다. + """, + content = @Content + ) + } + ) + public ResponseEntity> getDailyQuestion( + @AuthenticationPrincipal UserPrincipal principal + ) { + DailyQuestionResponseV2 response = questionCommandService.getOrCreateTodayQuestion(principal.getId()); + return ApiResponseEntity.ok(response); + } +} diff --git a/src/main/java/com/devkor/ifive/nadab/domain/question/api/dto/response/DailyQuestionResponseV2.java b/src/main/java/com/devkor/ifive/nadab/domain/question/api/dto/response/DailyQuestionResponseV2.java new file mode 100644 index 00000000..524bd218 --- /dev/null +++ b/src/main/java/com/devkor/ifive/nadab/domain/question/api/dto/response/DailyQuestionResponseV2.java @@ -0,0 +1,31 @@ +package com.devkor.ifive.nadab.domain.question.api.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "오늘의 질문 응답") +public record DailyQuestionResponseV2( + @Schema(description = "질문 ID") + Long questionId, + + @Schema(description = "관심 주제 코드", example = "PREFERENCE") + String interestCode, + + @Schema(description = "질문 텍스트", example = "요즘 자주 찾는 색깔은 무엇인가요?") + String questionText, + + @Schema(description = "공감 가이드 텍스트", example = "색깔 하나로 기분이 달라질 때가 있어요.") + String empathyGuide, + + @Schema(description = "힌트 가이드 텍스트", example = "지금 입은 옷이나 주변 소품을 보세요.") + String hintGuide, + + @Schema(description = "도입 질문 가이드 텍스트", example = "그 색을 보면 어떤 기분이 드나요?") + String leadingQuestionGuide, + + @Schema(description = "사용자가 오늘의 질문에 답변했는지 여부") + boolean answered, + + @Schema(description = "사용자의 오늘의 질문을 새로 받기 남은 횟수") + int rerollRemainingCount +) { +} diff --git a/src/main/java/com/devkor/ifive/nadab/domain/question/application/QuestionCommandServiceV2.java b/src/main/java/com/devkor/ifive/nadab/domain/question/application/QuestionCommandServiceV2.java new file mode 100644 index 00000000..2838f4d9 --- /dev/null +++ b/src/main/java/com/devkor/ifive/nadab/domain/question/application/QuestionCommandServiceV2.java @@ -0,0 +1,86 @@ +package com.devkor.ifive.nadab.domain.question.application; + +import com.devkor.ifive.nadab.domain.dailyreport.core.repository.AnswerEntryRepository; +import com.devkor.ifive.nadab.domain.question.api.dto.response.DailyQuestionResponseV2; +import com.devkor.ifive.nadab.domain.question.application.helper.DailyQuestionSelector; +import com.devkor.ifive.nadab.domain.question.application.helper.QuestionLevelPolicy; +import com.devkor.ifive.nadab.domain.question.core.entity.DailyQuestion; +import com.devkor.ifive.nadab.domain.question.core.entity.UserDailyQuestion; +import com.devkor.ifive.nadab.domain.question.core.repository.UserDailyQuestionRepository; +import com.devkor.ifive.nadab.domain.user.core.entity.User; +import com.devkor.ifive.nadab.domain.user.core.repository.UserInterestRepository; +import com.devkor.ifive.nadab.domain.user.core.repository.UserRepository; +import com.devkor.ifive.nadab.global.core.response.ErrorCode; +import com.devkor.ifive.nadab.global.exception.NotFoundException; +import com.devkor.ifive.nadab.global.shared.util.TodayDateTimeProvider; +import lombok.RequiredArgsConstructor; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; + +@Service +@RequiredArgsConstructor +@Transactional +public class QuestionCommandServiceV2 { + + private final UserRepository userRepository; + private final UserDailyQuestionRepository userDailyQuestionRepository; + private final UserInterestRepository userInterestRepository; + private final AnswerEntryRepository answerEntryRepository; + + private final QuestionLevelPolicy questionLevelPolicy; + private final DailyQuestionSelector dailyQuestionSelector; + + public DailyQuestionResponseV2 getOrCreateTodayQuestion(Long userId) { + + User user = userRepository.findById(userId) + .orElseThrow(() -> new NotFoundException(ErrorCode.USER_NOT_FOUND)); + + LocalDate today = TodayDateTimeProvider.getTodayDate(); + UserDailyQuestion udq = userDailyQuestionRepository.findByUserIdAndDate(userId, today) + .orElseGet(() -> this.createTodayQuestion(userId, today)); + + DailyQuestion question = udq.getDailyQuestion(); + + boolean answered = answerEntryRepository.existsActiveAnswer(userId, question.getId()); + + return new DailyQuestionResponseV2( + question.getId(), + question.getInterest().getCode().toString(), + question.getQuestionText(), + question.getEmpathyGuide(), + question.getHintGuide(), + question.getLeadingQuestionGuide(), + answered, + udq.getRerollLeft() + ); + } + + public UserDailyQuestion createTodayQuestion(Long userId, LocalDate todayKst) { + // 동시성: 여러 요청이 동시에 들어오면 UNIQUE(user_id, date)로 한 번만 성공해야 함 + // -> insert 시도 후 unique 위반이면 다시 조회해서 반환 + try { + User user = userRepository.findById(userId) + .orElseThrow(() -> new NotFoundException(ErrorCode.USER_NOT_FOUND)); + + Long userInterestId = userInterestRepository.findInterestIdByUserId(userId) + .orElseThrow(() -> new NotFoundException(ErrorCode.USER_INTEREST_NOT_FOUND)); + + boolean isFirstQuestion = !(userDailyQuestionRepository.existsByUserId(userId)); + + Integer levelOnly = questionLevelPolicy.levelOnlyForFirstTime(isFirstQuestion); + + DailyQuestion picked = dailyQuestionSelector.pickFirst(user.getId(), userInterestId, levelOnly); + + UserDailyQuestion udq = UserDailyQuestion.create(user, todayKst, picked); + return userDailyQuestionRepository.save(udq); + + } catch (DataIntegrityViolationException e) { + // 이미 생성됨(경합 상황) + return userDailyQuestionRepository.findByUserIdAndDate(userId, todayKst) + .orElseThrow(() -> e); + } + } +} diff --git a/src/main/java/com/devkor/ifive/nadab/domain/question/application/helper/QuestionLevelPolicy.java b/src/main/java/com/devkor/ifive/nadab/domain/question/application/helper/QuestionLevelPolicy.java index 098fe9d6..e68867a2 100644 --- a/src/main/java/com/devkor/ifive/nadab/domain/question/application/helper/QuestionLevelPolicy.java +++ b/src/main/java/com/devkor/ifive/nadab/domain/question/application/helper/QuestionLevelPolicy.java @@ -22,4 +22,8 @@ public Integer levelOnlyFor(User user, OffsetDateTime now) { boolean isNewbie = registeredAt.isAfter(now.minusDays(NEWBIE_DAYS)); return isNewbie ? NEWBIE_LEVEL_ONLY : null; } + + public Integer levelOnlyForFirstTime(boolean isFirstQuestion) { + return isFirstQuestion ? NEWBIE_LEVEL_ONLY : null; + } } diff --git a/src/main/java/com/devkor/ifive/nadab/domain/question/core/repository/UserDailyQuestionRepository.java b/src/main/java/com/devkor/ifive/nadab/domain/question/core/repository/UserDailyQuestionRepository.java index c3a4ce5d..1dde401b 100644 --- a/src/main/java/com/devkor/ifive/nadab/domain/question/core/repository/UserDailyQuestionRepository.java +++ b/src/main/java/com/devkor/ifive/nadab/domain/question/core/repository/UserDailyQuestionRepository.java @@ -9,4 +9,6 @@ public interface UserDailyQuestionRepository extends JpaRepository { Optional findByUserIdAndDate(Long userId, LocalDate date); + + boolean existsByUserId(Long userId); } diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index ed280ab7..0bf513ff 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -21,6 +21,7 @@ springdoc: enabled: true swagger-ui: path: /swagger-ui.html + tags-sorter: alpha oauth: naver: From 5a105df4164f9229cf14ae57676549075db1af15 Mon Sep 17 00:00:00 2001 From: 1Seob Date: Mon, 4 May 2026 15:23:22 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=EC=98=A4=EB=8A=98=EC=9D=98=20?= =?UTF-8?q?=EC=A7=88=EB=AC=B8=20=EC=A1=B0=ED=9A=8C=20V2=20API=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../question/api/QuestionControllerV2.java | 44 +++++++++++++++++++ .../application/QuestionCommandServiceV2.java | 42 ++++++++++++++++++ .../nadab/global/core/response/ErrorCode.java | 2 +- .../core/entity/UserDailyQuestionTest.java | 37 ++++++++++++++++ 4 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/devkor/ifive/nadab/domain/question/core/entity/UserDailyQuestionTest.java diff --git a/src/main/java/com/devkor/ifive/nadab/domain/question/api/QuestionControllerV2.java b/src/main/java/com/devkor/ifive/nadab/domain/question/api/QuestionControllerV2.java index 0b57d4ab..eeee26f8 100644 --- a/src/main/java/com/devkor/ifive/nadab/domain/question/api/QuestionControllerV2.java +++ b/src/main/java/com/devkor/ifive/nadab/domain/question/api/QuestionControllerV2.java @@ -16,6 +16,7 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -61,4 +62,47 @@ public ResponseEntity> getDailyQuestion( DailyQuestionResponseV2 response = questionCommandService.getOrCreateTodayQuestion(principal.getId()); return ApiResponseEntity.ok(response); } + + @PostMapping("/reroll") + @PreAuthorize("isAuthenticated()") + @Operation( + summary = "새로운 질문 받기", + description = "오늘의 질문을 새로 받습니다. 하루에 5번까지 가능합니다.", + security = @SecurityRequirement(name = "bearerAuth"), + responses = { + @ApiResponse( + responseCode = "200", + description = "성공", + content = @Content(schema = @Schema(implementation = DailyQuestionResponseV2.class), mediaType = "application/json") + ), + @ApiResponse( + responseCode = "401", + description = "사용자 인증 실패", + content = @Content + ), + @ApiResponse( + responseCode = "404", + description = """ + - ErrorCode: DAILY_QUESTION_NOT_FOUND - 오늘의 질문이 아직 생성되지 않았습니다. + - ErrorCode: USER_INTEREST_NOT_FOUND - 유저의 관심 주제를 찾을 수 없습니다. + - ErrorCode: QUESTION_NO_ALTERNATIVE - 리롤 가능한 질문이 없습니다. + """, + content = @Content + ), + @ApiResponse( + responseCode = "409", + description = """ + - ErrorCode: QUESTION_REROLL_LIMIT_EXCEEDED - 오늘의 질문은 하루에 5번까지만 새로 받을 수 있습니다. + - ErrorCode: QUESTION_ALREADY_ANSWERED - 오늘의 질문에 이미 답변을 작성함 + """, + content = @Content + ) + } + ) + public ResponseEntity> rerollDailyQuestion( + @AuthenticationPrincipal UserPrincipal principal + ) { + DailyQuestionResponseV2 response = questionCommandService.rerollTodayQuestion(principal.getId()); + return ApiResponseEntity.ok(response); + } } diff --git a/src/main/java/com/devkor/ifive/nadab/domain/question/application/QuestionCommandServiceV2.java b/src/main/java/com/devkor/ifive/nadab/domain/question/application/QuestionCommandServiceV2.java index 2838f4d9..c2385c8f 100644 --- a/src/main/java/com/devkor/ifive/nadab/domain/question/application/QuestionCommandServiceV2.java +++ b/src/main/java/com/devkor/ifive/nadab/domain/question/application/QuestionCommandServiceV2.java @@ -11,6 +11,7 @@ import com.devkor.ifive.nadab.domain.user.core.repository.UserInterestRepository; import com.devkor.ifive.nadab.domain.user.core.repository.UserRepository; import com.devkor.ifive.nadab.global.core.response.ErrorCode; +import com.devkor.ifive.nadab.global.exception.ConflictException; import com.devkor.ifive.nadab.global.exception.NotFoundException; import com.devkor.ifive.nadab.global.shared.util.TodayDateTimeProvider; import lombok.RequiredArgsConstructor; @@ -83,4 +84,45 @@ public UserDailyQuestion createTodayQuestion(Long userId, LocalDate todayKst) { .orElseThrow(() -> e); } } + + public DailyQuestionResponseV2 rerollTodayQuestion(Long userId) { + LocalDate today = TodayDateTimeProvider.getTodayDate(); + + UserDailyQuestion udq = userDailyQuestionRepository.findByUserIdAndDate(userId, today) + .orElseThrow(() -> new NotFoundException(ErrorCode.DAILY_QUESTION_NOT_FOUND)); + + if (udq.getRerollLeft() <= 0) { + throw new ConflictException(ErrorCode.QUESTION_REROLL_LIMIT_EXCEEDED); + } + + User user = udq.getUser(); + + boolean alreadyAnswered = answerEntryRepository.existsByUserAndDate(user, today); + if (alreadyAnswered) { + throw new ConflictException(ErrorCode.QUESTION_ALREADY_ANSWERED); + } + + Long userInterestId = userInterestRepository.findInterestIdByUserId(userId) + .orElseThrow(() -> new NotFoundException(ErrorCode.USER_INTEREST_NOT_FOUND)); + + DailyQuestion newQ = dailyQuestionSelector.pickReroll( + user.getId(), + userInterestId, + udq.getDailyQuestion().getId(), + null + ); + + udq.rerollTo(newQ); + + return new DailyQuestionResponseV2( + newQ.getId(), + newQ.getInterest().getCode().toString(), + newQ.getQuestionText(), + newQ.getEmpathyGuide(), + newQ.getHintGuide(), + newQ.getLeadingQuestionGuide(), + false, + udq.getRerollLeft() + ); + } } diff --git a/src/main/java/com/devkor/ifive/nadab/global/core/response/ErrorCode.java b/src/main/java/com/devkor/ifive/nadab/global/core/response/ErrorCode.java index bb38165e..a2c6053a 100644 --- a/src/main/java/com/devkor/ifive/nadab/global/core/response/ErrorCode.java +++ b/src/main/java/com/devkor/ifive/nadab/global/core/response/ErrorCode.java @@ -104,7 +104,7 @@ public enum ErrorCode { DAILY_QUESTION_NOT_FOUND(HttpStatus.NOT_FOUND, "오늘의 질문이 아직 생성되지 않았습니다"), // 409 Conflict - QUESTION_REROLL_LIMIT_EXCEEDED(HttpStatus.CONFLICT, "오늘의 질문은 하루에 한 번만 새로 받을 수 있습니다"), + QUESTION_REROLL_LIMIT_EXCEEDED(HttpStatus.CONFLICT, "오늘의 질문은 변경 가능 횟수가 모두 소진되었습니다"), QUESTION_ALREADY_ANSWERED(HttpStatus.CONFLICT, "오늘의 질문에 이미 답변을 작성한 후에는 질문을 새로 받을 수 없습니다"), // ==================== WALLET (지갑) ==================== diff --git a/src/test/java/com/devkor/ifive/nadab/domain/question/core/entity/UserDailyQuestionTest.java b/src/test/java/com/devkor/ifive/nadab/domain/question/core/entity/UserDailyQuestionTest.java new file mode 100644 index 00000000..adde0853 --- /dev/null +++ b/src/test/java/com/devkor/ifive/nadab/domain/question/core/entity/UserDailyQuestionTest.java @@ -0,0 +1,37 @@ +package com.devkor.ifive.nadab.domain.question.core.entity; + +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; + +import static org.assertj.core.api.Assertions.assertThat; + +class UserDailyQuestionTest { + + @Test + void create_초기_리롤_횟수는_5다() { + // given + LocalDate date = LocalDate.now(); + DailyQuestion dailyQuestion = new DailyQuestion(); + + // when + UserDailyQuestion userDailyQuestion = UserDailyQuestion.create(null, date, dailyQuestion); + + // then + assertThat(userDailyQuestion.getRerollLeft()).isEqualTo(5); + assertThat(userDailyQuestion.isRerollUsed()).isFalse(); + } + + @Test + void rerollTo_호출시_rerollUsed는_true가_된다() { + // given + LocalDate date = LocalDate.now(); + UserDailyQuestion userDailyQuestion = UserDailyQuestion.create(null, date, new DailyQuestion()); + + // when + userDailyQuestion.rerollTo(new DailyQuestion()); + + // then + assertThat(userDailyQuestion.isRerollUsed()).isTrue(); + } +} From 9c284c6b43b7319b9fac9e9927fb1f9def3e84f9 Mon Sep 17 00:00:00 2001 From: 1Seob Date: Mon, 4 May 2026 20:25:14 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat(infra):=20=EA=B0=9C=EB=B0=9C=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20Swagger=20UI=20=ED=83=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EB=B0=A9=EC=8B=9D=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 8b806859..e89709a2 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -20,6 +20,7 @@ springdoc: enabled: true swagger-ui: path: /swagger-ui.html + tags-sorter: alpha oauth: naver: From 24c47a8a1cc5fc122a54759dfcdf81c132fb282a Mon Sep 17 00:00:00 2001 From: 1Seob Date: Tue, 5 May 2026 01:58:54 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20reroll=5Fleft=EC=9D=98=20=EB=B0=B1?= =?UTF-8?q?=ED=95=84=20=EA=B0=92=EC=9D=84=205=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0260503_1953__IS_add_reroll_left_to_user_daily_questions.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/migration/V20260503_1953__IS_add_reroll_left_to_user_daily_questions.sql b/src/main/resources/db/migration/V20260503_1953__IS_add_reroll_left_to_user_daily_questions.sql index 1bde9cef..7ce4ef99 100644 --- a/src/main/resources/db/migration/V20260503_1953__IS_add_reroll_left_to_user_daily_questions.sql +++ b/src/main/resources/db/migration/V20260503_1953__IS_add_reroll_left_to_user_daily_questions.sql @@ -2,7 +2,7 @@ ALTER TABLE user_daily_questions ADD COLUMN reroll_left INT; UPDATE user_daily_questions -SET reroll_left = 0 +SET reroll_left = 5 WHERE reroll_left IS NULL; ALTER TABLE user_daily_questions