From 893336aff17761285791b027b7b26418600655e6 Mon Sep 17 00:00:00 2001 From: Juhyeon Lee Date: Mon, 23 Feb 2026 00:14:30 +0900 Subject: [PATCH] =?UTF-8?q?[FEAT]=20=EB=8F=85=EC=84=9C=EC=B7=A8=ED=96=A5?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=B9=84=ED=9A=8C=EC=9B=90=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20DB=20=EC=A0=80=EC=9E=A5=20=EB=B0=8F=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=EC=8B=9C=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=97=B0=EB=8F=99=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/api/book/dto/ReviewItemDTO.java | 2 +- .../api/member/dto/FollowResponseDTO.java | 2 +- .../backend/api/member/dto/UserInfoDTO.java | 2 +- .../backend/api/member/entity/Member.java | 1 + .../api/post/dto/CategoryPostDetailDTO.java | 2 +- .../backend/api/post/dto/PostDTO.java | 2 +- .../dto/WeeklyRecommendationResponseDTO.java | 2 +- .../api/post/repository/PostRepository.java | 2 +- .../backend/api/question/dto/AnswerDTO.java | 2 +- .../controller/ReadingTasteController.java | 38 +++++++++-- .../dto/TestRequestDTO.java | 9 ++- .../dto/TestResponseDTO.java | 2 +- .../dto/TestResultRequestDTO.java | 17 +++++ .../dto/TestStatisticsResponseDTO.java | 14 ++++ .../entity/ReadingTasteType.java | 2 +- .../api/readingTaste/entity/TestResult.java | 37 +++++++++++ .../repository/TestResultRepository.java | 12 ++++ .../service/ReadingTasteService.java | 65 ++++++++++++++++--- .../config/security/SecurityConfig.java | 3 +- .../backend/common/response/ErrorStatus.java | 1 + .../common/response/SuccessStatus.java | 6 +- 21 files changed, 197 insertions(+), 26 deletions(-) rename src/main/java/com/moongeul/backend/api/{member => readingTaste}/controller/ReadingTasteController.java (57%) rename src/main/java/com/moongeul/backend/api/{member => readingTaste}/dto/TestRequestDTO.java (68%) rename src/main/java/com/moongeul/backend/api/{member => readingTaste}/dto/TestResponseDTO.java (85%) create mode 100644 src/main/java/com/moongeul/backend/api/readingTaste/dto/TestResultRequestDTO.java create mode 100644 src/main/java/com/moongeul/backend/api/readingTaste/dto/TestStatisticsResponseDTO.java rename src/main/java/com/moongeul/backend/api/{member => readingTaste}/entity/ReadingTasteType.java (93%) create mode 100644 src/main/java/com/moongeul/backend/api/readingTaste/entity/TestResult.java create mode 100644 src/main/java/com/moongeul/backend/api/readingTaste/repository/TestResultRepository.java rename src/main/java/com/moongeul/backend/api/{member => readingTaste}/service/ReadingTasteService.java (81%) diff --git a/src/main/java/com/moongeul/backend/api/book/dto/ReviewItemDTO.java b/src/main/java/com/moongeul/backend/api/book/dto/ReviewItemDTO.java index 0c11cd6..571f8cd 100644 --- a/src/main/java/com/moongeul/backend/api/book/dto/ReviewItemDTO.java +++ b/src/main/java/com/moongeul/backend/api/book/dto/ReviewItemDTO.java @@ -1,6 +1,6 @@ package com.moongeul.backend.api.book.dto; -import com.moongeul.backend.api.member.entity.ReadingTasteType; +import com.moongeul.backend.api.readingTaste.entity.ReadingTasteType; import com.moongeul.backend.api.post.dto.PostDTO; import com.moongeul.backend.api.post.dto.QuoteDTO; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/moongeul/backend/api/member/dto/FollowResponseDTO.java b/src/main/java/com/moongeul/backend/api/member/dto/FollowResponseDTO.java index e0137bf..60c4a99 100644 --- a/src/main/java/com/moongeul/backend/api/member/dto/FollowResponseDTO.java +++ b/src/main/java/com/moongeul/backend/api/member/dto/FollowResponseDTO.java @@ -1,7 +1,7 @@ package com.moongeul.backend.api.member.dto; import com.moongeul.backend.api.member.entity.FollowStatus; -import com.moongeul.backend.api.member.entity.ReadingTasteType; +import com.moongeul.backend.api.readingTaste.entity.ReadingTasteType; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/com/moongeul/backend/api/member/dto/UserInfoDTO.java b/src/main/java/com/moongeul/backend/api/member/dto/UserInfoDTO.java index 193c64d..63d22fe 100644 --- a/src/main/java/com/moongeul/backend/api/member/dto/UserInfoDTO.java +++ b/src/main/java/com/moongeul/backend/api/member/dto/UserInfoDTO.java @@ -2,7 +2,7 @@ import com.moongeul.backend.api.member.entity.FollowStatus; import com.moongeul.backend.api.member.entity.PrivacyLevel; -import com.moongeul.backend.api.member.entity.ReadingTasteType; +import com.moongeul.backend.api.readingTaste.entity.ReadingTasteType; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/com/moongeul/backend/api/member/entity/Member.java b/src/main/java/com/moongeul/backend/api/member/entity/Member.java index 649697c..eb2703e 100644 --- a/src/main/java/com/moongeul/backend/api/member/entity/Member.java +++ b/src/main/java/com/moongeul/backend/api/member/entity/Member.java @@ -1,5 +1,6 @@ package com.moongeul.backend.api.member.entity; +import com.moongeul.backend.api.readingTaste.entity.ReadingTasteType; import com.moongeul.backend.common.entity.BaseTimeEntity; import jakarta.persistence.*; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/moongeul/backend/api/post/dto/CategoryPostDetailDTO.java b/src/main/java/com/moongeul/backend/api/post/dto/CategoryPostDetailDTO.java index dc4cc3b..82dc0f1 100644 --- a/src/main/java/com/moongeul/backend/api/post/dto/CategoryPostDetailDTO.java +++ b/src/main/java/com/moongeul/backend/api/post/dto/CategoryPostDetailDTO.java @@ -1,6 +1,6 @@ package com.moongeul.backend.api.post.dto; -import com.moongeul.backend.api.member.entity.ReadingTasteType; +import com.moongeul.backend.api.readingTaste.entity.ReadingTasteType; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/com/moongeul/backend/api/post/dto/PostDTO.java b/src/main/java/com/moongeul/backend/api/post/dto/PostDTO.java index bea70d8..170c98b 100644 --- a/src/main/java/com/moongeul/backend/api/post/dto/PostDTO.java +++ b/src/main/java/com/moongeul/backend/api/post/dto/PostDTO.java @@ -1,6 +1,6 @@ package com.moongeul.backend.api.post.dto; -import com.moongeul.backend.api.member.entity.ReadingTasteType; +import com.moongeul.backend.api.readingTaste.entity.ReadingTasteType; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/com/moongeul/backend/api/post/dto/WeeklyRecommendationResponseDTO.java b/src/main/java/com/moongeul/backend/api/post/dto/WeeklyRecommendationResponseDTO.java index d432e8c..9333a33 100644 --- a/src/main/java/com/moongeul/backend/api/post/dto/WeeklyRecommendationResponseDTO.java +++ b/src/main/java/com/moongeul/backend/api/post/dto/WeeklyRecommendationResponseDTO.java @@ -1,6 +1,6 @@ package com.moongeul.backend.api.post.dto; -import com.moongeul.backend.api.member.entity.ReadingTasteType; +import com.moongeul.backend.api.readingTaste.entity.ReadingTasteType; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/com/moongeul/backend/api/post/repository/PostRepository.java b/src/main/java/com/moongeul/backend/api/post/repository/PostRepository.java index 469224b..3fffc32 100644 --- a/src/main/java/com/moongeul/backend/api/post/repository/PostRepository.java +++ b/src/main/java/com/moongeul/backend/api/post/repository/PostRepository.java @@ -2,7 +2,7 @@ import com.moongeul.backend.api.book.entity.Book; import com.moongeul.backend.api.member.entity.Member; -import com.moongeul.backend.api.member.entity.ReadingTasteType; +import com.moongeul.backend.api.readingTaste.entity.ReadingTasteType; import com.moongeul.backend.api.post.entity.Post; import com.moongeul.backend.api.post.entity.PostVisibility; import org.springframework.data.domain.Page; diff --git a/src/main/java/com/moongeul/backend/api/question/dto/AnswerDTO.java b/src/main/java/com/moongeul/backend/api/question/dto/AnswerDTO.java index 92616b7..639a99b 100644 --- a/src/main/java/com/moongeul/backend/api/question/dto/AnswerDTO.java +++ b/src/main/java/com/moongeul/backend/api/question/dto/AnswerDTO.java @@ -1,6 +1,6 @@ package com.moongeul.backend.api.question.dto; -import com.moongeul.backend.api.member.entity.ReadingTasteType; +import com.moongeul.backend.api.readingTaste.entity.ReadingTasteType; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/com/moongeul/backend/api/member/controller/ReadingTasteController.java b/src/main/java/com/moongeul/backend/api/readingTaste/controller/ReadingTasteController.java similarity index 57% rename from src/main/java/com/moongeul/backend/api/member/controller/ReadingTasteController.java rename to src/main/java/com/moongeul/backend/api/readingTaste/controller/ReadingTasteController.java index 7d4670c..db0643e 100644 --- a/src/main/java/com/moongeul/backend/api/member/controller/ReadingTasteController.java +++ b/src/main/java/com/moongeul/backend/api/readingTaste/controller/ReadingTasteController.java @@ -1,8 +1,9 @@ -package com.moongeul.backend.api.member.controller; +package com.moongeul.backend.api.readingTaste.controller; -import com.moongeul.backend.api.member.dto.TestRequestDTO; -import com.moongeul.backend.api.member.dto.TestResponseDTO; -import com.moongeul.backend.api.member.service.ReadingTasteService; +import com.moongeul.backend.api.readingTaste.dto.TestRequestDTO; +import com.moongeul.backend.api.readingTaste.dto.TestResponseDTO; +import com.moongeul.backend.api.readingTaste.dto.TestStatisticsResponseDTO; +import com.moongeul.backend.api.readingTaste.service.ReadingTasteService; import com.moongeul.backend.common.response.ApiResponse; import com.moongeul.backend.common.response.SuccessStatus; import io.swagger.v3.oas.annotations.Operation; @@ -27,6 +28,7 @@ public class ReadingTasteController { summary = "독서 취향 테스트 API", description = "독서 취향 테스트 결과를 계산하여 유형을 반환하는 API 입니다." + "

요청 형식:" + + "
- guestUuid: 비회원 식별을 위한 UUID입니다.(브라우저 로컬스토리지 저장용) 로그인 여부 상관없이, 로컬스토리지에 있는 guestUuid를 전달바랍니다." + "
- answers: 질문 번호(1-12)와 답변(A or B)의 Map으로 전달바랍니다." + "

**예시:**\n" + "```json\n" + @@ -62,4 +64,32 @@ public ResponseEntity> calculateReadingTasteType(@A return ApiResponse.success(SuccessStatus.CALCULATE_READING_TASTE_SUCCESS, response); } + @Operation( + summary = "독서 취향 테스트 참여자 수 반환 API", + description = "독서 취향 테스트 참여자 수를 반환하는 API 입니다." + ) + @ApiResponses({ + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "독서 취향 테스트 참여자 수 반환 성공"), + }) + @GetMapping("/total-count") + public ResponseEntity> getTotalCount() { + + TestStatisticsResponseDTO response = readingTasteService.getTotalParticipantsCount(); + return ApiResponse.success(SuccessStatus.GET_READING_TASTE_PARTICIPANTS_SUCCESS, response); + } + + @Operation( + summary = "비회원 독서 취향 테스트 결과 조회 및 로그인 연동 API", + description = "회원가입 시, 비회원 상태에서 진행하였던 독서 취향 테스트 결과를 조회하여 결과가 있다면 로그인한 계정 정보에 저장하는 API 입니다." + ) + @ApiResponses({ + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "독서 취향 테스트 연동 성공"), + }) + @PostMapping("/link") + public ResponseEntity> linkTestResult(@AuthenticationPrincipal UserDetails userDetails, + @RequestParam String guestUuid) { + + readingTasteService.linkTestResult(guestUuid, userDetails.getUsername()); + return ApiResponse.success_only(SuccessStatus.LINK_READING_TASTE_SUCCESS); + } } diff --git a/src/main/java/com/moongeul/backend/api/member/dto/TestRequestDTO.java b/src/main/java/com/moongeul/backend/api/readingTaste/dto/TestRequestDTO.java similarity index 68% rename from src/main/java/com/moongeul/backend/api/member/dto/TestRequestDTO.java rename to src/main/java/com/moongeul/backend/api/readingTaste/dto/TestRequestDTO.java index f20375d..e9ceb0a 100644 --- a/src/main/java/com/moongeul/backend/api/member/dto/TestRequestDTO.java +++ b/src/main/java/com/moongeul/backend/api/readingTaste/dto/TestRequestDTO.java @@ -1,4 +1,4 @@ -package com.moongeul.backend.api.member.dto; +package com.moongeul.backend.api.readingTaste.dto; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; @@ -15,6 +15,13 @@ @Builder public class TestRequestDTO { + @Schema( + description = "비회원 식별을 위한 UUID (브라우저 로컬스토리지 저장용)", + example = "550e8400-e29b-41d4-a716-446655440000" + ) + @NotNull(message = "비회원 식별자는 필수입니다") + private String guestUuid; + @Schema( description = "질문 번호(1-12)와 답변(A or B) 매핑", example = "{\"1\":\"A\",\"2\":\"A\",\"3\":\"A\",\"4\":\"A\",\"5\":\"A\",\"6\":\"A\",\"7\":\"A\",\"8\":\"A\",\"9\":\"A\",\"10\":\"A\",\"11\":\"A\",\"12\":\"A\"}" diff --git a/src/main/java/com/moongeul/backend/api/member/dto/TestResponseDTO.java b/src/main/java/com/moongeul/backend/api/readingTaste/dto/TestResponseDTO.java similarity index 85% rename from src/main/java/com/moongeul/backend/api/member/dto/TestResponseDTO.java rename to src/main/java/com/moongeul/backend/api/readingTaste/dto/TestResponseDTO.java index 37a736b..71b0d6f 100644 --- a/src/main/java/com/moongeul/backend/api/member/dto/TestResponseDTO.java +++ b/src/main/java/com/moongeul/backend/api/readingTaste/dto/TestResponseDTO.java @@ -1,4 +1,4 @@ -package com.moongeul.backend.api.member.dto; +package com.moongeul.backend.api.readingTaste.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/moongeul/backend/api/readingTaste/dto/TestResultRequestDTO.java b/src/main/java/com/moongeul/backend/api/readingTaste/dto/TestResultRequestDTO.java new file mode 100644 index 0000000..c2c1358 --- /dev/null +++ b/src/main/java/com/moongeul/backend/api/readingTaste/dto/TestResultRequestDTO.java @@ -0,0 +1,17 @@ +package com.moongeul.backend.api.readingTaste.dto; + +import com.moongeul.backend.api.readingTaste.entity.ReadingTasteType; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class TestResultRequestDTO { + + private String guestUuid; + private ReadingTasteType readingTasteType; +} diff --git a/src/main/java/com/moongeul/backend/api/readingTaste/dto/TestStatisticsResponseDTO.java b/src/main/java/com/moongeul/backend/api/readingTaste/dto/TestStatisticsResponseDTO.java new file mode 100644 index 0000000..61d63c9 --- /dev/null +++ b/src/main/java/com/moongeul/backend/api/readingTaste/dto/TestStatisticsResponseDTO.java @@ -0,0 +1,14 @@ +package com.moongeul.backend.api.readingTaste.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class TestStatisticsResponseDTO { + private long totalParticipants; // 전체 참여자 수 +} diff --git a/src/main/java/com/moongeul/backend/api/member/entity/ReadingTasteType.java b/src/main/java/com/moongeul/backend/api/readingTaste/entity/ReadingTasteType.java similarity index 93% rename from src/main/java/com/moongeul/backend/api/member/entity/ReadingTasteType.java rename to src/main/java/com/moongeul/backend/api/readingTaste/entity/ReadingTasteType.java index 14bc18f..ffabe16 100644 --- a/src/main/java/com/moongeul/backend/api/member/entity/ReadingTasteType.java +++ b/src/main/java/com/moongeul/backend/api/readingTaste/entity/ReadingTasteType.java @@ -1,4 +1,4 @@ -package com.moongeul.backend.api.member.entity; +package com.moongeul.backend.api.readingTaste.entity; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/moongeul/backend/api/readingTaste/entity/TestResult.java b/src/main/java/com/moongeul/backend/api/readingTaste/entity/TestResult.java new file mode 100644 index 0000000..dddaf40 --- /dev/null +++ b/src/main/java/com/moongeul/backend/api/readingTaste/entity/TestResult.java @@ -0,0 +1,37 @@ +package com.moongeul.backend.api.readingTaste.entity; + +import com.moongeul.backend.common.entity.BaseTimeEntity; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Builder // 빌더 패턴 사용을 위한 롬복 애너테이션 +@NoArgsConstructor // 기본 생성자 +@AllArgsConstructor // 모든 필드를 포함한 생성자 +@Table(name = "TEST_RESULT") // 데이터베이스 테이블 이름 지정 +public class TestResult extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + // 비회원도 참여 가능하므로 필수값 아님 (null 가능) + @Column(name = "member_id") + private Long memberId; + + // 비회원 식별 UUID: 브라우저에서 생성해 보낸 값 저장 + @Column(nullable = false, length = 36) + private String guestUuid; + + @Enumerated(EnumType.STRING) + private ReadingTasteType readingTasteType; + + // 회원가입 후 데이터를 유저와 연결 + public void updateMemberId(Long memberId) { + this.memberId = memberId; + } +} diff --git a/src/main/java/com/moongeul/backend/api/readingTaste/repository/TestResultRepository.java b/src/main/java/com/moongeul/backend/api/readingTaste/repository/TestResultRepository.java new file mode 100644 index 0000000..efe9875 --- /dev/null +++ b/src/main/java/com/moongeul/backend/api/readingTaste/repository/TestResultRepository.java @@ -0,0 +1,12 @@ +package com.moongeul.backend.api.readingTaste.repository; + +import com.moongeul.backend.api.readingTaste.entity.TestResult; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface TestResultRepository extends JpaRepository { + + // guestUuid로 찾아 생성일(CreatedAt) 내림차순(Desc) 정렬 후 첫 번째(First) 행 반환 + Optional findFirstByGuestUuidOrderByCreatedAtDesc(String guestUuid); +} diff --git a/src/main/java/com/moongeul/backend/api/member/service/ReadingTasteService.java b/src/main/java/com/moongeul/backend/api/readingTaste/service/ReadingTasteService.java similarity index 81% rename from src/main/java/com/moongeul/backend/api/member/service/ReadingTasteService.java rename to src/main/java/com/moongeul/backend/api/readingTaste/service/ReadingTasteService.java index 35057b0..beb903d 100644 --- a/src/main/java/com/moongeul/backend/api/member/service/ReadingTasteService.java +++ b/src/main/java/com/moongeul/backend/api/readingTaste/service/ReadingTasteService.java @@ -1,10 +1,13 @@ -package com.moongeul.backend.api.member.service; +package com.moongeul.backend.api.readingTaste.service; -import com.moongeul.backend.api.member.dto.TestRequestDTO; -import com.moongeul.backend.api.member.dto.TestResponseDTO; +import com.moongeul.backend.api.readingTaste.dto.TestRequestDTO; +import com.moongeul.backend.api.readingTaste.dto.TestResponseDTO; import com.moongeul.backend.api.member.entity.Member; -import com.moongeul.backend.api.member.entity.ReadingTasteType; +import com.moongeul.backend.api.readingTaste.dto.TestStatisticsResponseDTO; +import com.moongeul.backend.api.readingTaste.entity.ReadingTasteType; import com.moongeul.backend.api.member.repository.MemberRepository; +import com.moongeul.backend.api.readingTaste.entity.TestResult; +import com.moongeul.backend.api.readingTaste.repository.TestResultRepository; import com.moongeul.backend.common.exception.BadRequestException; import com.moongeul.backend.common.exception.NotFoundException; import com.moongeul.backend.common.response.ErrorStatus; @@ -22,6 +25,7 @@ public class ReadingTasteService { private final MemberRepository memberRepository; + private final TestResultRepository testResultRepository; private static final String ANSWER_A = "A"; private static final String ANSWER_B = "B"; @@ -32,16 +36,22 @@ public TestResponseDTO calculateReadingTasteType(TestRequestDTO testRequestDTO, // 테스트 결과 계산 (가장 높은 유형 반환) ReadingTasteType type = findTopType(calculateScore(testRequestDTO.getAnswers())); + // 로그 엔티티 생성 + TestResult testLog = TestResult.builder() + .guestUuid(testRequestDTO.getGuestUuid()) + .readingTasteType(type) + .build(); + // 회원이라면 취향테스트 결과 DB 저장 if(!email.equals("anonymousUser")){ - Member member = memberRepository.findByEmail(email) - .orElseThrow(() -> new NotFoundException(ErrorStatus.USER_NOTFOUND_EXCEPTION.getMessage())); + Member member = getMemberByEmail(email); - // member 필드 readingTasteType 저장 - member.updateReadingTasteType(type); - memberRepository.save(member); + member.updateReadingTasteType(type); // Member 테이블 업데이트 + testLog.updateMemberId(member.getId()); // TestResult 로그에 member_id 연결 } + testResultRepository.save(testLog); + return TestResponseDTO.builder() .readingTasteType(type.getName()) .intro(type.getIntro()) @@ -236,4 +246,41 @@ private ReadingTasteType findTopType(Map typeScores){ return topType; } + + /* + * 전체 참여자 수 반환 API + */ + public TestStatisticsResponseDTO getTotalParticipantsCount() { + long count = testResultRepository.count(); // DB의 전체 레코드 개수 조회 + + return TestStatisticsResponseDTO.builder() + .totalParticipants(count) + .build(); + } + + /* + * 비회원 독서 취향 테스트 결과 조회 및 로그인 연동 API + */ + @Transactional + public void linkTestResult(String guestUuid, String email) { + + Member member = getMemberByEmail(email); + + // 가장 최신 테스트 결과 조회 + TestResult lastTestResult = testResultRepository.findFirstByGuestUuidOrderByCreatedAtDesc(guestUuid) + .orElseThrow(() -> new NotFoundException(ErrorStatus.READING_TASTE_TEST_RESULT_NOTFOUND_EXCEPTION.getMessage())); + + // 테스트 결과가 있다면 -> memberId 회원 연결 + Member 테이블 독서 취향 업데이트 반영 + lastTestResult.updateMemberId(member.getId()); + member.updateReadingTasteType(lastTestResult.getReadingTasteType()); + } + + /* + * 단순 데이터 불러오기용 코드 메서드 - 코드 깔끔하게 하기용 + */ + + private Member getMemberByEmail(String email) { + return memberRepository.findByEmail(email) + .orElseThrow(() -> new NotFoundException(ErrorStatus.USER_NOTFOUND_EXCEPTION.getMessage())); + } } diff --git a/src/main/java/com/moongeul/backend/common/config/security/SecurityConfig.java b/src/main/java/com/moongeul/backend/common/config/security/SecurityConfig.java index 097cb75..de42056 100644 --- a/src/main/java/com/moongeul/backend/common/config/security/SecurityConfig.java +++ b/src/main/java/com/moongeul/backend/common/config/security/SecurityConfig.java @@ -35,7 +35,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers("/", "/h2-console/**").permitAll() .requestMatchers("/static/**", "/index.html", "/firebase-messaging-sw.js", "/favicon.ico").permitAll() .requestMatchers("/v3/api-docs/**", "/api-doc/**", "/swagger-ui/**").permitAll() - .requestMatchers("/api/v2/member/google/login", "/api/v2/member/kakao/login", "/api/v2/member/reissue-token", "/api/v2/reading-taste").permitAll() + .requestMatchers("/api/v2/member/google/login", "/api/v2/member/kakao/login", "/api/v2/member/reissue-token").permitAll() + .requestMatchers("/api/v2/reading-taste", "/api/v2/reading-taste/total-count").permitAll() .requestMatchers(HttpMethod.GET, "/api/v2/post/**").permitAll() .anyRequest().authenticated() ); diff --git a/src/main/java/com/moongeul/backend/common/response/ErrorStatus.java b/src/main/java/com/moongeul/backend/common/response/ErrorStatus.java index 1882d66..1ddbc79 100644 --- a/src/main/java/com/moongeul/backend/common/response/ErrorStatus.java +++ b/src/main/java/com/moongeul/backend/common/response/ErrorStatus.java @@ -54,6 +54,7 @@ public enum ErrorStatus { ANSWER_NOTFOUND_EXCEPTION(HttpStatus.NOT_FOUND, "해당 답변을 찾을 수 없습니다."), TERMS_NOTFOUND_EXCEPTION(HttpStatus.NOT_FOUND, "약관 정보를 찾을 수 없습니다."), NOTIFICATION_NOTFOUND_EXCEPTION(HttpStatus.NOT_FOUND, "해당 알림을 찾을 수 없습니다."), + READING_TASTE_TEST_RESULT_NOTFOUND_EXCEPTION(HttpStatus.NOT_FOUND, "해당 UUID에 해당하는 독서 취향 테스트 결과가 없습니다."), /** * 400 BAD_REQUEST diff --git a/src/main/java/com/moongeul/backend/common/response/SuccessStatus.java b/src/main/java/com/moongeul/backend/common/response/SuccessStatus.java index 1640e4c..15b8dc3 100644 --- a/src/main/java/com/moongeul/backend/common/response/SuccessStatus.java +++ b/src/main/java/com/moongeul/backend/common/response/SuccessStatus.java @@ -19,7 +19,6 @@ public enum SuccessStatus { GET_USERINFO_SUCCESS(HttpStatus.OK, "사용자 정보 조회 성공"), GET_POST_STATS_SUCCESS(HttpStatus.OK, "기록 통계 조회 성공"), REISSUE_TOKEN_SUCCESS(HttpStatus.OK, "토큰 재발급 성공"), - CALCULATE_READING_TASTE_SUCCESS(HttpStatus.OK, "독서 취향 테스트 결과 계산 성공"), FOLLOW_SUCCESS(HttpStatus.OK, "팔로우 성공"), UNFOLLOW_SUCCESS(HttpStatus.OK, "언팔로우 성공"), GET_FOLLOWING_SUCCESS(HttpStatus.OK, "팔로잉 목록 조회 성공"), @@ -33,6 +32,11 @@ public enum SuccessStatus { UPDATE_PRIVACY_LEVEL_SUCCESS(HttpStatus.OK, "계정 공개 범위 수정 성공"), TERMS_AGREE_SUCCESS(HttpStatus.OK, "약관 동의 성공"), + /* READING TASTE */ + CALCULATE_READING_TASTE_SUCCESS(HttpStatus.OK, "독서 취향 테스트 결과 계산 성공"), + GET_READING_TASTE_PARTICIPANTS_SUCCESS(HttpStatus.OK, "독서 취향 테스트 참여자 수 반환 성공"), + LINK_READING_TASTE_SUCCESS(HttpStatus.OK, "독서 취향 테스트 연동 성공"), + /* BOOK */ SEARCH_BOOK_SUCCESS(HttpStatus.OK, "도서 검색 성공"), GET_BOOK_DETAIL_SUCCESS(HttpStatus.OK, "도서 상세 조회 성공"),