Skip to content

Commit 23e227b

Browse files
authored
[T3-108] 추천 루틴 조회 API (#28)
* fix: OneToOne에서 ManyToOne으로 변 * feat: 추천 루틴 조회 API * feat: swagger 추가 * feat: 루틴, 서브루틴 완료 ID 응답값 추가 * fix: 감정 구슬 1일 1회 선택여부 확인 validation 추가 * fix: onboarding 명세 수정 * feat: 추천 루틴 조회시 응답에 감정구슬 enum 값 추가 * fix: 명세 추가 * fix: 명세 수정
1 parent 58a6659 commit 23e227b

18 files changed

Lines changed: 316 additions & 10 deletions

src/main/java/bitnagil/bitnagil_backend/emotionMarble/repository/EmotionMarbleRepository.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
import bitnagil.bitnagil_backend.emotionMarble.domain.EmotionMarble;
44
import bitnagil.bitnagil_backend.global.entity.HistoryPk;
55
import org.springframework.data.jpa.repository.JpaRepository;
6+
import org.springframework.stereotype.Repository;
67

8+
import java.time.LocalDate;
9+
import java.util.UUID;
10+
11+
@Repository
712
public interface EmotionMarbleRepository extends JpaRepository<EmotionMarble, HistoryPk> {
13+
EmotionMarble findByUserId(UUID id);
14+
15+
EmotionMarble findByUserIdAndDateIs(UUID userId, LocalDate now);
16+
17+
boolean existsByUserIdAndDate(UUID userId, LocalDate nowDate);
818
}

src/main/java/bitnagil/bitnagil_backend/emotionMarble/response/RegisterEmotionMarbleResponse.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
@Schema(description = "감정 구슬 등록 응답 DTO")
1717
public class RegisterEmotionMarbleResponse {
1818

19+
@Schema(description = "추천 루틴 목록")
1920
private List<RecommendedRoutineDto> recommendedRoutines;
2021

2122
}

src/main/java/bitnagil/bitnagil_backend/emotionMarble/service/EmotionMarbleService.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,29 +43,34 @@ public EmotionMarbleTypeResponse getEmotionMarbles() {
4343
return EmotionMarbleTypeResponse.builder().emotionMarbleTypes(values).build();
4444
}
4545

46-
// 감정 구술 등록
46+
// 감정 구슬 등록(1일 1회)
4747
@Transactional
4848
public RegisterEmotionMarbleResponse registryEmotionMarble(User user, RegisterEmotionMarbleRequest request) {
4949
LocalDate nowDate = LocalDate.now();
5050
LocalDateTime nowDateTime = LocalDateTime.now();
5151
LocalDateTime endDateTime = LocalDateTime.of(nowDate, LocalTime.of(23, 59, 59));
5252

53+
// 감정구슬은 1일 1회만 선택할 수 있으므로, 존재 여부를 확인한다.
54+
if (emotionMarbleRepository.existsByUserIdAndDate(user.getUserPk().getId(), nowDate)) {
55+
throw new CustomException(ErrorCode.ALREADY_REGISTERED_EMOTION_MARBLE);
56+
}
57+
5358
EmotionMarble emotionMarble = EmotionMarble.builder()
5459
.emotionMarblePk(new HistoryPk(UUID.randomUUID(), 1L))
5560
.emotionMarbleType(request.getEmotionMarbleType())
5661
.date(nowDate)
5762
.userId(user.getUserPk().getId())
5863
.historyStartDateTime(nowDateTime)
5964
.historyEndDateTime(endDateTime) // historyEndDateTime은 당일 11시 59분 59초로 설정(하루씩 설정되기 때문. 이러면 매일 감정 갱신이 불필요함)
60-
.resultCase( // 감정 구술에 따른 추천 루틴을 찾기 위해 Case 객체를 생성
65+
.resultCase( // 감정 구슬에 따른 추천 루틴을 찾기 위해 Case 객체를 생성
6166
Case.builder()
6267
.caseId(request.getEmotionMarbleType().getCaseId())
6368
.build()
6469
).build();
6570

6671
emotionMarbleRepository.save(emotionMarble);
6772

68-
// 감정 구술에 따른 추천 루틴 응답
73+
// 감정 구슬에 따른 추천 루틴 응답
6974
List<RecommendedRoutine> recommendedRoutines = recommendRoutineRepository.findByResultCase(emotionMarble.getResultCase());
7075
if (recommendedRoutines.isEmpty()) {
7176
throw new CustomException(ErrorCode.NOT_FOUND_RECOMMENDED_ROUTINE);

src/main/java/bitnagil/bitnagil_backend/global/errorcode/ErrorCode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ public enum ErrorCode {
7474

7575
// 온보딩 관련 에러 코드
7676
NOT_FOUND_RECOMMENDED_ROUTINE("ON000", HttpStatus.NOT_FOUND, "조건에 맞는 추천 루틴을 찾을 수 없습니다."),
77-
;
77+
78+
// 감정구슬 관련 에러코드
79+
ALREADY_REGISTERED_EMOTION_MARBLE("EM000", HttpStatus.CONFLICT, "감정구슬은 하루에 한번만 등록할 수 있습니다.");
7880

7981

8082

src/main/java/bitnagil/bitnagil_backend/global/swagger/ApiTags.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ public class ApiTags {
1010
public static final String ROUTINE = "루틴 API";
1111
public static final String ONBOARDING = "온보딩 API";
1212
public static final String EMOTION_MARBLE = "감정구슬 API";
13+
public static final String RECOMMENDED_ROUTINE = "추천 루틴 API";
1314
}

src/main/java/bitnagil/bitnagil_backend/onboarding/request/OnboardingRequest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
@AllArgsConstructor
1919
public class OnboardingRequest {
2020

21-
@Schema(description = "시간대", required = true, example = "08:00:00")
21+
@Schema(description = "어떤 시간대를 더 잘 보내고 싶나요?", required = true, example = "08:00:00")
2222
private LocalTime timeSlot;
23-
@Schema(description = "서비스 이용약관 동의", required = true)
23+
@Schema(description = "요즘 어떤 회복이 필요하신가요?", required = true)
2424
private EmotionType emotionType;
25-
@Schema(description = "서비스 이용약관 동의", required = true)
25+
@Schema(description = "최근 얼마나 자주 바깥바람을 쐬시나요?", required = true)
2626
private RealOutingFrequency realOutingFrequency;
27-
@Schema(description = "서비스 이용약관 동의", required = true)
27+
@Schema(description = "일주일에 몇번 외출하고 싶으신가요?", required = true)
2828
private TargetOutingFrequency targetOutingFrequency;
2929

3030
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package bitnagil.bitnagil_backend.recommendedRoutine.controller;
2+
3+
import bitnagil.bitnagil_backend.global.annotation.CurrentUser;
4+
import bitnagil.bitnagil_backend.global.response.CustomResponseDto;
5+
import bitnagil.bitnagil_backend.recommendedRoutine.controller.spec.RecommendedRoutineSpec;
6+
import bitnagil.bitnagil_backend.recommendedRoutine.response.RecommendedRoutineSearchResponse;
7+
import bitnagil.bitnagil_backend.recommendedRoutine.service.RecommendedRoutineService;
8+
import bitnagil.bitnagil_backend.user.domain.User;
9+
import lombok.RequiredArgsConstructor;
10+
import org.springframework.web.bind.annotation.GetMapping;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
import org.springframework.web.bind.annotation.RestController;
13+
14+
@RestController
15+
@RequiredArgsConstructor
16+
@RequestMapping(value = "/api/v1/recommend-routines")
17+
public class RecommendedRoutineController implements RecommendedRoutineSpec {
18+
private final RecommendedRoutineService recommendedRoutineService;
19+
20+
@GetMapping("")
21+
public CustomResponseDto<RecommendedRoutineSearchResponse> searchRecommendedRoutines(@CurrentUser User user) {
22+
return CustomResponseDto.from(recommendedRoutineService.searchRecommendedRoutines(user));
23+
}
24+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package bitnagil.bitnagil_backend.recommendedRoutine.controller.spec;
2+
3+
import bitnagil.bitnagil_backend.auth.jwt.TokenResponse;
4+
import bitnagil.bitnagil_backend.global.annotation.CurrentUser;
5+
import bitnagil.bitnagil_backend.global.errorcode.ErrorCode;
6+
import bitnagil.bitnagil_backend.global.response.CustomResponseDto;
7+
import bitnagil.bitnagil_backend.global.swagger.ApiErrorCodeExamples;
8+
import bitnagil.bitnagil_backend.global.swagger.ApiTags;
9+
import bitnagil.bitnagil_backend.recommendedRoutine.response.RecommendedRoutineSearchResponse;
10+
import bitnagil.bitnagil_backend.user.domain.User;
11+
import io.swagger.v3.oas.annotations.Operation;
12+
import io.swagger.v3.oas.annotations.tags.Tag;
13+
14+
@Tag(name = ApiTags.RECOMMENDED_ROUTINE)
15+
public interface RecommendedRoutineSpec {
16+
17+
@Operation(summary = "추천 루틴을 조회합니다.")
18+
@ApiErrorCodeExamples({
19+
ErrorCode.NOT_FOUND_USER
20+
})
21+
CustomResponseDto<RecommendedRoutineSearchResponse> searchRecommendedRoutines(User user);
22+
23+
}

src/main/java/bitnagil/bitnagil_backend/recommendedRoutine/domain/enums/RecommendedRoutineType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
@RequiredArgsConstructor
88
@Getter
99
public enum RecommendedRoutineType implements EnumType {
10+
PERSONALIZED("맞춤 추천"),
1011
OUTING("나가봐요"),
1112
OUTING_REPORT("나가봐요-제보"),
1213
GROW("성장해요"),

src/main/java/bitnagil/bitnagil_backend/recommendedRoutine/repository/RecommendedRoutineRepository.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22

33
import bitnagil.bitnagil_backend.onboarding.domain.Case;
44
import bitnagil.bitnagil_backend.recommendedRoutine.domain.RecommendedRoutine;
5+
import bitnagil.bitnagil_backend.recommendedRoutine.domain.enums.RecommendedRoutineType;
56
import org.springframework.data.jpa.repository.JpaRepository;
67
import org.springframework.stereotype.Repository;
78

89
import java.util.List;
910

1011
@Repository
1112
public interface RecommendedRoutineRepository extends JpaRepository<RecommendedRoutine, Long> {
12-
List findByResultCase(Case resultCase);
13+
List<RecommendedRoutine> findByResultCase(Case resultCase);
14+
15+
List<RecommendedRoutine> findTop4ByRecommendedRoutineTypeOrderByRecommendedRoutineIdAsc(RecommendedRoutineType value);
1316
}

0 commit comments

Comments
 (0)