Skip to content

Commit f433e68

Browse files
authored
✨ [Feat] 데이트 취향 테스트 API 구현 (#71)
2 parents 7b8b4f9 + 372ca4a commit f433e68

29 files changed

+788
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package org.withtime.be.withtimebe.domain.date.preference.controller;
2+
3+
import io.swagger.v3.oas.annotations.Operation;
4+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
5+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
6+
import io.swagger.v3.oas.annotations.tags.Tag;
7+
import lombok.RequiredArgsConstructor;
8+
import org.namul.api.payload.response.DefaultResponse;
9+
import org.springframework.web.bind.annotation.*;
10+
import org.withtime.be.withtimebe.domain.date.preference.converter.DatePreferenceConverter;
11+
import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceRequestDTO;
12+
import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceResponseDTO;
13+
import org.withtime.be.withtimebe.domain.date.preference.service.command.DatePreferenceTestCommandService;
14+
import org.withtime.be.withtimebe.domain.date.preference.service.query.DatePreferenceDescriptionQueryService;
15+
import org.withtime.be.withtimebe.domain.date.preference.service.query.DatePreferenceQuestionQueryService;
16+
import org.withtime.be.withtimebe.domain.member.entity.Member;
17+
import org.withtime.be.withtimebe.global.security.annotation.AuthenticatedMember;
18+
19+
@RestController
20+
@RequiredArgsConstructor
21+
@RequestMapping("/api/v1/dates/preferences")
22+
@Tag(name = "데이트 취향 테스트 API")
23+
public class DatePreferenceController {
24+
25+
private final DatePreferenceTestCommandService datePreferenceTestCommandService;
26+
private final DatePreferenceDescriptionQueryService datePreferenceDescriptionQueryService;
27+
private final DatePreferenceQuestionQueryService datePreferenceQuestionQueryService;
28+
29+
@Operation(summary = "데이트 취향 조회 API", description = "데이트 취향 종류 조회")
30+
@ApiResponse(responseCode = "COMMON200", description = "성공적으로 정보를 가져왔습니다.")
31+
@GetMapping
32+
public DefaultResponse<DatePreferenceResponseDTO.FindTypes> findTypes() {
33+
return DefaultResponse.ok(DatePreferenceConverter.toFindTypes(datePreferenceDescriptionQueryService.findTypes()));
34+
}
35+
36+
@Operation(summary = "데이트 취향 테스트 질문 조회 API", description = "데이트 취향 테스트에 사용되는 질문 조회하는 API")
37+
@ApiResponse(responseCode = "COMMON200", description = "성공적으로 정보를 가져왔습니다.")
38+
@GetMapping("/questions")
39+
public DefaultResponse<DatePreferenceResponseDTO.FindQuestions> findQuestions() {
40+
return DefaultResponse.ok(DatePreferenceConverter.toFindQuestions(datePreferenceQuestionQueryService.findQuestions()));
41+
}
42+
43+
@Operation(summary = "데이트 취향 테스트 API", description = "질문에 대한 답변으로 결과 생성하는 API 1, 2 둘 중 하나로 40개로 채워 배열 형태로 전송")
44+
@ApiResponses({
45+
@ApiResponse(responseCode = "COMMON200", description = "테스트에 성공했습니다."),
46+
@ApiResponse(
47+
responseCode = "401",
48+
description = """
49+
다음과 같은 이유로 실패할 수 있습니다:
50+
- DATE_PREFERENCE400_1: 질문에 대한 형식이 잘못되었습니다.
51+
"""
52+
),
53+
})
54+
@PostMapping("/tests")
55+
public DefaultResponse<DatePreferenceResponseDTO.TestResult> test(@AuthenticatedMember Member member, @RequestBody DatePreferenceRequestDTO.Test request) {
56+
return DefaultResponse.ok(datePreferenceTestCommandService.test(member, request));
57+
}
58+
59+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package org.withtime.be.withtimebe.domain.date.preference.converter;
2+
3+
import org.withtime.be.withtimebe.domain.date.preference.dto.DatePreferenceResponseDTO;
4+
import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceDescription;
5+
import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferencePartDescription;
6+
import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceQuestion;
7+
import org.withtime.be.withtimebe.domain.date.preference.entity.DatePreferenceTestResult;
8+
import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferenceType;
9+
10+
import java.util.List;
11+
12+
public class DatePreferenceConverter {
13+
public static DatePreferenceResponseDTO.FindTypes toFindTypes(List<DatePreferenceDescription> datePreferenceDescriptions) {
14+
return DatePreferenceResponseDTO.FindTypes.builder()
15+
.types(datePreferenceDescriptions.stream().map(DatePreferenceConverter::toFindType).toList())
16+
.size(datePreferenceDescriptions.size())
17+
.build();
18+
}
19+
20+
public static DatePreferenceResponseDTO.FindType toFindType(DatePreferenceDescription datePreferenceDescription) {
21+
return DatePreferenceResponseDTO.FindType.builder()
22+
.symbolicAnimal(datePreferenceDescription.getSymbolicAnimal())
23+
.preferenceType(datePreferenceDescription.getPreferenceType())
24+
.simpleDescription(datePreferenceDescription.getSimpleDescription())
25+
.build();
26+
}
27+
28+
public static DatePreferenceResponseDTO.FindQuestions toFindQuestions(List<DatePreferenceQuestion> datePreferenceQuestions) {
29+
return DatePreferenceResponseDTO.FindQuestions.builder()
30+
.questions(datePreferenceQuestions.stream().map(DatePreferenceConverter::toFindQuestion).toList())
31+
.size(datePreferenceQuestions.size())
32+
.build();
33+
}
34+
35+
public static DatePreferenceResponseDTO.FindQuestion toFindQuestion(DatePreferenceQuestion datePreferenceQuestion) {
36+
return DatePreferenceResponseDTO.FindQuestion.builder()
37+
.question(datePreferenceQuestion.getQuestion())
38+
.firstAnswer(datePreferenceQuestion.getFirstAnswer())
39+
.secondAnswer(datePreferenceQuestion.getSecondAnswer())
40+
.build();
41+
}
42+
43+
public static DatePreferenceResponseDTO.TestResult toTestResult(DatePreferenceTestResult datePreferenceTestResult,
44+
DatePreferenceDescription datePreferenceDescription,
45+
List<DatePreferencePartDescription> datePreferencePartDescriptions) {
46+
return DatePreferenceResponseDTO.TestResult.builder()
47+
.preferenceType(datePreferenceTestResult.getPreferenceType())
48+
.aPercentage(datePreferenceTestResult.getAPercentage())
49+
.bPercentage(datePreferenceTestResult.getBPercentage())
50+
.cPercentage(datePreferenceTestResult.getCPercentage())
51+
.dPercentage(datePreferenceTestResult.getDPercentage())
52+
.typeDescription(datePreferenceDescription == null ? null : DatePreferenceConverter.toTypeDescription(datePreferenceDescription))
53+
.partTypeDescriptions(datePreferencePartDescriptions == null || datePreferencePartDescriptions.isEmpty() ? null : DatePreferenceConverter.toPartTypeDescriptions(datePreferencePartDescriptions))
54+
.build();
55+
}
56+
57+
public static DatePreferenceTestResult toDatePreferenceTestResult(PreferenceType preferenceType,
58+
Double aPercentage,
59+
Double bPercentage,
60+
Double cPercentage,
61+
Double dPercentage) {
62+
return DatePreferenceTestResult.builder()
63+
.preferenceType(preferenceType)
64+
.aPercentage(aPercentage)
65+
.bPercentage(bPercentage)
66+
.cPercentage(cPercentage)
67+
.dPercentage(dPercentage)
68+
.build();
69+
}
70+
71+
public static DatePreferenceResponseDTO.TypeDescription toTypeDescription(DatePreferenceDescription datePreferenceDescription) {
72+
return DatePreferenceResponseDTO.TypeDescription.builder()
73+
.symbolicAnimal(datePreferenceDescription.getSymbolicAnimal())
74+
.preferenceType(datePreferenceDescription.getPreferenceType())
75+
.simpleDescription(datePreferenceDescription.getSimpleDescription())
76+
.analysis(datePreferenceDescription.getAnalysis())
77+
.build();
78+
}
79+
80+
public static DatePreferenceResponseDTO.PartTypeDescriptions toPartTypeDescriptions(List<DatePreferencePartDescription> descriptions) {
81+
return DatePreferenceResponseDTO.PartTypeDescriptions.builder()
82+
.types(descriptions.stream().map(DatePreferenceConverter::toPartTypeDescription).toList())
83+
.size(descriptions.size())
84+
.build();
85+
}
86+
87+
public static DatePreferenceResponseDTO.PartTypeDescription toPartTypeDescription(DatePreferencePartDescription description) {
88+
return DatePreferenceResponseDTO.PartTypeDescription.builder()
89+
.typeInitial(description.getPreferencePartType())
90+
.type(description.getType())
91+
.typeEng(description.getTypeEng())
92+
.description(description.getDescription())
93+
.build();
94+
}
95+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.withtime.be.withtimebe.domain.date.preference.dto;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
5+
import java.util.List;
6+
7+
public record DatePreferenceRequestDTO() {
8+
public record Test(
9+
@Schema(
10+
description = "1 또는 2 중 하나의 값으로 이루어진 40개의 답변",
11+
example = """
12+
[
13+
1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
14+
1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
15+
1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
16+
1, 1, 1, 1, 1, 1, 2, 2, 2, 2
17+
]
18+
"""
19+
)
20+
List<Integer> answers
21+
) {
22+
23+
}
24+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package org.withtime.be.withtimebe.domain.date.preference.dto;
2+
3+
import lombok.Builder;
4+
import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferencePartType;
5+
import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferenceType;
6+
7+
import java.util.List;
8+
9+
public record DatePreferenceResponseDTO() {
10+
11+
@Builder
12+
public record FindTypes(
13+
List<FindType> types,
14+
Integer size
15+
) {
16+
17+
}
18+
19+
@Builder
20+
public record FindType(
21+
String symbolicAnimal,
22+
PreferenceType preferenceType,
23+
String simpleDescription
24+
) {
25+
26+
}
27+
28+
@Builder
29+
public record FindQuestions(
30+
List<FindQuestion> questions,
31+
Integer size
32+
) {
33+
34+
}
35+
36+
@Builder
37+
public record FindQuestion(
38+
String question,
39+
String firstAnswer,
40+
String secondAnswer
41+
) {
42+
43+
}
44+
45+
@Builder
46+
public record TestResult(
47+
PreferenceType preferenceType,
48+
Double aPercentage,
49+
Double bPercentage,
50+
Double cPercentage,
51+
Double dPercentage,
52+
TypeDescription typeDescription,
53+
PartTypeDescriptions partTypeDescriptions
54+
) {
55+
56+
}
57+
58+
@Builder
59+
public record TypeDescription(
60+
String symbolicAnimal,
61+
PreferenceType preferenceType,
62+
String simpleDescription,
63+
String analysis
64+
) {
65+
66+
}
67+
68+
@Builder
69+
public record PartTypeDescriptions(
70+
List<PartTypeDescription> types,
71+
Integer size
72+
) {
73+
74+
}
75+
76+
@Builder
77+
public record PartTypeDescription(
78+
PreferencePartType typeInitial,
79+
String typeEng,
80+
String type,
81+
String description
82+
) {
83+
84+
}
85+
86+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.withtime.be.withtimebe.domain.date.preference.entity;
2+
3+
import jakarta.persistence.*;
4+
import lombok.*;
5+
import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferenceType;
6+
7+
@Entity
8+
@Getter
9+
@Builder
10+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
11+
@AllArgsConstructor(access = AccessLevel.PRIVATE)
12+
@Table(name = "date_preference_description")
13+
public class DatePreferenceDescription {
14+
15+
@Id
16+
@GeneratedValue(strategy = GenerationType.IDENTITY)
17+
@Column(name = "date_preference_description_id")
18+
private Long id;
19+
20+
@Column(name = "symbolic_animal")
21+
private String symbolicAnimal;
22+
23+
@Enumerated(EnumType.STRING)
24+
@Column(name = "preference_type", unique = true)
25+
private PreferenceType preferenceType;
26+
27+
@Column(name = "simple_description")
28+
private String simpleDescription;
29+
30+
@Column(name = "analysis", columnDefinition = "TEXT")
31+
private String analysis;
32+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.withtime.be.withtimebe.domain.date.preference.entity;
2+
3+
import jakarta.persistence.*;
4+
import lombok.*;
5+
6+
@Entity
7+
@Getter
8+
@Builder
9+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
10+
@AllArgsConstructor(access = AccessLevel.PRIVATE)
11+
@Table(name = "date_preference_description_keyword")
12+
public class DatePreferenceDescriptionKeyword {
13+
14+
@Id
15+
@GeneratedValue(strategy = GenerationType.IDENTITY)
16+
@Column(name = "date_preference_description_keyword_id")
17+
private Long id;
18+
19+
@ManyToOne(fetch = FetchType.LAZY)
20+
@JoinColumn(name = "date_preference_description")
21+
private DatePreferenceDescription datePreferenceDescription;
22+
23+
@ManyToOne(fetch = FetchType.LAZY)
24+
@JoinColumn(name = "date_preference_keyword")
25+
private DatePreferenceKeyword datePreferenceKeyword;
26+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.withtime.be.withtimebe.domain.date.preference.entity;
2+
3+
import jakarta.persistence.*;
4+
import lombok.*;
5+
6+
@Entity
7+
@Getter
8+
@Builder
9+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
10+
@AllArgsConstructor(access = AccessLevel.PRIVATE)
11+
@Table(name = "date_preference_keyword")
12+
public class DatePreferenceKeyword {
13+
14+
@Id
15+
@GeneratedValue(strategy = GenerationType.IDENTITY)
16+
@Column(name = "date_preference_keyword_id")
17+
private Long id;
18+
19+
@Column(name = "keyword")
20+
private String keyword;
21+
22+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.withtime.be.withtimebe.domain.date.preference.entity;
2+
3+
import jakarta.persistence.*;
4+
import lombok.*;
5+
import org.withtime.be.withtimebe.domain.date.preference.entity.enums.PreferencePartType;
6+
7+
@Entity
8+
@Getter
9+
@Builder
10+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
11+
@AllArgsConstructor(access = AccessLevel.PRIVATE)
12+
@Table(name = "date_preference_part_description")
13+
public class DatePreferencePartDescription {
14+
15+
@Id
16+
@GeneratedValue(strategy = GenerationType.IDENTITY)
17+
@Column(name = "date_preference_part_description_id")
18+
private Long id;
19+
20+
@Enumerated(EnumType.STRING)
21+
@Column(name = "preference_part_type", unique = true)
22+
private PreferencePartType preferencePartType;
23+
24+
@Column(name = "type_eng")
25+
private String typeEng;
26+
27+
@Column(name = "type")
28+
private String type;
29+
30+
@Column(name = "description")
31+
private String description;
32+
}

0 commit comments

Comments
 (0)