From b01863b0874d6b285d54e769358eecc88c6eb94d Mon Sep 17 00:00:00 2001 From: joyfulviper Date: Tue, 23 Jan 2024 22:14:20 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=84=9C=EB=B2=84=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B3=B5=ED=95=98=EB=8A=94=20=EC=A7=88=EB=AC=B8?= =?UTF-8?q?=EC=A7=80=20=EB=A7=8C=EB=93=A4=EA=B8=B0=20api=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 --- .../docs/asciidoc/api/question/questions.adoc | 13 ++++++- .../controller/QuestionController.java | 8 ++++ .../CreateServerQuestionFormRequest.java | 23 +++++++++++ .../question/service/QuestionService.java | 6 +++ .../question/service/QuestionValidator.java | 6 +-- ...reateServerQuestionFormServiceRequest.java | 20 ++++++++++ .../docs/question/QuestionApiDocsTest.java | 39 +++++++++++++++++++ .../repository/QuestionRepository.java | 2 - 8 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 api/src/main/java/com/lovely4k/backend/question/controller/request/CreateServerQuestionFormRequest.java create mode 100644 api/src/main/java/com/lovely4k/backend/question/service/request/CreateServerQuestionFormServiceRequest.java diff --git a/api/src/docs/asciidoc/api/question/questions.adoc b/api/src/docs/asciidoc/api/question/questions.adoc index 8dc59045..c2eeb92d 100644 --- a/api/src/docs/asciidoc/api/question/questions.adoc +++ b/api/src/docs/asciidoc/api/question/questions.adoc @@ -98,4 +98,15 @@ include::{snippets}/find-question-game/response-fields.adoc[] include::{snippets}/delete-custom-questions-and-questionForm/http-request.adoc[] ==== Response -include::{snippets}/delete-custom-questions-and-questionForm/http-response.adoc[] \ No newline at end of file +include::{snippets}/delete-custom-questions-and-questionForm/http-response.adoc[] + +[[create-question-form-and-question-by-user]] +=== 서버에서 제공하는 질문 생성 API +서버에서 제공하는 질문을 생성하는 api 입니다. 오늘의 질문 받기가 오류가 발생한다면 해당 오류 메시지에 작성되어 있는 일차에 해당하는 질문을 생성해주세요 + +==== Request +include::{snippets}/create-question-form-and-question-by-user/http-request.adoc[] + +==== Response (Success) +include::{snippets}/create-question-form-and-question-by-user/http-response.adoc[] +include::{snippets}/create-question-form-and-question-by-user/response-fields.adoc[] \ No newline at end of file diff --git a/api/src/main/java/com/lovely4k/backend/question/controller/QuestionController.java b/api/src/main/java/com/lovely4k/backend/question/controller/QuestionController.java index cbc7e230..f800984f 100644 --- a/api/src/main/java/com/lovely4k/backend/question/controller/QuestionController.java +++ b/api/src/main/java/com/lovely4k/backend/question/controller/QuestionController.java @@ -6,6 +6,7 @@ import com.lovely4k.backend.question.controller.request.AnswerQuestionRequest; import com.lovely4k.backend.question.controller.request.AnsweredQuestionParamRequest; import com.lovely4k.backend.question.controller.request.CreateQuestionFormRequest; +import com.lovely4k.backend.question.controller.request.CreateServerQuestionFormRequest; import com.lovely4k.backend.question.repository.response.AnsweredQuestionResponse; import com.lovely4k.backend.question.repository.response.DailyQuestionResponse; import com.lovely4k.backend.question.repository.response.QuestionDetailsResponse; @@ -21,6 +22,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.springframework.web.util.UriComponentsBuilder; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; @@ -113,4 +115,10 @@ public ResponseEntity init() { questionService.deleteQuestion(); return ResponseEntity.noContent().build(); } + + //관리자용 엔드포인트 + @PostMapping("/server") + public ResponseEntity> addServerQuest(@RequestBody @Valid CreateServerQuestionFormRequest request) { + return ApiResponse.created(questionService.createServerQuestion(request.toServiceRequest())); + } } \ No newline at end of file diff --git a/api/src/main/java/com/lovely4k/backend/question/controller/request/CreateServerQuestionFormRequest.java b/api/src/main/java/com/lovely4k/backend/question/controller/request/CreateServerQuestionFormRequest.java new file mode 100644 index 00000000..91920162 --- /dev/null +++ b/api/src/main/java/com/lovely4k/backend/question/controller/request/CreateServerQuestionFormRequest.java @@ -0,0 +1,23 @@ +package com.lovely4k.backend.question.controller.request; + +import com.lovely4k.backend.question.service.request.CreateServerQuestionFormServiceRequest; +import jakarta.validation.constraints.NotBlank; + +public record CreateServerQuestionFormRequest( + @NotBlank(message = "질문 내용은 비어 있을 수 없습니다.") + String questionContent, + + @NotBlank(message = "첫 번째 선택지는 비어 있을 수 없습니다.") + String firstChoice, + + @NotBlank(message = "두 번째 선택지는 비어 있을 수 없습니다.") + String secondChoice, + + String thirdChoice, + String fourthChoice, + Long questionDay +) { + public CreateServerQuestionFormServiceRequest toServiceRequest() { + return new CreateServerQuestionFormServiceRequest(questionContent, firstChoice, secondChoice, thirdChoice, fourthChoice, questionDay); + } +} diff --git a/api/src/main/java/com/lovely4k/backend/question/service/QuestionService.java b/api/src/main/java/com/lovely4k/backend/question/service/QuestionService.java index 5a01d2b3..c5663ce1 100644 --- a/api/src/main/java/com/lovely4k/backend/question/service/QuestionService.java +++ b/api/src/main/java/com/lovely4k/backend/question/service/QuestionService.java @@ -9,6 +9,7 @@ import com.lovely4k.backend.question.repository.QuestionFormRepository; import com.lovely4k.backend.question.repository.QuestionRepository; import com.lovely4k.backend.question.service.request.CreateQuestionFormServiceRequest; +import com.lovely4k.backend.question.service.request.CreateServerQuestionFormServiceRequest; import com.lovely4k.backend.question.service.response.CreateQuestionFormResponse; import com.lovely4k.backend.question.service.response.CreateQuestionResponse; import jakarta.persistence.EntityNotFoundException; @@ -82,4 +83,9 @@ public void deleteQuestion() { questionFormRepository.deleteAllByQuestionFormType(QuestionFormType.CUSTOM); } + @Transactional + public Long createServerQuestion(CreateServerQuestionFormServiceRequest request) { + return questionFormRepository.save(request.toEntity()).getId(); + } + } \ No newline at end of file diff --git a/api/src/main/java/com/lovely4k/backend/question/service/QuestionValidator.java b/api/src/main/java/com/lovely4k/backend/question/service/QuestionValidator.java index 3a628605..76d0fc1c 100644 --- a/api/src/main/java/com/lovely4k/backend/question/service/QuestionValidator.java +++ b/api/src/main/java/com/lovely4k/backend/question/service/QuestionValidator.java @@ -18,16 +18,16 @@ public class QuestionValidator { @Transactional(readOnly = true) public void validateCreateQuestionForm(Long coupleId, long questionDay) { List questions = findQuestionWithLock(coupleId, questionDay); - validateDailyQuestionLimitAndAnswerCompletion(questions); + validateDailyQuestionLimitAndAnswerCompletion(questions, questionDay); } - private void validateDailyQuestionLimitAndAnswerCompletion(List questions) { + private void validateDailyQuestionLimitAndAnswerCompletion(List questions, Long questionDay) { if (questions.size() > 1) { throw new QuestionCreateCountExceedException(); } if (questions.isEmpty()) { - throw new IllegalStateException("서버에서 제공하는 질문을 먼저 생성해 주세요."); + throw new IllegalStateException("다음 일차에 해당하는 서버에서 제공하는 질문을 먼저 생성해 주세요" + questionDay); } questions.get(0).validateAnswer(); diff --git a/api/src/main/java/com/lovely4k/backend/question/service/request/CreateServerQuestionFormServiceRequest.java b/api/src/main/java/com/lovely4k/backend/question/service/request/CreateServerQuestionFormServiceRequest.java new file mode 100644 index 00000000..240751ad --- /dev/null +++ b/api/src/main/java/com/lovely4k/backend/question/service/request/CreateServerQuestionFormServiceRequest.java @@ -0,0 +1,20 @@ +package com.lovely4k.backend.question.service.request; + +import com.lovely4k.backend.question.QuestionChoices; +import com.lovely4k.backend.question.QuestionForm; +import com.lovely4k.backend.question.QuestionFormType; + +public record CreateServerQuestionFormServiceRequest( + String questionContent, + String firstChoice, + String secondChoice, + String thirdChoice, + String fourthChoice, + Long questionDay +) { + public QuestionForm toEntity() { + QuestionChoices questionChoices = QuestionChoices.create(firstChoice, secondChoice, thirdChoice, fourthChoice); + + return QuestionForm.create(null, questionContent, questionChoices, questionDay, QuestionFormType.SERVER); + } +} \ No newline at end of file diff --git a/api/src/test/java/com/lovely4k/docs/question/QuestionApiDocsTest.java b/api/src/test/java/com/lovely4k/docs/question/QuestionApiDocsTest.java index ef2440e5..1986df97 100644 --- a/api/src/test/java/com/lovely4k/docs/question/QuestionApiDocsTest.java +++ b/api/src/test/java/com/lovely4k/docs/question/QuestionApiDocsTest.java @@ -4,6 +4,7 @@ import com.lovely4k.backend.question.controller.QuestionController; import com.lovely4k.backend.question.controller.request.AnswerQuestionRequest; import com.lovely4k.backend.question.controller.request.CreateQuestionFormRequest; +import com.lovely4k.backend.question.controller.request.CreateServerQuestionFormRequest; import com.lovely4k.backend.question.repository.response.*; import com.lovely4k.backend.question.service.QuestionQueryService; import com.lovely4k.backend.question.service.QuestionService; @@ -286,4 +287,42 @@ void init() throws Exception { .andDo(document("delete-custom-questions-and-questionForm")); } + @DisplayName("서버의 질문 양식을 생성하는 API") + @Test + void createServerQuestionForm() throws Exception { + CreateServerQuestionFormRequest request = new CreateServerQuestionFormRequest( + "테스트 질문", + "선택지 1", + "선택지 2", + "선택지 3", + "선택지 4", + 1L + ); + + given(questionService.createServerQuestion(any())) + .willReturn(1L); + + mockMvc.perform(post("/v1/questions/server") + .content(objectMapper.writeValueAsString(request)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()) + .andDo(document("create-question-form-and-question-by-user", + responseHeaders( + headerWithName("Location").description("리소스 저장 경로") + ), + requestFields( + fieldWithPath("questionContent").type(STRING).description("질문 내용"), + fieldWithPath("firstChoice").type(STRING).description("첫 번째 선택지"), + fieldWithPath("secondChoice").type(STRING).description("두 번째 선택지"), + fieldWithPath("thirdChoice").type(STRING).description("세 번째 선택지"), + fieldWithPath("fourthChoice").type(STRING).description("네 번째 선택지"), + fieldWithPath("questionDay").type(NUMBER).description("질문에 해당하는 날짜") + ), + responseFields( + fieldWithPath("code").type(NUMBER).description("코드"), + fieldWithPath("body").type(NULL).description("응답 바디"), + fieldWithPath("links").type(ARRAY).description("연결된 url") + ) + )); + } } \ No newline at end of file diff --git a/model/src/main/java/com/lovely4k/backend/question/repository/QuestionRepository.java b/model/src/main/java/com/lovely4k/backend/question/repository/QuestionRepository.java index 9323df44..772f7fbc 100644 --- a/model/src/main/java/com/lovely4k/backend/question/repository/QuestionRepository.java +++ b/model/src/main/java/com/lovely4k/backend/question/repository/QuestionRepository.java @@ -12,6 +12,4 @@ public interface QuestionRepository extends JpaRepository { @Lock(LockModeType.PESSIMISTIC_WRITE) @Query("SELECT q FROM Question q WHERE q.coupleId = :coupleId AND q.questionDay = :questionDay") List findQuestionByCoupleIdAndQuestionDayWithLock(Long coupleId, Long questionDay); - - List findQuestionByCoupleIdAndQuestionDay(Long coupleId, Long questionDay); } \ No newline at end of file