From af5c0202ee2ab54741070df7c48b99983f5d83a0 Mon Sep 17 00:00:00 2001 From: Hyeonji <110809927+skylar1220@users.noreply.github.com> Date: Sun, 27 Oct 2024 15:32:27 +0900 Subject: [PATCH 01/11] =?UTF-8?q?[BE]=20=EC=98=88=EC=99=B8=EC=9D=98=20?= =?UTF-8?q?=EC=9E=98=EB=AA=BB=EB=90=9C=20=EB=A1=9C=EA=B7=B8=EB=A0=88?= =?UTF-8?q?=EB=B2=A8=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20(#951)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 로그 레벨 info로 조정 * refactor: 사용하지 않는 예외 삭제 --- .../HighlightStartIndexExceedEndIndexException.java | 13 ------------- .../MissingTextAnswerForQuestionException.java | 13 ------------- .../exception/AnswerNotFoundByIdException.java | 13 ------------- .../exception/InvalidTextAnswerLengthException.java | 2 +- ...uestionAndProvidedQuestionMismatchException.java | 6 ------ 5 files changed, 1 insertion(+), 46 deletions(-) delete mode 100644 backend/src/main/java/reviewme/highlight/domain/exception/HighlightStartIndexExceedEndIndexException.java delete mode 100644 backend/src/main/java/reviewme/review/domain/exception/MissingTextAnswerForQuestionException.java delete mode 100644 backend/src/main/java/reviewme/review/service/exception/AnswerNotFoundByIdException.java diff --git a/backend/src/main/java/reviewme/highlight/domain/exception/HighlightStartIndexExceedEndIndexException.java b/backend/src/main/java/reviewme/highlight/domain/exception/HighlightStartIndexExceedEndIndexException.java deleted file mode 100644 index 38c99ac9a..000000000 --- a/backend/src/main/java/reviewme/highlight/domain/exception/HighlightStartIndexExceedEndIndexException.java +++ /dev/null @@ -1,13 +0,0 @@ -package reviewme.highlight.domain.exception; - -import lombok.extern.slf4j.Slf4j; -import reviewme.global.exception.BadRequestException; - -@Slf4j -public class HighlightStartIndexExceedEndIndexException extends BadRequestException { - - public HighlightStartIndexExceedEndIndexException(int startIndex, int endIndex) { - super("하이라이트 끝 위치는 시작 위치보다 같거나 커야 해요."); - log.info("Highlight start index exceed end index - startIndex: {}, endIndex: {}", startIndex, endIndex); - } -} diff --git a/backend/src/main/java/reviewme/review/domain/exception/MissingTextAnswerForQuestionException.java b/backend/src/main/java/reviewme/review/domain/exception/MissingTextAnswerForQuestionException.java deleted file mode 100644 index 674dce41c..000000000 --- a/backend/src/main/java/reviewme/review/domain/exception/MissingTextAnswerForQuestionException.java +++ /dev/null @@ -1,13 +0,0 @@ -package reviewme.review.domain.exception; - -import lombok.extern.slf4j.Slf4j; -import reviewme.global.exception.DataInconsistencyException; - -@Slf4j -public class MissingTextAnswerForQuestionException extends DataInconsistencyException { - - public MissingTextAnswerForQuestionException(long questionId) { - super("서버 내부에 문제가 발생했습니다. 잠시 후 다시 시도해주세요."); - log.error("The question is a text question but text answer not found for questionId: {}", questionId, this); - } -} diff --git a/backend/src/main/java/reviewme/review/service/exception/AnswerNotFoundByIdException.java b/backend/src/main/java/reviewme/review/service/exception/AnswerNotFoundByIdException.java deleted file mode 100644 index aef381ffc..000000000 --- a/backend/src/main/java/reviewme/review/service/exception/AnswerNotFoundByIdException.java +++ /dev/null @@ -1,13 +0,0 @@ -package reviewme.review.service.exception; - -import lombok.extern.slf4j.Slf4j; -import reviewme.global.exception.NotFoundException; - -@Slf4j -public class AnswerNotFoundByIdException extends NotFoundException { - - public AnswerNotFoundByIdException(long answerId) { - super("답변을 찾을 수 없어요."); - log.info("Answer not found by id - answerId: {}", answerId); - } -} diff --git a/backend/src/main/java/reviewme/review/service/exception/InvalidTextAnswerLengthException.java b/backend/src/main/java/reviewme/review/service/exception/InvalidTextAnswerLengthException.java index 01c02ceb7..314f72673 100644 --- a/backend/src/main/java/reviewme/review/service/exception/InvalidTextAnswerLengthException.java +++ b/backend/src/main/java/reviewme/review/service/exception/InvalidTextAnswerLengthException.java @@ -8,7 +8,7 @@ public class InvalidTextAnswerLengthException extends BadRequestException { public InvalidTextAnswerLengthException(long questionId, int answerLength, int minLength, int maxLength) { super("답변의 길이는 %d자 이상 %d자 이하여야 해요.".formatted(minLength, maxLength)); - log.warn("AnswerLength is out of bound - questionId: {}, answerLength: {}, minLength: {}, maxLength: {}", + log.info("AnswerLength is out of bound - questionId: {}, answerLength: {}, minLength: {}, maxLength: {}", questionId, answerLength, minLength, maxLength, this); } diff --git a/backend/src/main/java/reviewme/review/service/exception/SubmittedQuestionAndProvidedQuestionMismatchException.java b/backend/src/main/java/reviewme/review/service/exception/SubmittedQuestionAndProvidedQuestionMismatchException.java index 1924b1cf5..97b0f77d9 100644 --- a/backend/src/main/java/reviewme/review/service/exception/SubmittedQuestionAndProvidedQuestionMismatchException.java +++ b/backend/src/main/java/reviewme/review/service/exception/SubmittedQuestionAndProvidedQuestionMismatchException.java @@ -1,7 +1,6 @@ package reviewme.review.service.exception; import java.util.Collection; -import java.util.List; import lombok.extern.slf4j.Slf4j; import reviewme.global.exception.BadRequestException; @@ -16,9 +15,4 @@ public SubmittedQuestionAndProvidedQuestionMismatchException(Collection su submittedQuestionIds, providedQuestionIds, this ); } - - public SubmittedQuestionAndProvidedQuestionMismatchException(long submittedQuestionId, - Collection providedQuestionIds) { - this(List.of(submittedQuestionId), providedQuestionIds); - } } From 28ee86dbc5f0ca1d66c806e3e84a5954828bf436 Mon Sep 17 00:00:00 2001 From: Donghoon Lee Date: Thu, 31 Oct 2024 19:46:12 +0900 Subject: [PATCH 02/11] =?UTF-8?q?[BE]=20docs:=20=EB=A6=AC=EB=93=9C?= =?UTF-8?q?=EB=AF=B8=EC=97=90=20=EC=9D=B8=ED=94=84=EB=9D=BC=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EC=B6=94=EA=B0=80=20(#952)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 7f807fd6a..63ae0b310 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,9 @@ ### 백엔드

+### Infrastructure +

+ ## 🧑‍💻 팀원 소개 ### 프론트엔드 @@ -59,3 +62,4 @@ | | | | | | :---: | :---: | :---: | :---: | | [🦧 산초](https://github.com/nayonsoso) | [🤸🏻‍♂️ 아루](https://github.com/donghoony) | [💃 커비](https://github.com/skylar1220) | [🐻 테드](https://github.com/Kimprodp) | + From cfdaeac92e093f61127fabe46f18dc9ae4a97f2f Mon Sep 17 00:00:00 2001 From: Donghoon Lee Date: Tue, 5 Nov 2024 16:29:36 +0900 Subject: [PATCH 03/11] =?UTF-8?q?[BE]=20Question=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=EB=A5=BC=20Template=20=ED=95=98=EC=9C=84=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20(#956)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: Question 도메인을 Template 아래로 이동 - 전체적인 경계를 아래와 같이 나눔: 1. 템플릿 (질문, 옵션, 섹션, 템플릿) 2. 리뷰 (답변) 3. 하이라이트 4. 리뷰 그룹 * refactor: TemplateService에서 리뷰 그룹 Repository 계층을 참조하지 않도록 수정 --- .../main/java/reviewme/DatabaseInitializer.java | 16 ++++++++-------- .../service/ReviewGatheredLookupService.java | 4 ++-- .../response/detail/QuestionAnswerResponse.java | 2 +- .../gathered/SimpleQuestionResponse.java | 2 +- .../review/service/mapper/AnswerMapper.java | 2 +- .../service/mapper/AnswerMapperFactory.java | 2 +- .../service/mapper/CheckboxAnswerMapper.java | 2 +- .../service/mapper/ReviewDetailMapper.java | 12 ++++++------ .../service/mapper/ReviewGatherMapper.java | 6 +++--- .../review/service/mapper/ReviewListMapper.java | 6 +++--- .../review/service/mapper/ReviewMapper.java | 4 ++-- .../review/service/mapper/TextAnswerMapper.java | 2 +- .../mapper/UnsupportedQuestionTypeException.java | 2 +- .../validator/CheckboxAnswerValidator.java | 12 ++++++------ .../service/validator/ReviewValidator.java | 4 ++-- .../service/validator/TextAnswerValidator.java | 4 ++-- .../domain/OptionGroup.java | 2 +- .../domain/OptionItem.java | 2 +- .../domain/OptionType.java | 2 +- .../{question => template}/domain/Question.java | 2 +- .../domain/QuestionType.java | 2 +- .../repository/OptionGroupRepository.java | 4 ++-- .../repository/OptionItemRepository.java | 6 +++--- .../repository/QuestionRepository.java | 6 +++--- .../template/service/TemplateService.java | 12 +++--------- .../template/service/mapper/TemplateMapper.java | 12 ++++++------ .../test/java/reviewme/api/ReviewApiTest.java | 3 +-- .../test/java/reviewme/api/TemplateFixture.java | 2 +- .../reviewme/fixture/OptionGroupFixture.java | 2 +- .../java/reviewme/fixture/OptionItemFixture.java | 4 ++-- .../java/reviewme/fixture/QuestionFixture.java | 4 ++-- .../highlight/service/HighlightServiceTest.java | 2 +- .../service/mapper/HighlightMapperTest.java | 2 +- .../validator/HighlightValidatorTest.java | 2 +- .../review/repository/AnswerRepositoryTest.java | 4 ++-- .../review/repository/ReviewRepositoryTest.java | 4 ++-- .../service/ReviewDetailLookupServiceTest.java | 12 ++++++------ .../service/ReviewGatheredLookupServiceTest.java | 16 ++++++++-------- .../service/ReviewListLookupServiceTest.java | 12 ++++++------ .../service/ReviewRegisterServiceTest.java | 12 ++++++------ .../review/service/ReviewSummaryServiceTest.java | 4 ++-- .../service/mapper/AnswerMapperFactoryTest.java | 2 +- .../service/mapper/ReviewGatherMapperTest.java | 12 ++++++------ .../service/mapper/ReviewListMapperTest.java | 4 ++-- .../review/service/mapper/ReviewMapperTest.java | 12 ++++++------ .../validator/CheckboxAnswerValidatorTest.java | 12 ++++++------ .../service/validator/ReviewValidatorTest.java | 12 ++++++------ .../validator/TextAnswerValidatorTest.java | 4 ++-- .../repository/OptionGroupRepositoryTest.java | 9 +++++---- .../repository/OptionItemRepositoryTest.java | 13 ++++++++----- .../repository/QuestionRepositoryTest.java | 11 +++++++---- .../template/service/TemplateServiceTest.java | 14 ++------------ .../service/mapper/TemplateMapperTest.java | 10 +++++----- 53 files changed, 161 insertions(+), 171 deletions(-) rename backend/src/main/java/reviewme/{question => template}/domain/OptionGroup.java (96%) rename backend/src/main/java/reviewme/{question => template}/domain/OptionItem.java (97%) rename backend/src/main/java/reviewme/{question => template}/domain/OptionType.java (61%) rename backend/src/main/java/reviewme/{question => template}/domain/Question.java (97%) rename backend/src/main/java/reviewme/{question => template}/domain/QuestionType.java (64%) rename backend/src/main/java/reviewme/{question => template}/repository/OptionGroupRepository.java (87%) rename backend/src/main/java/reviewme/{question => template}/repository/OptionItemRepository.java (86%) rename backend/src/main/java/reviewme/{question => template}/repository/QuestionRepository.java (92%) rename backend/src/test/java/reviewme/{question => template}/repository/OptionGroupRepositoryTest.java (88%) rename backend/src/test/java/reviewme/{question => template}/repository/OptionItemRepositoryTest.java (87%) rename backend/src/test/java/reviewme/{question => template}/repository/QuestionRepositoryTest.java (94%) diff --git a/backend/src/main/java/reviewme/DatabaseInitializer.java b/backend/src/main/java/reviewme/DatabaseInitializer.java index 38d1e3496..71c18843b 100644 --- a/backend/src/main/java/reviewme/DatabaseInitializer.java +++ b/backend/src/main/java/reviewme/DatabaseInitializer.java @@ -5,14 +5,14 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.OptionType; -import reviewme.question.domain.Question; -import reviewme.question.domain.QuestionType; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.OptionType; +import reviewme.template.domain.Question; +import reviewme.template.domain.QuestionType; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.template.domain.Section; import reviewme.template.domain.Template; import reviewme.template.domain.VisibleType; diff --git a/backend/src/main/java/reviewme/review/service/ReviewGatheredLookupService.java b/backend/src/main/java/reviewme/review/service/ReviewGatheredLookupService.java index 703348c9e..82de0ab16 100644 --- a/backend/src/main/java/reviewme/review/service/ReviewGatheredLookupService.java +++ b/backend/src/main/java/reviewme/review/service/ReviewGatheredLookupService.java @@ -9,8 +9,8 @@ import org.springframework.transaction.annotation.Transactional; import reviewme.highlight.domain.Highlight; import reviewme.highlight.repository.HighlightRepository; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.Question; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Answer; import reviewme.review.repository.AnswerRepository; import reviewme.review.service.dto.response.gathered.ReviewsGatheredBySectionResponse; diff --git a/backend/src/main/java/reviewme/review/service/dto/response/detail/QuestionAnswerResponse.java b/backend/src/main/java/reviewme/review/service/dto/response/detail/QuestionAnswerResponse.java index 000eb83c8..fccc3c752 100644 --- a/backend/src/main/java/reviewme/review/service/dto/response/detail/QuestionAnswerResponse.java +++ b/backend/src/main/java/reviewme/review/service/dto/response/detail/QuestionAnswerResponse.java @@ -1,7 +1,7 @@ package reviewme.review.service.dto.response.detail; import jakarta.annotation.Nullable; -import reviewme.question.domain.QuestionType; +import reviewme.template.domain.QuestionType; public record QuestionAnswerResponse( long questionId, diff --git a/backend/src/main/java/reviewme/review/service/dto/response/gathered/SimpleQuestionResponse.java b/backend/src/main/java/reviewme/review/service/dto/response/gathered/SimpleQuestionResponse.java index e16df25e6..d7f1647d9 100644 --- a/backend/src/main/java/reviewme/review/service/dto/response/gathered/SimpleQuestionResponse.java +++ b/backend/src/main/java/reviewme/review/service/dto/response/gathered/SimpleQuestionResponse.java @@ -1,6 +1,6 @@ package reviewme.review.service.dto.response.gathered; -import reviewme.question.domain.QuestionType; +import reviewme.template.domain.QuestionType; public record SimpleQuestionResponse( long id, diff --git a/backend/src/main/java/reviewme/review/service/mapper/AnswerMapper.java b/backend/src/main/java/reviewme/review/service/mapper/AnswerMapper.java index 7b3cbb631..1181808a5 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/AnswerMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/AnswerMapper.java @@ -1,6 +1,6 @@ package reviewme.review.service.mapper; -import reviewme.question.domain.QuestionType; +import reviewme.template.domain.QuestionType; import reviewme.review.domain.Answer; import reviewme.review.service.dto.request.ReviewAnswerRequest; diff --git a/backend/src/main/java/reviewme/review/service/mapper/AnswerMapperFactory.java b/backend/src/main/java/reviewme/review/service/mapper/AnswerMapperFactory.java index 6dc804547..624c3ba81 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/AnswerMapperFactory.java +++ b/backend/src/main/java/reviewme/review/service/mapper/AnswerMapperFactory.java @@ -3,7 +3,7 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import reviewme.question.domain.QuestionType; +import reviewme.template.domain.QuestionType; @Component @RequiredArgsConstructor diff --git a/backend/src/main/java/reviewme/review/service/mapper/CheckboxAnswerMapper.java b/backend/src/main/java/reviewme/review/service/mapper/CheckboxAnswerMapper.java index 3648e32f6..7fb87b0dc 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/CheckboxAnswerMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/CheckboxAnswerMapper.java @@ -1,7 +1,7 @@ package reviewme.review.service.mapper; import org.springframework.stereotype.Component; -import reviewme.question.domain.QuestionType; +import reviewme.template.domain.QuestionType; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.service.dto.request.ReviewAnswerRequest; import reviewme.review.service.exception.CheckBoxAnswerIncludedTextException; diff --git a/backend/src/main/java/reviewme/review/service/mapper/ReviewDetailMapper.java b/backend/src/main/java/reviewme/review/service/mapper/ReviewDetailMapper.java index 7121d99b5..c2874c1c1 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/ReviewDetailMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/ReviewDetailMapper.java @@ -7,12 +7,12 @@ import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.CheckboxAnswerSelectedOption; import reviewme.review.domain.Review; diff --git a/backend/src/main/java/reviewme/review/service/mapper/ReviewGatherMapper.java b/backend/src/main/java/reviewme/review/service/mapper/ReviewGatherMapper.java index 2a1f4e135..d53fd0905 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/ReviewGatherMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/ReviewGatherMapper.java @@ -7,9 +7,9 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import reviewme.highlight.domain.Highlight; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Answer; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.CheckboxAnswerSelectedOption; diff --git a/backend/src/main/java/reviewme/review/service/mapper/ReviewListMapper.java b/backend/src/main/java/reviewme/review/service/mapper/ReviewListMapper.java index aa882802a..ab5ec4327 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/ReviewListMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/ReviewListMapper.java @@ -5,9 +5,9 @@ import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.OptionType; -import reviewme.question.repository.OptionItemRepository; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.OptionType; +import reviewme.template.repository.OptionItemRepository; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.CheckboxAnswerSelectedOption; import reviewme.review.domain.Review; diff --git a/backend/src/main/java/reviewme/review/service/mapper/ReviewMapper.java b/backend/src/main/java/reviewme/review/service/mapper/ReviewMapper.java index 68ee776b9..58d0c6a6f 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/ReviewMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/ReviewMapper.java @@ -8,8 +8,8 @@ import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.Question; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Answer; import reviewme.review.domain.Review; import reviewme.review.service.dto.request.ReviewAnswerRequest; diff --git a/backend/src/main/java/reviewme/review/service/mapper/TextAnswerMapper.java b/backend/src/main/java/reviewme/review/service/mapper/TextAnswerMapper.java index afd47ac97..48bd55789 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/TextAnswerMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/TextAnswerMapper.java @@ -1,7 +1,7 @@ package reviewme.review.service.mapper; import org.springframework.stereotype.Component; -import reviewme.question.domain.QuestionType; +import reviewme.template.domain.QuestionType; import reviewme.review.domain.TextAnswer; import reviewme.review.service.dto.request.ReviewAnswerRequest; import reviewme.review.service.exception.TextAnswerIncludedOptionItemException; diff --git a/backend/src/main/java/reviewme/review/service/mapper/UnsupportedQuestionTypeException.java b/backend/src/main/java/reviewme/review/service/mapper/UnsupportedQuestionTypeException.java index b08870515..26a22f0fd 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/UnsupportedQuestionTypeException.java +++ b/backend/src/main/java/reviewme/review/service/mapper/UnsupportedQuestionTypeException.java @@ -2,7 +2,7 @@ import lombok.extern.slf4j.Slf4j; import reviewme.global.exception.DataInconsistencyException; -import reviewme.question.domain.QuestionType; +import reviewme.template.domain.QuestionType; @Slf4j public class UnsupportedQuestionTypeException extends DataInconsistencyException { diff --git a/backend/src/main/java/reviewme/review/service/validator/CheckboxAnswerValidator.java b/backend/src/main/java/reviewme/review/service/validator/CheckboxAnswerValidator.java index 62d39728b..ab57ead79 100644 --- a/backend/src/main/java/reviewme/review/service/validator/CheckboxAnswerValidator.java +++ b/backend/src/main/java/reviewme/review/service/validator/CheckboxAnswerValidator.java @@ -5,12 +5,12 @@ import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Answer; import reviewme.review.domain.CheckboxAnswerSelectedOption; import reviewme.review.domain.CheckboxAnswer; diff --git a/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java b/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java index 2906a8507..9c68894c9 100644 --- a/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java +++ b/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java @@ -7,8 +7,8 @@ import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.Question; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Answer; import reviewme.review.domain.CheckboxAnswerSelectedOption; import reviewme.review.domain.CheckboxAnswer; diff --git a/backend/src/main/java/reviewme/review/service/validator/TextAnswerValidator.java b/backend/src/main/java/reviewme/review/service/validator/TextAnswerValidator.java index 78a0701dd..59d9d476b 100644 --- a/backend/src/main/java/reviewme/review/service/validator/TextAnswerValidator.java +++ b/backend/src/main/java/reviewme/review/service/validator/TextAnswerValidator.java @@ -3,8 +3,8 @@ import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.Question; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Answer; import reviewme.review.domain.TextAnswer; import reviewme.review.service.exception.InvalidTextAnswerLengthException; diff --git a/backend/src/main/java/reviewme/question/domain/OptionGroup.java b/backend/src/main/java/reviewme/template/domain/OptionGroup.java similarity index 96% rename from backend/src/main/java/reviewme/question/domain/OptionGroup.java rename to backend/src/main/java/reviewme/template/domain/OptionGroup.java index 61aa3d23a..a5ee115ca 100644 --- a/backend/src/main/java/reviewme/question/domain/OptionGroup.java +++ b/backend/src/main/java/reviewme/template/domain/OptionGroup.java @@ -1,4 +1,4 @@ -package reviewme.question.domain; +package reviewme.template.domain; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/backend/src/main/java/reviewme/question/domain/OptionItem.java b/backend/src/main/java/reviewme/template/domain/OptionItem.java similarity index 97% rename from backend/src/main/java/reviewme/question/domain/OptionItem.java rename to backend/src/main/java/reviewme/template/domain/OptionItem.java index 59b29bc3b..7232dd3df 100644 --- a/backend/src/main/java/reviewme/question/domain/OptionItem.java +++ b/backend/src/main/java/reviewme/template/domain/OptionItem.java @@ -1,4 +1,4 @@ -package reviewme.question.domain; +package reviewme.template.domain; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/backend/src/main/java/reviewme/question/domain/OptionType.java b/backend/src/main/java/reviewme/template/domain/OptionType.java similarity index 61% rename from backend/src/main/java/reviewme/question/domain/OptionType.java rename to backend/src/main/java/reviewme/template/domain/OptionType.java index dfa86920b..80e4e2c1b 100644 --- a/backend/src/main/java/reviewme/question/domain/OptionType.java +++ b/backend/src/main/java/reviewme/template/domain/OptionType.java @@ -1,4 +1,4 @@ -package reviewme.question.domain; +package reviewme.template.domain; public enum OptionType { CATEGORY, diff --git a/backend/src/main/java/reviewme/question/domain/Question.java b/backend/src/main/java/reviewme/template/domain/Question.java similarity index 97% rename from backend/src/main/java/reviewme/question/domain/Question.java rename to backend/src/main/java/reviewme/template/domain/Question.java index f59e4ae87..f4384d854 100644 --- a/backend/src/main/java/reviewme/question/domain/Question.java +++ b/backend/src/main/java/reviewme/template/domain/Question.java @@ -1,4 +1,4 @@ -package reviewme.question.domain; +package reviewme.template.domain; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/backend/src/main/java/reviewme/question/domain/QuestionType.java b/backend/src/main/java/reviewme/template/domain/QuestionType.java similarity index 64% rename from backend/src/main/java/reviewme/question/domain/QuestionType.java rename to backend/src/main/java/reviewme/template/domain/QuestionType.java index 863ba56e5..78b84fb58 100644 --- a/backend/src/main/java/reviewme/question/domain/QuestionType.java +++ b/backend/src/main/java/reviewme/template/domain/QuestionType.java @@ -1,4 +1,4 @@ -package reviewme.question.domain; +package reviewme.template.domain; public enum QuestionType { CHECKBOX, diff --git a/backend/src/main/java/reviewme/question/repository/OptionGroupRepository.java b/backend/src/main/java/reviewme/template/repository/OptionGroupRepository.java similarity index 87% rename from backend/src/main/java/reviewme/question/repository/OptionGroupRepository.java rename to backend/src/main/java/reviewme/template/repository/OptionGroupRepository.java index ad2994537..ce57a64e7 100644 --- a/backend/src/main/java/reviewme/question/repository/OptionGroupRepository.java +++ b/backend/src/main/java/reviewme/template/repository/OptionGroupRepository.java @@ -1,11 +1,11 @@ -package reviewme.question.repository; +package reviewme.template.repository; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; -import reviewme.question.domain.OptionGroup; +import reviewme.template.domain.OptionGroup; @Repository public interface OptionGroupRepository extends JpaRepository { diff --git a/backend/src/main/java/reviewme/question/repository/OptionItemRepository.java b/backend/src/main/java/reviewme/template/repository/OptionItemRepository.java similarity index 86% rename from backend/src/main/java/reviewme/question/repository/OptionItemRepository.java rename to backend/src/main/java/reviewme/template/repository/OptionItemRepository.java index e42274c33..305df2ef1 100644 --- a/backend/src/main/java/reviewme/question/repository/OptionItemRepository.java +++ b/backend/src/main/java/reviewme/template/repository/OptionItemRepository.java @@ -1,11 +1,11 @@ -package reviewme.question.repository; +package reviewme.template.repository; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.OptionType; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.OptionType; @Repository public interface OptionItemRepository extends JpaRepository { diff --git a/backend/src/main/java/reviewme/question/repository/QuestionRepository.java b/backend/src/main/java/reviewme/template/repository/QuestionRepository.java similarity index 92% rename from backend/src/main/java/reviewme/question/repository/QuestionRepository.java rename to backend/src/main/java/reviewme/template/repository/QuestionRepository.java index 9db137d25..aa21a0167 100644 --- a/backend/src/main/java/reviewme/question/repository/QuestionRepository.java +++ b/backend/src/main/java/reviewme/template/repository/QuestionRepository.java @@ -1,12 +1,12 @@ -package reviewme.question.repository; +package reviewme.template.repository; import java.util.List; import java.util.Set; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; @Repository public interface QuestionRepository extends JpaRepository { diff --git a/backend/src/main/java/reviewme/template/service/TemplateService.java b/backend/src/main/java/reviewme/template/service/TemplateService.java index a49fc5160..1b6370878 100644 --- a/backend/src/main/java/reviewme/template/service/TemplateService.java +++ b/backend/src/main/java/reviewme/template/service/TemplateService.java @@ -3,9 +3,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import reviewme.review.service.exception.ReviewGroupNotFoundByReviewRequestCodeException; import reviewme.reviewgroup.domain.ReviewGroup; -import reviewme.reviewgroup.repository.ReviewGroupRepository; +import reviewme.reviewgroup.service.ReviewGroupService; import reviewme.template.service.dto.response.TemplateResponse; import reviewme.template.service.mapper.TemplateMapper; @@ -13,17 +12,12 @@ @RequiredArgsConstructor public class TemplateService { - private final ReviewGroupRepository reviewGroupRepository; + private final ReviewGroupService reviewGroupService; private final TemplateMapper templateMapper; @Transactional(readOnly = true) public TemplateResponse generateReviewForm(String reviewRequestCode) { - ReviewGroup reviewGroup = findReviewGroupByRequestCodeOrThrow(reviewRequestCode); + ReviewGroup reviewGroup = reviewGroupService.getReviewGroupByReviewRequestCode(reviewRequestCode); return templateMapper.mapToTemplateResponse(reviewGroup); } - - private ReviewGroup findReviewGroupByRequestCodeOrThrow(String reviewRequestCode) { - return reviewGroupRepository.findByReviewRequestCode(reviewRequestCode) - .orElseThrow(() -> new ReviewGroupNotFoundByReviewRequestCodeException(reviewRequestCode)); - } } diff --git a/backend/src/main/java/reviewme/template/service/mapper/TemplateMapper.java b/backend/src/main/java/reviewme/template/service/mapper/TemplateMapper.java index 02b6084f1..7151003d5 100644 --- a/backend/src/main/java/reviewme/template/service/mapper/TemplateMapper.java +++ b/backend/src/main/java/reviewme/template/service/mapper/TemplateMapper.java @@ -3,12 +3,12 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.reviewgroup.domain.ReviewGroup; import reviewme.template.domain.Section; import reviewme.template.domain.SectionQuestion; diff --git a/backend/src/test/java/reviewme/api/ReviewApiTest.java b/backend/src/test/java/reviewme/api/ReviewApiTest.java index 5add4cfbd..4552b02d5 100644 --- a/backend/src/test/java/reviewme/api/ReviewApiTest.java +++ b/backend/src/test/java/reviewme/api/ReviewApiTest.java @@ -3,7 +3,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; import static org.springframework.restdocs.cookies.CookieDocumentation.cookieWithName; import static org.springframework.restdocs.cookies.CookieDocumentation.requestCookies; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; @@ -22,7 +21,7 @@ import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; import org.springframework.restdocs.payload.FieldDescriptor; import org.springframework.restdocs.request.ParameterDescriptor; -import reviewme.question.domain.QuestionType; +import reviewme.template.domain.QuestionType; import reviewme.review.service.dto.request.ReviewRegisterRequest; import reviewme.review.service.dto.response.gathered.HighlightResponse; import reviewme.review.service.dto.response.gathered.RangeResponse; diff --git a/backend/src/test/java/reviewme/api/TemplateFixture.java b/backend/src/test/java/reviewme/api/TemplateFixture.java index aba719fbb..7a8f3c194 100644 --- a/backend/src/test/java/reviewme/api/TemplateFixture.java +++ b/backend/src/test/java/reviewme/api/TemplateFixture.java @@ -2,7 +2,7 @@ import java.time.LocalDate; import java.util.List; -import reviewme.question.domain.QuestionType; +import reviewme.template.domain.QuestionType; import reviewme.review.service.dto.response.detail.OptionGroupAnswerResponse; import reviewme.review.service.dto.response.detail.OptionItemAnswerResponse; import reviewme.review.service.dto.response.detail.QuestionAnswerResponse; diff --git a/backend/src/test/java/reviewme/fixture/OptionGroupFixture.java b/backend/src/test/java/reviewme/fixture/OptionGroupFixture.java index 259a3ebcf..f880cbfb7 100644 --- a/backend/src/test/java/reviewme/fixture/OptionGroupFixture.java +++ b/backend/src/test/java/reviewme/fixture/OptionGroupFixture.java @@ -1,6 +1,6 @@ package reviewme.fixture; -import reviewme.question.domain.OptionGroup; +import reviewme.template.domain.OptionGroup; public class OptionGroupFixture { diff --git a/backend/src/test/java/reviewme/fixture/OptionItemFixture.java b/backend/src/test/java/reviewme/fixture/OptionItemFixture.java index 3b7e50725..c076cb205 100644 --- a/backend/src/test/java/reviewme/fixture/OptionItemFixture.java +++ b/backend/src/test/java/reviewme/fixture/OptionItemFixture.java @@ -1,7 +1,7 @@ package reviewme.fixture; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.OptionType; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.OptionType; public class OptionItemFixture { diff --git a/backend/src/test/java/reviewme/fixture/QuestionFixture.java b/backend/src/test/java/reviewme/fixture/QuestionFixture.java index f4ce28b88..3484116af 100644 --- a/backend/src/test/java/reviewme/fixture/QuestionFixture.java +++ b/backend/src/test/java/reviewme/fixture/QuestionFixture.java @@ -1,7 +1,7 @@ package reviewme.fixture; -import reviewme.question.domain.Question; -import reviewme.question.domain.QuestionType; +import reviewme.template.domain.Question; +import reviewme.template.domain.QuestionType; public class QuestionFixture { diff --git a/backend/src/test/java/reviewme/highlight/service/HighlightServiceTest.java b/backend/src/test/java/reviewme/highlight/service/HighlightServiceTest.java index 32eed36b8..207a68d29 100644 --- a/backend/src/test/java/reviewme/highlight/service/HighlightServiceTest.java +++ b/backend/src/test/java/reviewme/highlight/service/HighlightServiceTest.java @@ -17,7 +17,7 @@ import reviewme.highlight.service.dto.HighlightRequest; import reviewme.highlight.service.dto.HighlightedLineRequest; import reviewme.highlight.service.dto.HighlightsRequest; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; import reviewme.review.repository.ReviewRepository; diff --git a/backend/src/test/java/reviewme/highlight/service/mapper/HighlightMapperTest.java b/backend/src/test/java/reviewme/highlight/service/mapper/HighlightMapperTest.java index 14a6639f9..66101cf31 100644 --- a/backend/src/test/java/reviewme/highlight/service/mapper/HighlightMapperTest.java +++ b/backend/src/test/java/reviewme/highlight/service/mapper/HighlightMapperTest.java @@ -17,7 +17,7 @@ import reviewme.highlight.service.dto.HighlightRequest; import reviewme.highlight.service.dto.HighlightedLineRequest; import reviewme.highlight.service.dto.HighlightsRequest; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; import reviewme.review.repository.ReviewRepository; diff --git a/backend/src/test/java/reviewme/highlight/service/validator/HighlightValidatorTest.java b/backend/src/test/java/reviewme/highlight/service/validator/HighlightValidatorTest.java index 84bf793d2..4c98fa75b 100644 --- a/backend/src/test/java/reviewme/highlight/service/validator/HighlightValidatorTest.java +++ b/backend/src/test/java/reviewme/highlight/service/validator/HighlightValidatorTest.java @@ -12,7 +12,7 @@ import reviewme.highlight.service.dto.HighlightRequest; import reviewme.highlight.service.dto.HighlightsRequest; import reviewme.highlight.service.exception.SubmittedAnswerAndProvidedAnswerMismatchException; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; import reviewme.review.repository.ReviewRepository; diff --git a/backend/src/test/java/reviewme/review/repository/AnswerRepositoryTest.java b/backend/src/test/java/reviewme/review/repository/AnswerRepositoryTest.java index e13ce1427..9d2ad447d 100644 --- a/backend/src/test/java/reviewme/review/repository/AnswerRepositoryTest.java +++ b/backend/src/test/java/reviewme/review/repository/AnswerRepositoryTest.java @@ -11,8 +11,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.Question; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Answer; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; diff --git a/backend/src/test/java/reviewme/review/repository/ReviewRepositoryTest.java b/backend/src/test/java/reviewme/review/repository/ReviewRepositoryTest.java index 2149c7ed9..3855c1520 100644 --- a/backend/src/test/java/reviewme/review/repository/ReviewRepositoryTest.java +++ b/backend/src/test/java/reviewme/review/repository/ReviewRepositoryTest.java @@ -13,8 +13,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.Question; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Review; import reviewme.reviewgroup.domain.ReviewGroup; import reviewme.reviewgroup.repository.ReviewGroupRepository; diff --git a/backend/src/test/java/reviewme/review/service/ReviewDetailLookupServiceTest.java b/backend/src/test/java/reviewme/review/service/ReviewDetailLookupServiceTest.java index ab296d796..236143e75 100644 --- a/backend/src/test/java/reviewme/review/service/ReviewDetailLookupServiceTest.java +++ b/backend/src/test/java/reviewme/review/service/ReviewDetailLookupServiceTest.java @@ -17,12 +17,12 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Answer; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.Review; diff --git a/backend/src/test/java/reviewme/review/service/ReviewGatheredLookupServiceTest.java b/backend/src/test/java/reviewme/review/service/ReviewGatheredLookupServiceTest.java index 141992950..f6c8c4690 100644 --- a/backend/src/test/java/reviewme/review/service/ReviewGatheredLookupServiceTest.java +++ b/backend/src/test/java/reviewme/review/service/ReviewGatheredLookupServiceTest.java @@ -18,14 +18,14 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.OptionType; -import reviewme.question.domain.Question; -import reviewme.question.domain.QuestionType; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.OptionType; +import reviewme.template.domain.Question; +import reviewme.template.domain.QuestionType; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; diff --git a/backend/src/test/java/reviewme/review/service/ReviewListLookupServiceTest.java b/backend/src/test/java/reviewme/review/service/ReviewListLookupServiceTest.java index d8384afe5..ebc559924 100644 --- a/backend/src/test/java/reviewme/review/service/ReviewListLookupServiceTest.java +++ b/backend/src/test/java/reviewme/review/service/ReviewListLookupServiceTest.java @@ -12,12 +12,12 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; diff --git a/backend/src/test/java/reviewme/review/service/ReviewRegisterServiceTest.java b/backend/src/test/java/reviewme/review/service/ReviewRegisterServiceTest.java index 73ab64897..5852dae7c 100644 --- a/backend/src/test/java/reviewme/review/service/ReviewRegisterServiceTest.java +++ b/backend/src/test/java/reviewme/review/service/ReviewRegisterServiceTest.java @@ -15,12 +15,12 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; diff --git a/backend/src/test/java/reviewme/review/service/ReviewSummaryServiceTest.java b/backend/src/test/java/reviewme/review/service/ReviewSummaryServiceTest.java index 2a2ffa7a5..0f83f4c3f 100644 --- a/backend/src/test/java/reviewme/review/service/ReviewSummaryServiceTest.java +++ b/backend/src/test/java/reviewme/review/service/ReviewSummaryServiceTest.java @@ -10,8 +10,8 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.Question; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Review; import reviewme.review.repository.ReviewRepository; import reviewme.review.service.dto.response.list.ReceivedReviewsSummaryResponse; diff --git a/backend/src/test/java/reviewme/review/service/mapper/AnswerMapperFactoryTest.java b/backend/src/test/java/reviewme/review/service/mapper/AnswerMapperFactoryTest.java index 25d1b5018..bdf37e905 100644 --- a/backend/src/test/java/reviewme/review/service/mapper/AnswerMapperFactoryTest.java +++ b/backend/src/test/java/reviewme/review/service/mapper/AnswerMapperFactoryTest.java @@ -8,7 +8,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import reviewme.question.domain.QuestionType; +import reviewme.template.domain.QuestionType; import reviewme.review.domain.Answer; import reviewme.review.service.dto.request.ReviewAnswerRequest; diff --git a/backend/src/test/java/reviewme/review/service/mapper/ReviewGatherMapperTest.java b/backend/src/test/java/reviewme/review/service/mapper/ReviewGatherMapperTest.java index 1e411f13e..63fcd7615 100644 --- a/backend/src/test/java/reviewme/review/service/mapper/ReviewGatherMapperTest.java +++ b/backend/src/test/java/reviewme/review/service/mapper/ReviewGatherMapperTest.java @@ -12,12 +12,12 @@ import org.assertj.core.groups.Tuple; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; diff --git a/backend/src/test/java/reviewme/review/service/mapper/ReviewListMapperTest.java b/backend/src/test/java/reviewme/review/service/mapper/ReviewListMapperTest.java index 0cdfe0a32..0032b7cb2 100644 --- a/backend/src/test/java/reviewme/review/service/mapper/ReviewListMapperTest.java +++ b/backend/src/test/java/reviewme/review/service/mapper/ReviewListMapperTest.java @@ -10,8 +10,8 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.Question; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; import reviewme.review.repository.ReviewRepository; diff --git a/backend/src/test/java/reviewme/review/service/mapper/ReviewMapperTest.java b/backend/src/test/java/reviewme/review/service/mapper/ReviewMapperTest.java index 8ca15f312..4065c63de 100644 --- a/backend/src/test/java/reviewme/review/service/mapper/ReviewMapperTest.java +++ b/backend/src/test/java/reviewme/review/service/mapper/ReviewMapperTest.java @@ -16,12 +16,12 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; diff --git a/backend/src/test/java/reviewme/review/service/validator/CheckboxAnswerValidatorTest.java b/backend/src/test/java/reviewme/review/service/validator/CheckboxAnswerValidatorTest.java index 5c64c2503..c405ab4ba 100644 --- a/backend/src/test/java/reviewme/review/service/validator/CheckboxAnswerValidatorTest.java +++ b/backend/src/test/java/reviewme/review/service/validator/CheckboxAnswerValidatorTest.java @@ -8,12 +8,12 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.service.exception.CheckBoxAnswerIncludedNotProvidedOptionItemException; import reviewme.review.service.exception.OptionGroupNotFoundByQuestionIdException; diff --git a/backend/src/test/java/reviewme/review/service/validator/ReviewValidatorTest.java b/backend/src/test/java/reviewme/review/service/validator/ReviewValidatorTest.java index dca5dd59d..dd8ebfc94 100644 --- a/backend/src/test/java/reviewme/review/service/validator/ReviewValidatorTest.java +++ b/backend/src/test/java/reviewme/review/service/validator/ReviewValidatorTest.java @@ -15,12 +15,12 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; diff --git a/backend/src/test/java/reviewme/review/service/validator/TextAnswerValidatorTest.java b/backend/src/test/java/reviewme/review/service/validator/TextAnswerValidatorTest.java index 0e8265bb6..27854e02c 100644 --- a/backend/src/test/java/reviewme/review/service/validator/TextAnswerValidatorTest.java +++ b/backend/src/test/java/reviewme/review/service/validator/TextAnswerValidatorTest.java @@ -9,8 +9,8 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.Question; +import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.TextAnswer; import reviewme.review.service.exception.InvalidTextAnswerLengthException; import reviewme.review.service.exception.SubmittedQuestionNotFoundException; diff --git a/backend/src/test/java/reviewme/question/repository/OptionGroupRepositoryTest.java b/backend/src/test/java/reviewme/template/repository/OptionGroupRepositoryTest.java similarity index 88% rename from backend/src/test/java/reviewme/question/repository/OptionGroupRepositoryTest.java rename to backend/src/test/java/reviewme/template/repository/OptionGroupRepositoryTest.java index 1bc3ea107..d121c3688 100644 --- a/backend/src/test/java/reviewme/question/repository/OptionGroupRepositoryTest.java +++ b/backend/src/test/java/reviewme/template/repository/OptionGroupRepositoryTest.java @@ -1,7 +1,6 @@ -package reviewme.question.repository; +package reviewme.template.repository; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; import static reviewme.fixture.OptionGroupFixture.선택지_그룹; import static reviewme.fixture.QuestionFixture.선택형_필수_질문; @@ -9,8 +8,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.Question; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.QuestionRepository; @DataJpaTest class OptionGroupRepositoryTest { diff --git a/backend/src/test/java/reviewme/question/repository/OptionItemRepositoryTest.java b/backend/src/test/java/reviewme/template/repository/OptionItemRepositoryTest.java similarity index 87% rename from backend/src/test/java/reviewme/question/repository/OptionItemRepositoryTest.java rename to backend/src/test/java/reviewme/template/repository/OptionItemRepositoryTest.java index 5aebbf06b..5e1c7a288 100644 --- a/backend/src/test/java/reviewme/question/repository/OptionItemRepositoryTest.java +++ b/backend/src/test/java/reviewme/template/repository/OptionItemRepositoryTest.java @@ -1,4 +1,4 @@ -package reviewme.question.repository; +package reviewme.template.repository; import static org.assertj.core.api.Assertions.assertThat; import static reviewme.fixture.OptionGroupFixture.선택지_그룹; @@ -9,10 +9,13 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.OptionType; -import reviewme.question.domain.Question; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.OptionType; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; @DataJpaTest class OptionItemRepositoryTest { diff --git a/backend/src/test/java/reviewme/question/repository/QuestionRepositoryTest.java b/backend/src/test/java/reviewme/template/repository/QuestionRepositoryTest.java similarity index 94% rename from backend/src/test/java/reviewme/question/repository/QuestionRepositoryTest.java rename to backend/src/test/java/reviewme/template/repository/QuestionRepositoryTest.java index da694e335..584057104 100644 --- a/backend/src/test/java/reviewme/question/repository/QuestionRepositoryTest.java +++ b/backend/src/test/java/reviewme/template/repository/QuestionRepositoryTest.java @@ -1,4 +1,4 @@ -package reviewme.question.repository; +package reviewme.template.repository; import static org.assertj.core.api.Assertions.assertThat; import static reviewme.fixture.OptionGroupFixture.선택지_그룹; @@ -13,13 +13,16 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.OptionItem; +import reviewme.template.domain.Question; import reviewme.reviewgroup.domain.ReviewGroup; import reviewme.reviewgroup.repository.ReviewGroupRepository; import reviewme.template.domain.Section; import reviewme.template.domain.Template; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.template.repository.SectionRepository; import reviewme.template.repository.TemplateRepository; diff --git a/backend/src/test/java/reviewme/template/service/TemplateServiceTest.java b/backend/src/test/java/reviewme/template/service/TemplateServiceTest.java index 7c512d99f..9f372e1d8 100644 --- a/backend/src/test/java/reviewme/template/service/TemplateServiceTest.java +++ b/backend/src/test/java/reviewme/template/service/TemplateServiceTest.java @@ -5,7 +5,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.review.service.exception.ReviewGroupNotFoundByReviewRequestCodeException; import reviewme.reviewgroup.domain.ReviewGroup; import reviewme.reviewgroup.repository.ReviewGroupRepository; import reviewme.support.ServiceTest; @@ -20,23 +19,14 @@ class TemplateServiceTest { @Autowired private ReviewGroupRepository reviewGroupRepository; - @Test - void 잘못된_리뷰_요청_코드로_리뷰_작성폼을_요청할_경우_예외가_발생한다() { - // given - ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); - - // when, then - assertThatThrownBy(() -> templateService.generateReviewForm(reviewGroup.getReviewRequestCode() + " ")) - .isInstanceOf(ReviewGroupNotFoundByReviewRequestCodeException.class); - } - @Test void 리뷰이에게_작성될_리뷰_양식_생성_시_저장된_템플릿이_없을_경우_예외가_발생한다() { // given ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); + String reviewRequestCode = reviewGroup.getReviewRequestCode(); // when, then - assertThatThrownBy(() -> templateService.generateReviewForm(reviewGroup.getReviewRequestCode())) + assertThatThrownBy(() -> templateService.generateReviewForm(reviewRequestCode)) .isInstanceOf(TemplateNotFoundByReviewGroupException.class); } } diff --git a/backend/src/test/java/reviewme/template/service/mapper/TemplateMapperTest.java b/backend/src/test/java/reviewme/template/service/mapper/TemplateMapperTest.java index e1a0f1853..0814b4400 100644 --- a/backend/src/test/java/reviewme/template/service/mapper/TemplateMapperTest.java +++ b/backend/src/test/java/reviewme/template/service/mapper/TemplateMapperTest.java @@ -14,11 +14,11 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; +import reviewme.template.domain.OptionGroup; +import reviewme.template.domain.Question; +import reviewme.template.repository.OptionGroupRepository; +import reviewme.template.repository.OptionItemRepository; +import reviewme.template.repository.QuestionRepository; import reviewme.reviewgroup.domain.ReviewGroup; import reviewme.reviewgroup.repository.ReviewGroupRepository; import reviewme.support.ServiceTest; From 7cd031ccf32e0be7f982be3451718962dfaef6c7 Mon Sep 17 00:00:00 2001 From: Donghoon Lee Date: Sun, 10 Nov 2024 12:09:07 +0900 Subject: [PATCH 04/11] =?UTF-8?q?[All]=20fix:=20`[Release]`=20PR=20?= =?UTF-8?q?=EB=A8=B8=EB=A6=BF=EB=A7=90=20=EB=94=94=EC=8A=A4=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=95=8C=EB=A6=BC=20=EC=B2=98=EB=A6=AC=20(#940)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: [Release] 머릿말에도 디스코드 알림 처리 * refactor: `Release`인 경우 `All`로 처리 --- .github/workflows/discord-pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/discord-pull-request.yml b/.github/workflows/discord-pull-request.yml index 52b446ebb..9f9919b42 100644 --- a/.github/workflows/discord-pull-request.yml +++ b/.github/workflows/discord-pull-request.yml @@ -31,7 +31,7 @@ jobs: elif [ "$PR_PREFIX" = '[FE]' ]; then echo Frontend PR Found! echo "PR_PREFIX=FE" >> $GITHUB_ENV - elif [ "$PR_PREFIX" = '[All]' ]; then + elif [ "$PR_PREFIX" = '[All]' ] || [ "$PR_PREFIX" = '[Release]' ]; then echo All PR Found! echo "PR_PREFIX=All" >> $GITHUB_ENV fi From 11a2b05f18a54836bbdc90e9035b4ff67047d68c Mon Sep 17 00:00:00 2001 From: Donghoon Lee Date: Sun, 10 Nov 2024 13:29:04 +0900 Subject: [PATCH 05/11] =?UTF-8?q?[BE]=20refactor:=20Config=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EB=B6=84=EB=A6=AC,=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EC=A0=81=EC=9A=A9=20(#957)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: use `@Slf4j` instead of `LoggerFactory.getLogger` * refactor: `WebConfig`가 하나의 역할만 하도록 수정 * style: dto 불필요한 개행 제거 * refactor: Config는 상위 패키지, Resolver/Interceptor는 각 도메인에 두기 --- .../main/java/reviewme/config/WebConfig.java | 10 ---------- .../config/{ => cors}/CorsConfig.java | 8 +++----- .../config/{ => cors}/CorsProperties.java | 2 +- .../{ => datasource}/DataSourceType.java | 2 +- .../ReplicationDatasourceConfig.java | 3 +-- .../ReplicationRoutingDataSource.java | 2 +- .../RequestLimitInterceptor.java | 4 +--- .../RequestLimitProperties.java | 9 ++------- .../RequestLimitRedisConfig.java | 2 +- .../requestlimit/RequestLimitWebConfig.java | 20 +++++++++++++++++++ .../TooManyRequestException.java | 3 ++- .../global/GlobalExceptionHandler.java | 2 +- .../global/exception/FieldErrorResponse.java | 6 +----- .../review/service/ReviewRegisterService.java | 4 ---- .../config/{ => cors}/CorsConfigTest.java | 3 ++- .../{ => cors}/ExternalCorsConfigTest.java | 2 +- .../{ => cors}/LocalCorsConfigTest.java | 2 +- .../RequestLimitInterceptorTest.java | 5 +---- 18 files changed, 40 insertions(+), 49 deletions(-) rename backend/src/main/java/reviewme/config/{ => cors}/CorsConfig.java (90%) rename backend/src/main/java/reviewme/config/{ => cors}/CorsProperties.java (91%) rename backend/src/main/java/reviewme/config/{ => datasource}/DataSourceType.java (62%) rename backend/src/main/java/reviewme/config/{ => datasource}/ReplicationDatasourceConfig.java (98%) rename backend/src/main/java/reviewme/config/{ => datasource}/ReplicationRoutingDataSource.java (93%) rename backend/src/main/java/reviewme/{global => config/requestlimit}/RequestLimitInterceptor.java (93%) rename backend/src/main/java/reviewme/config/{ => requestlimit}/RequestLimitProperties.java (50%) rename backend/src/main/java/reviewme/config/{ => requestlimit}/RequestLimitRedisConfig.java (97%) create mode 100644 backend/src/main/java/reviewme/config/requestlimit/RequestLimitWebConfig.java rename backend/src/main/java/reviewme/{global/exception => config/requestlimit}/TooManyRequestException.java (80%) rename backend/src/test/java/reviewme/config/{ => cors}/CorsConfigTest.java (93%) rename backend/src/test/java/reviewme/config/{ => cors}/ExternalCorsConfigTest.java (98%) rename backend/src/test/java/reviewme/config/{ => cors}/LocalCorsConfigTest.java (97%) rename backend/src/test/java/reviewme/{global => config/requestlimit}/RequestLimitInterceptorTest.java (93%) diff --git a/backend/src/main/java/reviewme/config/WebConfig.java b/backend/src/main/java/reviewme/config/WebConfig.java index 916ea5a41..d855040f0 100644 --- a/backend/src/main/java/reviewme/config/WebConfig.java +++ b/backend/src/main/java/reviewme/config/WebConfig.java @@ -3,11 +3,8 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import reviewme.global.RequestLimitInterceptor; import reviewme.reviewgroup.controller.ReviewGroupSessionResolver; import reviewme.reviewgroup.service.ReviewGroupService; @@ -16,16 +13,9 @@ public class WebConfig implements WebMvcConfigurer { private final ReviewGroupService reviewGroupService; - private final RedisTemplate redisTemplate; - private final RequestLimitProperties requestLimitProperties; @Override public void addArgumentResolvers(List resolvers) { resolvers.add(new ReviewGroupSessionResolver(reviewGroupService)); } - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(new RequestLimitInterceptor(redisTemplate, requestLimitProperties)); - } } diff --git a/backend/src/main/java/reviewme/config/CorsConfig.java b/backend/src/main/java/reviewme/config/cors/CorsConfig.java similarity index 90% rename from backend/src/main/java/reviewme/config/CorsConfig.java rename to backend/src/main/java/reviewme/config/cors/CorsConfig.java index 2f51720ea..ff1a483a3 100644 --- a/backend/src/main/java/reviewme/config/CorsConfig.java +++ b/backend/src/main/java/reviewme/config/cors/CorsConfig.java @@ -1,18 +1,16 @@ -package reviewme.config; +package reviewme.config.cors; import lombok.RequiredArgsConstructor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +@Slf4j public class CorsConfig { - private static final Logger log = LoggerFactory.getLogger(CorsConfig.class); - private CorsConfig() { } diff --git a/backend/src/main/java/reviewme/config/CorsProperties.java b/backend/src/main/java/reviewme/config/cors/CorsProperties.java similarity index 91% rename from backend/src/main/java/reviewme/config/CorsProperties.java rename to backend/src/main/java/reviewme/config/cors/CorsProperties.java index 69a7d1c4d..e11a93667 100644 --- a/backend/src/main/java/reviewme/config/CorsProperties.java +++ b/backend/src/main/java/reviewme/config/cors/CorsProperties.java @@ -1,4 +1,4 @@ -package reviewme.config; +package reviewme.config.cors; import java.util.List; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/backend/src/main/java/reviewme/config/DataSourceType.java b/backend/src/main/java/reviewme/config/datasource/DataSourceType.java similarity index 62% rename from backend/src/main/java/reviewme/config/DataSourceType.java rename to backend/src/main/java/reviewme/config/datasource/DataSourceType.java index c48080ab4..b40750df2 100644 --- a/backend/src/main/java/reviewme/config/DataSourceType.java +++ b/backend/src/main/java/reviewme/config/datasource/DataSourceType.java @@ -1,4 +1,4 @@ -package reviewme.config; +package reviewme.config.datasource; public enum DataSourceType { READ, diff --git a/backend/src/main/java/reviewme/config/ReplicationDatasourceConfig.java b/backend/src/main/java/reviewme/config/datasource/ReplicationDatasourceConfig.java similarity index 98% rename from backend/src/main/java/reviewme/config/ReplicationDatasourceConfig.java rename to backend/src/main/java/reviewme/config/datasource/ReplicationDatasourceConfig.java index 6a33a9e08..fb59b2498 100644 --- a/backend/src/main/java/reviewme/config/ReplicationDatasourceConfig.java +++ b/backend/src/main/java/reviewme/config/datasource/ReplicationDatasourceConfig.java @@ -1,4 +1,4 @@ -package reviewme.config; +package reviewme.config.datasource; import java.util.HashMap; import java.util.Map; @@ -54,4 +54,3 @@ public DataSource dataSource(@Qualifier(ROUTING_DATA_SOURCE_NAME) DataSource rou return new LazyConnectionDataSourceProxy(routingDataSource); } } - diff --git a/backend/src/main/java/reviewme/config/ReplicationRoutingDataSource.java b/backend/src/main/java/reviewme/config/datasource/ReplicationRoutingDataSource.java similarity index 93% rename from backend/src/main/java/reviewme/config/ReplicationRoutingDataSource.java rename to backend/src/main/java/reviewme/config/datasource/ReplicationRoutingDataSource.java index 49b7aa22b..f8a802467 100644 --- a/backend/src/main/java/reviewme/config/ReplicationRoutingDataSource.java +++ b/backend/src/main/java/reviewme/config/datasource/ReplicationRoutingDataSource.java @@ -1,4 +1,4 @@ -package reviewme.config; +package reviewme.config.datasource; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import org.springframework.transaction.support.TransactionSynchronizationManager; diff --git a/backend/src/main/java/reviewme/global/RequestLimitInterceptor.java b/backend/src/main/java/reviewme/config/requestlimit/RequestLimitInterceptor.java similarity index 93% rename from backend/src/main/java/reviewme/global/RequestLimitInterceptor.java rename to backend/src/main/java/reviewme/config/requestlimit/RequestLimitInterceptor.java index b5747dfd1..ef25b711e 100644 --- a/backend/src/main/java/reviewme/global/RequestLimitInterceptor.java +++ b/backend/src/main/java/reviewme/config/requestlimit/RequestLimitInterceptor.java @@ -1,4 +1,4 @@ -package reviewme.global; +package reviewme.config.requestlimit; import static org.springframework.http.HttpHeaders.USER_AGENT; @@ -11,8 +11,6 @@ import org.springframework.http.HttpMethod; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; -import reviewme.config.RequestLimitProperties; -import reviewme.global.exception.TooManyRequestException; @Component @EnableConfigurationProperties(RequestLimitProperties.class) diff --git a/backend/src/main/java/reviewme/config/RequestLimitProperties.java b/backend/src/main/java/reviewme/config/requestlimit/RequestLimitProperties.java similarity index 50% rename from backend/src/main/java/reviewme/config/RequestLimitProperties.java rename to backend/src/main/java/reviewme/config/requestlimit/RequestLimitProperties.java index efea3b4f8..558378094 100644 --- a/backend/src/main/java/reviewme/config/RequestLimitProperties.java +++ b/backend/src/main/java/reviewme/config/requestlimit/RequestLimitProperties.java @@ -1,13 +1,8 @@ -package reviewme.config; +package reviewme.config.requestlimit; import java.time.Duration; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "request-limit") -public record RequestLimitProperties( - long threshold, - Duration duration, - String host, - int port -) { +public record RequestLimitProperties(long threshold, Duration duration, String host, int port) { } diff --git a/backend/src/main/java/reviewme/config/RequestLimitRedisConfig.java b/backend/src/main/java/reviewme/config/requestlimit/RequestLimitRedisConfig.java similarity index 97% rename from backend/src/main/java/reviewme/config/RequestLimitRedisConfig.java rename to backend/src/main/java/reviewme/config/requestlimit/RequestLimitRedisConfig.java index a8307db5f..d8bb458a9 100644 --- a/backend/src/main/java/reviewme/config/RequestLimitRedisConfig.java +++ b/backend/src/main/java/reviewme/config/requestlimit/RequestLimitRedisConfig.java @@ -1,4 +1,4 @@ -package reviewme.config; +package reviewme.config.requestlimit; import lombok.RequiredArgsConstructor; import org.springframework.boot.context.properties.EnableConfigurationProperties; diff --git a/backend/src/main/java/reviewme/config/requestlimit/RequestLimitWebConfig.java b/backend/src/main/java/reviewme/config/requestlimit/RequestLimitWebConfig.java new file mode 100644 index 000000000..19f3b2fe4 --- /dev/null +++ b/backend/src/main/java/reviewme/config/requestlimit/RequestLimitWebConfig.java @@ -0,0 +1,20 @@ +package reviewme.config.requestlimit; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@RequiredArgsConstructor +public class RequestLimitWebConfig implements WebMvcConfigurer { + + private final RedisTemplate redisTemplate; + private final RequestLimitProperties requestLimitProperties; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new RequestLimitInterceptor(redisTemplate, requestLimitProperties)); + } +} diff --git a/backend/src/main/java/reviewme/global/exception/TooManyRequestException.java b/backend/src/main/java/reviewme/config/requestlimit/TooManyRequestException.java similarity index 80% rename from backend/src/main/java/reviewme/global/exception/TooManyRequestException.java rename to backend/src/main/java/reviewme/config/requestlimit/TooManyRequestException.java index 4f26fee3e..544fb5885 100644 --- a/backend/src/main/java/reviewme/global/exception/TooManyRequestException.java +++ b/backend/src/main/java/reviewme/config/requestlimit/TooManyRequestException.java @@ -1,6 +1,7 @@ -package reviewme.global.exception; +package reviewme.config.requestlimit; import lombok.extern.slf4j.Slf4j; +import reviewme.global.exception.ReviewMeException; @Slf4j public class TooManyRequestException extends ReviewMeException { diff --git a/backend/src/main/java/reviewme/global/GlobalExceptionHandler.java b/backend/src/main/java/reviewme/global/GlobalExceptionHandler.java index 9d4511618..161e43172 100644 --- a/backend/src/main/java/reviewme/global/GlobalExceptionHandler.java +++ b/backend/src/main/java/reviewme/global/GlobalExceptionHandler.java @@ -22,7 +22,7 @@ import org.springframework.web.servlet.resource.NoResourceFoundException; import reviewme.global.exception.BadRequestException; import reviewme.global.exception.DataInconsistencyException; -import reviewme.global.exception.TooManyRequestException; +import reviewme.config.requestlimit.TooManyRequestException; import reviewme.global.exception.FieldErrorResponse; import reviewme.global.exception.NotFoundException; import reviewme.global.exception.UnauthorizedException; diff --git a/backend/src/main/java/reviewme/global/exception/FieldErrorResponse.java b/backend/src/main/java/reviewme/global/exception/FieldErrorResponse.java index e44edf619..ae0c678a4 100644 --- a/backend/src/main/java/reviewme/global/exception/FieldErrorResponse.java +++ b/backend/src/main/java/reviewme/global/exception/FieldErrorResponse.java @@ -1,8 +1,4 @@ package reviewme.global.exception; -public record FieldErrorResponse( - String field, - Object value, - String message -) { +public record FieldErrorResponse(String field, Object value, String message) { } diff --git a/backend/src/main/java/reviewme/review/service/ReviewRegisterService.java b/backend/src/main/java/reviewme/review/service/ReviewRegisterService.java index 966eaa602..87e5f8538 100644 --- a/backend/src/main/java/reviewme/review/service/ReviewRegisterService.java +++ b/backend/src/main/java/reviewme/review/service/ReviewRegisterService.java @@ -1,8 +1,6 @@ package reviewme.review.service; import lombok.RequiredArgsConstructor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import reviewme.review.domain.Review; @@ -15,8 +13,6 @@ @RequiredArgsConstructor public class ReviewRegisterService { - private static final Logger log = LoggerFactory.getLogger(ReviewRegisterService.class); - private final ReviewMapper reviewMapper; private final ReviewValidator reviewValidator; private final ReviewRepository reviewRepository; diff --git a/backend/src/test/java/reviewme/config/CorsConfigTest.java b/backend/src/test/java/reviewme/config/cors/CorsConfigTest.java similarity index 93% rename from backend/src/test/java/reviewme/config/CorsConfigTest.java rename to backend/src/test/java/reviewme/config/cors/CorsConfigTest.java index 90af4a342..d7f20bfd2 100644 --- a/backend/src/test/java/reviewme/config/CorsConfigTest.java +++ b/backend/src/test/java/reviewme/config/cors/CorsConfigTest.java @@ -1,4 +1,4 @@ -package reviewme.config; +package reviewme.config.cors; import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; @@ -32,6 +32,7 @@ void setUp() { static class TestController { @RequestMapping("/test") public void test() { + // Testing controller calls, no-op } } } diff --git a/backend/src/test/java/reviewme/config/ExternalCorsConfigTest.java b/backend/src/test/java/reviewme/config/cors/ExternalCorsConfigTest.java similarity index 98% rename from backend/src/test/java/reviewme/config/ExternalCorsConfigTest.java rename to backend/src/test/java/reviewme/config/cors/ExternalCorsConfigTest.java index 095bb1bc7..39445b70f 100644 --- a/backend/src/test/java/reviewme/config/ExternalCorsConfigTest.java +++ b/backend/src/test/java/reviewme/config/cors/ExternalCorsConfigTest.java @@ -1,4 +1,4 @@ -package reviewme.config; +package reviewme.config.cors; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; diff --git a/backend/src/test/java/reviewme/config/LocalCorsConfigTest.java b/backend/src/test/java/reviewme/config/cors/LocalCorsConfigTest.java similarity index 97% rename from backend/src/test/java/reviewme/config/LocalCorsConfigTest.java rename to backend/src/test/java/reviewme/config/cors/LocalCorsConfigTest.java index cd050b988..214de0857 100644 --- a/backend/src/test/java/reviewme/config/LocalCorsConfigTest.java +++ b/backend/src/test/java/reviewme/config/cors/LocalCorsConfigTest.java @@ -1,4 +1,4 @@ -package reviewme.config; +package reviewme.config.cors; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; diff --git a/backend/src/test/java/reviewme/global/RequestLimitInterceptorTest.java b/backend/src/test/java/reviewme/config/requestlimit/RequestLimitInterceptorTest.java similarity index 93% rename from backend/src/test/java/reviewme/global/RequestLimitInterceptorTest.java rename to backend/src/test/java/reviewme/config/requestlimit/RequestLimitInterceptorTest.java index 998639691..969040683 100644 --- a/backend/src/test/java/reviewme/global/RequestLimitInterceptorTest.java +++ b/backend/src/test/java/reviewme/config/requestlimit/RequestLimitInterceptorTest.java @@ -1,4 +1,4 @@ -package reviewme.global; +package reviewme.config.requestlimit; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; @@ -14,8 +14,6 @@ import org.junit.jupiter.api.Test; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; -import reviewme.config.RequestLimitProperties; -import reviewme.global.exception.TooManyRequestException; class RequestLimitInterceptorTest { @@ -41,7 +39,6 @@ void setUp() { @Test void POST_요청이_아니면_통과한다() { // given - HttpServletRequest request = mock(HttpServletRequest.class); given(request.getMethod()).willReturn("GET"); // when From 55db0f6ebb512f783876d528097d1f27c4f7e43d Mon Sep 17 00:00:00 2001 From: Donghoon Lee Date: Tue, 12 Nov 2024 16:32:18 +0900 Subject: [PATCH 06/11] [All] chore: add CODEOWNERS (#959) --- .github/CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..06032ab2f --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +* @chysis @BadaHertz52 @soosoo22 @ImxYJL @donghoony @Kimprodp @nayonsoso @skylar1220 +/frontend/ @chysis @BadaHertz52 @soosoo22 @ImxYJL +/backend/ @donghoony @Kimprodp @nayonsoso @skylar1220 From 8858e0221de07aad22015be37802fba73309bbb2 Mon Sep 17 00:00:00 2001 From: Donghoon Lee Date: Sun, 17 Nov 2024 16:00:26 +0900 Subject: [PATCH 07/11] =?UTF-8?q?[BE]=20feat:=20=ED=95=98=EC=9D=B4?= =?UTF-8?q?=EB=9D=BC=EC=9D=B4=ED=8A=B8=20=EB=B2=8C=ED=81=AC=20=EC=82=BD?= =?UTF-8?q?=EC=9E=85=20=EC=B6=94=EA=B0=80=20(#961)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 하이라이트 벌크 삽입 추가 * refactor: 불필요한 `@Repository` 제거 * fix: `findAll` 사용하지 않도록 수정 * fix: 테스트 수정 * refactor: `NamedParameterJdbcTemplate` 사용하도록 수정 --- .../repository/HighlightJdbcRepository.java | 9 +++++++ .../HighlightJdbcRepositoryImpl.java | 24 +++++++++++++++++++ .../repository/HighlightRepository.java | 8 +++++-- .../repository/HighlightRepositoryTest.java | 18 ++++++++++++++ .../service/HighlightServiceTest.java | 2 +- 5 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 backend/src/main/java/reviewme/highlight/repository/HighlightJdbcRepository.java create mode 100644 backend/src/main/java/reviewme/highlight/repository/HighlightJdbcRepositoryImpl.java diff --git a/backend/src/main/java/reviewme/highlight/repository/HighlightJdbcRepository.java b/backend/src/main/java/reviewme/highlight/repository/HighlightJdbcRepository.java new file mode 100644 index 000000000..b1e20ef36 --- /dev/null +++ b/backend/src/main/java/reviewme/highlight/repository/HighlightJdbcRepository.java @@ -0,0 +1,9 @@ +package reviewme.highlight.repository; + +import java.util.Collection; +import reviewme.highlight.domain.Highlight; + +public interface HighlightJdbcRepository { + + void saveAll(Collection highlights); +} diff --git a/backend/src/main/java/reviewme/highlight/repository/HighlightJdbcRepositoryImpl.java b/backend/src/main/java/reviewme/highlight/repository/HighlightJdbcRepositoryImpl.java new file mode 100644 index 000000000..077f6a531 --- /dev/null +++ b/backend/src/main/java/reviewme/highlight/repository/HighlightJdbcRepositoryImpl.java @@ -0,0 +1,24 @@ +package reviewme.highlight.repository; + +import java.util.Collection; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.namedparam.SqlParameterSource; +import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils; +import reviewme.highlight.domain.Highlight; + +@RequiredArgsConstructor +public class HighlightJdbcRepositoryImpl implements HighlightJdbcRepository { + + private final NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + @Override + public void saveAll(Collection highlights) { + SqlParameterSource[] parameterSources = SqlParameterSourceUtils.createBatch(highlights.toArray()); + String insertSql = """ + INSERT INTO highlight (answer_id, line_index, start_index, end_index) + VALUES (:answerId, :lineIndex, :highlightRange.startIndex, :highlightRange.endIndex) + """; + namedParameterJdbcTemplate.batchUpdate(insertSql, parameterSources); + } +} diff --git a/backend/src/main/java/reviewme/highlight/repository/HighlightRepository.java b/backend/src/main/java/reviewme/highlight/repository/HighlightRepository.java index 74760e09c..104e4cfc1 100644 --- a/backend/src/main/java/reviewme/highlight/repository/HighlightRepository.java +++ b/backend/src/main/java/reviewme/highlight/repository/HighlightRepository.java @@ -2,12 +2,16 @@ import java.util.Collection; import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.Repository; import reviewme.highlight.domain.Highlight; -public interface HighlightRepository extends JpaRepository { +public interface HighlightRepository extends Repository, HighlightJdbcRepository { + + Highlight save(Highlight highlight); + + boolean existsById(long id); @Modifying @Query(""" diff --git a/backend/src/test/java/reviewme/highlight/repository/HighlightRepositoryTest.java b/backend/src/test/java/reviewme/highlight/repository/HighlightRepositoryTest.java index 40b584f47..6e46ed088 100644 --- a/backend/src/test/java/reviewme/highlight/repository/HighlightRepositoryTest.java +++ b/backend/src/test/java/reviewme/highlight/repository/HighlightRepositoryTest.java @@ -16,6 +16,24 @@ class HighlightRepositoryTest { @Autowired private HighlightRepository highlightRepository; + @Test + void 한_번에_여러_하이라이트를_벌크_삽입한다() { + // given + List highlights = List.of( + new Highlight(1L, 1, new HighlightRange(1, 2)), + new Highlight(1L, 1, new HighlightRange(3, 5)) + ); + + // when + highlightRepository.saveAll(highlights); + + // then + List actual = highlightRepository.findAllByAnswerIdsOrderedAsc(List.of(1L)); + assertThat(actual) + .extracting(Highlight::getHighlightRange) + .containsExactly(new HighlightRange(1, 2), new HighlightRange(3, 5)); + } + @Test void 하이라이트를_줄번호_시작_인덱스_순서대로_정렬해서_가져온다() { // given diff --git a/backend/src/test/java/reviewme/highlight/service/HighlightServiceTest.java b/backend/src/test/java/reviewme/highlight/service/HighlightServiceTest.java index 207a68d29..c4ea9f3bb 100644 --- a/backend/src/test/java/reviewme/highlight/service/HighlightServiceTest.java +++ b/backend/src/test/java/reviewme/highlight/service/HighlightServiceTest.java @@ -102,7 +102,7 @@ class HighlightServiceTest { highlightService.editHighlight(highlightsRequest, reviewGroup); // then - List highlights = highlightRepository.findAll(); + List highlights = highlightRepository.findAllByAnswerIdsOrderedAsc(List.of(textAnswer.getId())); assertAll( () -> assertThat(highlights.get(0).getAnswerId()).isEqualTo(textAnswer.getId()), () -> assertThat(highlights.get(0).getHighlightRange()).isEqualTo( From 9b59f8d58b1766af0263d4c19289392f55b157b6 Mon Sep 17 00:00:00 2001 From: Donghoon Lee Date: Sun, 17 Nov 2024 16:01:21 +0900 Subject: [PATCH 08/11] =?UTF-8?q?[BE]=20refactor:=20=ED=95=98=EC=9D=B4?= =?UTF-8?q?=EB=9D=BC=EC=9D=B4=ED=8A=B8=20=EB=A7=A4=ED=95=91=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B0=84=EC=86=8C=ED=99=94=20(#962)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 하이라이트 매핑 로직 간소화 * refactor: `Fragments` 변환 로직 dto 내부로 이동 * refactor: 내부 값 사용하도록 변경 * refactor: Stream 가독성 향상 * style: 개행 삭제 * test: 하이라이트가 안 쳐지는 라인이 잘 변환되는지 테스트 Co-authored-by: Hyeonji <110809927+skylar1220@users.noreply.github.com> * refactor: 메서드 네임 확실하게 수정 --------- Co-authored-by: Hyeonji <110809927+skylar1220@users.noreply.github.com> --- .../highlight/domain/HighlightedLines.java | 10 +++ .../highlight/service/HighlightService.java | 1 - .../service/dto/HighlightRequest.java | 13 ++++ .../service/dto/HighlightsRequest.java | 7 +++ .../service/mapper/HighlightFragment.java | 4 ++ .../service/mapper/HighlightMapper.java | 63 ++++--------------- .../domain/HighlightedLinesTest.java | 17 +++++ 7 files changed, 62 insertions(+), 53 deletions(-) create mode 100644 backend/src/main/java/reviewme/highlight/service/mapper/HighlightFragment.java diff --git a/backend/src/main/java/reviewme/highlight/domain/HighlightedLines.java b/backend/src/main/java/reviewme/highlight/domain/HighlightedLines.java index f7000ecb2..f24827d30 100644 --- a/backend/src/main/java/reviewme/highlight/domain/HighlightedLines.java +++ b/backend/src/main/java/reviewme/highlight/domain/HighlightedLines.java @@ -2,6 +2,8 @@ import java.util.Arrays; import java.util.List; +import java.util.function.Function; +import java.util.stream.IntStream; import lombok.Getter; import reviewme.highlight.domain.exception.InvalidHighlightLineIndexException; import reviewme.highlight.domain.exception.NegativeHighlightLineIndexException; @@ -37,4 +39,12 @@ private void validateLineIndexRange(int lineIndex) { throw new InvalidHighlightLineIndexException(lineIndex, lines.size()); } } + + public List toHighlights(long answerId) { + return IntStream.range(0, lines.size()) + .mapToObj(lineIndex -> lines.get(lineIndex).getRanges().stream() + .map(range -> new Highlight(answerId, lineIndex, range))) + .flatMap(Function.identity()) + .toList(); + } } diff --git a/backend/src/main/java/reviewme/highlight/service/HighlightService.java b/backend/src/main/java/reviewme/highlight/service/HighlightService.java index 7cb9f9c70..cff5063a5 100644 --- a/backend/src/main/java/reviewme/highlight/service/HighlightService.java +++ b/backend/src/main/java/reviewme/highlight/service/HighlightService.java @@ -30,7 +30,6 @@ public void editHighlight(HighlightsRequest highlightsRequest, ReviewGroup revie Set answerIds = answerRepository.findIdsByQuestionId(highlightsRequest.questionId()); highlightRepository.deleteAllByAnswerIds(answerIds); - highlightRepository.saveAll(highlights); } } diff --git a/backend/src/main/java/reviewme/highlight/service/dto/HighlightRequest.java b/backend/src/main/java/reviewme/highlight/service/dto/HighlightRequest.java index 673cc8e6a..1371c6959 100644 --- a/backend/src/main/java/reviewme/highlight/service/dto/HighlightRequest.java +++ b/backend/src/main/java/reviewme/highlight/service/dto/HighlightRequest.java @@ -4,6 +4,8 @@ import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import java.util.List; +import java.util.stream.Stream; +import reviewme.highlight.service.mapper.HighlightFragment; public record HighlightRequest( @@ -13,4 +15,15 @@ public record HighlightRequest( @Valid @NotEmpty(message = "하이라이트 된 라인을 입력해주세요.") List lines ) { + public List toFragments() { + return lines.stream() + .flatMap(this::mapRangesToFragment) + .toList(); + } + + private Stream mapRangesToFragment(HighlightedLineRequest line) { + return line.ranges() + .stream() + .map(range -> new HighlightFragment(answerId, line.index(), range.startIndex(), range.endIndex())); + } } diff --git a/backend/src/main/java/reviewme/highlight/service/dto/HighlightsRequest.java b/backend/src/main/java/reviewme/highlight/service/dto/HighlightsRequest.java index b8f26cba6..b1f7f6de3 100644 --- a/backend/src/main/java/reviewme/highlight/service/dto/HighlightsRequest.java +++ b/backend/src/main/java/reviewme/highlight/service/dto/HighlightsRequest.java @@ -3,6 +3,7 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import java.util.List; +import reviewme.highlight.service.mapper.HighlightFragment; public record HighlightsRequest( @@ -20,4 +21,10 @@ public List getUniqueAnswerIds() { .distinct() .toList(); } + + public List toFragments() { + return highlights.stream() + .flatMap(request -> request.toFragments().stream()) + .toList(); + } } diff --git a/backend/src/main/java/reviewme/highlight/service/mapper/HighlightFragment.java b/backend/src/main/java/reviewme/highlight/service/mapper/HighlightFragment.java new file mode 100644 index 000000000..33e08f56e --- /dev/null +++ b/backend/src/main/java/reviewme/highlight/service/mapper/HighlightFragment.java @@ -0,0 +1,4 @@ +package reviewme.highlight.service.mapper; + +public record HighlightFragment(long answerId, int lineIndex, int startIndex, int endIndex) { +} diff --git a/backend/src/main/java/reviewme/highlight/service/mapper/HighlightMapper.java b/backend/src/main/java/reviewme/highlight/service/mapper/HighlightMapper.java index edbec9013..512546030 100644 --- a/backend/src/main/java/reviewme/highlight/service/mapper/HighlightMapper.java +++ b/backend/src/main/java/reviewme/highlight/service/mapper/HighlightMapper.java @@ -1,21 +1,14 @@ package reviewme.highlight.service.mapper; -import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import reviewme.highlight.domain.HighlightedLines; -import reviewme.highlight.domain.HighlightedLine; import reviewme.highlight.domain.Highlight; -import reviewme.highlight.domain.HighlightRange; -import reviewme.highlight.service.dto.HighlightIndexRangeRequest; -import reviewme.highlight.service.dto.HighlightRequest; -import reviewme.highlight.service.dto.HighlightedLineRequest; +import reviewme.highlight.domain.HighlightedLines; import reviewme.highlight.service.dto.HighlightsRequest; -import reviewme.review.domain.Answer; +import reviewme.review.domain.TextAnswer; import reviewme.review.repository.TextAnswerRepository; @Component @@ -25,53 +18,19 @@ public class HighlightMapper { private final TextAnswerRepository textAnswerRepository; public List mapToHighlights(HighlightsRequest highlightsRequest) { - Map answerHighlightLines = textAnswerRepository + Map answerIdHighlightedLines = textAnswerRepository .findAllById(highlightsRequest.getUniqueAnswerIds()) .stream() - .collect(Collectors.toMap(Answer::getId, answer -> new HighlightedLines(answer.getContent()))); - addIndexRanges(highlightsRequest, answerHighlightLines); - return mapLinesToHighlights(answerHighlightLines); - } - - private void addIndexRanges(HighlightsRequest highlightsRequest, Map answerHighlightLines) { - for (HighlightRequest highlightRequest : highlightsRequest.highlights()) { - HighlightedLines highlightedLines = answerHighlightLines.get(highlightRequest.answerId()); - addIndexRangesForAnswer(highlightRequest, highlightedLines); - } - } - - private void addIndexRangesForAnswer(HighlightRequest highlightRequest, HighlightedLines highlightedLines) { - for (HighlightedLineRequest lineRequest : highlightRequest.lines()) { - int lineIndex = lineRequest.index(); - for (HighlightIndexRangeRequest rangeRequest : lineRequest.ranges()) { - highlightedLines.addRange(lineIndex, rangeRequest.startIndex(), rangeRequest.endIndex()); - } - } - } - - private List mapLinesToHighlights(Map answerHighlightLines) { - List highlights = new ArrayList<>(); - for (Entry answerHighlightLine : answerHighlightLines.entrySet()) { - createHighlightsForAnswer(answerHighlightLine, highlights); - } - return highlights; - } + .collect(Collectors.toMap(TextAnswer::getId, answer -> new HighlightedLines(answer.getContent()))); - private void createHighlightsForAnswer(Entry answerHighlightLine, - List highlights) { - long answerId = answerHighlightLine.getKey(); - List highlightedLines = answerHighlightLine.getValue().getLines(); - - for (int lineIndex = 0; lineIndex < highlightedLines.size(); lineIndex++) { - createHighlightForLine(highlightedLines, lineIndex, answerId, highlights); + for (HighlightFragment fragment : highlightsRequest.toFragments()) { + HighlightedLines highlightedLines = answerIdHighlightedLines.get(fragment.answerId()); + highlightedLines.addRange(fragment.lineIndex(), fragment.startIndex(), fragment.endIndex()); } - } - private void createHighlightForLine(List highlightedLines, int lineIndex, long answerId, - List highlights) { - for (HighlightRange range : highlightedLines.get(lineIndex).getRanges()) { - Highlight highlight = new Highlight(answerId, lineIndex, range); - highlights.add(highlight); - } + return answerIdHighlightedLines.entrySet() + .stream() + .flatMap(entry -> entry.getValue().toHighlights(entry.getKey()).stream()) + .toList(); } } diff --git a/backend/src/test/java/reviewme/highlight/domain/HighlightedLinesTest.java b/backend/src/test/java/reviewme/highlight/domain/HighlightedLinesTest.java index 53d81c209..d3e4a443c 100644 --- a/backend/src/test/java/reviewme/highlight/domain/HighlightedLinesTest.java +++ b/backend/src/test/java/reviewme/highlight/domain/HighlightedLinesTest.java @@ -84,4 +84,21 @@ class HighlightedLinesTest { assertThatCode(() -> highlightedLines.addRange(invalidLineIndex, 0, 1)) .isInstanceOf(InvalidHighlightLineIndexException.class); } + + @Test + void 하이라이트가_존재하는_부분만_엔티티로_변환한다() { + // given + HighlightedLines lines = new HighlightedLines("0\n11\n222"); + lines.addRange(0, 0, 0); + lines.addRange(2, 2, 2); + + // when + List highlights = lines.toHighlights(1L); + + // then + assertThat(highlights).containsExactly( + new Highlight(1L, 0, new HighlightRange(0, 0)), + new Highlight(1L, 2, new HighlightRange(2, 2)) + ); + } } From 9e017a19ba06fb887ea305dd02a0a9fcb4295570 Mon Sep 17 00:00:00 2001 From: Donghoon Lee Date: Mon, 18 Nov 2024 01:12:21 +0900 Subject: [PATCH 09/11] =?UTF-8?q?[BE]=20refactor/fix:=20=ED=95=98=EC=9D=B4?= =?UTF-8?q?=EB=9D=BC=EC=9D=B4=ED=8A=B8=20=EA=B2=80=EC=A6=9D=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=20=EC=B1=85=EC=9E=84=20=EC=9D=B4=EB=8F=99,=20?= =?UTF-8?q?=ED=95=98=EC=9D=B4=EB=9D=BC=EC=9D=B4=ED=8A=B8=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95=20(#966)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: `HighlightValidator` 삭제 * chore: add todos * refactor: 타입에 따라 검증하는 객체 이름에 `Typed-`를 접두사로 추가 * feat: `AnswerValidator`에서 정답과 관련된 검증 진행 * refactor: `List` -> `Collection` 받도록 수정 * fix: 리뷰 그룹에 해당하는 하이라이트만 삭제하도록 수정 * refactor: 사용하지 않는 상수 삭제 * refactor: `TypedAnswerValidatorFactory`로 수정 * refactor: 쿼리 수정, 테스트 추가 --- .../repository/HighlightRepository.java | 19 +-- .../highlight/service/HighlightService.java | 16 ++- ...werAndProvidedAnswerMismatchException.java | 16 --- .../service/validator/HighlightValidator.java | 41 ------- ...QuestionNotContainingAnswersException.java | 15 +++ ...iewGroupNotContainingAnswersException.java | 15 +++ .../service/validator/AnswerValidator.java | 29 ++++- ...java => CheckboxTypedAnswerValidator.java} | 2 +- .../service/validator/ReviewValidator.java | 12 +- ...tor.java => TextTypedAnswerValidator.java} | 3 +- .../validator/TypedAnswerValidator.java | 10 ++ ....java => TypedAnswerValidatorFactory.java} | 8 +- .../repository/HighlightRepositoryTest.java | 53 +++++++++ .../validator/HighlightValidatorTest.java | 109 ------------------ .../validator/AnswerValidatorTest.java | 90 +++++++++++++++ ... => CheckboxTypedAnswerValidatorTest.java} | 4 +- ...java => TextTypedAnswerValidatorTest.java} | 4 +- ...TypedTypedAnswerValidatorFactoryTest.java} | 13 ++- 18 files changed, 249 insertions(+), 210 deletions(-) delete mode 100644 backend/src/main/java/reviewme/highlight/service/exception/SubmittedAnswerAndProvidedAnswerMismatchException.java delete mode 100644 backend/src/main/java/reviewme/highlight/service/validator/HighlightValidator.java create mode 100644 backend/src/main/java/reviewme/review/service/exception/QuestionNotContainingAnswersException.java create mode 100644 backend/src/main/java/reviewme/review/service/exception/ReviewGroupNotContainingAnswersException.java rename backend/src/main/java/reviewme/review/service/validator/{CheckboxAnswerValidator.java => CheckboxTypedAnswerValidator.java} (97%) rename backend/src/main/java/reviewme/review/service/validator/{TextAnswerValidator.java => TextTypedAnswerValidator.java} (94%) create mode 100644 backend/src/main/java/reviewme/review/service/validator/TypedAnswerValidator.java rename backend/src/main/java/reviewme/review/service/validator/{AnswerValidatorFactory.java => TypedAnswerValidatorFactory.java} (68%) delete mode 100644 backend/src/test/java/reviewme/highlight/service/validator/HighlightValidatorTest.java create mode 100644 backend/src/test/java/reviewme/review/service/validator/AnswerValidatorTest.java rename backend/src/test/java/reviewme/review/service/validator/{CheckboxAnswerValidatorTest.java => CheckboxTypedAnswerValidatorTest.java} (97%) rename backend/src/test/java/reviewme/review/service/validator/{TextAnswerValidatorTest.java => TextTypedAnswerValidatorTest.java} (96%) rename backend/src/test/java/reviewme/review/service/validator/{AnswerValidatorFactoryTest.java => TypedTypedAnswerValidatorFactoryTest.java} (68%) diff --git a/backend/src/main/java/reviewme/highlight/repository/HighlightRepository.java b/backend/src/main/java/reviewme/highlight/repository/HighlightRepository.java index 104e4cfc1..2733b2027 100644 --- a/backend/src/main/java/reviewme/highlight/repository/HighlightRepository.java +++ b/backend/src/main/java/reviewme/highlight/repository/HighlightRepository.java @@ -13,18 +13,21 @@ public interface HighlightRepository extends Repository, Highli boolean existsById(long id); - @Modifying @Query(""" - DELETE FROM Highlight h + SELECT h FROM Highlight h WHERE h.answerId IN :answerIds + ORDER BY h.lineIndex, h.highlightRange.startIndex ASC """) - void deleteAllByAnswerIds(Collection answerIds); + List findAllByAnswerIdsOrderedAsc(Collection answerIds); + @Modifying @Query(""" - SELECT h - FROM Highlight h - WHERE h.answerId IN :answerIds - ORDER BY h.lineIndex, h.highlightRange.startIndex ASC + DELETE FROM Highlight h + WHERE h.answerId IN ( + SELECT a.id FROM Answer a + JOIN Review r ON a.reviewId = r.id + WHERE r.reviewGroupId = :reviewGroupId AND a.questionId = :questionId + ) """) - List findAllByAnswerIdsOrderedAsc(Collection answerIds); + void deleteByReviewGroupIdAndQuestionId(long reviewGroupId, long questionId); } diff --git a/backend/src/main/java/reviewme/highlight/service/HighlightService.java b/backend/src/main/java/reviewme/highlight/service/HighlightService.java index cff5063a5..8651bca86 100644 --- a/backend/src/main/java/reviewme/highlight/service/HighlightService.java +++ b/backend/src/main/java/reviewme/highlight/service/HighlightService.java @@ -1,7 +1,6 @@ package reviewme.highlight.service; import java.util.List; -import java.util.Set; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -9,8 +8,7 @@ import reviewme.highlight.repository.HighlightRepository; import reviewme.highlight.service.dto.HighlightsRequest; import reviewme.highlight.service.mapper.HighlightMapper; -import reviewme.highlight.service.validator.HighlightValidator; -import reviewme.review.repository.AnswerRepository; +import reviewme.review.service.validator.AnswerValidator; import reviewme.reviewgroup.domain.ReviewGroup; @Service @@ -18,18 +16,18 @@ public class HighlightService { private final HighlightRepository highlightRepository; - private final AnswerRepository answerRepository; - private final HighlightValidator highlightValidator; private final HighlightMapper highlightMapper; + private final AnswerValidator answerValidator; @Transactional public void editHighlight(HighlightsRequest highlightsRequest, ReviewGroup reviewGroup) { - highlightValidator.validate(highlightsRequest, reviewGroup); - List highlights = highlightMapper.mapToHighlights(highlightsRequest); + List requestedAnswerIds = highlightsRequest.getUniqueAnswerIds(); + answerValidator.validateQuestionContainsAnswers(highlightsRequest.questionId(), requestedAnswerIds); + answerValidator.validateReviewGroupContainsAnswers(reviewGroup, requestedAnswerIds); - Set answerIds = answerRepository.findIdsByQuestionId(highlightsRequest.questionId()); - highlightRepository.deleteAllByAnswerIds(answerIds); + List highlights = highlightMapper.mapToHighlights(highlightsRequest); + highlightRepository.deleteByReviewGroupIdAndQuestionId(reviewGroup.getId(), highlightsRequest.questionId()); highlightRepository.saveAll(highlights); } } diff --git a/backend/src/main/java/reviewme/highlight/service/exception/SubmittedAnswerAndProvidedAnswerMismatchException.java b/backend/src/main/java/reviewme/highlight/service/exception/SubmittedAnswerAndProvidedAnswerMismatchException.java deleted file mode 100644 index 0282bd983..000000000 --- a/backend/src/main/java/reviewme/highlight/service/exception/SubmittedAnswerAndProvidedAnswerMismatchException.java +++ /dev/null @@ -1,16 +0,0 @@ -package reviewme.highlight.service.exception; - -import java.util.Collection; -import lombok.extern.slf4j.Slf4j; -import reviewme.global.exception.BadRequestException; - -@Slf4j -public class SubmittedAnswerAndProvidedAnswerMismatchException extends BadRequestException { - - public SubmittedAnswerAndProvidedAnswerMismatchException(Collection providedAnswerIds, - Collection submittedAnswerIds) { - super("제출된 응답이 제공된 응답과 일치하지 않아요."); - log.info("SubmittedAnswer and providedAnswer mismatch - providedAnswerIds: {}, submittedAnswerIds: {}", - providedAnswerIds, submittedAnswerIds); - } -} diff --git a/backend/src/main/java/reviewme/highlight/service/validator/HighlightValidator.java b/backend/src/main/java/reviewme/highlight/service/validator/HighlightValidator.java deleted file mode 100644 index e05f0f9df..000000000 --- a/backend/src/main/java/reviewme/highlight/service/validator/HighlightValidator.java +++ /dev/null @@ -1,41 +0,0 @@ - -package reviewme.highlight.service.validator; - -import java.util.List; -import java.util.Set; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -import reviewme.highlight.service.dto.HighlightsRequest; -import reviewme.highlight.service.exception.SubmittedAnswerAndProvidedAnswerMismatchException; -import reviewme.review.repository.AnswerRepository; -import reviewme.reviewgroup.domain.ReviewGroup; - -@Component -@RequiredArgsConstructor -public class HighlightValidator { - - private final AnswerRepository answerRepository; - - public void validate(HighlightsRequest request, ReviewGroup reviewGroup) { - validateQuestionContainsAnswer(request); - validateReviewGroupContainsAnswer(request, reviewGroup); - } - - private void validateQuestionContainsAnswer(HighlightsRequest request) { - Set providedAnswerIds = answerRepository.findIdsByQuestionId(request.questionId()); - List submittedAnswerIds = request.getUniqueAnswerIds(); - - if (!providedAnswerIds.containsAll(submittedAnswerIds)) { - throw new SubmittedAnswerAndProvidedAnswerMismatchException(providedAnswerIds, submittedAnswerIds); - } - } - - private void validateReviewGroupContainsAnswer(HighlightsRequest request, ReviewGroup reviewGroup) { - Set providedAnswerIds = answerRepository.findIdsByReviewGroupId(reviewGroup.getId()); - List submittedAnswerIds = request.getUniqueAnswerIds(); - - if (!providedAnswerIds.containsAll(submittedAnswerIds)) { - throw new SubmittedAnswerAndProvidedAnswerMismatchException(providedAnswerIds, submittedAnswerIds); - } - } -} diff --git a/backend/src/main/java/reviewme/review/service/exception/QuestionNotContainingAnswersException.java b/backend/src/main/java/reviewme/review/service/exception/QuestionNotContainingAnswersException.java new file mode 100644 index 000000000..3a7740787 --- /dev/null +++ b/backend/src/main/java/reviewme/review/service/exception/QuestionNotContainingAnswersException.java @@ -0,0 +1,15 @@ +package reviewme.review.service.exception; + +import java.util.Collection; +import lombok.extern.slf4j.Slf4j; +import reviewme.global.exception.ReviewMeException; + +@Slf4j +public class QuestionNotContainingAnswersException extends ReviewMeException { + + public QuestionNotContainingAnswersException(long questionId, Collection providedAnswerIds) { + super("질문에 속하지 않는 답변이예요."); + log.info("Question not containing provided answers - questionId: {}, providedAnswerIds: {}", + questionId, providedAnswerIds); + } +} diff --git a/backend/src/main/java/reviewme/review/service/exception/ReviewGroupNotContainingAnswersException.java b/backend/src/main/java/reviewme/review/service/exception/ReviewGroupNotContainingAnswersException.java new file mode 100644 index 000000000..7f641512f --- /dev/null +++ b/backend/src/main/java/reviewme/review/service/exception/ReviewGroupNotContainingAnswersException.java @@ -0,0 +1,15 @@ +package reviewme.review.service.exception; + +import java.util.Collection; +import lombok.extern.slf4j.Slf4j; +import reviewme.global.exception.ReviewMeException; + +@Slf4j +public class ReviewGroupNotContainingAnswersException extends ReviewMeException { + + public ReviewGroupNotContainingAnswersException(long reviewGroupId, Collection providedAnswerIds) { + super("리뷰 그룹에 속하지 않는 답변이예요."); + log.info("ReviewGroup not containing provided answers - reviewGroupId: {}, providedAnswerIds: {}", + reviewGroupId, providedAnswerIds); + } +} diff --git a/backend/src/main/java/reviewme/review/service/validator/AnswerValidator.java b/backend/src/main/java/reviewme/review/service/validator/AnswerValidator.java index 11162cc26..bb9f85434 100644 --- a/backend/src/main/java/reviewme/review/service/validator/AnswerValidator.java +++ b/backend/src/main/java/reviewme/review/service/validator/AnswerValidator.java @@ -1,10 +1,31 @@ package reviewme.review.service.validator; -import reviewme.review.domain.Answer; +import java.util.Collection; +import java.util.Set; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import reviewme.review.repository.AnswerRepository; +import reviewme.review.service.exception.QuestionNotContainingAnswersException; +import reviewme.review.service.exception.ReviewGroupNotContainingAnswersException; +import reviewme.reviewgroup.domain.ReviewGroup; -public interface AnswerValidator { +@Component +@RequiredArgsConstructor +public class AnswerValidator { - boolean supports(Class answerClass); + private final AnswerRepository answerRepository; - void validate(Answer answer); + public void validateQuestionContainsAnswers(long questionId, Collection answerIds) { + Set receivedAnswerIds = answerRepository.findIdsByQuestionId(questionId); + if (!receivedAnswerIds.containsAll(answerIds)) { + throw new QuestionNotContainingAnswersException(questionId, answerIds); + } + } + + public void validateReviewGroupContainsAnswers(ReviewGroup reviewGroup, Collection answerIds) { + Set receivedAnswerIds = answerRepository.findIdsByReviewGroupId(reviewGroup.getId()); + if (!receivedAnswerIds.containsAll(answerIds)) { + throw new ReviewGroupNotContainingAnswersException(reviewGroup.getId(), answerIds); + } + } } diff --git a/backend/src/main/java/reviewme/review/service/validator/CheckboxAnswerValidator.java b/backend/src/main/java/reviewme/review/service/validator/CheckboxTypedAnswerValidator.java similarity index 97% rename from backend/src/main/java/reviewme/review/service/validator/CheckboxAnswerValidator.java rename to backend/src/main/java/reviewme/review/service/validator/CheckboxTypedAnswerValidator.java index ab57ead79..d6cd50eec 100644 --- a/backend/src/main/java/reviewme/review/service/validator/CheckboxAnswerValidator.java +++ b/backend/src/main/java/reviewme/review/service/validator/CheckboxTypedAnswerValidator.java @@ -21,7 +21,7 @@ @Component @RequiredArgsConstructor(access = AccessLevel.PROTECTED) -public class CheckboxAnswerValidator implements AnswerValidator { +public class CheckboxTypedAnswerValidator implements TypedAnswerValidator { private final QuestionRepository questionRepository; private final OptionGroupRepository optionGroupRepository; diff --git a/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java b/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java index 9c68894c9..96fb55ec4 100644 --- a/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java +++ b/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java @@ -7,23 +7,23 @@ import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import reviewme.template.domain.Question; -import reviewme.template.repository.QuestionRepository; import reviewme.review.domain.Answer; -import reviewme.review.domain.CheckboxAnswerSelectedOption; import reviewme.review.domain.CheckboxAnswer; +import reviewme.review.domain.CheckboxAnswerSelectedOption; import reviewme.review.domain.Review; import reviewme.review.service.exception.MissingRequiredQuestionException; import reviewme.review.service.exception.SubmittedQuestionAndProvidedQuestionMismatchException; +import reviewme.template.domain.Question; import reviewme.template.domain.Section; import reviewme.template.domain.SectionQuestion; +import reviewme.template.repository.QuestionRepository; import reviewme.template.repository.SectionRepository; @Component @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class ReviewValidator { - private final AnswerValidatorFactory answerValidatorFactory; + private final TypedAnswerValidatorFactory typedAnswerValidatorFactory; private final SectionRepository sectionRepository; private final QuestionRepository questionRepository; @@ -36,8 +36,8 @@ public void validate(Review review) { private void validateAnswer(List answers) { for (Answer answer : answers) { - AnswerValidator validator = answerValidatorFactory.getAnswerValidator(answer.getClass()); - validator.validate(answer); + typedAnswerValidatorFactory.getAnswerValidator(answer.getClass()) + .validate(answer); } } diff --git a/backend/src/main/java/reviewme/review/service/validator/TextAnswerValidator.java b/backend/src/main/java/reviewme/review/service/validator/TextTypedAnswerValidator.java similarity index 94% rename from backend/src/main/java/reviewme/review/service/validator/TextAnswerValidator.java rename to backend/src/main/java/reviewme/review/service/validator/TextTypedAnswerValidator.java index 59d9d476b..0dffa56c1 100644 --- a/backend/src/main/java/reviewme/review/service/validator/TextAnswerValidator.java +++ b/backend/src/main/java/reviewme/review/service/validator/TextTypedAnswerValidator.java @@ -12,9 +12,8 @@ @Component @RequiredArgsConstructor(access = AccessLevel.PROTECTED) -public class TextAnswerValidator implements AnswerValidator { +public class TextTypedAnswerValidator implements TypedAnswerValidator { - private static final int ZERO_LENGTH = 0; private static final int MIN_LENGTH = 20; private static final int MAX_LENGTH = 1_000; diff --git a/backend/src/main/java/reviewme/review/service/validator/TypedAnswerValidator.java b/backend/src/main/java/reviewme/review/service/validator/TypedAnswerValidator.java new file mode 100644 index 000000000..2bc060c52 --- /dev/null +++ b/backend/src/main/java/reviewme/review/service/validator/TypedAnswerValidator.java @@ -0,0 +1,10 @@ +package reviewme.review.service.validator; + +import reviewme.review.domain.Answer; + +public interface TypedAnswerValidator { + + boolean supports(Class answerClass); + + void validate(Answer answer); +} diff --git a/backend/src/main/java/reviewme/review/service/validator/AnswerValidatorFactory.java b/backend/src/main/java/reviewme/review/service/validator/TypedAnswerValidatorFactory.java similarity index 68% rename from backend/src/main/java/reviewme/review/service/validator/AnswerValidatorFactory.java rename to backend/src/main/java/reviewme/review/service/validator/TypedAnswerValidatorFactory.java index b1adc5933..a0ff54733 100644 --- a/backend/src/main/java/reviewme/review/service/validator/AnswerValidatorFactory.java +++ b/backend/src/main/java/reviewme/review/service/validator/TypedAnswerValidatorFactory.java @@ -8,12 +8,12 @@ @Component @RequiredArgsConstructor(access = AccessLevel.PROTECTED) -public class AnswerValidatorFactory { +public class TypedAnswerValidatorFactory { - private final List answerValidators; + private final List validators; - public AnswerValidator getAnswerValidator(Class answerClass) { - return answerValidators.stream() + public TypedAnswerValidator getAnswerValidator(Class answerClass) { + return validators.stream() .filter(validator -> validator.supports(answerClass)) .findFirst() .orElseThrow(() -> new UnsupportedAnswerTypeException(answerClass)); diff --git a/backend/src/test/java/reviewme/highlight/repository/HighlightRepositoryTest.java b/backend/src/test/java/reviewme/highlight/repository/HighlightRepositoryTest.java index 6e46ed088..528ccbfff 100644 --- a/backend/src/test/java/reviewme/highlight/repository/HighlightRepositoryTest.java +++ b/backend/src/test/java/reviewme/highlight/repository/HighlightRepositoryTest.java @@ -2,13 +2,21 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import static reviewme.fixture.ReviewGroupFixture.리뷰_그룹; +import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import reviewme.highlight.domain.Highlight; import reviewme.highlight.domain.HighlightRange; +import reviewme.review.domain.Answer; +import reviewme.review.domain.Review; +import reviewme.review.domain.TextAnswer; +import reviewme.review.repository.ReviewRepository; +import reviewme.reviewgroup.domain.ReviewGroup; +import reviewme.reviewgroup.repository.ReviewGroupRepository; @DataJpaTest class HighlightRepositoryTest { @@ -16,6 +24,12 @@ class HighlightRepositoryTest { @Autowired private HighlightRepository highlightRepository; + @Autowired + private ReviewRepository reviewRepository; + + @Autowired + private ReviewGroupRepository reviewGroupRepository; + @Test void 한_번에_여러_하이라이트를_벌크_삽입한다() { // given @@ -62,4 +76,43 @@ class HighlightRepositoryTest { .containsExactly(1, 4, 2, 6, 3) ); } + + @Test + void 그룹_아이디와_질문_아이디로_하이라이트를_삭제한다() { + // given + ReviewGroup reviewGroup1 = reviewGroupRepository.save(리뷰_그룹()); + ReviewGroup reviewGroup2 = reviewGroupRepository.save(리뷰_그룹()); + + List answers1 = List.of( + new TextAnswer(1L, "A1"), + new TextAnswer(2L, "A2"), + new TextAnswer(3L, "A3") + ); + List answers2 = List.of( + new TextAnswer(1L, "B1"), + new TextAnswer(2L, "B2"), + new TextAnswer(3L, "B3") + ); + reviewRepository.save(new Review(1L, reviewGroup1.getId(), answers1)); + reviewRepository.save(new Review(2L, reviewGroup2.getId(), answers2)); + + List answerIds = new ArrayList<>(); + answerIds.addAll(answers1.stream().map(Answer::getId).toList()); + answerIds.addAll(answers2.stream().map(Answer::getId).toList()); + + HighlightRange range = new HighlightRange(0, 1); + answerIds.stream() + .map(answerId -> new Highlight(answerId, 0, range)) + .forEach(highlightRepository::save); + + // when + highlightRepository.deleteByReviewGroupIdAndQuestionId(reviewGroup1.getId(), 1L); + + // then + List actual = highlightRepository.findAllByAnswerIdsOrderedAsc(answerIds); + assertAll( + () -> assertThat(actual).hasSize(5), + () -> assertThat(actual).extracting(Highlight::getAnswerId).doesNotContain(answers1.get(0).getId()) + ); + } } diff --git a/backend/src/test/java/reviewme/highlight/service/validator/HighlightValidatorTest.java b/backend/src/test/java/reviewme/highlight/service/validator/HighlightValidatorTest.java deleted file mode 100644 index 4c98fa75b..000000000 --- a/backend/src/test/java/reviewme/highlight/service/validator/HighlightValidatorTest.java +++ /dev/null @@ -1,109 +0,0 @@ -package reviewme.highlight.service.validator; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static reviewme.fixture.QuestionFixture.서술형_필수_질문; -import static reviewme.fixture.ReviewGroupFixture.리뷰_그룹; -import static reviewme.fixture.SectionFixture.항상_보이는_섹션; -import static reviewme.fixture.TemplateFixture.템플릿; - -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import reviewme.highlight.service.dto.HighlightRequest; -import reviewme.highlight.service.dto.HighlightsRequest; -import reviewme.highlight.service.exception.SubmittedAnswerAndProvidedAnswerMismatchException; -import reviewme.template.repository.QuestionRepository; -import reviewme.review.domain.Review; -import reviewme.review.domain.TextAnswer; -import reviewme.review.repository.ReviewRepository; -import reviewme.reviewgroup.domain.ReviewGroup; -import reviewme.reviewgroup.repository.ReviewGroupRepository; -import reviewme.support.ServiceTest; -import reviewme.template.domain.Section; -import reviewme.template.domain.Template; -import reviewme.template.repository.SectionRepository; -import reviewme.template.repository.TemplateRepository; - -@ServiceTest -class HighlightValidatorTest { - - @Autowired - private HighlightValidator highlightValidator; - - @Autowired - private ReviewGroupRepository reviewGroupRepository; - - @Autowired - private ReviewRepository reviewRepository; - - @Autowired - private QuestionRepository questionRepository; - - @Autowired - private SectionRepository sectionRepository; - - @Autowired - private TemplateRepository templateRepository; - - @Test - void 하이라이트의_답변_id가_하이라이트의_질문_id에_해당하는_답변이_아니면_예외를_발생한다() { - // given - long questionId1 = questionRepository.save(서술형_필수_질문()).getId(); - long questionId2 = questionRepository.save(서술형_필수_질문()).getId(); - Section section = sectionRepository.save(항상_보이는_섹션(List.of(questionId1, questionId2))); - Template template = templateRepository.save(템플릿(List.of(section.getId()))); - - ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); - TextAnswer textAnswer_Q1 = new TextAnswer(questionId1, "text answer 1"); - - HighlightRequest highlightRequest = new HighlightRequest(textAnswer_Q1.getId(), List.of()); - HighlightsRequest highlightsRequest = new HighlightsRequest(questionId2, List.of(highlightRequest)); - - // when && then - assertThatCode(() -> highlightValidator.validate(highlightsRequest, reviewGroup)) - .isInstanceOf(SubmittedAnswerAndProvidedAnswerMismatchException.class); - } - - @Test - void 하이라이트의_답변_id가_리뷰_그룹에_달린_답변이_아니면_예외를_발생한다() { - // given - long questionId = questionRepository.save(서술형_필수_질문()).getId(); - Section section = sectionRepository.save(항상_보이는_섹션(List.of(questionId))); - Template template = templateRepository.save(템플릿(List.of(section.getId()))); - - ReviewGroup reviewGroup1 = reviewGroupRepository.save(리뷰_그룹()); - ReviewGroup reviewGroup2 = reviewGroupRepository.save(리뷰_그룹()); - TextAnswer textAnswer1 = new TextAnswer(questionId, "text answer1"); - TextAnswer textAnswer2 = new TextAnswer(questionId, "text answer2"); - reviewRepository.saveAll(List.of( - new Review(template.getId(), reviewGroup1.getId(), List.of(textAnswer1)), - new Review(template.getId(), reviewGroup2.getId(), List.of(textAnswer2)) - )); - - HighlightRequest highlightRequest = new HighlightRequest(textAnswer2.getId(), List.of()); - HighlightsRequest highlightsRequest = new HighlightsRequest(1L, List.of(highlightRequest)); - - // when && then - assertThatCode(() -> highlightValidator.validate(highlightsRequest, reviewGroup1)) - .isInstanceOf(SubmittedAnswerAndProvidedAnswerMismatchException.class); - } - - @Test - void 하이라이트의_질문_id가_리뷰_그룹의_템플릿에_속한_질문이_아니면_예외를_발생한다() { - // given - long questionId1 = questionRepository.save(서술형_필수_질문()).getId(); - long questionId2 = questionRepository.save(서술형_필수_질문()).getId(); - Section section = sectionRepository.save(항상_보이는_섹션(List.of(questionId1))); - Template template = templateRepository.save(템플릿(List.of(section.getId()))); - - ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); - TextAnswer textAnswer_Q1 = new TextAnswer(questionId1, "text answer 1"); - - HighlightRequest highlightRequest = new HighlightRequest(textAnswer_Q1.getId(), List.of()); - HighlightsRequest highlightsRequest = new HighlightsRequest(questionId2, List.of(highlightRequest)); - - // when && then - assertThatCode(() -> highlightValidator.validate(highlightsRequest, reviewGroup)) - .isInstanceOf(SubmittedAnswerAndProvidedAnswerMismatchException.class); - } -} diff --git a/backend/src/test/java/reviewme/review/service/validator/AnswerValidatorTest.java b/backend/src/test/java/reviewme/review/service/validator/AnswerValidatorTest.java new file mode 100644 index 000000000..9cce52a1b --- /dev/null +++ b/backend/src/test/java/reviewme/review/service/validator/AnswerValidatorTest.java @@ -0,0 +1,90 @@ +package reviewme.review.service.validator; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static reviewme.fixture.QuestionFixture.서술형_필수_질문; +import static reviewme.fixture.ReviewGroupFixture.리뷰_그룹; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import reviewme.review.domain.Answer; +import reviewme.review.domain.Review; +import reviewme.review.domain.TextAnswer; +import reviewme.review.repository.ReviewRepository; +import reviewme.review.service.exception.QuestionNotContainingAnswersException; +import reviewme.review.service.exception.ReviewGroupNotContainingAnswersException; +import reviewme.reviewgroup.domain.ReviewGroup; +import reviewme.reviewgroup.repository.ReviewGroupRepository; +import reviewme.support.ServiceTest; +import reviewme.template.domain.Question; +import reviewme.template.repository.QuestionRepository; + +@ServiceTest +class AnswerValidatorTest { + + @Autowired + private AnswerValidator answerValidator; + + @Autowired + private ReviewGroupRepository reviewGroupRepository; + + @Autowired + private ReviewRepository reviewRepository; + + @Autowired + private QuestionRepository questionRepository; + + @Test + void 답변이_질문에_속하는지_검증한다() { + // given + ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); + Question question1 = questionRepository.save(서술형_필수_질문()); + Question question2 = questionRepository.save(서술형_필수_질문()); + List answers = List.of( + new TextAnswer(question1.getId(), "답변1"), + new TextAnswer(question2.getId(), "답변2") + ); + Review review = reviewRepository.save(new Review(1L, reviewGroup.getId(), answers)); + Set answerIds = review.getAnsweredQuestionIds(); + List firstAnswerId = List.of(answers.get(0).getId()); + + // when, then + assertAll( + () -> assertDoesNotThrow( + () -> answerValidator.validateQuestionContainsAnswers(question1.getId(), firstAnswerId)), + () -> assertThatThrownBy( + () -> answerValidator.validateQuestionContainsAnswers(question1.getId(), answerIds)) + .isInstanceOf(QuestionNotContainingAnswersException.class) + ); + } + + @Test + void 답변이_리뷰그룹에_속하는지_검증한다() { + // given + ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); + Question question1 = questionRepository.save(서술형_필수_질문()); + Question question2 = questionRepository.save(서술형_필수_질문()); + List answers = List.of( + new TextAnswer(question1.getId(), "답변1"), + new TextAnswer(question2.getId(), "답변2") + ); + Review review = reviewRepository.save(new Review(1L, reviewGroup.getId(), answers)); + + List answerIds = review.getAnswers().stream().map(Answer::getQuestionId).toList(); + List wrongAnswerIds = new ArrayList<>(answerIds); + wrongAnswerIds.add(Long.MAX_VALUE); + + // when, then + assertAll( + () -> assertDoesNotThrow( + () -> answerValidator.validateReviewGroupContainsAnswers(reviewGroup, answerIds)), + () -> assertThatThrownBy( + () -> answerValidator.validateReviewGroupContainsAnswers(reviewGroup, wrongAnswerIds)) + .isInstanceOf(ReviewGroupNotContainingAnswersException.class) + ); + } +} diff --git a/backend/src/test/java/reviewme/review/service/validator/CheckboxAnswerValidatorTest.java b/backend/src/test/java/reviewme/review/service/validator/CheckboxTypedAnswerValidatorTest.java similarity index 97% rename from backend/src/test/java/reviewme/review/service/validator/CheckboxAnswerValidatorTest.java rename to backend/src/test/java/reviewme/review/service/validator/CheckboxTypedAnswerValidatorTest.java index c405ab4ba..57e7dfd4b 100644 --- a/backend/src/test/java/reviewme/review/service/validator/CheckboxAnswerValidatorTest.java +++ b/backend/src/test/java/reviewme/review/service/validator/CheckboxTypedAnswerValidatorTest.java @@ -22,10 +22,10 @@ import reviewme.support.ServiceTest; @ServiceTest -class CheckboxAnswerValidatorTest { +class CheckboxTypedAnswerValidatorTest { @Autowired - private CheckboxAnswerValidator checkBoxAnswerValidator; + private CheckboxTypedAnswerValidator checkBoxAnswerValidator; @Autowired private QuestionRepository questionRepository; diff --git a/backend/src/test/java/reviewme/review/service/validator/TextAnswerValidatorTest.java b/backend/src/test/java/reviewme/review/service/validator/TextTypedAnswerValidatorTest.java similarity index 96% rename from backend/src/test/java/reviewme/review/service/validator/TextAnswerValidatorTest.java rename to backend/src/test/java/reviewme/review/service/validator/TextTypedAnswerValidatorTest.java index 27854e02c..9773112e8 100644 --- a/backend/src/test/java/reviewme/review/service/validator/TextAnswerValidatorTest.java +++ b/backend/src/test/java/reviewme/review/service/validator/TextTypedAnswerValidatorTest.java @@ -17,10 +17,10 @@ import reviewme.support.ServiceTest; @ServiceTest -class TextAnswerValidatorTest { +class TextTypedAnswerValidatorTest { @Autowired - private TextAnswerValidator textAnswerValidator; + private TextTypedAnswerValidator textAnswerValidator; @Autowired private QuestionRepository questionRepository; diff --git a/backend/src/test/java/reviewme/review/service/validator/AnswerValidatorFactoryTest.java b/backend/src/test/java/reviewme/review/service/validator/TypedTypedAnswerValidatorFactoryTest.java similarity index 68% rename from backend/src/test/java/reviewme/review/service/validator/AnswerValidatorFactoryTest.java rename to backend/src/test/java/reviewme/review/service/validator/TypedTypedAnswerValidatorFactoryTest.java index 0a6e75db5..d808c53d3 100644 --- a/backend/src/test/java/reviewme/review/service/validator/AnswerValidatorFactoryTest.java +++ b/backend/src/test/java/reviewme/review/service/validator/TypedTypedAnswerValidatorFactoryTest.java @@ -8,9 +8,9 @@ import reviewme.review.domain.Answer; import reviewme.review.domain.CheckboxAnswer; -class AnswerValidatorFactoryTest { +class TypedTypedAnswerValidatorFactoryTest { - private final AnswerValidator validator = new AnswerValidator() { + private final TypedAnswerValidator validator = new TypedAnswerValidator() { @Override public boolean supports(Class answerClass) { @@ -19,17 +19,18 @@ public boolean supports(Class answerClass) { @Override public void validate(Answer answer) { + // no-op } }; @Test void 지원하는_타입에_따른_밸리데이터를_가져온다() { // given - List validators = List.of(validator); - AnswerValidatorFactory factory = new AnswerValidatorFactory(validators); + List validators = List.of(validator); + TypedAnswerValidatorFactory factory = new TypedAnswerValidatorFactory(validators); // when - AnswerValidator actual = factory.getAnswerValidator(CheckboxAnswer.class); + TypedAnswerValidator actual = factory.getAnswerValidator(CheckboxAnswer.class); // then assertThat(actual).isEqualTo(validator); @@ -38,7 +39,7 @@ public void validate(Answer answer) { @Test void 지원하지_않는_타입에_대한_밸리데이터_요청_시_예외가_발생한다() { // given - AnswerValidatorFactory factory = new AnswerValidatorFactory(List.of()); + TypedAnswerValidatorFactory factory = new TypedAnswerValidatorFactory(List.of()); // when, then assertThatThrownBy(() -> factory.getAnswerValidator(CheckboxAnswer.class)) From 1b8799328a550a2174b6104bfb7c6d6f4664ee25 Mon Sep 17 00:00:00 2001 From: Donghoon Lee Date: Mon, 18 Nov 2024 14:23:01 +0900 Subject: [PATCH 10/11] =?UTF-8?q?[All]=20fix:=20Release=20PR=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EB=A6=AC=EB=B7=B0=20=EC=8B=9C=20=EB=94=94=EC=8A=A4?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=95=8C=EB=A6=BC=20(#969)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/discord-pull-request-comment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/discord-pull-request-comment.yml b/.github/workflows/discord-pull-request-comment.yml index e1a3fc36b..d3594088f 100644 --- a/.github/workflows/discord-pull-request-comment.yml +++ b/.github/workflows/discord-pull-request-comment.yml @@ -31,7 +31,7 @@ jobs: elif [ "$PR_PREFIX" = '[FE]' ]; then echo Frontend PR Found! echo "PR_PREFIX=FE" >> $GITHUB_ENV - elif [ "$PR_PREFIX" = '[All]' ]; then + elif [ "$PR_PREFIX" = '[All]' ] || [ "$PR_PREFIX" = '[Release]' ]; then echo All PR Found! echo "PR_PREFIX=All" >> $GITHUB_ENV fi From 90646b60946aa52bd9aea5befbc0ba5bc41a7d4f Mon Sep 17 00:00:00 2001 From: badahertz52 Date: Tue, 19 Nov 2024 16:17:39 +0900 Subject: [PATCH 11/11] =?UTF-8?q?[FE]=20fix=20:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EB=AA=A8=EC=95=84=EB=B3=B4=EA=B8=B0=20=EC=BF=BC=EB=A6=AC=20?= =?UTF-8?q?=EC=BA=90=EC=8B=9C=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EB=90=9C=20=ED=98=95=EA=B4=91=ED=8E=9C=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EB=B0=98=EC=98=81=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#976)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: 질문별 모아보기 목 데이터 주관식 답변 변경 * feat : 현재 sectionId sessionSotrage에 저장하고, 모아보기 페이지 언마운트 시 삭제하는 기능 추가 * feat : 형광펜 API 요청 성공 후, 해당 질문 쿼리 무효화하는 기능 추가 * feat : 형광펜 데이터 로컬 스토리지에 저장한 코드 삭제 * feat : ReviewCollectionPage 에서 clearEditorAnswerMapStorage 코드 삭제 --- .../HighlightEditor/hooks/useHighlight.ts | 19 ++--------------- .../hooks/useMutateHighlight/index.ts | 21 +++++++++++++++++-- frontend/src/constants/storageKey.ts | 2 +- .../src/mocks/mockData/reviewCollection.ts | 12 +++++------ .../ReviewCollectionPageContents/index.tsx | 11 ++++++++-- .../hooks/useGetGroupedReviews.ts | 3 ++- .../src/pages/ReviewCollectionPage/index.tsx | 21 ------------------- 7 files changed, 39 insertions(+), 50 deletions(-) diff --git a/frontend/src/components/highlight/components/HighlightEditor/hooks/useHighlight.ts b/frontend/src/components/highlight/components/HighlightEditor/hooks/useHighlight.ts index 703f8acd7..2b91ac8e3 100644 --- a/frontend/src/components/highlight/components/HighlightEditor/hooks/useHighlight.ts +++ b/frontend/src/components/highlight/components/HighlightEditor/hooks/useHighlight.ts @@ -1,11 +1,6 @@ -import { useEffect, useState } from 'react'; +import { useState } from 'react'; -import { - EDITOR_ANSWER_CLASS_NAME, - HIGHLIGHT_EVENT_NAME, - HIGHLIGHT_SPAN_CLASS_NAME, - SESSION_STORAGE_KEY, -} from '@/constants'; +import { EDITOR_ANSWER_CLASS_NAME, HIGHLIGHT_EVENT_NAME, HIGHLIGHT_SPAN_CLASS_NAME } from '@/constants'; import { EditorAnswerMap, EditorLine, HighlightResponseData, ReviewAnswerResponseData } from '@/types'; import { getEndLineOffset, @@ -76,14 +71,6 @@ const useHighlight = ({ handleModalMessage, }: UseHighlightProps) => { const [editorAnswerMap, setEditorAnswerMap] = useState(makeInitialEditorAnswerMap(answerList)); - const storageKey = `${SESSION_STORAGE_KEY.editorAnswerMap}-${questionId}`; - - useEffect(() => { - const item = localStorage.getItem(storageKey); - if (item) { - setEditorAnswerMap(new Map(JSON.parse(item)) as EditorAnswerMap); - } - }, []); // span 클릭 시, 제공되는 형광펜 삭제 기능 타겟 const [longPressRemovalTarget, setLongPressRemovalTarget] = useState(null); @@ -92,8 +79,6 @@ const useHighlight = ({ const updateEditorAnswerMap = (newEditorAnswerMap: EditorAnswerMap) => { setEditorAnswerMap(newEditorAnswerMap); - // editorAnswerMap이 변경될 때 새로운 값을 로컬 스토리지에 저장 - localStorage.setItem(storageKey, JSON.stringify(Array.from(newEditorAnswerMap))); }; const resetHighlightMenu = () => { diff --git a/frontend/src/components/highlight/components/HighlightEditor/hooks/useMutateHighlight/index.ts b/frontend/src/components/highlight/components/HighlightEditor/hooks/useMutateHighlight/index.ts index 56681e41e..d607901cc 100644 --- a/frontend/src/components/highlight/components/HighlightEditor/hooks/useMutateHighlight/index.ts +++ b/frontend/src/components/highlight/components/HighlightEditor/hooks/useMutateHighlight/index.ts @@ -1,7 +1,7 @@ -import { useMutation } from '@tanstack/react-query'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; import { postHighlight } from '@/apis/highlight'; -import { LOCAL_STORAGE_KEY } from '@/constants'; +import { LOCAL_STORAGE_KEY, REVIEW_QUERY_KEY, SESSION_STORAGE_KEY } from '@/constants'; import { EditorAnswerMap } from '@/types'; export interface UseMutateHighlightProps { @@ -17,6 +17,21 @@ const useMutateHighlight = ({ updateEditorAnswerMap, resetHighlightMenu, }: UseMutateHighlightProps) => { + const queryClient = useQueryClient(); + /** + * 형광펜 API 성공 후, 현재 질문에 대한 쿼리 캐시 무효화해서, 변경된 형광펜 데이터 불러오도록 함 + */ + const invalidateCurrentSectionQuery = () => { + const sectionId = sessionStorage.getItem(SESSION_STORAGE_KEY.currentReviewCollectionSectionId); + + if (sectionId) { + queryClient.invalidateQueries({ + predicate: (query) => + query.queryKey[0] === REVIEW_QUERY_KEY.groupedReviews && query.queryKey[1] === Number(sectionId), + }); + } + }; + const mutation = useMutation({ mutationFn: (newEditorAnswerMap: EditorAnswerMap) => postHighlight(newEditorAnswerMap, questionId), onMutate: () => { @@ -28,6 +43,8 @@ const useMutateHighlight = ({ // 토스트 모달 지우기 handleErrorModal(false); localStorage.removeItem(LOCAL_STORAGE_KEY.isHighlightError); + // 해당 질문 쿼리 캐시 무효화 + invalidateCurrentSectionQuery(); }, onError: (error) => { //토스트 모달 띄움 diff --git a/frontend/src/constants/storageKey.ts b/frontend/src/constants/storageKey.ts index f25f48312..5fb04d984 100644 --- a/frontend/src/constants/storageKey.ts +++ b/frontend/src/constants/storageKey.ts @@ -4,5 +4,5 @@ export const LOCAL_STORAGE_KEY = { }; export const SESSION_STORAGE_KEY = { - editorAnswerMap: 'editorAnswerMap-question', + currentReviewCollectionSectionId: 'currentReviewCollectionSectionId', }; diff --git a/frontend/src/mocks/mockData/reviewCollection.ts b/frontend/src/mocks/mockData/reviewCollection.ts index c2946f3bf..4b8b5df43 100644 --- a/frontend/src/mocks/mockData/reviewCollection.ts +++ b/frontend/src/mocks/mockData/reviewCollection.ts @@ -115,7 +115,7 @@ export const GROUPED_REVIEWS_MOCK_DATA: GroupedReviews[] = [ { id: 2, content: - 'http://localhost:3000/user/review-zone/5WkYQLqW1http://localhost:3000/user/review-zone/5WkYQLqW2http://localhost:3000/user/review-zone/5WkYQLqW3http://localhost:3000/user/review-zone/5WkYQLqW4http://localhost:3000/user/review-zone/5WkYQLqW5http://localhost:3000/user/review-zone/5WkYQLqW6http://localhost:3000/user/review-zone/5WkYQLqW7http://localhost:3000/user/review-zone/5WkYQLqW8http://localhost:3000/user/review-zone/5WkYQLqW9http://localhost:3000/user/review-zone/5WkYQLqW10', + ' 복잡한 문제를 체계적으로 분석하고, 창의적인 해결책을 제안하며 이를 실행하는 데 뛰어난 역량을 보여줍니다. 특히, 제한된 시간과 자원 속에서도 효과적으로 우선순위를 정하고 문제를 해결하는 모습을 통해 팀에 큰 신뢰를 주었습니다. 이러한 능력은 팀의 목표 달성과 성장에 큰 기여를 하며, 앞으로도 더 많은 성과를 낼 수 있을 것으로 기대됩니다.!!!!!', highlights: [ { lineIndex: 0, @@ -132,13 +132,13 @@ export const GROUPED_REVIEWS_MOCK_DATA: GroupedReviews[] = [ { id: 3, content: - '장의 시작부분은 짧고 직접적이며, 뒤따라 나올 복잡한 정보를 어떻게 해석해야 할 것인지 프레임을 짜주는 역할을 해야 한다. 그러면 아무리 긴 문장이라도 쉽게 읽힌다.', + '문제의 핵심 원인을 빠르게 파악하고, 이를 바탕으로 실행 가능한 솔루션을 제시하며 팀의 목표를 달성하는 데 큰 기여를 했습니다. 특히, 예상치 못한 상황에서도 냉철한 판단과 적극적인 태도로 해결책을 찾아가는 모습은 팀원들에게 좋은 자극이 되었습니다.', highlights: [], }, { id: 4, content: - '고액공제건강보험과 건강저축계좌를 만들어 노동자와 고용주가 세금공제를 받을 수 있도록 하면 결과적으로 노동자의 의료보험 부담이 커진다. 세금공제를 받을 수 있도록 하면------------------------------------------- 결과적으로 노동자의 의료보험 부담이 커진다.', + '문제를 다양한 관점에서 바라보며 가장 적합한 해결책을 찾아내는 능력이 뛰어납니다. 특히, 여러 이해관계자 간의 의견을 조율하며 모두가 만족할 수 있는 방안을 제안한 점이 돋보였습니다. 이 과정에서 보여준 적극적인 소통과 논리적인 접근법은 팀의 신뢰를 더욱 높였고, 어려운 과제를 성공적으로 마무리할 수 있는 원동력이 되었습니다.', highlights: [], }, ], @@ -181,7 +181,7 @@ export const GROUPED_REVIEWS_MOCK_DATA: GroupedReviews[] = [ { id: 2, content: - 'http://localhost:3000/user/review-zone/5WkYQLqW1http://localhost:3000/user/review-zone/5WkYQLqW2http://localhost:3000/user/review-zone/5WkYQLqW3http://localhost:3000/user/review-zone/5WkYQLqW4http://localhost:3000/user/review-zone/5WkYQLqW5http://localhost:3000/user/review-zone/5WkYQLqW6http://localhost:3000/user/review-zone/5WkYQLqW7http://localhost:3000/user/review-zone/5WkYQLqW8http://localhost:3000/user/review-zone/5WkYQLqW9http://localhost:3000/user/review-zone/5WkYQLqW10', + '효율적인 시간 관리 능력을 통해 중요한 작업을 기한 내에 완수하는 모습이 매우 인상적이었습니다. 특히, 작업의 우선순위를 명확히 구분하고 이를 기반으로 체계적으로 계획을 세워 진행하는 점이 돋보였습니다. 이러한 능력 덕분에 팀 전체의 생산성이 향상되었고, 예상치 못한 문제가 발생했을 때도 유연하게 대처하며 프로젝트를 성공적으로 이끌었습니다.', highlights: [ { lineIndex: 0, @@ -198,13 +198,13 @@ export const GROUPED_REVIEWS_MOCK_DATA: GroupedReviews[] = [ { id: 3, content: - '장의 시작부분은 짧고 직접적이며, 뒤따라 나올 복잡한 정보를 어떻게 해석해야 할 것인지 프레임을 짜주는 역할을 해야 한다. 그러면 아무리 긴 문장이라도 쉽게 읽힌다.', + '시간을 효율적으로 활용하는 뛰어난 능력을 보여주셨습니다. 작업 초기부터 명확한 계획을 수립하고 이를 끝까지 유지하는 모습이 인상적이었으며, 예상치 못한 변수에도 침착하게 대처하며 프로젝트의 일정과 품질을 모두 충족시켰습니다. 이러한 점은 팀에 큰 안정감을 주었고, 함께 일하는 사람들에게도 좋은 본보기가 되었습니다.', highlights: [], }, { id: 4, content: - '고액공제건강보험과 건강저축계좌를 만들어 노동자와 고용주가 세금공제를 받을 수 있도록 하면 결과적으로 노동자의 의료보험 부담이 커진다. 세금공제를 받을 수 있도록 하면------------------------------------------- 결과적으로 노동자의 의료보험 부담이 커진다.', + '타이트한 일정 속에서도 주어진 목표를 체계적으로 달성하며, 동시에 세부적인 디테일까지 놓치지 않는 모습을 보여주셨습니다. 특히, 작업 과정에서 우선순위를 명확히 설정하고, 불필요한 시간 낭비를 줄이는 효율적인 접근 방식은 팀의 전반적인 속도와 성과에 크게 기여했습니다. 앞으로도 이런 시간 관리 능력을 통해 더 많은 성과를 이루시리라 믿습니다.', highlights: [], }, ], diff --git a/frontend/src/pages/ReviewCollectionPage/components/ReviewCollectionPageContents/index.tsx b/frontend/src/pages/ReviewCollectionPage/components/ReviewCollectionPageContents/index.tsx index 5b8f77b54..44cd6c5e0 100644 --- a/frontend/src/pages/ReviewCollectionPage/components/ReviewCollectionPageContents/index.tsx +++ b/frontend/src/pages/ReviewCollectionPage/components/ReviewCollectionPageContents/index.tsx @@ -1,10 +1,10 @@ -import React, { useContext, useState } from 'react'; +import { useContext, useEffect, useState } from 'react'; import { Accordion, Dropdown, HighlightEditorContainer } from '@/components'; import { DropdownItem } from '@/components/common/Dropdown'; import ReviewEmptySection from '@/components/common/ReviewEmptySection'; import { ReviewInfoDataContext } from '@/components/layouts/ReviewDisplayLayout/ReviewInfoDataProvider'; -import { REVIEW_EMPTY } from '@/constants'; +import { REVIEW_EMPTY, SESSION_STORAGE_KEY } from '@/constants'; import { GroupedReview } from '@/types'; import { substituteString } from '@/utils'; @@ -18,6 +18,7 @@ const ReviewCollectionPageContents = () => { const { revieweeName, projectName, totalReviewCount } = useContext(ReviewInfoDataContext); const { data: reviewSectionList } = useGetSectionList(); + const dropdownSectionList = reviewSectionList.sections.map((section) => { return { text: section.name, value: section.id }; }); @@ -29,6 +30,12 @@ const ReviewCollectionPageContents = () => { review.votes?.sort((voteA, voteB) => voteB.count - voteA.count); }); + useEffect(() => { + return () => { + sessionStorage.removeItem(SESSION_STORAGE_KEY.currentReviewCollectionSectionId); + }; + }, []); + const renderContent = (review: GroupedReview) => { if (review.question.type === 'CHECKBOX') { const hasNoCheckboxAnswer = review.votes?.every((vote) => vote.count === 0); diff --git a/frontend/src/pages/ReviewCollectionPage/hooks/useGetGroupedReviews.ts b/frontend/src/pages/ReviewCollectionPage/hooks/useGetGroupedReviews.ts index be16a1427..27b2d687f 100644 --- a/frontend/src/pages/ReviewCollectionPage/hooks/useGetGroupedReviews.ts +++ b/frontend/src/pages/ReviewCollectionPage/hooks/useGetGroupedReviews.ts @@ -1,7 +1,7 @@ import { useSuspenseQuery } from '@tanstack/react-query'; import { getGroupedReviews } from '@/apis/review'; -import { REVIEW_QUERY_KEY } from '@/constants'; +import { REVIEW_QUERY_KEY, SESSION_STORAGE_KEY } from '@/constants'; import { GroupedReviews } from '@/types'; interface UseGetGroupedReviewsProps { @@ -11,6 +11,7 @@ interface UseGetGroupedReviewsProps { const useGetGroupedReviews = ({ sectionId }: UseGetGroupedReviewsProps) => { const fetchGroupedReviews = async () => { const result = await getGroupedReviews({ sectionId }); + sessionStorage.setItem(SESSION_STORAGE_KEY.currentReviewCollectionSectionId, sectionId.toString()); return result; }; diff --git a/frontend/src/pages/ReviewCollectionPage/index.tsx b/frontend/src/pages/ReviewCollectionPage/index.tsx index 9b838b0d0..c582d30e6 100644 --- a/frontend/src/pages/ReviewCollectionPage/index.tsx +++ b/frontend/src/pages/ReviewCollectionPage/index.tsx @@ -1,30 +1,9 @@ -import { useEffect } from 'react'; - import { AuthAndServerErrorFallback, ErrorSuspenseContainer, TopButton } from '@/components'; import ReviewDisplayLayout from '@/components/layouts/ReviewDisplayLayout'; -import { SESSION_STORAGE_KEY } from '@/constants'; import ReviewCollectionPageContents from './components/ReviewCollectionPageContents'; const ReviewCollectionPage = () => { - const clearEditorAnswerMapStorage = () => { - for (let i = 0; i < localStorage.length; i++) { - const key = localStorage.key(i); - - // 키에 특정 문자열이 포함되어 있는지 확인 - if (key?.includes(SESSION_STORAGE_KEY.editorAnswerMap)) { - localStorage.removeItem(key); // 해당 키 삭제 - i--; // removeItem 후에 인덱스가 변경되므로 i를 감소시켜야 함 - } - } - }; - - useEffect(() => { - return () => { - clearEditorAnswerMapStorage(); - }; - }, []); - return (