From d28f0d12833d8e419f97ebdf7e8ff320e8238e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Mon, 22 Jul 2024 20:06:02 +0900 Subject: [PATCH 1/9] =?UTF-8?q?refactor:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=EC=97=90=20=EB=8C=80=ED=95=9C=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../maru_egg/answer/dto/response/LLMAnswerResponse.java | 7 +++++-- .../iphak/maru_egg/question/api/QuestionController.java | 6 +++--- .../question/application/QuestionProcessingService.java | 7 ++++--- .../iphak/maru_egg/question/domain/QuestionCategory.java | 4 +--- .../mju/iphak/maru_egg/question/domain/QuestionType.java | 3 +-- .../question/dto/request/FindQuestionsRequest.java | 2 +- .../maru_egg/question/dto/request/QuestionRequest.java | 4 ++-- .../maru_egg/answer/application/AnswerServiceTest.java | 2 +- .../application/QuestionProcessingServiceTest.java | 8 +++++--- .../question/application/QuestionServiceTest.java | 3 ++- .../question/repository/QuestionRepositoryTest.java | 2 +- 11 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/main/java/mju/iphak/maru_egg/answer/dto/response/LLMAnswerResponse.java b/src/main/java/mju/iphak/maru_egg/answer/dto/response/LLMAnswerResponse.java index 3fa97cb..b5b0384 100644 --- a/src/main/java/mju/iphak/maru_egg/answer/dto/response/LLMAnswerResponse.java +++ b/src/main/java/mju/iphak/maru_egg/answer/dto/response/LLMAnswerResponse.java @@ -2,14 +2,17 @@ import lombok.Builder; import mju.iphak.maru_egg.answer.domain.Answer; +import mju.iphak.maru_egg.question.domain.QuestionCategory; @Builder public record LLMAnswerResponse( - String answer + String answer, + QuestionCategory questionCategory ) { - public static LLMAnswerResponse from(Answer answer) { + public static LLMAnswerResponse of(Answer answer, QuestionCategory category) { return LLMAnswerResponse.builder() .answer(answer.getContent()) + .questionCategory(category) .build(); } } \ No newline at end of file diff --git a/src/main/java/mju/iphak/maru_egg/question/api/QuestionController.java b/src/main/java/mju/iphak/maru_egg/question/api/QuestionController.java index f3623c0..7c039bf 100644 --- a/src/main/java/mju/iphak/maru_egg/question/api/QuestionController.java +++ b/src/main/java/mju/iphak/maru_egg/question/api/QuestionController.java @@ -39,7 +39,7 @@ public class QuestionController { @ApiResponse(responseCode = "200", description = "질문 성공") }) @CustomApiResponses({ - @CustomApiResponse(error = "HttpMessageNotReadableException", status = 400, message = "Invalid input format: JSON parse error: Cannot deserialize value of type `mju.iphak.maru_egg.question.domain.QuestionType` from String \\\"SUSI 또는 PYEONIP 또는 JEONGSI 또는 JAEOEGUGMIN\\\": not one of the values accepted for Enum class: [SUSI, PYEONIP, JEONGSI, JAEOEGUGMIN]", description = "validation에 맞지 않은 요청을 할 경우"), + @CustomApiResponse(error = "HttpMessageNotReadableException", status = 400, message = "Invalid input format: JSON parse error: Cannot deserialize value of type `mju.iphak.maru_egg.question.domain.QuestionType` from String \\\"SUSI 또는 PYEONIP 또는 JEONGSI\\\": not one of the values accepted for Enum class: [SUSI, PYEONIP, JEONGSI]", description = "validation에 맞지 않은 요청을 할 경우"), @CustomApiResponse(error = "EntityNotFoundException", status = 404, message = "type: SUSI, category: PAST_QUESTIONS, content: 수시 입학 요강에 대해 알려주세요.인 질문을 찾을 수 없습니다.", description = "질문 또는 답변을 찾지 못한 경우"), @CustomApiResponse(error = "InternalServerError", status = 500, message = "내부 서버 오류가 발생했습니다.", description = "내부 서버 오류") }) @@ -52,7 +52,7 @@ public QuestionResponse question(@Valid @RequestBody QuestionRequest request) { @ApiResponse(responseCode = "200", description = "질문 성공") }) @CustomApiResponses({ - @CustomApiResponse(error = "HttpMessageNotReadableException", status = 400, message = "Invalid input format: JSON parse error: Cannot deserialize value of type `mju.iphak.maru_egg.question.domain.QuestionType` from String \\\"SUSI 또는 PYEONIP 또는 JEONGSI 또는 JAEOEGUGMIN\\\": not one of the values accepted for Enum class: [SUSI, PYEONIP, JEONGSI, JAEOEGUGMIN]", description = "validation에 맞지 않은 요청을 할 경우"), + @CustomApiResponse(error = "HttpMessageNotReadableException", status = 400, message = "Invalid input format: JSON parse error: Cannot deserialize value of type `mju.iphak.maru_egg.question.domain.QuestionType` from String \\\"SUSI 또는 PYEONIP 또는 JEONGSI\\\": not one of the values accepted for Enum class: [SUSI, PYEONIP, JEONGSI]", description = "validation에 맞지 않은 요청을 할 경우"), @CustomApiResponse(error = "InternalServerError", status = 500, message = "내부 서버 오류가 발생했습니다.", description = "내부 서버 오류") }) @GetMapping() @@ -64,7 +64,7 @@ public List getQuestions(@Valid @ModelAttribute FindQu @ApiResponse(responseCode = "200", description = "질문 자동완성 성공") }) @CustomApiResponses({ - @CustomApiResponse(error = "HttpMessageNotReadableException", status = 400, message = "Invalid input format: JSON parse error: Cannot deserialize value of type `mju.iphak.maru_egg.question.domain.QuestionType` from String \\\"SUSI 또는 PYEONIP 또는 JEONGSI 또는 JAEOEGUGMIN\\\": not one of the values accepted for Enum class: [SUSI, PYEONIP, JEONGSI, JAEOEGUGMIN]", description = "validation에 맞지 않은 요청을 할 경우"), + @CustomApiResponse(error = "HttpMessageNotReadableException", status = 400, message = "Invalid input format: JSON parse error: Cannot deserialize value of type `mju.iphak.maru_egg.question.domain.QuestionType` from String \\\"SUSI 또는 PYEONIP 또는 JEONGSI\\\": not one of the values accepted for Enum class: [SUSI, PYEONIP, JEONGSI]", description = "validation에 맞지 않은 요청을 할 경우"), @CustomApiResponse(error = "InternalServerError", status = 500, message = "내부 서버 오류가 발생했습니다.", description = "내부 서버 오류") }) @GetMapping("/search") diff --git a/src/main/java/mju/iphak/maru_egg/question/application/QuestionProcessingService.java b/src/main/java/mju/iphak/maru_egg/question/application/QuestionProcessingService.java index 465e6c8..645a41c 100644 --- a/src/main/java/mju/iphak/maru_egg/question/application/QuestionProcessingService.java +++ b/src/main/java/mju/iphak/maru_egg/question/application/QuestionProcessingService.java @@ -34,6 +34,7 @@ public class QuestionProcessingService { private static final double STANDARD_SIMILARITY = 0.95; + private static final String UNCLASSIFIED = ""; private final QuestionRepository questionRepository; private final AnswerService answerService; @@ -66,14 +67,14 @@ private QuestionResponse askNewQuestion(QuestionType type, QuestionCategory cate LLMAnswerResponse llmAnswerResponse = answerService.askQuestion(askQuestionRequest).block(); - Question newQuestion = saveQuestion(type, category, content, contentToken); + Question newQuestion = saveQuestion(type, llmAnswerResponse.questionCategory(), content, contentToken); Answer newAnswer = saveAnswer(newQuestion, llmAnswerResponse.answer()); return createQuestionResponse(newQuestion, newAnswer); } private static String isCategoryNullThen(final QuestionCategory category) { - if (category.toString() == null) { - return QuestionCategory.UNCLASSIFIED.getQuestionCategory(); + if (category == null) { + return UNCLASSIFIED; } return category.toString(); } diff --git a/src/main/java/mju/iphak/maru_egg/question/domain/QuestionCategory.java b/src/main/java/mju/iphak/maru_egg/question/domain/QuestionCategory.java index 6ef2a57..97bc633 100644 --- a/src/main/java/mju/iphak/maru_egg/question/domain/QuestionCategory.java +++ b/src/main/java/mju/iphak/maru_egg/question/domain/QuestionCategory.java @@ -11,9 +11,7 @@ public enum QuestionCategory { ADMISSION_GUIDELINE("모집요강"), PASSING_RESULT("입시결과"), PAST_QUESTIONS("기출문제"), - UNIV_LIFE("대학생활"), - INTERVIEW_PRACTICAL_TEST("면접/실기"), - UNCLASSIFIED("미분류"); + INTERVIEW_PRACTICAL_TEST("면접/실기"); private final String questionCategory; diff --git a/src/main/java/mju/iphak/maru_egg/question/domain/QuestionType.java b/src/main/java/mju/iphak/maru_egg/question/domain/QuestionType.java index 3564569..1006b97 100644 --- a/src/main/java/mju/iphak/maru_egg/question/domain/QuestionType.java +++ b/src/main/java/mju/iphak/maru_egg/question/domain/QuestionType.java @@ -8,8 +8,7 @@ public enum QuestionType { SUSI("수시"), JEONGSI("정시"), - PYEONIP("편입학"), - JAEOEGUGMIN("재외국민"); + PYEONIP("편입학"); private final String questionType; diff --git a/src/main/java/mju/iphak/maru_egg/question/dto/request/FindQuestionsRequest.java b/src/main/java/mju/iphak/maru_egg/question/dto/request/FindQuestionsRequest.java index 4cc2209..83b0103 100644 --- a/src/main/java/mju/iphak/maru_egg/question/dto/request/FindQuestionsRequest.java +++ b/src/main/java/mju/iphak/maru_egg/question/dto/request/FindQuestionsRequest.java @@ -16,7 +16,7 @@ public record FindQuestionsRequest( QuestionType type, @Schema(description = "질문 카테고리(모집요강, 입시결과, 기출 문제)", allowableValues = {"ADMISSION_GUIDELINE", "PASSING_RESULT", - "PAST_QUESTIONS", "UNCLASSIFIED", "UNIV_LIFE", "INTERVIEW_PRACTICAL_TEST"}) + "PAST_QUESTIONS", "INTERVIEW_PRACTICAL_TEST"}) QuestionCategory category ) { } \ No newline at end of file diff --git a/src/main/java/mju/iphak/maru_egg/question/dto/request/QuestionRequest.java b/src/main/java/mju/iphak/maru_egg/question/dto/request/QuestionRequest.java index 35dc8f1..33fcb34 100644 --- a/src/main/java/mju/iphak/maru_egg/question/dto/request/QuestionRequest.java +++ b/src/main/java/mju/iphak/maru_egg/question/dto/request/QuestionRequest.java @@ -8,8 +8,8 @@ @Schema(description = "질문 생성 요청 DTO", example = """ { - "type": "SUSI 또는 PYEONIP 또는 JEONGSI 또는 JAEOEGUGMIN", - "category": "PAST_QUESTIONS 또는 UNIV_LIFE 또는 INTERVIEW_PRACTICAL_TEST 또는 PASSING_RESULT 또는 ADMISSION_GUIDELINE 또는 UNCLASSIFIED", + "type": "SUSI 또는 PYEONIP 또는 JEONGSI", + "category": "PAST_QUESTIONS 또는 INTERVIEW_PRACTICAL_TEST 또는 PASSING_RESULT 또는 ADMISSION_GUIDELINE", "content": "수시 입학 요강에 대해 알려주세요." } """) diff --git a/src/test/java/mju/iphak/maru_egg/answer/application/AnswerServiceTest.java b/src/test/java/mju/iphak/maru_egg/answer/application/AnswerServiceTest.java index e61575e..ae07736 100644 --- a/src/test/java/mju/iphak/maru_egg/answer/application/AnswerServiceTest.java +++ b/src/test/java/mju/iphak/maru_egg/answer/application/AnswerServiceTest.java @@ -104,7 +104,7 @@ public void setUp() { question.getContent()); // when - LLMAnswerResponse expectedResponse = LLMAnswerResponse.from(answer); + LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(answer, QuestionCategory.ADMISSION_GUIDELINE); LLMAnswerResponse result = answerService.askQuestion(request).block(); // then diff --git a/src/test/java/mju/iphak/maru_egg/question/application/QuestionProcessingServiceTest.java b/src/test/java/mju/iphak/maru_egg/question/application/QuestionProcessingServiceTest.java index 8681053..39d90fe 100644 --- a/src/test/java/mju/iphak/maru_egg/question/application/QuestionProcessingServiceTest.java +++ b/src/test/java/mju/iphak/maru_egg/question/application/QuestionProcessingServiceTest.java @@ -67,7 +67,8 @@ private LLMAnswerResponse mockAskQuestion(LLMAskQuestionRequest request) { formData.add("question", request.question()); Question testQuestion = Question.of("새로운 질문입니다.", "새로운 질문", QuestionType.SUSI, QuestionCategory.ADMISSION_GUIDELINE); - LLMAnswerResponse expectedResponse = LLMAnswerResponse.from(Answer.of(testQuestion, "새로운 답변입니다.")); + LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(Answer.of(testQuestion, "새로운 답변입니다."), + QuestionCategory.ADMISSION_GUIDELINE); mockWebServer.enqueue(new MockResponse() .setHeader("Content-type", MediaType.APPLICATION_JSON_VALUE) @@ -205,7 +206,7 @@ void setUp() { String contentToken = PhraseExtractionUtils.extractPhrases(content); Question testQuestion = Question.of(content, contentToken, type, category); Answer testAnswer = Answer.of(testQuestion, "새로운 답변입니다."); - LLMAnswerResponse expectedResponse = LLMAnswerResponse.from(testAnswer); + LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(testAnswer, QuestionCategory.ADMISSION_GUIDELINE); when(questionRepository.searchQuestionsByContentTokenAndTypeAndCategory(contentToken, type, category)) .thenReturn(Optional.of(Collections.emptyList())); @@ -234,7 +235,8 @@ void setUp() { question.getContent()); Question testQuestion = Question.of("새로운 질문입니다.", "새로운 질문", QuestionType.SUSI, QuestionCategory.ADMISSION_GUIDELINE); - LLMAnswerResponse expectedResponse = LLMAnswerResponse.from(Answer.of(testQuestion, "새로운 답변입니다.")); + LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(Answer.of(testQuestion, "새로운 답변입니다."), + QuestionCategory.ADMISSION_GUIDELINE); // when LLMAnswerResponse result = mockAskQuestion(request); diff --git a/src/test/java/mju/iphak/maru_egg/question/application/QuestionServiceTest.java b/src/test/java/mju/iphak/maru_egg/question/application/QuestionServiceTest.java index e20a2b5..8291cea 100644 --- a/src/test/java/mju/iphak/maru_egg/question/application/QuestionServiceTest.java +++ b/src/test/java/mju/iphak/maru_egg/question/application/QuestionServiceTest.java @@ -68,7 +68,8 @@ private LLMAnswerResponse mockAskQuestion(LLMAskQuestionRequest request) { formData.add("question", request.question()); Question testQuestion = Question.of("새로운 질문입니다.", "새로운 질문", QuestionType.SUSI, QuestionCategory.ADMISSION_GUIDELINE); - LLMAnswerResponse expectedResponse = LLMAnswerResponse.from(Answer.of(testQuestion, "새로운 답변입니다.")); + LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(Answer.of(testQuestion, "새로운 답변입니다."), + QuestionCategory.ADMISSION_GUIDELINE); mockWebServer.enqueue(new MockResponse() .setHeader("Content-type", MediaType.APPLICATION_JSON_VALUE) diff --git a/src/test/java/mju/iphak/maru_egg/question/repository/QuestionRepositoryTest.java b/src/test/java/mju/iphak/maru_egg/question/repository/QuestionRepositoryTest.java index 45f9571..278cb88 100644 --- a/src/test/java/mju/iphak/maru_egg/question/repository/QuestionRepositoryTest.java +++ b/src/test/java/mju/iphak/maru_egg/question/repository/QuestionRepositoryTest.java @@ -42,7 +42,7 @@ public void setUp() throws Exception { QuestionCategory.ADMISSION_GUIDELINE); questionRepository.save(additionalQuestion3); Question additionalQuestionUNCLASSIFIED = Question.of("추가4 테스트 질문 예시입니다.", "추가 테스트 질문 예시", QuestionType.SUSI, - QuestionCategory.UNCLASSIFIED); + null); questionRepository.save(additionalQuestionUNCLASSIFIED); answer = Answer.of(question, "테스트 답변입니다."); From ed47b1aeae83dfe1cc53345774a4344254c13433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Tue, 23 Jul 2024 16:49:19 +0900 Subject: [PATCH 2/9] =?UTF-8?q?refactor:=20llm=20=EC=84=9C=EB=B2=84=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../answer/application/AnswerService.java | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/main/java/mju/iphak/maru_egg/answer/application/AnswerService.java b/src/main/java/mju/iphak/maru_egg/answer/application/AnswerService.java index 26ae2c1..4995438 100644 --- a/src/main/java/mju/iphak/maru_egg/answer/application/AnswerService.java +++ b/src/main/java/mju/iphak/maru_egg/answer/application/AnswerService.java @@ -48,22 +48,17 @@ public Mono askQuestion(LLMAskQuestionRequest request) { .contentType(MediaType.APPLICATION_FORM_URLENCODED) .body(BodyInserters.fromFormData(formData)) .retrieve() - .onStatus( - HttpStatusCode::isError, - response -> { - return switch (response.statusCode().value()) { - case 400 -> Mono.error( - new BadRequestWebClientException( - String.format(BAD_REQUEST_WEBCLIENT.getMessage(), "LLM 서버", request.questionType(), - request.questionCategory(), request.question()))); - case 404 -> Mono.error( - new NotFoundWebClientException(String.format(NOT_FOUND_WEBCLIENT.getMessage(), "LLM 서버"))); - default -> Mono.error( - new InternalServerErrorWebClientException( - String.format(INTERNAL_ERROR_WEBCLIENT.getMessage(), "LLM 서버"))); - }; - } - ) + .onStatus(HttpStatusCode::isError, response -> { + return switch (response.statusCode().value()) { + case 400 -> Mono.error(new BadRequestWebClientException( + String.format(BAD_REQUEST_WEBCLIENT.getMessage(), "LLM 서버", request.questionType(), + request.questionCategory(), request.question()))); + case 404 -> Mono.error(new NotFoundWebClientException( + String.format(NOT_FOUND_WEBCLIENT.getMessage(), "LLM 서버"))); + default -> Mono.error(new InternalServerErrorWebClientException( + String.format(INTERNAL_ERROR_WEBCLIENT.getMessage(), "LLM 서버"))); + }; + }) .bodyToMono(LLMAnswerResponse.class); } From e910902d15da20f3413e305242284a118289eece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Tue, 23 Jul 2024 16:49:44 +0900 Subject: [PATCH 3/9] =?UTF-8?q?refactor:=20llm=20=EC=84=9C=EB=B2=84=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../answer/dto/response/LLMAnswerResponse.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/mju/iphak/maru_egg/answer/dto/response/LLMAnswerResponse.java b/src/main/java/mju/iphak/maru_egg/answer/dto/response/LLMAnswerResponse.java index b5b0384..9dc7dca 100644 --- a/src/main/java/mju/iphak/maru_egg/answer/dto/response/LLMAnswerResponse.java +++ b/src/main/java/mju/iphak/maru_egg/answer/dto/response/LLMAnswerResponse.java @@ -2,17 +2,18 @@ import lombok.Builder; import mju.iphak.maru_egg.answer.domain.Answer; -import mju.iphak.maru_egg.question.domain.QuestionCategory; @Builder public record LLMAnswerResponse( - String answer, - QuestionCategory questionCategory + String questionType, + String questionCategory, + String answer ) { - public static LLMAnswerResponse of(Answer answer, QuestionCategory category) { + public static LLMAnswerResponse of(String questionType, String questionCategory, Answer answer) { return LLMAnswerResponse.builder() + .questionType(questionType) + .questionCategory(questionCategory) .answer(answer.getContent()) - .questionCategory(category) .build(); } } \ No newline at end of file From bdbfd7df9f08836bf77129f8f60a29ca1cdc6da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Tue, 23 Jul 2024 16:52:28 +0900 Subject: [PATCH 4/9] =?UTF-8?q?refactor:=20category=20enum=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=EC=99=80=20=EA=B0=9D=EC=B2=B4=20=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EC=97=B4=20=EB=B9=84=EA=B5=90=20=ED=95=A8=EC=88=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../question/application/QuestionProcessingService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/mju/iphak/maru_egg/question/application/QuestionProcessingService.java b/src/main/java/mju/iphak/maru_egg/question/application/QuestionProcessingService.java index 645a41c..af6ad5e 100644 --- a/src/main/java/mju/iphak/maru_egg/question/application/QuestionProcessingService.java +++ b/src/main/java/mju/iphak/maru_egg/question/application/QuestionProcessingService.java @@ -61,13 +61,13 @@ public QuestionResponse question(final QuestionType type, final QuestionCategory private QuestionResponse askNewQuestion(QuestionType type, QuestionCategory category, String content, String contentToken) { - LLMAskQuestionRequest askQuestionRequest = LLMAskQuestionRequest.of(type.toString(), + LLMAskQuestionRequest askQuestionRequest = LLMAskQuestionRequest.of(type.getType(), isCategoryNullThen(category), content); LLMAnswerResponse llmAnswerResponse = answerService.askQuestion(askQuestionRequest).block(); - - Question newQuestion = saveQuestion(type, llmAnswerResponse.questionCategory(), content, contentToken); + Question newQuestion = saveQuestion(type, + QuestionCategory.convertToCategory(llmAnswerResponse.questionCategory()), content, contentToken); Answer newAnswer = saveAnswer(newQuestion, llmAnswerResponse.answer()); return createQuestionResponse(newQuestion, newAnswer); } @@ -76,7 +76,7 @@ private static String isCategoryNullThen(final QuestionCategory category) { if (category == null) { return UNCLASSIFIED; } - return category.toString(); + return category.getCategory(); } private Answer saveAnswer(final Question question, final String content) { From 181a49963a385f8884851aa1ceb05181a0a0e22f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Tue, 23 Jul 2024 16:53:18 +0900 Subject: [PATCH 5/9] =?UTF-8?q?refactor:=20QuestionCategory=EC=99=80=20Que?= =?UTF-8?q?stionType=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../question/domain/QuestionCategory.java | 24 +++++++++++++++++-- .../question/domain/QuestionType.java | 6 +++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/main/java/mju/iphak/maru_egg/question/domain/QuestionCategory.java b/src/main/java/mju/iphak/maru_egg/question/domain/QuestionCategory.java index 97bc633..c2c4e90 100644 --- a/src/main/java/mju/iphak/maru_egg/question/domain/QuestionCategory.java +++ b/src/main/java/mju/iphak/maru_egg/question/domain/QuestionCategory.java @@ -13,10 +13,30 @@ public enum QuestionCategory { PAST_QUESTIONS("기출문제"), INTERVIEW_PRACTICAL_TEST("면접/실기"); - private final String questionCategory; + private final String category; @Override public String toString() { - return this.questionCategory; + return this.category; + } + + public static QuestionCategory convertToCategory(String category) { + if (category.equals(ADMISSION_GUIDELINE.getCategory())) { + return ADMISSION_GUIDELINE; + } + + if (category.equals(PASSING_RESULT.getCategory())) { + return PASSING_RESULT; + } + + if (category.equals(PAST_QUESTIONS.getCategory())) { + return PAST_QUESTIONS; + } + + if (category.equals(INTERVIEW_PRACTICAL_TEST.getCategory())) { + return INTERVIEW_PRACTICAL_TEST; + } + + return null; } } diff --git a/src/main/java/mju/iphak/maru_egg/question/domain/QuestionType.java b/src/main/java/mju/iphak/maru_egg/question/domain/QuestionType.java index 1006b97..b3c8b4a 100644 --- a/src/main/java/mju/iphak/maru_egg/question/domain/QuestionType.java +++ b/src/main/java/mju/iphak/maru_egg/question/domain/QuestionType.java @@ -1,19 +1,21 @@ package mju.iphak.maru_egg.question.domain; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; import lombok.RequiredArgsConstructor; @Schema(description = "질문 타입", enumAsRef = true) +@Getter @RequiredArgsConstructor public enum QuestionType { SUSI("수시"), JEONGSI("정시"), PYEONIP("편입학"); - private final String questionType; + private final String type; @Override public String toString() { - return this.questionType; + return this.type; } } From 46a34c995846b44a4800c03afa85fb5e695fc3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Tue, 23 Jul 2024 16:53:46 +0900 Subject: [PATCH 6/9] =?UTF-8?q?refactor:=20WebClientConfig=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EB=A1=9C=EA=B7=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../maru_egg/common/config/WebClientConfig.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/mju/iphak/maru_egg/common/config/WebClientConfig.java b/src/main/java/mju/iphak/maru_egg/common/config/WebClientConfig.java index e780b5b..75c45fb 100644 --- a/src/main/java/mju/iphak/maru_egg/common/config/WebClientConfig.java +++ b/src/main/java/mju/iphak/maru_egg/common/config/WebClientConfig.java @@ -22,6 +22,7 @@ public WebClient webClient(WebClient.Builder builder) { .baseUrl(baseUrl) .filter(logRequest()) .filter(logResponse()) + .filter(logError()) .build(); } @@ -42,4 +43,15 @@ private ExchangeFilterFunction logResponse() { return Mono.just(clientResponse); }); } + + private ExchangeFilterFunction logError() { + return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> { + if (clientResponse.statusCode().isError()) { + clientResponse.bodyToMono(String.class).subscribe(body -> { + log.error("Response Error Body: {}", body); + }); + } + return Mono.just(clientResponse); + }); + } } \ No newline at end of file From 2dc21e5dd26f843253a16f1471e576fcf47d5fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Tue, 23 Jul 2024 16:54:12 +0900 Subject: [PATCH 7/9] =?UTF-8?q?test:=20service=20layer=20test=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../answer/application/AnswerServiceTest.java | 13 ++++++++----- .../QuestionProcessingServiceTest.java | 15 ++++++++------- .../question/application/QuestionServiceTest.java | 4 ++-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/test/java/mju/iphak/maru_egg/answer/application/AnswerServiceTest.java b/src/test/java/mju/iphak/maru_egg/answer/application/AnswerServiceTest.java index ae07736..23007fc 100644 --- a/src/test/java/mju/iphak/maru_egg/answer/application/AnswerServiceTest.java +++ b/src/test/java/mju/iphak/maru_egg/answer/application/AnswerServiceTest.java @@ -47,7 +47,7 @@ public class AnswerServiceTest extends MockTest { @Before public void setUp() { - question = Question.of("수시 일정 알려주세요.", "수시 일정", QuestionType.JEONGSI, + question = Question.of("수시 일정 알려주세요.", "수시 일정", QuestionType.SUSI, QuestionCategory.ADMISSION_GUIDELINE); answer = Answer.of(question, "수시 일정은 2024년 12월 19일(목)부터 2024년 12월 26일(목) 18:00까지 최초합격자 발표가 있고, 2025년 2월 10일(월) 10:00부터 2025년 2월 12일(수) 15:00까지 문서등록 및 등록금 납부가 진행됩니다. 등록금 납부 기간은 2024년 12월 16일(월) 10:00부터 2024년 12월 18일(수) 15:00까지이며, 방법은 입학처 홈페이지를 통한 문서등록 및 등록금 납부를 하시면 됩니다. 상세 안내는 추후 입학처 홈페이지를 통해 공지될 예정입니다."); @@ -61,7 +61,9 @@ public void setUp() { ClientResponse clientResponse = ClientResponse.create(HttpStatusCode.valueOf(200)) .header("Content-Type", "application/json") - .body("{\"answer\":\"" + answer.getContent() + "\"}") + .body(String.format("{\"questionType\":\"%s\",\"questionCategory\":\"%s\",\"answer\":\"%s\"}", + question.getQuestionType().getType(), question.getQuestionCategory().getCategory(), + answer.getContent())) .build(); when(exchangeFunction.exchange(any())).thenReturn(Mono.just(clientResponse)); @@ -99,12 +101,13 @@ public void setUp() { @Test public void LLM_질문_요청() { // given - LLMAskQuestionRequest request = LLMAskQuestionRequest.of(QuestionType.SUSI.toString(), - QuestionCategory.ADMISSION_GUIDELINE.toString(), + LLMAskQuestionRequest request = LLMAskQuestionRequest.of(QuestionType.SUSI.getType(), + QuestionCategory.ADMISSION_GUIDELINE.getCategory(), question.getContent()); // when - LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(answer, QuestionCategory.ADMISSION_GUIDELINE); + LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(QuestionType.SUSI.getType(), + QuestionCategory.ADMISSION_GUIDELINE.getCategory(), answer); LLMAnswerResponse result = answerService.askQuestion(request).block(); // then diff --git a/src/test/java/mju/iphak/maru_egg/question/application/QuestionProcessingServiceTest.java b/src/test/java/mju/iphak/maru_egg/question/application/QuestionProcessingServiceTest.java index 39d90fe..1309532 100644 --- a/src/test/java/mju/iphak/maru_egg/question/application/QuestionProcessingServiceTest.java +++ b/src/test/java/mju/iphak/maru_egg/question/application/QuestionProcessingServiceTest.java @@ -67,8 +67,8 @@ private LLMAnswerResponse mockAskQuestion(LLMAskQuestionRequest request) { formData.add("question", request.question()); Question testQuestion = Question.of("새로운 질문입니다.", "새로운 질문", QuestionType.SUSI, QuestionCategory.ADMISSION_GUIDELINE); - LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(Answer.of(testQuestion, "새로운 답변입니다."), - QuestionCategory.ADMISSION_GUIDELINE); + LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(QuestionType.SUSI.getType(), + QuestionCategory.ADMISSION_GUIDELINE.getCategory(), Answer.of(testQuestion, "새로운 답변입니다.")); mockWebServer.enqueue(new MockResponse() .setHeader("Content-type", MediaType.APPLICATION_JSON_VALUE) @@ -206,7 +206,8 @@ void setUp() { String contentToken = PhraseExtractionUtils.extractPhrases(content); Question testQuestion = Question.of(content, contentToken, type, category); Answer testAnswer = Answer.of(testQuestion, "새로운 답변입니다."); - LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(testAnswer, QuestionCategory.ADMISSION_GUIDELINE); + LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(QuestionType.SUSI.getType(), + QuestionCategory.ADMISSION_GUIDELINE.getCategory(), testAnswer); when(questionRepository.searchQuestionsByContentTokenAndTypeAndCategory(contentToken, type, category)) .thenReturn(Optional.of(Collections.emptyList())); @@ -230,13 +231,13 @@ void setUp() { public void MOCK_LLM_질문_요청() { // given startServer(new ReactorClientHttpConnector()); - LLMAskQuestionRequest request = LLMAskQuestionRequest.of(QuestionType.SUSI.toString(), - QuestionCategory.ADMISSION_GUIDELINE.toString(), + LLMAskQuestionRequest request = LLMAskQuestionRequest.of(QuestionType.SUSI.getType(), + QuestionCategory.ADMISSION_GUIDELINE.getCategory(), question.getContent()); Question testQuestion = Question.of("새로운 질문입니다.", "새로운 질문", QuestionType.SUSI, QuestionCategory.ADMISSION_GUIDELINE); - LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(Answer.of(testQuestion, "새로운 답변입니다."), - QuestionCategory.ADMISSION_GUIDELINE); + LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(QuestionType.SUSI.getType(), + QuestionCategory.ADMISSION_GUIDELINE.getCategory(), Answer.of(testQuestion, "새로운 답변입니다.")); // when LLMAnswerResponse result = mockAskQuestion(request); diff --git a/src/test/java/mju/iphak/maru_egg/question/application/QuestionServiceTest.java b/src/test/java/mju/iphak/maru_egg/question/application/QuestionServiceTest.java index 8291cea..ce96e99 100644 --- a/src/test/java/mju/iphak/maru_egg/question/application/QuestionServiceTest.java +++ b/src/test/java/mju/iphak/maru_egg/question/application/QuestionServiceTest.java @@ -68,8 +68,8 @@ private LLMAnswerResponse mockAskQuestion(LLMAskQuestionRequest request) { formData.add("question", request.question()); Question testQuestion = Question.of("새로운 질문입니다.", "새로운 질문", QuestionType.SUSI, QuestionCategory.ADMISSION_GUIDELINE); - LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(Answer.of(testQuestion, "새로운 답변입니다."), - QuestionCategory.ADMISSION_GUIDELINE); + LLMAnswerResponse expectedResponse = LLMAnswerResponse.of(QuestionType.SUSI.getType(), + QuestionCategory.ADMISSION_GUIDELINE.getCategory(), Answer.of(testQuestion, "새로운 답변입니다.")); mockWebServer.enqueue(new MockResponse() .setHeader("Content-type", MediaType.APPLICATION_JSON_VALUE) From 1c6cbba289f52fdd2ff61c9e5f9db8305384c600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Tue, 23 Jul 2024 17:00:40 +0900 Subject: [PATCH 8/9] =?UTF-8?q?test:=20test=20=EB=AA=85=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/mju/iphak/maru_egg/auth/api/AuthControllerTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/mju/iphak/maru_egg/auth/api/AuthControllerTest.java b/src/test/java/mju/iphak/maru_egg/auth/api/AuthControllerTest.java index 127efde..15c3b7f 100644 --- a/src/test/java/mju/iphak/maru_egg/auth/api/AuthControllerTest.java +++ b/src/test/java/mju/iphak/maru_egg/auth/api/AuthControllerTest.java @@ -5,6 +5,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.springframework.beans.factory.annotation.Autowired; @@ -50,8 +51,9 @@ void setUp() { userRepository.save(user); } + @DisplayName("회원가입 성공") @Test - void testSignUp() throws Exception { + void 회원가입_성공() throws Exception { // given SignUpRequest signUpRequest = new SignUpRequest("testuser2@example.com", "Password123!"); From 7c6f41a803669cffd0c733cdaa55fbff5b7386e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Tue, 23 Jul 2024 17:16:38 +0900 Subject: [PATCH 9/9] =?UTF-8?q?chore:=20spring=20=EC=8B=A4=ED=96=89=20?= =?UTF-8?q?=EB=B0=B0=EB=84=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/banner.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/resources/banner.txt diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt new file mode 100644 index 0000000..10cd809 --- /dev/null +++ b/src/main/resources/banner.txt @@ -0,0 +1,12 @@ + + + ░▒▓██████████████▓▒░ ░▒▓██████▓▒░ ░▒▓███████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓████████▓▒░ ░▒▓██████▓▒░ ░▒▓██████▓▒░ + ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ + ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ + ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓████████▓▒░ ░▒▓███████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒▒▓███▓▒░ ░▒▓█▓▒▒▓███▓▒░ + ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ + ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ + ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓██████▓▒░ ░▒▓████████▓▒░ ░▒▓██████▓▒░ ░▒▓██████▓▒░ + + +[based on Spring Boot version ${spring-boot.version}]