-
Notifications
You must be signed in to change notification settings - Fork 0
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
[✨ feat] 약속 가능 시간 조회 API 구현 #65
Conversation
- `AvailableTimeRequest` → `AppointmentMemberAvailableTimeRequest`로 변경하여 명확한 의미 전달 - 관련 생성 메서드(`of`)에서 변경된 DTO명 반영
- `AvailableTimesRequest` → `AppointmentMemberAvailableTimesRequest`로 변경하여 의미를 보다 명확하게 표현 - 내부 필드 타입을 `AppointmentMemberAvailableTimeRequest`로 변경 - 관련 정적 팩토리 메서드(`of`)에서 변경 사항 반영
… 변경에 따른 테스트 코드 수정
약속의 호스트 선택 시간을 저장하는 `AppointmentHostSelectionTime` 엔티티를 추가하였습니다. - `Appointment`와 N:1 관계를 가짐 (`@ManyToOne`) - 선택 날짜(date), 시작 시간(startTime), 종료 시간(endTime) 필드 포함 - 생성자 숨기고 `of` 정적 메서드를 통해 객체 생성 가능하도록 구현 - `BaseTimeEntity`를 상속하여 생성 및 수정 시간 관리
약속 호스트 선택 시간을 관리하는 `AppointmentHostSelectionTimeRepository`를 추가하였습니다. - `JpaRepository<AppointmentHostSelectionTime, Long>`를 상속하여 기본 CRUD 기능 제공 - 특정 약속 ID에 대한 호스트 선택 시간을 조회하는 `findByAppointmentId` 메서드 구현
- `AppointmentHostSelectionTimes`를 `AppointmentHostSelectionTimeRequest`로 변경 - DTO에서 엔티티를 직접 참조하지 않도록 수정하여 계층 분리 강화 - 정적 팩토리 메서드(`of`)도 변경된 타입을 반영하도록 수정
- 약속 호스트 선택 시간 정보를 전달하기 위한 `AppointmentHostSelectionTimeRequest` DTO 추가 - `date`, `startTime`, `endTime` 필드 포함 - 정적 팩토리 메서드(`of`)를 제공하여 객체 생성 지원 - 엔티티(`AppointmentHostSelectionTime`)와의 분리를 통해 계층 간 의존성 최소화
- 기존 `AppointmentMemberAvailableTimes` 엔티티를 `AppointmentMemberAvailableTime`으로 대체하여 삭제 - 단수형(`Time`)으로 변경하여 의미 명확화 - `of` 정적 메서드에서 동일한 로직을 유지하며 새 클래스에 맞게 수정 - 관련 코드에서 새로운 엔티티를 참조하도록 정리
- 기존 `AppointmentMemberAvailableTimesRepository`를 `AppointmentMemberAvailableTimeRepository`로 변경하여 단수형으로 통일 - 패키지 경로에서 `repository` 디렉터리 제거하여 구조 단순화 - 관련 코드에서 새로운 인터페이스를 참조하도록 정리
- `repository` 패키지를 제거하고 `AppointmentMemberRepository`를 `domain` 패키지로 이동 - 기존 인터페이스와 동일한 기능 유지 - 코드 구조 단순화 및 패키지 일관성 유지
- `repository` 패키지를 제거하고 `AppointmentMemberRepositoryCustom`을 `domain` 패키지로 이동 - 기존 `findByMemberIdAndAppointmentId` 메서드 유지 - `findAllWithAvailableTimes(appointmentId)` 메서드 추가하여 특정 약속의 모든 멤버와 가능한 시간을 조회할 수 있도록 개선
- `repository` 패키지를 제거하고 `AppointmentMemberRepositoryImpl`을 `domain` 패키지로 이동 - QueryDSL을 활용한 `findByMemberIdAndAppointmentId` 메서드 유지 - `findAllWithAvailableTimes(appointmentId)` 메서드 추가하여 특정 약속의 멤버와 가능 시간을 함께 조회할 수 있도록 개선 - Q타입 필드를 정리하고 `static import`를 활용하여 코드 가독성 향상
- `GroupRepositoryTest`의 패키지를 `org.noostak.server.group.domain`에서 `org.noostak.group.domain`으로 이동 - 중복된 `import org.noostak.server.group.domain.GroupRepositoryTest;` 제거 - 관련된 테스트 코드에서 변경된 패키지를 참조하도록 수정하여 일관성 유지
- `AvailableTimesRequest`를 `AppointmentMemberAvailableTimesRequest`로 변경하여 명확성 강화 - `appointmentSaveAvailableTimesService`를 `appointmentMemberSaveAvailableTimesService`로 교체하여 일관성 유지 - 기존 주석 처리된 `@AuthenticationPrincipal`을 유지하고, 하드코딩된 `memberId` 값 유지 - 관련된 서비스 호출 및 요청 DTO 변경에 맞춰 코드 수정
… 서비스 인터페이스 추가 - 특정 멤버의 약속 가용 시간을 조회하는 `getAvailableTimes` 메서드 정의 - `memberId`와 `appointmentId`를 입력받아 `AppointmentMembersAvailableTimesResponse` 반환 - 가용 시간 조회 기능을 추상화하여 서비스 구현 클래스에서 활용 가능하도록 설계
…간 조회 서비스 구현 - 특정 약속에 대한 멤버들의 가용 시간을 조회하는 서비스 구현 클래스 추가 - `findAppointmentMember` : 특정 멤버가 약속에 속하는지 검증 - `findHostSelectionTimes` : 호스트가 설정한 선택 가능 시간 조회 - `findAppointmentMembersInfo` : 약속에 속한 멤버들의 가용 시간 조회 - `findAvailableTimesForMember` : 특정 멤버의 가용 시간 조회 - `createAppointmentResponse` : 조회된 데이터를 가공하여 응답 DTO 생성 - `AppointmentMemberRetrieveAvailableTimesService` 인터페이스 구현 - `@Transactional(readOnly = true)` 적용하여 조회 성능 최적화
…변경 및 로직 개선 - `AppointmentMemberAvailableTimes` → `AppointmentMemberAvailableTime`으로 변경하여 단수형 일관성 유지 - 기존 `refreshAvailableTimes` 로직을 `isTimeUpdateRequired`, `updateAvailableTimes`, `markAppointmentTimeIfNecessary`로 분리하여 가독성과 유지보수성 개선 - `isTimeUpdateRequired` : 변경이 필요한 경우만 업데이트 수행하도록 검증 로직 추가 - `updateAvailableTimes` : 기존 데이터를 삭제 후 새로운 데이터 저장 - `markAppointmentTimeIfNecessary` : 멤버의 가용 시간 업데이트 - 기존 Set 비교 방식 정리하여 코드 간결화
- `APPOINTMENT_MEMBER_AVAILABLE_TIMES_RETRIEVED` 성공 코드 추가 - 약속 멤버의 가용 시간을 성공적으로 조회했을 때 반환되는 메시지 정의 - 기존 `SUCCESS_SAVE_AVAILABLE_TIMES` 코드와 일관성을 유지하며 기능 확장
- `appointmentTimeSet` 필드 추가하여 약속 멤버가 가용 시간을 설정했는지 여부 저장 (`false` 기본값) - `updateAvailableTimes` 메서드 추가하여 가용 시간이 존재할 경우 `appointmentTimeSet`을 `true`로 변경 - `of` 정적 팩토리 메서드에서 `appointmentTimeSet`을 기본 `false`로 초기화하여 일관성 유지
- 호스트가 설정한 선택 가능 시간을 응답하기 위한 DTO 추가 - `date`, `startTime`, `endTime` 필드를 포함하여 시간 정보를 제공 - 정적 팩토리 메서드(`of`)를 추가하여 객체 생성 방식 통일
- 여러 개의 호스트 선택 시간을 포함하는 응답 DTO 추가 - `appointmentHostSelectionTimeResponses` 리스트 필드 포함 - 정적 팩토리 메서드(`of`)를 제공하여 객체 생성 방식 통일
- 멤버가 설정한 가용 시간을 응답하기 위한 DTO 추가 - `date`, `startTime`, `endTime` 필드를 포함하여 시간 정보를 제공 - 정적 팩토리 메서드(`of`)를 추가하여 객체 생성 방식 통일
- 여러 개의 멤버 가용 시간을 포함하는 응답 DTO 추가 - `appointmentMemberAvailableTimesResponseResponse` 리스트 필드 포함 - 정적 팩토리 메서드(`of`)를 제공하여 객체 생성 방식 통일
- 멤버의 기본 정보와 가용 시간을 포함하는 응답 DTO 추가 - `memberId`, `memberName`, `appointmentMemberAvailableTimesResponse` 필드 포함 - 정적 팩토리 메서드(`of`)를 제공하여 객체 생성 방식 통일
…O 추가 - 멤버의 가용 시간 설정 여부(`isAppointMemberTimeSet`)를 포함하는 응답 DTO 추가 - 전체 일정 정보를 담는 `appointmentScheduleResponse` 필드 포함 - 정적 팩토리 메서드(`of`)를 제공하여 객체 생성 방식 통일
- 호스트가 설정한 선택 가능 시간(`appointmentHostSelectionTimesResponse`) 포함 - 약속 멤버들의 정보(`appointmentMemberInfoResponse`) 목록 포함 - 정적 팩토리 메서드(`of`)를 제공하여 객체 생성 방식 통일
…트 수정 - `AppointmentHostSelectionTimes` → `AppointmentHostSelectionTimeRequest`로 변경하여 DTO 사용 - `createSelectionTimes` 메서드에서 DTO 객체를 생성하도록 수정 - `appointmentHostSelectionTimeRepository` 추가 및 `AppointmentCreateServiceImpl` 생성자 변경 반영 - `appointments.get(0)` → `appointments.getFirst()`로 수정하여 가독성 향상
… 테스트 구현 - `AppointmentHostSelectionTimeRepository`의 테스트용 구현 추가 - 인메모리 리스트를 사용하여 엔티티 저장 및 조회 기능 지원 - `save`, `findByAppointmentId`, `deleteByAppointmentId` 등 핵심 기능 구현 - `AtomicLong`을 사용하여 ID 자동 증가 기능 추가 - `findAll`, `count`, `existsById` 등 기본적인 CRUD 메서드 지원 - 사용되지 않는 일부 메서드는 기본 반환값으로 설정
…가용 시간 조회 서비스 테스트 구현 - 약속 멤버의 가용 시간을 조회하는 서비스의 단위 테스트 추가 - 성공 케이스: - `shouldRetrieveAvailableTimesSuccessfully` : 멤버의 약속 가능 시간을 정상 조회 - `shouldRetrieveCorrectAvailableTimes` : 특정 시간대의 가용 시간 검증 - `shouldRetrieveAvailableTimesForMultipleMembers` : 여러 멤버의 가용 시간 조회 검증 - 실패 케이스: - `shouldThrowExceptionWhenUserIsNotAppointmentMember` : 약속 멤버가 아닌 경우 예외 발생 - `shouldThrowExceptionWhenMemberDoesNotExist` : 존재하지 않는 멤버 조회 시 예외 발생 - `shouldThrowExceptionWhenAppointmentDoesNotExist` : 존재하지 않는 약속 조회 시 예외 발생 - `shouldThrowExceptionWhenMemberIsNotLinkedToAppointment` : 멤버가 약속과 연결되지 않은 경우 예외 발생 - 테스트 데이터 초기화 및 정리: - `setUp`, `tearDown`을 활용하여 테스트 환경 유지 - `initializeRepositories`, `initializeTestData`를 통해 초기 데이터 설정 - `AppointmentMemberAvailableTimesResponse`의 필드명 `appointmentMemberAvailableTimesResponseResponse` 수정 필요 가능성 검토
…비스 테스트 개선 - `AppointmentMemberAvailableTimes` → `AppointmentMemberAvailableTime`으로 변경하여 단수형 적용 - `shouldNotChangeAppointmentTimeSetWhenSameTimesExist` 테스트 추가: - 동일한 시간 정보 저장 시 `appointmentTimeSet`이 변경되지 않는지 검증 - `shouldNotSetAppointmentTimeSetWhenNoNewTimes` 테스트 추가: - 가능 시간이 없을 경우 `appointmentTimeSet`이 `true`로 변경되지 않는지 검증 - 기존 `findByAppointmentMember` 관련 검증 코드에서 변경된 엔티티 명칭 반영
…및 명칭 변경 - `AppointmentMemberAvailableTimes` → `AppointmentMemberAvailableTime`으로 변경하여 단수형 적용 - `save`, `findByAppointmentMember`, `deleteAll` 등 관련 메서드의 타입 변경 - 기존 `getOne`, `getById`, `getReferenceById` 등의 불필요한 메서드는 기본 반환값 유지 - 코드 일관성을 위해 `availableTimes` 리스트의 제네릭 타입 변경 - `saveAll` 및 `findAll` 메서드에서 변경된 엔티티 명칭 반영
- `findAllWithAvailableTimes(Long appointmentId)` 메서드 추가하여 특정 약속의 모든 멤버 조회 지원 - 중복된 `deleteAllById`, `deleteAll`, `deleteAllInBatch` 메서드 정리 - `findById(Long id)`, `saveAll(Iterable<S> entities)` 등 기존 메서드 유지 - 코드 정리 및 가독성 향상을 위한 불필요한 줄바꿈 제거
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니다! DTO 클래스 변환 관련해서 리뷰 남겨드렸고, 질문 몇 가지 남겨 놓았습니다.
그리고 누락된 연관관계 설정이 어디 부분인지 알 수 있을까요?
private AppointmentMember(final AppointmentAvailability appointmentAvailability, final Appointment appointment, final Member member) { | ||
@Column(name = "appointment_time_set") | ||
private boolean appointmentTimeSet; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 혹시 어떤 필드인가요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ERD에서 약속 멤버 테이블을 확인해 보니, 약속 시간 입력 여부를 고려하지 않고 초반 설계에서 빠뜨렸던 것 같아요. 이번에 해당 부분을 반영하여 추가했습니다! 😊
time.getStartTime(), | ||
time.getEndTime() | ||
)) | ||
.collect(Collectors.toList()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
검토 요청 사항이 이 부분인 듯 한데, findBy를 통해 찾은 List를 DTO 변환하는 메소드는..
findHostSelectionTimes
보다 fetchHostSelectionTimes
를 사용하는게 적절해 보입니다 🙂
로직 자체는 문제 없습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
피드백 감사합니다!
저도 find보다는 fetch가 이 상황에 더 적절한 네이밍이라는 의견에 공감합니다. 🙂
해당 부분 반영하겠습니다!
|
||
private boolean isTimeUpdateRequired(AppointmentMember appointmentMember, List<AppointmentMemberAvailableTime> newTimes) { | ||
List<AppointmentMemberAvailableTime> existingTimes = appointmentMemberAvailableTimesRepository.findByAppointmentMember(appointmentMember); | ||
return !Set.copyOf(existingTimes).equals(Set.copyOf(newTimes)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
피드백 감사합니다!
네, copyOf를 사용하면 객체의 주소값을 기준으로 비교가 이루어지므로, 이를 고려하여 AppointmentMemberAvailableTime 클래스에 @EqualsAndHashCode 어노테이션을 추가했습니다. 해당 어노테이션을 통해 값 자체를 기준으로 비교하도록 설정하여, 기존 데이터와 새로운 데이터의 동등성 판단이 정확하게 이루어지도록 했습니다. 😊
🚀 What’s this PR about?
🛠️ What’s been done?
🧪 Testing Details
👀 Checkpoints for Reviewers
🎯 Related Issues