From 78c37017be977a080f6fa593b72d74e223fb9dfd Mon Sep 17 00:00:00 2001 From: Jeongmo Seo Date: Thu, 31 Jul 2025 16:39:13 +0900 Subject: [PATCH 1/5] =?UTF-8?q?:sparkles:=20feat:=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20=EC=B7=A8=ED=96=A5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/DatePreferenceDescription.java | 32 ++++++++++++++ .../DatePreferenceDescriptionKeyword.java | 25 +++++++++++ .../entity/DatePreferenceKeyword.java | 22 ++++++++++ .../entity/DatePreferencePartDescription.java | 32 ++++++++++++++ .../entity/DatePreferenceQuestion.java | 27 ++++++++++++ .../entity/DatePreferenceTestResult.java | 42 +++++++++++++++++++ .../entity/enums/PreferencePartType.java | 8 ++++ .../entity/enums/PreferenceType.java | 20 +++++++++ 8 files changed, 208 insertions(+) create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescription.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescriptionKeyword.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceKeyword.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferencePartDescription.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceQuestion.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceTestResult.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/enums/PreferencePartType.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/enums/PreferenceType.java diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescription.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescription.java new file mode 100644 index 0000000..a695fba --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescription.java @@ -0,0 +1,32 @@ +package org.withtime.be.withtimebe.domain.date.preference.entity; + +import jakarta.persistence.*; +import lombok.*; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferenceType; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Table(name = "date_preference_description") +public class DatePreferenceDescription { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "date_preference_description_id") + private Long id; + + @Column(name = "symbolic_animal") + private String symbolicAnimal; + + @Enumerated(EnumType.STRING) + @Column(name = "preference_type", unique = true) + private PreferenceType preferenceType; + + @Column(name = "simple_description") + private String simpleDescription; + + @Column(name = "analysis", columnDefinition = "TEXT") + private String analysis; +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescriptionKeyword.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescriptionKeyword.java new file mode 100644 index 0000000..7d0ad6c --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescriptionKeyword.java @@ -0,0 +1,25 @@ +package org.withtime.be.withtimebe.domain.date.preference.entity; + +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Table(name = "date_preference_description_keyword") +public class DatePreferenceDescriptionKeyword { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "date_preference_description") + private DatePreferenceDescription datePreferenceDescription; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "date_preference_keyword") + private DatePreferenceKeyword datePreferenceKeyword; +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceKeyword.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceKeyword.java new file mode 100644 index 0000000..9908f9e --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceKeyword.java @@ -0,0 +1,22 @@ +package org.withtime.be.withtimebe.domain.date.preference.entity; + +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Table(name = "date_preference_keyword") +public class DatePreferenceKeyword { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "date_preference_keyword_id") + private Long id; + + @Column(name = "keyword") + private String keyword; + +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferencePartDescription.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferencePartDescription.java new file mode 100644 index 0000000..e412133 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferencePartDescription.java @@ -0,0 +1,32 @@ +package org.withtime.be.withtimebe.domain.date.preference.entity; + +import jakarta.persistence.*; +import lombok.*; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferencePartType; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Table(name = "date_preference_part_description") +public class DatePreferencePartDescription { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "date_preference_description_id") + private Long id; + + @Enumerated(EnumType.STRING) + @Column(name = "preference_part_type", unique = true) + private PreferencePartType preferencePartType; + + @Column(name = "type_eng") + private String typeEng; + + @Column(name = "type") + private String type; + + @Column(name = "description") + private String description; +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceQuestion.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceQuestion.java new file mode 100644 index 0000000..8fc00a8 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceQuestion.java @@ -0,0 +1,27 @@ +package org.withtime.be.withtimebe.domain.date.preference.entity; + +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Table(name = "date_preference_question") +public class DatePreferenceQuestion { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "date_preference_question") + private Long id; + + @Column(name = "question") + private String question; + + @Column(name = "first_answer") + private String firstAnswer; + + @Column(name = "second_answer") + private String secondAnswer; +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceTestResult.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceTestResult.java new file mode 100644 index 0000000..814096e --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceTestResult.java @@ -0,0 +1,42 @@ +package org.withtime.be.withtimebe.domain.date.preference.entity; + +import jakarta.persistence.*; +import lombok.*; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferenceType; +import org.withtime.be.withtimebe.domain.member.entity.Member; +import org.withtime.be.withtimebe.global.common.BaseEntity; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Table(name = "date_preference_test_result") +public class DatePreferenceTestResult extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "date_preference_test_result_id") + private Long id; + + @Enumerated(EnumType.STRING) + @Column(name = "preferencePartType") + private PreferenceType preferenceType; + + @Column(name = "a_percentage") + private Double aPercentage; + + @Column(name = "b_percentage") + private Double bPercentage; + + @Column(name = "c_percentage") + private Double cPercentage; + + @Column(name = "d_percentage") + private Double dPercentage; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/enums/PreferencePartType.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/enums/PreferencePartType.java new file mode 100644 index 0000000..d752eaa --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/enums/PreferencePartType.java @@ -0,0 +1,8 @@ +package org.withtime.be.withtimebe.domain.date.preference.entity.enums; + +public enum PreferencePartType { + S,F, + A,C, + M,P, + O,E +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/enums/PreferenceType.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/enums/PreferenceType.java new file mode 100644 index 0000000..50c92dc --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/enums/PreferenceType.java @@ -0,0 +1,20 @@ +package org.withtime.be.withtimebe.domain.date.preference.entity.enums; + +public enum PreferenceType { + SAME, + SAMO, + SAPE, + SAPO, + SCME, + SCMO, + SCPE, + SCPO, + FAME, + FAMO, + FAPE, + FAPO, + FCME, + FCMO, + FCPE, + FCPO +} From 82a6872288b60ff616cae18ebb30b28fca1aa3c9 Mon Sep 17 00:00:00 2001 From: Jeongmo Seo Date: Fri, 1 Aug 2025 15:21:54 +0900 Subject: [PATCH 2/5] =?UTF-8?q?:bug:=20fix:=20=EC=97=94=ED=8B=B0=ED=8B=B0?= =?UTF-8?q?=20Column=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../preference/entity/DatePreferenceDescriptionKeyword.java | 1 + .../date/preference/entity/DatePreferencePartDescription.java | 2 +- .../domain/date/preference/entity/DatePreferenceQuestion.java | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescriptionKeyword.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescriptionKeyword.java index 7d0ad6c..69e5c24 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescriptionKeyword.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceDescriptionKeyword.java @@ -13,6 +13,7 @@ public class DatePreferenceDescriptionKeyword { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "date_preference_description_keyword_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferencePartDescription.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferencePartDescription.java index e412133..02d0590 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferencePartDescription.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferencePartDescription.java @@ -14,7 +14,7 @@ public class DatePreferencePartDescription { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "date_preference_description_id") + @Column(name = "date_preference_part_description_id") private Long id; @Enumerated(EnumType.STRING) diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceQuestion.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceQuestion.java index 8fc00a8..0c7e0be 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceQuestion.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceQuestion.java @@ -13,7 +13,7 @@ public class DatePreferenceQuestion { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "date_preference_question") + @Column(name = "date_preference_question_id") private Long id; @Column(name = "question") From 0caa15a96b4f455619325213dd50331dda847176 Mon Sep 17 00:00:00 2001 From: Jeongmo Seo Date: Fri, 1 Aug 2025 15:22:46 +0900 Subject: [PATCH 3/5] =?UTF-8?q?:sparkles:=20feat:=20Repository=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=B0=8F=20=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=B7=A8?= =?UTF-8?q?=ED=96=A5=20=EC=9C=A0=ED=98=95=EA=B3=BC=20=EC=A7=88=EB=AC=B8=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/DatePreferenceController.java | 38 ++++++++++++++++ .../converter/DatePreferenceConverter.java | 39 ++++++++++++++++ .../dto/DatePreferenceResponseDTO.java | 45 +++++++++++++++++++ ...referenceDescriptionKeywordRepository.java | 7 +++ .../DatePreferenceDescriptionRepository.java | 7 +++ .../DatePreferenceKeywordRepository.java | 7 +++ ...tePreferencePartDescriptionRepository.java | 7 +++ .../DatePreferenceQuestionRepository.java | 10 +++++ .../DatePreferenceTestResultRepository.java | 7 +++ ...JpaDatePreferenceTestResultRepository.java | 7 +++ ...DatePreferenceDescriptionQueryService.java | 11 +++++ ...PreferenceDescriptionQueryServiceImpl.java | 21 +++++++++ .../DatePreferenceQuestionQueryService.java | 9 ++++ ...atePreferenceQuestionQueryServiceImpl.java | 20 +++++++++ 14 files changed, 235 insertions(+) create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/converter/DatePreferenceConverter.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceResponseDTO.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionKeywordRepository.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionRepository.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceKeywordRepository.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferencePartDescriptionRepository.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceQuestionRepository.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceTestResultRepository.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/JpaDatePreferenceTestResultRepository.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceDescriptionQueryService.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceDescriptionQueryServiceImpl.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceQuestionQueryService.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceQuestionQueryServiceImpl.java diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java new file mode 100644 index 0000000..213520a --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java @@ -0,0 +1,38 @@ +package org.withtime.be.withtimebe.domain.date.preference.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.namul.api.payload.response.DefaultResponse; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.withtime.be.withtimebe.domain.date.preference.converter.DatePreferenceConverter; +import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceResponseDTO; +import org.withtime.be.withtimebe.domain.date.preference.service.query.DatePreferenceDescriptionQueryService; +import org.withtime.be.withtimebe.domain.date.preference.service.query.DatePreferenceQuestionQueryService; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/dates/preferences") +@Tag(name = "데이트 취향 테스트 API") +public class DatePreferenceController { + + private final DatePreferenceDescriptionQueryService datePreferenceDescriptionQueryService; + private final DatePreferenceQuestionQueryService datePreferenceQuestionQueryService; + + @Operation(summary = "데이트 취향 조회 API", description = "데이트 취향 종류 조회") + @ApiResponse(responseCode = "COMMON200", description = "성공적으로 정보를 가져왔습니다.") + @GetMapping + public DefaultResponse findTypes() { + return DefaultResponse.ok(DatePreferenceConverter.toFindTypes(datePreferenceDescriptionQueryService.findTypes())); + } + + @Operation(summary = "데이트 취향 테스트 질문 조회 API", description = "데이트 취향 테스트에 사용되는 질문 조회하는 API") + @ApiResponse(responseCode = "COMMON200", description = "성공적으로 정보를 가져왔습니다.") + @GetMapping("/questions") + public DefaultResponse findQuestions() { + return DefaultResponse.ok(DatePreferenceConverter.toFindQuestions(datePreferenceQuestionQueryService.findQuestions())); + } +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/converter/DatePreferenceConverter.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/converter/DatePreferenceConverter.java new file mode 100644 index 0000000..b4782b0 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/converter/DatePreferenceConverter.java @@ -0,0 +1,39 @@ +package org.withtime.be.withtimebe.domain.date.preference.converter; + +import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceResponseDTO; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceDescription; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceQuestion; + +import java.util.List; + +public class DatePreferenceConverter { + public static DatePreferenceResponseDTO.FindTypes toFindTypes(List datePreferenceDescriptions) { + return DatePreferenceResponseDTO.FindTypes.builder() + .types(datePreferenceDescriptions.stream().map(DatePreferenceConverter::toFindType).toList()) + .size(datePreferenceDescriptions.size()) + .build(); + } + + public static DatePreferenceResponseDTO.FindType toFindType(DatePreferenceDescription datePreferenceDescription) { + return DatePreferenceResponseDTO.FindType.builder() + .symbolicAnimal(datePreferenceDescription.getSymbolicAnimal()) + .preferenceType(datePreferenceDescription.getPreferenceType()) + .simpleDescription(datePreferenceDescription.getSimpleDescription()) + .build(); + } + + public static DatePreferenceResponseDTO.FindQuestions toFindQuestions(List datePreferenceQuestions) { + return DatePreferenceResponseDTO.FindQuestions.builder() + .questions(datePreferenceQuestions.stream().map(DatePreferenceConverter::toFindQuestion).toList()) + .size(datePreferenceQuestions.size()) + .build(); + } + + public static DatePreferenceResponseDTO.FindQuestion toFindQuestion(DatePreferenceQuestion datePreferenceQuestion) { + return DatePreferenceResponseDTO.FindQuestion.builder() + .question(datePreferenceQuestion.getQuestion()) + .firstAnswer(datePreferenceQuestion.getFirstAnswer()) + .secondAnswer(datePreferenceQuestion.getSecondAnswer()) + .build(); + } +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceResponseDTO.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceResponseDTO.java new file mode 100644 index 0000000..3de832b --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceResponseDTO.java @@ -0,0 +1,45 @@ +package org.withtime.be.withtimebe.domain.date.preference.dto; + +import lombok.Builder; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferenceType; + +import java.util.List; + +public record DatePreferenceResponseDTO() { + + @Builder + public record FindTypes( + List types, + Integer size + ) { + + } + + @Builder + public record FindType( + String symbolicAnimal, + PreferenceType preferenceType, + String simpleDescription + ) { + + } + + @Builder + public record FindQuestions( + List questions, + Integer size + ) { + + } + + @Builder + public record FindQuestion( + String question, + String firstAnswer, + String secondAnswer + ) { + + } + + +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionKeywordRepository.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionKeywordRepository.java new file mode 100644 index 0000000..54a4b82 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionKeywordRepository.java @@ -0,0 +1,7 @@ +package org.withtime.be.withtimebe.domain.date.preference.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceDescriptionKeyword; + +public interface DatePreferenceDescriptionKeywordRepository extends JpaRepository { +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionRepository.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionRepository.java new file mode 100644 index 0000000..a56f2a9 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionRepository.java @@ -0,0 +1,7 @@ +package org.withtime.be.withtimebe.domain.date.preference.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceDescription; + +public interface DatePreferenceDescriptionRepository extends JpaRepository { +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceKeywordRepository.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceKeywordRepository.java new file mode 100644 index 0000000..aebb932 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceKeywordRepository.java @@ -0,0 +1,7 @@ +package org.withtime.be.withtimebe.domain.date.preference.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceKeyword; + +public interface DatePreferenceKeywordRepository extends JpaRepository { +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferencePartDescriptionRepository.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferencePartDescriptionRepository.java new file mode 100644 index 0000000..dca2a23 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferencePartDescriptionRepository.java @@ -0,0 +1,7 @@ +package org.withtime.be.withtimebe.domain.date.preference.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferencePartDescription; + +public interface DatePreferencePartDescriptionRepository extends JpaRepository { +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceQuestionRepository.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceQuestionRepository.java new file mode 100644 index 0000000..b77ea19 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceQuestionRepository.java @@ -0,0 +1,10 @@ +package org.withtime.be.withtimebe.domain.date.preference.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceQuestion; + +import java.util.List; + +public interface DatePreferenceQuestionRepository extends JpaRepository { + List findAllByOrderByIdAsc(); +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceTestResultRepository.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceTestResultRepository.java new file mode 100644 index 0000000..d614183 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceTestResultRepository.java @@ -0,0 +1,7 @@ +package org.withtime.be.withtimebe.domain.date.preference.repository; + +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceTestResult; + +public interface DatePreferenceTestResultRepository { + DatePreferenceTestResult save(DatePreferenceTestResult datePreferenceTestResult); +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/JpaDatePreferenceTestResultRepository.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/JpaDatePreferenceTestResultRepository.java new file mode 100644 index 0000000..842e374 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/JpaDatePreferenceTestResultRepository.java @@ -0,0 +1,7 @@ +package org.withtime.be.withtimebe.domain.date.preference.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceTestResult; + +public interface JpaDatePreferenceTestResultRepository extends DatePreferenceTestResultRepository, JpaRepository { +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceDescriptionQueryService.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceDescriptionQueryService.java new file mode 100644 index 0000000..c953712 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceDescriptionQueryService.java @@ -0,0 +1,11 @@ +package org.withtime.be.withtimebe.domain.date.preference.service.query; + +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceDescription; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceQuestion; + +import java.util.List; + +public interface DatePreferenceDescriptionQueryService { + + List findTypes(); +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceDescriptionQueryServiceImpl.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceDescriptionQueryServiceImpl.java new file mode 100644 index 0000000..b88923f --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceDescriptionQueryServiceImpl.java @@ -0,0 +1,21 @@ +package org.withtime.be.withtimebe.domain.date.preference.service.query; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceDescription; +import org.withtime.be.withtimebe.domain.date.preference.repository.DatePreferenceDescriptionRepository; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class DatePreferenceDescriptionQueryServiceImpl implements DatePreferenceDescriptionQueryService { + + private final DatePreferenceDescriptionRepository datePreferenceDescriptionRepository; + + @Override + public List findTypes() { + return datePreferenceDescriptionRepository.findAll(); + } + +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceQuestionQueryService.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceQuestionQueryService.java new file mode 100644 index 0000000..6d972b4 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceQuestionQueryService.java @@ -0,0 +1,9 @@ +package org.withtime.be.withtimebe.domain.date.preference.service.query; + +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceQuestion; + +import java.util.List; + +public interface DatePreferenceQuestionQueryService { + List findQuestions(); +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceQuestionQueryServiceImpl.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceQuestionQueryServiceImpl.java new file mode 100644 index 0000000..dae072d --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/query/DatePreferenceQuestionQueryServiceImpl.java @@ -0,0 +1,20 @@ +package org.withtime.be.withtimebe.domain.date.preference.service.query; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceQuestion; +import org.withtime.be.withtimebe.domain.date.preference.repository.DatePreferenceQuestionRepository; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class DatePreferenceQuestionQueryServiceImpl implements DatePreferenceQuestionQueryService { + + private final DatePreferenceQuestionRepository datePreferenceQuestionRepository; + + @Override + public List findQuestions() { + return datePreferenceQuestionRepository.findAllByOrderByIdAsc(); + } +} From 5eacdb1cdd9c771e2d0324e790d0b1c75ea2abab Mon Sep 17 00:00:00 2001 From: Jeongmo Seo Date: Sat, 2 Aug 2025 14:27:59 +0900 Subject: [PATCH 4/5] =?UTF-8?q?:sparkles:=20feat:=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20=EC=B7=A8=ED=96=A5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EB=B0=8F=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/DatePreferenceController.java | 16 ++++- .../converter/DatePreferenceConverter.java | 56 +++++++++++++++ .../dto/DatePreferenceRequestDTO.java | 24 +++++++ .../dto/DatePreferenceResponseDTO.java | 41 +++++++++++ .../entity/DatePreferenceTestResult.java | 4 ++ .../DatePreferenceDescriptionRepository.java | 4 ++ ...tePreferencePartDescriptionRepository.java | 4 ++ .../DatePreferenceTestCommandService.java | 9 +++ .../DatePreferenceTestCommandServiceImpl.java | 70 +++++++++++++++++++ .../DatePreferenceTestScoreCalculator.java | 8 +++ .../util/WeightBaseTestScoreCalculator.java | 67 ++++++++++++++++++ .../error/code/DatePreferenceErrorCode.java | 25 +++++++ .../exception/DatePreferenceException.java | 11 +++ 13 files changed, 336 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceRequestDTO.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/command/DatePreferenceTestCommandService.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/command/DatePreferenceTestCommandServiceImpl.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/util/DatePreferenceTestScoreCalculator.java create mode 100644 src/main/java/org/withtime/be/withtimebe/domain/date/preference/util/WeightBaseTestScoreCalculator.java create mode 100644 src/main/java/org/withtime/be/withtimebe/global/error/code/DatePreferenceErrorCode.java create mode 100644 src/main/java/org/withtime/be/withtimebe/global/error/exception/DatePreferenceException.java diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java index 213520a..d95478f 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java @@ -5,13 +5,15 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.namul.api.payload.response.DefaultResponse; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.withtime.be.withtimebe.domain.date.preference.converter.DatePreferenceConverter; +import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceRequestDTO; import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceResponseDTO; +import org.withtime.be.withtimebe.domain.date.preference.service.command.DatePreferenceTestCommandService; import org.withtime.be.withtimebe.domain.date.preference.service.query.DatePreferenceDescriptionQueryService; import org.withtime.be.withtimebe.domain.date.preference.service.query.DatePreferenceQuestionQueryService; +import org.withtime.be.withtimebe.domain.member.entity.Member; +import org.withtime.be.withtimebe.global.security.annotation.AuthenticatedMember; @RestController @RequiredArgsConstructor @@ -19,6 +21,7 @@ @Tag(name = "데이트 취향 테스트 API") public class DatePreferenceController { + private final DatePreferenceTestCommandService datePreferenceTestCommandService; private final DatePreferenceDescriptionQueryService datePreferenceDescriptionQueryService; private final DatePreferenceQuestionQueryService datePreferenceQuestionQueryService; @@ -35,4 +38,11 @@ public DefaultResponse findTypes() { public DefaultResponse findQuestions() { return DefaultResponse.ok(DatePreferenceConverter.toFindQuestions(datePreferenceQuestionQueryService.findQuestions())); } + + @Operation(summary = "데이트 취향 테스트 API", description = "질문에 대한 답변으로 결과 생성하는 API 1, 2 둘 중 하나로 40개로 채워 배열 형태로 전송") + @PostMapping("/tests") + public DefaultResponse test(@AuthenticatedMember Member member, @RequestBody DatePreferenceRequestDTO.Test request) { + return DefaultResponse.ok(datePreferenceTestCommandService.test(member, request)); + } + } diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/converter/DatePreferenceConverter.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/converter/DatePreferenceConverter.java index b4782b0..27e87e7 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/converter/DatePreferenceConverter.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/converter/DatePreferenceConverter.java @@ -2,7 +2,10 @@ import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceResponseDTO; import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceDescription; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferencePartDescription; import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceQuestion; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceTestResult; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferenceType; import java.util.List; @@ -36,4 +39,57 @@ public static DatePreferenceResponseDTO.FindQuestion toFindQuestion(DatePreferen .secondAnswer(datePreferenceQuestion.getSecondAnswer()) .build(); } + + public static DatePreferenceResponseDTO.TestResult toTestResult(DatePreferenceTestResult datePreferenceTestResult, + DatePreferenceDescription datePreferenceDescription, + List datePreferencePartDescriptions) { + return DatePreferenceResponseDTO.TestResult.builder() + .preferenceType(datePreferenceTestResult.getPreferenceType()) + .aPercentage(datePreferenceTestResult.getAPercentage()) + .bPercentage(datePreferenceTestResult.getBPercentage()) + .cPercentage(datePreferenceTestResult.getCPercentage()) + .dPercentage(datePreferenceTestResult.getDPercentage()) + .typeDescription(datePreferenceDescription == null ? null : DatePreferenceConverter.toTypeDescription(datePreferenceDescription)) + .partTypeDescriptions(datePreferencePartDescriptions == null || datePreferencePartDescriptions.isEmpty() ? null : DatePreferenceConverter.toPartTypeDescriptions(datePreferencePartDescriptions)) + .build(); + } + + public static DatePreferenceTestResult toDatePreferenceTestResult(PreferenceType preferenceType, + Double aPercentage, + Double bPercentage, + Double cPercentage, + Double dPercentage) { + return DatePreferenceTestResult.builder() + .preferenceType(preferenceType) + .aPercentage(aPercentage) + .bPercentage(bPercentage) + .cPercentage(cPercentage) + .dPercentage(dPercentage) + .build(); + } + + public static DatePreferenceResponseDTO.TypeDescription toTypeDescription(DatePreferenceDescription datePreferenceDescription) { + return DatePreferenceResponseDTO.TypeDescription.builder() + .symbolicAnimal(datePreferenceDescription.getSymbolicAnimal()) + .preferenceType(datePreferenceDescription.getPreferenceType()) + .simpleDescription(datePreferenceDescription.getSimpleDescription()) + .analysis(datePreferenceDescription.getAnalysis()) + .build(); + } + + public static DatePreferenceResponseDTO.PartTypeDescriptions toPartTypeDescriptions(List descriptions) { + return DatePreferenceResponseDTO.PartTypeDescriptions.builder() + .types(descriptions.stream().map(DatePreferenceConverter::toPartTypeDescription).toList()) + .size(descriptions.size()) + .build(); + } + + public static DatePreferenceResponseDTO.PartTypeDescription toPartTypeDescription(DatePreferencePartDescription description) { + return DatePreferenceResponseDTO.PartTypeDescription.builder() + .typeInitial(description.getPreferencePartType()) + .type(description.getType()) + .typeEng(description.getTypeEng()) + .description(description.getDescription()) + .build(); + } } diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceRequestDTO.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceRequestDTO.java new file mode 100644 index 0000000..fff5b58 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceRequestDTO.java @@ -0,0 +1,24 @@ +package org.withtime.be.withtimebe.domain.date.preference.dto; + +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.List; + +public record DatePreferenceRequestDTO() { + public record Test( + @Schema( + description = "1 또는 2 중 하나의 값으로 이루어진 40개의 답변", + example = """ + [ + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2 + ] + """ + ) + List answers + ) { + + } +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceResponseDTO.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceResponseDTO.java index 3de832b..ab12ee4 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceResponseDTO.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/dto/DatePreferenceResponseDTO.java @@ -1,6 +1,7 @@ package org.withtime.be.withtimebe.domain.date.preference.dto; import lombok.Builder; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferencePartType; import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferenceType; import java.util.List; @@ -41,5 +42,45 @@ public record FindQuestion( } + @Builder + public record TestResult( + PreferenceType preferenceType, + Double aPercentage, + Double bPercentage, + Double cPercentage, + Double dPercentage, + TypeDescription typeDescription, + PartTypeDescriptions partTypeDescriptions + ) { + + } + + @Builder + public record TypeDescription( + String symbolicAnimal, + PreferenceType preferenceType, + String simpleDescription, + String analysis + ) { + + } + + @Builder + public record PartTypeDescriptions( + List types, + Integer size + ) { + + } + + @Builder + public record PartTypeDescription( + PreferencePartType typeInitial, + String typeEng, + String type, + String description + ) { + + } } diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceTestResult.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceTestResult.java index 814096e..40e243f 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceTestResult.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/entity/DatePreferenceTestResult.java @@ -39,4 +39,8 @@ public class DatePreferenceTestResult extends BaseEntity { @JoinColumn(name = "member_id") private Member member; + public void mappingMember(Member member) { + this.member = member; + } + } diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionRepository.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionRepository.java index a56f2a9..ec490d2 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionRepository.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferenceDescriptionRepository.java @@ -2,6 +2,10 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceDescription; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferenceType; + +import java.util.Optional; public interface DatePreferenceDescriptionRepository extends JpaRepository { + Optional findByPreferenceType(PreferenceType preferenceType); } diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferencePartDescriptionRepository.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferencePartDescriptionRepository.java index dca2a23..7c567d3 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferencePartDescriptionRepository.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/repository/DatePreferencePartDescriptionRepository.java @@ -2,6 +2,10 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferencePartDescription; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferencePartType; + +import java.util.Optional; public interface DatePreferencePartDescriptionRepository extends JpaRepository { + Optional findByPreferencePartType(PreferencePartType preferencePartType); } diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/command/DatePreferenceTestCommandService.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/command/DatePreferenceTestCommandService.java new file mode 100644 index 0000000..9b9bb42 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/command/DatePreferenceTestCommandService.java @@ -0,0 +1,9 @@ +package org.withtime.be.withtimebe.domain.date.preference.service.command; + +import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceRequestDTO; +import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceResponseDTO; +import org.withtime.be.withtimebe.domain.member.entity.Member; + +public interface DatePreferenceTestCommandService { + DatePreferenceResponseDTO.TestResult test(Member member, DatePreferenceRequestDTO.Test request); +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/command/DatePreferenceTestCommandServiceImpl.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/command/DatePreferenceTestCommandServiceImpl.java new file mode 100644 index 0000000..15609e0 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/service/command/DatePreferenceTestCommandServiceImpl.java @@ -0,0 +1,70 @@ +package org.withtime.be.withtimebe.domain.date.preference.service.command; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.withtime.be.withtimebe.domain.date.preference.converter.DatePreferenceConverter; +import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceRequestDTO; +import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceResponseDTO; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferencePartDescription; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceTestResult; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferencePartType; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferenceType; +import org.withtime.be.withtimebe.domain.date.preference.repository.DatePreferenceDescriptionRepository; +import org.withtime.be.withtimebe.domain.date.preference.repository.DatePreferencePartDescriptionRepository; +import org.withtime.be.withtimebe.domain.date.preference.repository.DatePreferenceQuestionRepository; +import org.withtime.be.withtimebe.domain.date.preference.repository.DatePreferenceTestResultRepository; +import org.withtime.be.withtimebe.domain.date.preference.util.DatePreferenceTestScoreCalculator; +import org.withtime.be.withtimebe.domain.member.entity.Member; +import org.withtime.be.withtimebe.global.error.code.DatePreferenceErrorCode; +import org.withtime.be.withtimebe.global.error.exception.DatePreferenceException; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class DatePreferenceTestCommandServiceImpl implements DatePreferenceTestCommandService { + + private final DatePreferenceDescriptionRepository datePreferenceDescriptionRepository; + private final DatePreferencePartDescriptionRepository datePreferencePartDescriptionRepository; + private final DatePreferenceTestResultRepository datePreferenceTestResultRepository; + private final DatePreferenceQuestionRepository datePreferenceQuestionRepository; + private final DatePreferenceTestScoreCalculator datePreferenceTestScoreCalculator; + + @Override + public DatePreferenceResponseDTO.TestResult test(Member member, DatePreferenceRequestDTO.Test request) { + // valid 판단 + if (!validateRequest(request)) { + throw new DatePreferenceException(DatePreferenceErrorCode.INVALID_ANSWERS); + } + + // 점수 계산 + DatePreferenceTestResult result = datePreferenceTestScoreCalculator.calculateTestScore(request); + result.mappingMember(member); + + // 엔티티 저장 (로그) + datePreferenceTestResultRepository.save(result); + + // 응답 생성 + return buildResponse(result); + } + + private boolean validateRequest(DatePreferenceRequestDTO.Test request) { + return datePreferenceQuestionRepository.count() == request.answers().size() && request.answers().stream().allMatch(value -> value >= 1 && value <= 2); + } + + private DatePreferenceResponseDTO.TestResult buildResponse(DatePreferenceTestResult testResult) { + List partDescriptionList = new ArrayList<>(); + PreferenceType preferenceType = testResult.getPreferenceType(); + for (int i = 0; i < 4; i++) { + PreferencePartType preferencePartType = PreferencePartType.valueOf(preferenceType.name().substring(i, i + 1)); + datePreferencePartDescriptionRepository.findByPreferencePartType(preferencePartType).ifPresent(partDescriptionList::add); + } + return DatePreferenceConverter.toTestResult( + testResult, + datePreferenceDescriptionRepository.findByPreferenceType(preferenceType).orElse(null), + partDescriptionList + ); + } +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/util/DatePreferenceTestScoreCalculator.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/util/DatePreferenceTestScoreCalculator.java new file mode 100644 index 0000000..c3ab67f --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/util/DatePreferenceTestScoreCalculator.java @@ -0,0 +1,8 @@ +package org.withtime.be.withtimebe.domain.date.preference.util; + +import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceRequestDTO; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceTestResult; + +public interface DatePreferenceTestScoreCalculator { + DatePreferenceTestResult calculateTestScore(DatePreferenceRequestDTO.Test request); +} diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/util/WeightBaseTestScoreCalculator.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/util/WeightBaseTestScoreCalculator.java new file mode 100644 index 0000000..2e6b496 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/util/WeightBaseTestScoreCalculator.java @@ -0,0 +1,67 @@ +package org.withtime.be.withtimebe.domain.date.preference.util; + +import org.springframework.stereotype.Component; +import org.withtime.be.withtimebe.domain.date.preference.converter.DatePreferenceConverter; +import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceRequestDTO; +import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceTestResult; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferencePartType; +import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferenceType; + +import java.util.List; + +@Component +public class WeightBaseTestScoreCalculator implements DatePreferenceTestScoreCalculator { + + private static final PreferencePartType[][] types = { + {PreferencePartType.S, PreferencePartType.F}, + {PreferencePartType.A, PreferencePartType.C}, + {PreferencePartType.M, PreferencePartType.P}, + {PreferencePartType.E, PreferencePartType.O} + }; + + private static final double[] weights = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + + @Override + public DatePreferenceTestResult calculateTestScore(DatePreferenceRequestDTO.Test request) { + List answers = request.answers(); // 정답 배열 + int number = types.length; // PartType 개수 + int size = answers.size() / number; // PartType 개수 별 정답 개수 + Double[] percentages = new Double[number]; + StringBuilder type = new StringBuilder(); + + // 계산 + for (int i = 0; i < number ; i++) { + type.append(calculatePartType(answers, percentages, i * size, size)); + } + + return DatePreferenceConverter.toDatePreferenceTestResult( + PreferenceType.valueOf(type.toString()), + percentages[0], + percentages[1], + percentages[2], + percentages[3] + ); + } + + private String calculatePartType(List list, Double[] percentages, int start, int size) { + double score = calculateScore(list, start, size); + int index = start / size; + percentages[index] = Math.floor((score - 1) * 1000) / 10; + return score < 1.5 ? types[index][0].name() : types[index][1].name(); + } + + // return value between 1, 2 + private double calculateScore(List list, int start, int size) { + int end = start + size; + double sum = 0.0; + for (int i = start; i < end; i++) { + sum += list.get(i) * weights[i]; + } + return sum / size; + } +} diff --git a/src/main/java/org/withtime/be/withtimebe/global/error/code/DatePreferenceErrorCode.java b/src/main/java/org/withtime/be/withtimebe/global/error/code/DatePreferenceErrorCode.java new file mode 100644 index 0000000..a3209a7 --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/global/error/code/DatePreferenceErrorCode.java @@ -0,0 +1,25 @@ +package org.withtime.be.withtimebe.global.error.code; + +import lombok.AllArgsConstructor; +import org.namul.api.payload.code.BaseErrorCode; +import org.namul.api.payload.code.dto.supports.DefaultResponseErrorReasonDTO; +import org.springframework.http.HttpStatus; + +@AllArgsConstructor +public enum DatePreferenceErrorCode implements BaseErrorCode { + + INVALID_ANSWERS(HttpStatus.BAD_REQUEST, "DATE_PREFERENCE400_1", "질문에 대한 응답의 형식이 잘못되었습니다.") + ; + private final HttpStatus httpStatus; + private final String code; + private final String message; + + @Override + public DefaultResponseErrorReasonDTO getReason() { + return DefaultResponseErrorReasonDTO.builder() + .httpStatus(this.httpStatus) + .code(this.code) + .message(this.message) + .build(); + } +} diff --git a/src/main/java/org/withtime/be/withtimebe/global/error/exception/DatePreferenceException.java b/src/main/java/org/withtime/be/withtimebe/global/error/exception/DatePreferenceException.java new file mode 100644 index 0000000..f72ff6f --- /dev/null +++ b/src/main/java/org/withtime/be/withtimebe/global/error/exception/DatePreferenceException.java @@ -0,0 +1,11 @@ +package org.withtime.be.withtimebe.global.error.exception; + +import org.namul.api.payload.code.BaseErrorCode; +import org.namul.api.payload.error.exception.ServerApplicationException; + +public class DatePreferenceException extends ServerApplicationException { + + public DatePreferenceException(BaseErrorCode code) { + super(code); + } +} From 372ca4a8b0d4f1eead9973ea0adeefcaa7ce7665 Mon Sep 17 00:00:00 2001 From: Jeongmo Seo Date: Sat, 2 Aug 2025 14:30:52 +0900 Subject: [PATCH 5/5] =?UTF-8?q?:memo:=20docs:=20=EC=8A=A4=EC=9B=A8?= =?UTF-8?q?=EA=B1=B0=20=EC=84=A4=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/DatePreferenceController.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java index d95478f..69f0cdf 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/preference/controller/DatePreferenceController.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.namul.api.payload.response.DefaultResponse; @@ -40,6 +41,16 @@ public DefaultResponse findQuestions() } @Operation(summary = "데이트 취향 테스트 API", description = "질문에 대한 답변으로 결과 생성하는 API 1, 2 둘 중 하나로 40개로 채워 배열 형태로 전송") + @ApiResponses({ + @ApiResponse(responseCode = "COMMON200", description = "테스트에 성공했습니다."), + @ApiResponse( + responseCode = "401", + description = """ + 다음과 같은 이유로 실패할 수 있습니다: + - DATE_PREFERENCE400_1: 질문에 대한 형식이 잘못되었습니다. + """ + ), + }) @PostMapping("/tests") public DefaultResponse test(@AuthenticatedMember Member member, @RequestBody DatePreferenceRequestDTO.Test request) { return DefaultResponse.ok(datePreferenceTestCommandService.test(member, request));