diff --git a/src/main/java/side/onetime/domain/FixedEvent.java b/src/main/java/side/onetime/domain/FixedEvent.java index 3692296..7236e9f 100644 --- a/src/main/java/side/onetime/domain/FixedEvent.java +++ b/src/main/java/side/onetime/domain/FixedEvent.java @@ -26,32 +26,16 @@ public class FixedEvent extends BaseEntity { @Column(name = "title", nullable = false, length = 30) private String title; - @Column(name = "start_time", nullable = false) - private String startTime; - - @Column(name = "end_time", nullable = false) - private String endTime; - @OneToMany(mappedBy = "fixedEvent",cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List fixedSelections; @Builder - public FixedEvent(User user, String title, String startTime, String endTime) { + public FixedEvent(User user, String title) { this.user = user; this.title = title; - this.startTime = startTime; - this.endTime = endTime; } public void updateTitle(String title) { this.title = title; } - - public void updateStartTime(String startTime) { - this.startTime = startTime; - } - - public void updateEndTime(String endTime) { - this.endTime = endTime; - } -} \ No newline at end of file +} diff --git a/src/main/java/side/onetime/dto/fixed/request/CreateFixedEventRequest.java b/src/main/java/side/onetime/dto/fixed/request/CreateFixedEventRequest.java index a4bc7a5..51eb3bc 100644 --- a/src/main/java/side/onetime/dto/fixed/request/CreateFixedEventRequest.java +++ b/src/main/java/side/onetime/dto/fixed/request/CreateFixedEventRequest.java @@ -11,20 +11,16 @@ import java.util.List; -import static side.onetime.util.DateUtil.addThirtyMinutes; - @JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) @JsonInclude(JsonInclude.Include.NON_NULL) public record CreateFixedEventRequest( @NotBlank(message = "제목은 필수 값입니다.") String title, @NotNull(message = "스케줄 목록은 필수 값입니다.") List schedules ) { - public FixedEvent toEntity(User user, String startTime, String endTime) { + public FixedEvent toEntity(User user) { return FixedEvent.builder() .user(user) .title(title) - .startTime(startTime) - .endTime(addThirtyMinutes(endTime)) .build(); } -} \ No newline at end of file +} diff --git a/src/main/java/side/onetime/dto/fixed/request/ModifyFixedEventRequest.java b/src/main/java/side/onetime/dto/fixed/request/ModifyFixedEventRequest.java index 6a87bf5..7dffad7 100644 --- a/src/main/java/side/onetime/dto/fixed/request/ModifyFixedEventRequest.java +++ b/src/main/java/side/onetime/dto/fixed/request/ModifyFixedEventRequest.java @@ -3,26 +3,14 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.annotation.JsonNaming; -import side.onetime.domain.FixedEvent; -import side.onetime.domain.User; import side.onetime.dto.fixed.response.FixedScheduleResponse; import java.util.List; -import static side.onetime.util.DateUtil.addThirtyMinutes; - @JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) @JsonInclude(JsonInclude.Include.NON_NULL) public record ModifyFixedEventRequest( String title, List schedules ) { - public FixedEvent toEntity(User user, String startTime, String endTime) { - return FixedEvent.builder() - .user(user) - .title(title) - .startTime(startTime) - .endTime(addThirtyMinutes(endTime)) - .build(); - } -} \ No newline at end of file +} diff --git a/src/main/java/side/onetime/dto/fixed/response/FixedEventDetailResponse.java b/src/main/java/side/onetime/dto/fixed/response/FixedEventDetailResponse.java index b7e779b..68338cb 100644 --- a/src/main/java/side/onetime/dto/fixed/response/FixedEventDetailResponse.java +++ b/src/main/java/side/onetime/dto/fixed/response/FixedEventDetailResponse.java @@ -10,16 +10,12 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public record FixedEventDetailResponse( String title, - String startTime, - String endTime, List schedules ) { - public static FixedEventDetailResponse of(String title, String startTime, String endTime, List schedules) { + public static FixedEventDetailResponse of(String title, List schedules) { return new FixedEventDetailResponse( title, - startTime, - endTime, schedules ); } -} \ No newline at end of file +} diff --git a/src/main/java/side/onetime/dto/fixed/response/FixedEventResponse.java b/src/main/java/side/onetime/dto/fixed/response/FixedEventResponse.java index 10c84de..2d5769a 100644 --- a/src/main/java/side/onetime/dto/fixed/response/FixedEventResponse.java +++ b/src/main/java/side/onetime/dto/fixed/response/FixedEventResponse.java @@ -10,16 +10,12 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public record FixedEventResponse( Long id, - String startTime, - String endTime, List schedules ) { - public static FixedEventResponse of(Long id, String startTime, String endTime, List schedules) { + public static FixedEventResponse of(Long id, List schedules) { return new FixedEventResponse( id, - startTime, - endTime, schedules ); } -} \ No newline at end of file +} diff --git a/src/main/java/side/onetime/repository/custom/FixedEventRepositoryCustom.java b/src/main/java/side/onetime/repository/custom/FixedEventRepositoryCustom.java index 73c2852..1b794f8 100644 --- a/src/main/java/side/onetime/repository/custom/FixedEventRepositoryCustom.java +++ b/src/main/java/side/onetime/repository/custom/FixedEventRepositoryCustom.java @@ -10,4 +10,4 @@ public interface FixedEventRepositoryCustom { FixedEvent findByUserAndFixedEventIdCustom(User user, Long fixedEventId); void deleteFixedEventAndSelections(User user, Long fixedEventId); List findFixedEventsByUserAndDay(User user, String day); -} \ No newline at end of file +} diff --git a/src/main/java/side/onetime/repository/custom/FixedEventRepositoryImpl.java b/src/main/java/side/onetime/repository/custom/FixedEventRepositoryImpl.java index b57e73b..975fefa 100644 --- a/src/main/java/side/onetime/repository/custom/FixedEventRepositoryImpl.java +++ b/src/main/java/side/onetime/repository/custom/FixedEventRepositoryImpl.java @@ -74,5 +74,4 @@ public List findFixedEventsByUserAndDay(User user, String day) { .and(fixedSchedule.day.eq(day))) .fetch(); } - -} \ No newline at end of file +} diff --git a/src/main/java/side/onetime/service/FixedEventService.java b/src/main/java/side/onetime/service/FixedEventService.java index c9c1280..b5cfa75 100644 --- a/src/main/java/side/onetime/service/FixedEventService.java +++ b/src/main/java/side/onetime/service/FixedEventService.java @@ -4,6 +4,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import side.onetime.domain.FixedEvent; +import side.onetime.domain.FixedSelection; import side.onetime.domain.User; import side.onetime.dto.fixed.request.CreateFixedEventRequest; import side.onetime.dto.fixed.request.ModifyFixedEventRequest; @@ -11,6 +12,7 @@ import side.onetime.exception.CustomException; import side.onetime.exception.status.FixedErrorStatus; import side.onetime.repository.FixedEventRepository; +import side.onetime.util.DateUtil; import side.onetime.util.JwtUtil; import java.util.List; @@ -23,19 +25,32 @@ public class FixedEventService { private final FixedEventRepository fixedEventRepository; private final JwtUtil jwtUtil; - // 고정 이벤트 생성 메서드 + /** + * 고정 이벤트 생성 메서드. + * + * 유저 인증 정보를 기반으로 새로운 고정 이벤트를 생성하고, + * 관련된 고정 스케줄을 등록합니다. + * + * @param authorizationHeader 인증 토큰 + * @param createFixedEventRequest 고정 이벤트 생성 요청 데이터 + */ @Transactional public void createFixedEvent(String authorizationHeader, CreateFixedEventRequest createFixedEventRequest) { User user = jwtUtil.getUserFromHeader(authorizationHeader); - List times = createFixedEventRequest.schedules().get(0).times(); - String startTime = times.get(0); - String endTime = times.get(times.size() - 1); - FixedEvent fixedEvent = createFixedEventRequest.toEntity(user, startTime, endTime); + FixedEvent fixedEvent = createFixedEventRequest.toEntity(user); fixedEventRepository.save(fixedEvent); fixedScheduleService.createFixedSchedules(createFixedEventRequest.schedules(), fixedEvent); } - // 고정 이벤트 수정 메서드 + /** + * 고정 이벤트 수정 메서드. + * + * 고정 이벤트의 제목을 수정합니다. + * + * @param authorizationHeader 인증 토큰 + * @param fixedEventId 수정할 고정 이벤트 ID + * @param modifyFixedEventRequest 고정 이벤트 수정 요청 데이터 + */ @Transactional public void modifyFixedEvent(String authorizationHeader, Long fixedEventId, ModifyFixedEventRequest modifyFixedEventRequest) { User user = jwtUtil.getUserFromHeader(authorizationHeader); @@ -45,7 +60,14 @@ public void modifyFixedEvent(String authorizationHeader, Long fixedEventId, Modi fixedEventRepository.save(fixedEvent); } - // 고정 이벤트 & 스케줄 삭제 메서드 + /** + * 고정 이벤트 및 관련 스케줄 삭제 메서드. + * + * 고정 이벤트와 해당 이벤트에 관련된 모든 스케줄을 삭제합니다. + * + * @param authorizationHeader 인증 토큰 + * @param fixedEventId 삭제할 고정 이벤트 ID + */ @Transactional public void removeFixedEvent(String authorizationHeader, Long fixedEventId) { User user = jwtUtil.getUserFromHeader(authorizationHeader); @@ -54,25 +76,44 @@ public void removeFixedEvent(String authorizationHeader, Long fixedEventId) { fixedEventRepository.deleteFixedEventAndSelections(user, fixedEventId); } - // 요일 별 고정 이벤트 조회 메서드 + /** + * 요일별 고정 이벤트 조회 메서드. + * + * 특정 요일에 해당하는 고정 이벤트 목록을 조회합니다. + * + * @param authorizationHeader 인증 토큰 + * @param day 조회할 요일 (예: "mon", "tue" 등) + * @return 고정 이벤트 목록 + */ @Transactional(readOnly = true) public List getFixedEventByDay(String authorizationHeader, String day) { User user = jwtUtil.getUserFromHeader(authorizationHeader); String koreanDay = convertDayToKorean(day); - List fixedEvents = fixedEventRepository.findFixedEventsByUserAndDay(user, koreanDay); - - return fixedEvents.stream() - .map(fixedEvent -> FixedEventByDayResponse.of( - fixedEvent.getId(), - fixedEvent.getTitle(), - fixedEvent.getStartTime(), - fixedEvent.getEndTime() - )) + return fixedEventRepository.findFixedEventsByUserAndDay(user, koreanDay).stream() + .map(fixedEvent -> { + List fixedSelections = fixedEvent.getFixedSelections(); + String startTime = fixedSelections.get(0).getFixedSchedule().getTime(); + String endTime = fixedSelections.get(fixedSelections.size() - 1).getFixedSchedule().getTime(); + return FixedEventByDayResponse.of( + fixedEvent.getId(), + fixedEvent.getTitle(), + startTime, + DateUtil.addThirtyMinutes(endTime) + ); + }) .toList(); } - // 영어 요일 -> 한글 요일 변환 메서드 + /** + * 영어 요일 -> 한글 요일 변환 메서드. + * + * 영어로 입력된 요일을 한글 요일로 변환합니다. + * 입력이 올바르지 않을 경우 예외를 발생시킵니다. + * + * @param day 영어 요일 (예: "mon", "tue" 등) + * @return 한글 요일 (예: "월", "화" 등) + */ private String convertDayToKorean(String day) { return switch (day.toLowerCase()) { case "mon" -> "월"; @@ -85,4 +126,4 @@ private String convertDayToKorean(String day) { default -> throw new CustomException(FixedErrorStatus._IS_NOT_RIGHT_DAY); }; } -} \ No newline at end of file +} diff --git a/src/main/java/side/onetime/service/FixedScheduleService.java b/src/main/java/side/onetime/service/FixedScheduleService.java index 45eb88c..ffed611 100644 --- a/src/main/java/side/onetime/service/FixedScheduleService.java +++ b/src/main/java/side/onetime/service/FixedScheduleService.java @@ -24,8 +24,6 @@ import java.util.Map; import java.util.stream.Collectors; -import static side.onetime.util.DateUtil.addThirtyMinutes; - @Service @RequiredArgsConstructor public class FixedScheduleService { @@ -34,7 +32,15 @@ public class FixedScheduleService { private final FixedSelectionRepository fixedSelectionRepository; private final JwtUtil jwtUtil; - // 고정 스케줄 등록 메서드 + /** + * 고정 스케줄 등록 메서드. + * + * 주어진 고정 이벤트에 대해 요청된 스케줄 데이터를 등록합니다. + * FixedSelection을 생성하고 데이터베이스에 저장합니다. + * + * @param fixedScheduleResponses 등록할 스케줄 데이터 + * @param fixedEvent 고정 이벤트 객체 + */ @Transactional public void createFixedSchedules(List fixedScheduleResponses, FixedEvent fixedEvent) { List fixedSelections = new ArrayList<>(); @@ -54,10 +60,19 @@ public void createFixedSchedules(List fixedScheduleRespon } } } + fixedSelectionRepository.saveAll(fixedSelections); } - // 전체 고정 스케줄 조회 메서드 + /** + * 전체 고정 스케줄 조회 메서드. + * + * 현재 유저의 모든 고정 스케줄 데이터를 조회합니다. + * FixedEventResponse 리스트로 반환합니다. + * + * @param authorizationHeader 인증 토큰 + * @return 고정 스케줄 응답 데이터 리스트 + */ @Transactional(readOnly = true) public List getAllFixedSchedules(String authorizationHeader) { User user = jwtUtil.getUserFromHeader(authorizationHeader); @@ -66,7 +81,6 @@ public List getAllFixedSchedules(String authorizationHeader) List fixedEventResponses = new ArrayList<>(); for (FixedEvent fixedEvent : fixedEvents) { - // 각 이벤트에 대한 고정 선택을 그룹화하여 요일별 스케줄을 생성 (times를 오름차순 정렬) Map> groupedSchedules = fixedEvent.getFixedSelections().stream() .collect(Collectors.groupingBy( selection -> selection.getFixedSchedule().getDay(), @@ -79,31 +93,36 @@ public List getAllFixedSchedules(String authorizationHeader) ) )); - // 고정 스케줄 정보 생성 List scheduleResponses = groupedSchedules.entrySet().stream() .map(entry -> FixedScheduleResponse.of(entry.getKey(), entry.getValue())) .collect(Collectors.toList()); - // 고정 이벤트 정보 생성 - FixedEventResponse fixedEventResponse = FixedEventResponse.of(fixedEvent.getId(), fixedEvent.getStartTime(), fixedEvent.getEndTime(), scheduleResponses); + FixedEventResponse fixedEventResponse = FixedEventResponse.of(fixedEvent.getId(), scheduleResponses); fixedEventResponses.add(fixedEventResponse); } return fixedEventResponses; } - // 특정 고정 스케줄 상세 조회 메서드 + /** + * 특정 고정 스케줄 상세 조회 메서드. + * + * 특정 고정 이벤트 ID를 기반으로 상세 데이터를 조회합니다. + * FixedEventDetailResponse 객체로 반환합니다. + * + * @param authorizationHeader 인증 토큰 + * @param fixedEventId 조회할 고정 이벤트 ID + * @return 고정 이벤트 상세 데이터 + */ @Transactional(readOnly = true) public FixedEventDetailResponse getFixedScheduleDetail(String authorizationHeader, Long fixedEventId) { User user = jwtUtil.getUserFromHeader(authorizationHeader); - // 고정 이벤트 조회 FixedEvent fixedEvent = fixedEventRepository.findByUserAndFixedEventIdCustom(user, fixedEventId); if (fixedEvent == null) { throw new CustomException(FixedErrorStatus._NOT_FOUND_FIXED_EVENT); } - // 고정 선택을 요일별로 그룹화하여 시간 목록을 생성 (times를 오름차순 정렬) Map> groupedSchedules = fixedEvent.getFixedSelections().stream() .collect(Collectors.groupingBy( selection -> selection.getFixedSchedule().getDay(), @@ -116,30 +135,30 @@ public FixedEventDetailResponse getFixedScheduleDetail(String authorizationHeade ) )); - // 고정 스케줄 정보 생성 List scheduleResponses = groupedSchedules.entrySet().stream() .map(entry -> FixedScheduleResponse.of(entry.getKey(), entry.getValue())) .collect(Collectors.toList()); - // 고정 이벤트 상세 정보 반환 - return FixedEventDetailResponse.of(fixedEvent.getTitle(), fixedEvent.getStartTime(), fixedEvent.getEndTime(), scheduleResponses); + return FixedEventDetailResponse.of(fixedEvent.getTitle(), scheduleResponses); } - // 고정 스케줄 수정 메서드 + /** + * 고정 스케줄 수정 메서드. + * + * 기존 고정 이벤트의 스케줄 데이터를 삭제하고, + * 새로운 스케줄 데이터를 기반으로 수정합니다. + * + * @param authorizationHeader 인증 토큰 + * @param fixedEventId 수정할 고정 이벤트 ID + * @param modifyFixedEventRequest 수정 요청 데이터 + */ @Transactional public void modifyFixedSchedule(String authorizationHeader, Long fixedEventId, ModifyFixedEventRequest modifyFixedEventRequest) { User user = jwtUtil.getUserFromHeader(authorizationHeader); FixedEvent fixedEvent = fixedEventRepository.findByUserAndId(user, fixedEventId) .orElseThrow(() -> new CustomException(FixedErrorStatus._NOT_FOUND_FIXED_EVENT)); - List times = modifyFixedEventRequest.schedules().get(0).times(); - String startTime = times.get(0); - String endTime = times.get(times.size() - 1); - fixedEvent.updateStartTime(startTime); - fixedEvent.updateEndTime(addThirtyMinutes(endTime)); - fixedEventRepository.save(fixedEvent); - fixedSelectionRepository.deleteFixedSelectionsByEvent(fixedEvent); createFixedSchedules(modifyFixedEventRequest.schedules(), fixedEvent); } -} \ No newline at end of file +} diff --git a/src/test/java/side/onetime/fixed/FixedControllerTest.java b/src/test/java/side/onetime/fixed/FixedControllerTest.java index 9f50398..59bab2d 100644 --- a/src/test/java/side/onetime/fixed/FixedControllerTest.java +++ b/src/test/java/side/onetime/fixed/FixedControllerTest.java @@ -94,8 +94,8 @@ public void createFixedEvent() throws Exception { public void getAllFixedSchedules() throws Exception { // given List responses = List.of( - new FixedEventResponse(1L, "09:00", "10:00", List.of(new FixedScheduleResponse("월", List.of("09:00", "09:30")))), - new FixedEventResponse(2L, "09:00", "10:00", List.of(new FixedScheduleResponse("화", List.of("09:00", "09:30")))) + new FixedEventResponse(1L, List.of(new FixedScheduleResponse("월", List.of("09:00", "09:30")))), + new FixedEventResponse(2L, List.of(new FixedScheduleResponse("화", List.of("09:00", "09:30")))) ); Mockito.when(fixedScheduleService.getAllFixedSchedules(authorizationHeader)).thenReturn(responses); @@ -123,8 +123,6 @@ public void getAllFixedSchedules() throws Exception { fieldWithPath("code").type(JsonFieldType.STRING).description("HTTP 상태 코드"), fieldWithPath("message").type(JsonFieldType.STRING).description("응답 메시지"), fieldWithPath("payload[].id").type(JsonFieldType.NUMBER).description("고정 스케줄 ID"), - fieldWithPath("payload[].start_time").type(JsonFieldType.STRING).description("시작 시간"), - fieldWithPath("payload[].end_time").type(JsonFieldType.STRING).description("종료 시간"), fieldWithPath("payload[].schedules[].time_point").type(JsonFieldType.STRING).description("요일"), fieldWithPath("payload[].schedules[].times[]").type(JsonFieldType.ARRAY).description("시간 목록") ) @@ -138,7 +136,7 @@ public void getAllFixedSchedules() throws Exception { public void getFixedScheduleDetail() throws Exception { // given Long fixedEventId = 1L; - FixedEventDetailResponse response = new FixedEventDetailResponse("고정 이벤트", "09:00", "10:00", List.of(new FixedScheduleResponse("월", List.of("09:00", "09:30")))); + FixedEventDetailResponse response = new FixedEventDetailResponse("고정 이벤트", List.of(new FixedScheduleResponse("월", List.of("09:00", "09:30")))); Mockito.when(fixedScheduleService.getFixedScheduleDetail(authorizationHeader, fixedEventId)).thenReturn(response); // when @@ -168,8 +166,6 @@ public void getFixedScheduleDetail() throws Exception { fieldWithPath("code").type(JsonFieldType.STRING).description("HTTP 상태 코드"), fieldWithPath("message").type(JsonFieldType.STRING).description("응답 메시지"), fieldWithPath("payload.title").type(JsonFieldType.STRING).description("고정 스케줄 제목"), - fieldWithPath("payload.start_time").type(JsonFieldType.STRING).description("시작 시간"), - fieldWithPath("payload.end_time").type(JsonFieldType.STRING).description("종료 시간"), fieldWithPath("payload.schedules[].time_point").type(JsonFieldType.STRING).description("요일"), fieldWithPath("payload.schedules[].times[]").type(JsonFieldType.ARRAY).description("시간 목록") ) @@ -306,4 +302,4 @@ public void getFixedEventByDay() throws Exception { ) )); } -} \ No newline at end of file +}