Skip to content

Commit ce726c1

Browse files
committed
refact: record 조회 기준 시간 오전 0시로 + validation 추가
1 parent a9832c8 commit ce726c1

File tree

4 files changed

+20
-41
lines changed

4 files changed

+20
-41
lines changed

src/main/java/com/back/domain/study/record/controller/StudyRecordController.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import com.back.domain.study.record.service.StudyRecordService;
66
import com.back.global.common.dto.RsData;
77
import com.back.global.security.user.CustomUserDetails;
8+
import io.swagger.v3.oas.annotations.Operation;
9+
import io.swagger.v3.oas.annotations.tags.Tag;
810
import jakarta.validation.Valid;
911
import lombok.RequiredArgsConstructor;
1012
import org.springframework.format.annotation.DateTimeFormat;
@@ -18,12 +20,15 @@
1820
@RestController
1921
@RequiredArgsConstructor
2022
@RequestMapping("/api/plans/records")
23+
@Tag(name = "StudyPlan", description = "학습 계획 관련 API")
2124
public class StudyRecordController {
2225
private final StudyRecordService studyRecordService;
2326

2427
// ======================= 생성 ======================
2528
// 학습 기록 생성
2629
@PostMapping
30+
@Operation( summary = "학습 기록 생성",
31+
description = "기록을 생성합니다.")
2732
public ResponseEntity<RsData<StudyRecordResponseDto>> createStudyRecord(
2833
@AuthenticationPrincipal CustomUserDetails user,
2934
@Valid @RequestBody StudyRecordRequestDto request

src/main/java/com/back/domain/study/record/dto/StudyRecordRequestDto.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.back.domain.study.record.dto;
22

3+
import jakarta.validation.constraints.NotNull;
34
import lombok.Getter;
45
import lombok.NoArgsConstructor;
56

@@ -10,10 +11,15 @@
1011
@Getter
1112
@NoArgsConstructor
1213
public class StudyRecordRequestDto {
14+
@NotNull(message = "계획 ID는 필수입니다.")
1315
private Long planId;
16+
@NotNull(message = "방 ID는 필수입니다.")
1417
private Long roomId;
18+
@NotNull(message = "시작 시간은 필수입니다.")
1519
private LocalDateTime startTime;
20+
@NotNull(message = "종료 시간은 필수입니다.")
1621
private LocalDateTime endTime;
22+
1723
private Long duration;
1824
private List<PauseInfoRequestDto> pauseInfos = new ArrayList<>();
1925

src/main/java/com/back/domain/study/record/service/StudyRecordService.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,9 @@ public StudyRecordResponseDto createStudyRecord(Long userId, StudyRecordRequestD
5454
throw new CustomException(ErrorCode.PLAN_FORBIDDEN);
5555
}
5656

57-
// 방 조회 (우선은 옵셔널로 설정)
58-
Room room = null;
59-
if (request.getRoomId() != null) {
60-
room = roomRepository.findById(request.getRoomId())
61-
.orElseThrow(() -> new CustomException(ErrorCode.ROOM_NOT_FOUND));
62-
}
57+
// 방 조회 (필수)
58+
Room room = roomRepository.findById(request.getRoomId())
59+
.orElseThrow(() -> new CustomException(ErrorCode.ROOM_NOT_FOUND));
6360

6461
// 일시정지 정보를 엔티티로 생성
6562
List<PauseInfo> pauseInfos = request.getPauseInfos().stream()
@@ -125,9 +122,9 @@ public List<StudyRecordResponseDto> getStudyRecordsByDate(Long userId, LocalDate
125122
User user = userRepository.findById(userId)
126123
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));
127124

128-
// 오전 4시 기준 하루의 시작과 끝 설정
129-
LocalDateTime startOfDay = date.atTime(4, 0, 0);
130-
LocalDateTime endOfDay = date.plusDays(1).atTime(4, 0, 0);
125+
// 오전 0시 기준 하루의 시작과 끝 설정
126+
LocalDateTime startOfDay = date.atStartOfDay();
127+
LocalDateTime endOfDay = date.plusDays(1).atStartOfDay();
131128

132129
// 시작~종료 시간을 포함하는 일자의 학습 기록 조회
133130
List<StudyRecord> records = studyRecordRepository
@@ -151,8 +148,8 @@ private void checkAndNotifyDailyGoalAchievement(Long userId, LocalDate date) {
151148

152149
// 오늘 완료한 계획 개수
153150
int completedCount = 0;
154-
LocalDateTime startOfDay = date.atTime(4, 0);
155-
LocalDateTime endOfDay = date.plusDays(1).atTime(4, 0);
151+
LocalDateTime startOfDay = date.atStartOfDay();
152+
LocalDateTime endOfDay = date.plusDays(1).atStartOfDay();
156153

157154
for (StudyPlan plan : todayPlans) {
158155
boolean hasRecord = studyRecordRepository.existsByStudyPlanIdAndDate(

src/test/java/com/back/domain/study/record/controller/StudyRecordControllerTest.java

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -250,36 +250,7 @@ void t3() throws Exception {
250250
}
251251

252252
@Test
253-
@DisplayName("학습 기록 조회 - 전날 밤~당일 새벽 기록의 경우")
254-
void t4() throws Exception {
255-
mvc.perform(post("/api/plans/records")
256-
.header("Authorization", "Bearer faketoken")
257-
.contentType(MediaType.APPLICATION_JSON)
258-
.content("""
259-
{
260-
"planId": %d,
261-
"startTime": "2025-10-02T23:00:00",
262-
"endTime": "2025-10-03T02:00:00",
263-
"duration": 10800,
264-
"pauseInfos": []
265-
}
266-
""".formatted(singlePlan.getId())))
267-
.andExpect(status().isOk());
268-
269-
// 10월 2일로 조회 (04:00 기준이므로 이 기록이 포함되어야 함)
270-
ResultActions resultActions = mvc.perform(get("/api/plans/records?date=2025-10-02")
271-
.header("Authorization", "Bearer faketoken"))
272-
.andDo(print());
273-
274-
resultActions
275-
.andExpect(status().isOk())
276-
.andExpect(jsonPath("$.data", hasSize(1)))
277-
.andExpect(jsonPath("$.data[0].startTime").value("2025-10-02T23:00:00"))
278-
.andExpect(jsonPath("$.data[0].endTime").value("2025-10-03T02:00:00"));
279-
}
280-
281-
@Test
282-
@DisplayName("학습 기록 조회 - 전날 밤~당일 오전 4시 이후 끝난 기록의 경우")
253+
@DisplayName("학습 기록 조회 - 전날 밤 시작 ~ 당일 끝난 기록의 경우")
283254
void t5() throws Exception {
284255
mvc.perform(post("/api/plans/records")
285256
.header("Authorization", "Bearer faketoken")

0 commit comments

Comments
 (0)