Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

달력 조회 API를 작성 #50

Open
wants to merge 33 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
52eec9f
feat: 캘린더 조회 전략 패턴 적용
jiwon83 Oct 6, 2024
8689bf2
Merge remote-tracking branch 'origin/dev' into feat/#38
jiwon83 Oct 20, 2024
1c7b4c9
chore: querydsl 의존성 추가
jiwon83 Oct 20, 2024
271708e
feat: ScheduleRepository 에서 calendarId, startDate, endDate 로 List<Sch…
jiwon83 Oct 20, 2024
00d8042
feat: CalendarService 추가
jiwon83 Oct 20, 2024
42ec4e4
feat: CalendarServiceUtil의 Day, Week 반복 일정 조회 기능 구현
jiwon83 Nov 9, 2024
85a1f70
Test: Calendar, Schedule, Scheduleinfo Fixture 생성
jiwon83 Nov 9, 2024
3c99aa5
chore: wypl-core 모듈 lombok 설정
jiwon83 Nov 9, 2024
6d2f219
feat: 반복 주기 = Month 조회 기능 구현 in CalendarServiceUtil
jiwon83 Nov 10, 2024
979305d
fix: 반복 주기 = Week 조회 기능의 버그 수정
jiwon83 Nov 10, 2024
014915d
feat: 반복 주기 = Year 조회 기능 구현 in CalendarServiceUtil
jiwon83 Nov 17, 2024
0720586
refactor: 반복주기에 따른 할일 조회 기능 리팩토링
jiwon83 Nov 17, 2024
01c0a28
feat: Calendar Type에 따른 전략 클래스 구현
jiwon83 Nov 17, 2024
ed2643d
refactor: Calendar Type에 따른 전략 클래스 구현
jiwon83 Nov 23, 2024
3378cff
feat: ScheduleFindResponse.java 구현
jiwon83 Nov 23, 2024
f19b02a
Merge remote-tracking branch 'refs/remotes/origin/dev' into feat/#38
jiwon83 Nov 23, 2024
2c62b29
fix: fix build error
jiwon83 Nov 23, 2024
0ddc92b
Refactor(#38): refactor code related to calendar strategy
jiwon83 Nov 24, 2024
e023533
Merge remote-tracking branch 'origin/dev' into feat/#38
jiwon83 Dec 1, 2024
7527b60
refactor(#38): refactor & remove unnecessary code
jiwon83 Dec 1, 2024
697c02e
chore(#38): add dependency "testAnnotationProcessor"
jiwon83 Dec 1, 2024
2721398
feat(#38): add CalendarRepository
jiwon83 Dec 1, 2024
f609235
refactor(#38): reformat code for applying code convention
jiwon83 Dec 1, 2024
9bb8664
feat(#38): 달 반복 일정 조회 -
jiwon83 Dec 13, 2024
8ff0080
refactor(#38): Schedule 엔티티의 getDuration method 추가
jiwon83 Dec 15, 2024
5c43dcd
fix(#38): Week 반복주기 버그 개선
jiwon83 Dec 26, 2024
93200ad
refactor(#38): Stream 적용 및 리팩토링
jiwon83 Dec 26, 2024
5bd8b96
refactor(#38): Q클래스 static import 적용
jiwon83 Dec 28, 2024
dcfe121
feat(#38): dayOfYear과 dayOfWeek를 매개변수로 갖는 getNextOrSame 기능 구현
jiwon83 Dec 28, 2024
98a55a3
feat(#38): Add DateUtil.java
jiwon83 Jan 25, 2025
23f3794
refactor(#38): Year 반복 조회를 위한 findNextOrSame 수정
jiwon83 Jan 25, 2025
9b1b408
refactor(#38): RepetitionStrategy 리팩토링
jiwon83 Jan 25, 2025
d25eb0b
Merge branch 'dev' into feat/#38
KIMSEI1124 Jan 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.wypl.wyplcore.calendar.data;

import java.time.LocalDate;

public record DateSearchCondition(LocalDate startDate, LocalDate endDate) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.wypl.wyplcore.calendar.data.request;

import java.time.LocalDate;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.wypl.wyplcore.schedule.data.CalendarType;

public record CalendarFindRequest(

@JsonProperty("calendar_type")
CalendarType calendarType,

@JsonProperty("start_date")
LocalDate today
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.wypl.wyplcore.calendar.data.response;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.wypl.wyplcore.schedule.data.response.ScheduleFindResponse;

public record CalendarSchedulesResponse(

@JsonProperty("schedule_count")
int scheduleCount,

@JsonProperty("schedules")
List<ScheduleFindResponse> schedules
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.wypl.wyplcore.calendar.service;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.wypl.googleoauthclient.domain.AuthMember;
import com.wypl.jpacalendardomain.calendar.domain.Calendar;
import com.wypl.jpacalendardomain.calendar.domain.MemberCalendar;
import com.wypl.jpacalendardomain.calendar.domain.Schedule;
import com.wypl.jpacalendardomain.calendar.repository.ScheduleRepository;
import com.wypl.jpamemberdomain.member.domain.Member;
import com.wypl.wyplcore.calendar.data.DateSearchCondition;
import com.wypl.wyplcore.calendar.data.request.CalendarFindRequest;
import com.wypl.wyplcore.calendar.data.response.CalendarSchedulesResponse;
import com.wypl.wyplcore.calendar.service.strategy.CalendarStrategy;
import com.wypl.wyplcore.schedule.data.CalendarType;
import com.wypl.wyplcore.schedule.data.response.ScheduleFindResponse;
import com.wypl.wyplcore.schedule.service.repetition.RepetitionService;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class CalendarService {

private final ScheduleRepository scheduleRepository;

private final Map<CalendarType, CalendarStrategy> calendarStrategyMap;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 개인적인 의견이지만 calendarStrategies로 수정하는게 어떨까요?! 변수명에 자료구조 형식이 드러나는 것이 좋아보이지 않습니다!


/**
* 캘린더의 일정을 조회한다.
* @param authMember : 인증된 사용자 정보
* @param calendarId : 조회할 캘린더 ID
* @param calendarFindRequest : 캘린더 조회 조건
* @return FindCalendarResponse
*/
@Transactional(readOnly = true)
public CalendarSchedulesResponse findCalendar(AuthMember authMember, long calendarId,
CalendarFindRequest calendarFindRequest) {
Comment on lines +42 to +43
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public CalendarSchedulesResponse findCalendar(AuthMember authMember, long calendarId,
CalendarFindRequest calendarFindRequest) {
public CalendarSchedulesResponse findCalendar(
AuthMember authMember,
long calendarId,
CalendarFindRequest calendarFindRequest
) {

이런 형식으로 매개변수를 작성해보는건 어떨까요?!


Calendar foundCalendar = null; // FIXME: calendarId로 foundCalendar 엔티티 검증 필요.
MemberCalendar foundMemberCalendar = null; // FIXME: memberCalendar 엔티티 검증 필요.
Member foundMember = null; // FIXME: member 엔티티 검증 필요.

DateSearchCondition dateSearchCondition = getDateSearchCondition(calendarFindRequest.today(),
calendarFindRequest.calendarType());

List<Schedule> schedules = scheduleRepository.findByCalendarIdAndBetweenStartDateAndEndDate(calendarId,
dateSearchCondition.startDate(), dateSearchCondition.endDate());

List<ScheduleFindResponse> responses = schedules.stream()
.flatMap(schedule -> getScheduleResponsesWithRepetition(schedule, dateSearchCondition.startDate(),
dateSearchCondition.endDate()).stream())
.toList();

return new CalendarSchedulesResponse(responses.size(), responses);
}

/**
* RepetitionService를 통해 반복 일정을 가공하여 조회한다.
* @param schedule : 일정 정보
* @param startDate : 조회 시작일
* @param endDate : 조회 종료일
* @return List<ScheduleFindResponse> : 일정 반복 정보를 통해 리스트 형태로 가공하여 반환된다.
*/
private List<ScheduleFindResponse> getScheduleResponsesWithRepetition(Schedule schedule, LocalDate startDate,
LocalDate endDate) {
return RepetitionService.getScheduleResponses(schedule, startDate, endDate);
}

/**
* CalendarType에 따라 DateSearchCondition을 반환한다.
* @param today : 조회 기준일
* @param calendarType : 조회할 캘린더 타입
* @return DateSearchCondition : DateSearchCondition 객체를 반환한다.
*/
private DateSearchCondition getDateSearchCondition(LocalDate today, CalendarType calendarType) {
return calendarStrategyMap.get(calendarType).getDateSearchCondition(today);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.wypl.wyplcore.calendar.service;

import java.time.LocalDate;

public class CalendarServiceUtil {

public static LocalDate getMaxDate(LocalDate date1, LocalDate date2) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음 혹시 getNewestDate는 어떨까요?? 아래 내용도 getOldestDate도 괜찮을 것 같다고 생각합니다!

해당 반환값이 Number형식이 아닌 날짜 형식이기 때문에 메서드명을 수정하시는게 어떨까 생각합니다!

return date1.isBefore(date2) ? date2 : date1;
}

public static LocalDate getMinDate(LocalDate date1, LocalDate date2) {
return date1.isBefore(date2) ? date1 : date2;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.wypl.wyplcore.calendar.service.strategy;

import java.time.LocalDate;

import com.wypl.wyplcore.calendar.data.DateSearchCondition;
import com.wypl.wyplcore.schedule.data.CalendarType;

public interface CalendarStrategy {

CalendarType getCalendarType();

DateSearchCondition getDateSearchCondition(LocalDate today);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.wypl.wyplcore.calendar.service.strategy;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.wypl.wyplcore.schedule.data.CalendarType;

@Configuration
public class CalendarStrategyConfig {

private final Map<CalendarType, CalendarStrategy> calendarStrategyMap = new HashMap<>();

@Autowired
public CalendarStrategyConfig(List<CalendarStrategy> calendarStrategies) {
calendarStrategies.forEach(calendarStrategy -> {
calendarStrategyMap.put(calendarStrategy.getCalendarType(), calendarStrategy);
});
}

@Bean
public Map<CalendarType, CalendarStrategy> calendarStrategyMap() {
return calendarStrategyMap;
}
Comment on lines +25 to +28
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CalendarService에서 피드백을 준 내용을 토대로 수정한다면 해당 @Bean의 이름이 수정되어야 합니다!

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.wypl.wyplcore.calendar.service.strategy;

import java.time.LocalDate;

import org.springframework.stereotype.Component;

import com.wypl.wyplcore.calendar.data.DateSearchCondition;
import com.wypl.wyplcore.schedule.data.CalendarType;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class DayCalendarStrategy implements CalendarStrategy {

@Override
public CalendarType getCalendarType() {
return CalendarType.DAY;
}

@Override
public DateSearchCondition getDateSearchCondition(LocalDate today) {
return new DateSearchCondition(today, today);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.wypl.wyplcore.calendar.service.strategy;

import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;

import org.springframework.stereotype.Component;

import com.wypl.wyplcore.calendar.data.DateSearchCondition;
import com.wypl.wyplcore.schedule.data.CalendarType;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class MonthCalendarStrategy implements CalendarStrategy {

@Override
public CalendarType getCalendarType() {
return CalendarType.MONTH;
}

@Override
public DateSearchCondition getDateSearchCondition(LocalDate today) {
LocalDate searchStartDate = today.withDayOfMonth(1);
LocalDate searchEndDate = today.with(TemporalAdjusters.lastDayOfMonth());
return new DateSearchCondition(searchStartDate, searchEndDate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.wypl.wyplcore.calendar.service.strategy;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;

import org.springframework.stereotype.Component;

import com.wypl.wyplcore.calendar.data.DateSearchCondition;
import com.wypl.wyplcore.schedule.data.CalendarType;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class WeekCalendarStrategy implements CalendarStrategy {

@Override
public CalendarType getCalendarType() {
return CalendarType.WEEK;
}

@Override
public DateSearchCondition getDateSearchCondition(LocalDate today) {
LocalDate searchStartDate = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
LocalDate searchEndDate = today.plusDays(6);
return new DateSearchCondition(searchStartDate, searchEndDate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
public enum ReviewErrorCode implements ServerErrorCode {
EMPTY_CONTENTS(500, "REVIEW_001", "작성된 내용이 없습니다."),
INVALID_TITLE(500, "REVIEW_002", "제목의 길이가 올바르지 않습니다."),
NO_SUCH_REVIEW(500, "REVIEW_003", "존재하지 않는 회고입니다.")
;
NO_SUCH_REVIEW(500, "REVIEW_003", "존재하지 않는 회고입니다.");

private final int statusCode;
private final String errorCode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public ReviewIdResponse createReview(long memberId, ReviewCreateRequest reviewCr
public ReviewIdResponse updateReview(long memberId, long reviewId, ReviewUpdateRequest reviewUpdateRequest) {
validateReviewContents(reviewUpdateRequest.contents(), reviewUpdateRequest.title());

Member member = null; // Todo : 조회
Member member = null; // Todo : 조회

Review review = ReviewUtils.findByReviewIdAndMember(reviewRepository, reviewId, member);
review.updateTitle(reviewUpdateRequest.title());
Expand All @@ -82,7 +82,7 @@ public ReviewIdResponse updateReview(long memberId, long reviewId, ReviewUpdateR
@Override
@Transactional
public ReviewIdResponse deleteReview(long memberId, long reviewId) {
Member member = null; // Todo : 조회
Member member = null; // Todo : 조회
Review review = ReviewUtils.findByReviewIdAndMember(reviewRepository, reviewId, member);

ReviewContents reviewContents = reviewContentsRepository.findByReviewIdAndDeletedAtNull(review.getReviewId());
Expand All @@ -97,7 +97,7 @@ public ReviewIdResponse deleteReview(long memberId, long reviewId) {

@Override
public ReviewDetailResponse getDetailReview(long memberId, long reviewId) {
Member member = null; // Todo : 조회
Member member = null; // Todo : 조회
Review review = ReviewUtils.findByReviewIdAndMember(reviewRepository, reviewId, member);
Schedule schedule = review.getSchedule();

Expand Down Expand Up @@ -165,8 +165,8 @@ public ReviewListResponse getReviewsByScheduleId(long memberId, long scheduleId,
// MemberSchedule memberSchedule = memberScheduleService.getMemberScheduleByMemberAndSchedule(memberId,
// ScheduleServiceUtils.findById(scheduleRepository, scheduleId));

Member member = null; // Todo : 조회
Schedule schedule = null; // Todo : 조회
Member member = null; // Todo : 조회
Schedule schedule = null; // Todo : 조회

List<Review> reviews = switch (reviewType) {
case NEWEST -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@
@RequestMapping("/schedule/v2/schedules")
public class ScheduleController {

private final ScheduleService scheduleService;
private final ScheduleService scheduleService;

@PostMapping
public WyplResponseEntity<ScheduleInfoCreateResponse> addSchedule(@Authenticated AuthMember authMember, @RequestBody ScheduleCreateRequest scheduleCreateRequest) {
ScheduleInfoCreateResponse response = scheduleService.createSchedule(authMember, scheduleCreateRequest);
return WyplResponseEntity.created(response, "일정이 생성됐습니다.");
}
@PostMapping
public WyplResponseEntity<ScheduleInfoCreateResponse> addSchedule(@Authenticated AuthMember authMember,
@RequestBody ScheduleCreateRequest scheduleCreateRequest) {
Comment on lines +25 to +26
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 내용도 위에는 있지만!

Suggested change
public WyplResponseEntity<ScheduleInfoCreateResponse> addSchedule(@Authenticated AuthMember authMember,
@RequestBody ScheduleCreateRequest scheduleCreateRequest) {
public WyplResponseEntity<ScheduleInfoCreateResponse> addSchedule(
@Authenticated AuthMember authMember,
@RequestBody ScheduleCreateRequest scheduleCreateRequest
) {

와 같이 수정하는게 더 보기 편하다고 생각하는데 어떠신가요?

ScheduleInfoCreateResponse response = scheduleService.createSchedule(authMember, scheduleCreateRequest);
return WyplResponseEntity.created(response, "일정이 생성됐습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.wypl.wyplcore.schedule.data;

public enum CalendarType {
DAY, WEEK, MONTH
}
Loading
Loading