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

[🧬 merge] develop -> staging #109

Merged
merged 551 commits into from
Feb 27, 2025
Merged

[🧬 merge] develop -> staging #109

merged 551 commits into from
Feb 27, 2025

Conversation

jsoonworld
Copy link
Member

πŸš€ Merge PR: develop -> main

  • μš”μ•½: develop λΈŒλžœμΉ˜μ—μ„œ μž‘μ—…ν•œ μ‹ κ·œ κΈ°λŠ₯ 및 κ΅¬ν˜„ 사항을 staging 브랜치둜 λ³‘ν•©ν•©λ‹ˆλ‹€.

πŸ› οΈ Key Updates

  • μ£Όμš” 변경사항:
    • κ΅¬ν˜„λœ API 머지

πŸ“Œ Notes for Reviewers

  • 확인할 사항:
    • 병합 ν›„ μ£Όμš” κΈ°λŠ₯ 정상 μž‘λ™ μ—¬λΆ€.
    • μ½”λ“œ 좩돌 κ°€λŠ₯μ„± 및 영ν–₯ λ²”μœ„ 확인.

0-tae and others added 30 commits February 25, 2025 16:07
- null을 ν—ˆμš©ν•  수 없도둝 λ³€κ²½
- νŒŒλΌλ―Έν„°λ‘œ 받은 token에 λŒ€ν•˜μ—¬ μœ νš¨μ„± 검증을 μˆ˜ν–‰ν•˜λ„λ‘ 둜직 λ³€κ²½
- 정적 νŒ©ν† λ¦¬ λ©”μ†Œλ“œ νŒ¨ν„΄ μΆ”κ°€
- ν•΄λ‹Ή Repository λ‚΄λΆ€μ—μ„œ μ˜ˆμ™Έμ²˜λ¦¬ 진행
- MEMBER_NOT_FOUND μƒμˆ˜ 클래슀 μΆ”κ°€
- ν•΄λ‹Ή Repository λ‚΄λΆ€μ—μ„œ μ˜ˆμ™Έμ²˜λ¦¬ 진행
- ν•΄λ‹Ή Repository λ‚΄λΆ€μ—μ„œ μ˜ˆμ™Έμ²˜λ¦¬ 진행
- optionId에 ν•΄λ‹Ήλœ Like 갯수λ₯Ό κ΅¬ν•˜λŠ” getLikeCountByOptionId κ΅¬ν˜„
- appointmentMemberId에 ν•΄λ‹Ήλœ Like 갯수λ₯Ό κ΅¬ν•˜λŠ” getLikeCountByAppointmentMemberId κ΅¬ν˜„
- μ’‹μ•„μš”λ₯Ό μ €μž₯ν•œ λ’€, OptionId에 ν•΄λ‹Ήν•˜λŠ” μ’‹μ•„μš”μ˜ 갯수λ₯Ό λ°˜ν™˜
- JwtInterceptorμ—μ„œ λ°˜ν™˜ν•œλ‹€ κ°€μ •
- κ°’ 인자λ₯Ό λ©”μ‹œμ§€μ— μ „λ‹¬ν•˜κΈ° μœ„ν•΄ μΆ”κ°€
- 0일 λ•Œ μ‚­μ œν•˜λ €λŠ” 경우 μ˜ˆμ™Έμ²˜λ¦¬ μΆ”κ°€
- μ’‹μ•„μš” μ‚­μ œ 정상 처리 μ—¬λΆ€ 확인
- μ’‹μ•„μš” κ°―μˆ˜κ°€ 0개일 λ•Œ μ‚­μ œν•˜λ €λŠ” 경우 μ˜ˆμ™Έμ²˜λ¦¬ 확인
- μ—”λ“œν¬μΈνŠΈ ꡬ쑰λ₯Ό `/api/v1` 기반으둜 λ³€κ²½
- κΈ°μ‘΄ `@PostMapping` 경둜λ₯Ό `/groups/{groupId}/appointments`둜 λͺ…μ‹œμ μœΌλ‘œ λ³€κ²½
- `getRecommendedAppointmentOptions` λ©”μ„œλ“œ μΆ”κ°€ν•˜μ—¬ μΆ”μ²œ μ˜΅μ…˜ 쑰회 κΈ°λŠ₯ κ΅¬ν˜„
- TODO: GROUP으둜 이동해야 ν•˜λŠ” 둜직 쑴재 (μΆ”ν›„ μˆ˜μ • ν•„μš”)
- `org.noostak.appointment.application`μ—μ„œ `org.noostak.appointment.application.create`둜 이동
- μ„œλΉ„μŠ€ 역할을 λͺ…ν™•νžˆ ν•˜κΈ° μœ„ν•΄ `create` ν•˜μœ„ νŒ¨ν‚€μ§€λ‘œ 뢄리
- `GroupConfirmedAppointmentsService` μΈν„°νŽ˜μ΄μŠ€ μΆ”κ°€
- `getGroupConfirmedAppointments(Long memberId, Long groupId)` λ©”μ„œλ“œ μ •μ˜ (κ·Έλ£Ή λ‚΄ ν™•μ •λœ 약속 쑰회)
- κ·Έλ£Ή ν™•μ •λœ 약속 데이터λ₯Ό μ„œλΉ„μŠ€ κ³„μΈ΅μ—μ„œ κ΄€λ¦¬ν•˜λ„λ‘ κΈ°λŠ₯ ν™•μž₯
- `GroupConfirmedAppointmentsServiceImpl` 클래슀 μΆ”κ°€ 및 `GroupConfirmedAppointmentsService` κ΅¬ν˜„
- `getGroupConfirmedAppointments(Long memberId, Long groupId)` λ©”μ„œλ“œ κ΅¬ν˜„ (κ·Έλ£Ή λ‚΄ ν™•μ •λœ 약속 쑰회)
  - κ·Έλ£Ή 정보 쑰회 및 ν”„λ‘œν•„ 이미지 URL λ°˜ν™˜ (`getGroup`, `getGroupProfileImageUrl`)
  - 그룹에 μ†ν•œ ν™•μ •λœ 약속 λͺ©λ‘ 쑰회 (`getConfirmedAppointments`)
  - ν™•μ •λœ 약속 μ˜΅μ…˜ 쑰회 (`getConfirmedAppointmentOptions`)
  - μ‘°νšŒν•œ 데이터λ₯Ό `GroupConfirmedAppointmentsResponse`둜 λ³€ν™˜ν•˜μ—¬ λ°˜ν™˜
- `S3Service`λ₯Ό ν™œμš©ν•΄ κ·Έλ£Ή ν”„λ‘œν•„ 이미지 URL 쑰회
- κ·Έλ£Ή ν™•μ •λœ 약속을 효율적으둜 μ‘°νšŒν•˜κ³  응닡을 κ΅¬μ„±ν•˜λŠ” κΈ°λŠ₯ κ΅¬ν˜„
- `GroupCreateService` μΈν„°νŽ˜μ΄μŠ€ μΆ”κ°€
- `createGroup(Long memberId, GroupCreateRequest createGroupRequest)` λ©”μ„œλ“œ μ •μ˜ (κ·Έλ£Ή 생성 κΈ°λŠ₯ 제곡)
- κ·Έλ£Ή 생성 μš”μ²­μ„ μ²˜λ¦¬ν•˜κ³  λ‚΄λΆ€ 응닡 객체 λ°˜ν™˜ (`GroupCreateInternalResponse`)
- κ·Έλ£Ή 생성 κ΄€λ ¨ λ‘œμ§μ„ μ„œλΉ„μŠ€ κ³„μΈ΅μ—μ„œ κ΄€λ¦¬ν•˜λ„λ‘ 섀계
- `GroupCreateService` μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„ (`GroupCreateServiceImpl` 클래슀 μΆ”κ°€)
- `createGroup(Long memberId, GroupCreateRequest request)` λ©”μ„œλ“œ κ΅¬ν˜„
  - `findGroupHost(memberId)`: κ·Έλ£Ή 호슀트 쑰회 및 검증
  - `uploadGroupProfileImageSafely(request.file())`: ν”„λ‘œν•„ 이미지 μ—…λ‘œλ“œ
  - `createGroup(groupHost, request.groupName(), response.getKey())`: κ·Έλ£Ή 객체 생성
  - `saveGroup(group, response.getUrl(), response.getKey())`: κ·Έλ£Ή μ €μž₯ 및 응닡 λ°˜ν™˜
- μ˜ˆμ™Έ λ°œμƒ μ‹œ μ—…λ‘œλ“œλœ ν”„λ‘œν•„ 이미지λ₯Ό μ•ˆμ „ν•˜κ²Œ μ‚­μ œν•˜λŠ” 둜직 μΆ”κ°€ (`deleteUploadedImageSafely`)
- S3λ₯Ό μ΄μš©ν•œ 이미지 μ—…λ‘œλ“œ 및 μ‚­μ œ κΈ°λŠ₯ 포함
- κ·Έλ£Ή 생성 κΈ°λŠ₯을 μ•ˆμ •μ μœΌλ‘œ μ œκ³΅ν•˜κΈ° μœ„ν•œ μ„œλΉ„μŠ€ κ΅¬ν˜„
- `GroupConfirmedAppointmentsService` μ˜μ‘΄μ„± μΆ”κ°€
- `getGroupConfirmedAppointments(Long memberId, Long groupId)` λ©”μ„œλ“œ κ΅¬ν˜„
  - `groupConfirmedAppointmentsService.getGroupConfirmedAppointments(memberId, groupId)` ν˜ΈμΆœν•˜μ—¬ κ·Έλ£Ή ν™•μ •λœ 약속 쑰회
- κ·Έλ£Ή μ„œλΉ„μŠ€μ—μ„œ ν™•μ •λœ 약속을 μ‘°νšŒν•  수 μžˆλ„λ‘ κΈ°λŠ₯ ν™•μž₯
- `CONFIRMED_OPTION_NOT_FOUND` 였λ₯˜ μ½”λ“œ μΆ”κ°€ (ν™•μ •λœ 약속 μ˜΅μ…˜μ„ 찾을 수 μ—†λŠ” 경우)
- `MEMBER_NOT_FOUND` 였λ₯˜ μ½”λ“œ 쀑볡 μ„ μ–Έ μˆ˜μ •
- κ·Έλ£Ή κ΄€λ ¨ μ˜ˆμ™Έ 처리λ₯Ό λͺ…ν™•ν•˜κ²Œ κ΅¬λΆ„ν•˜κΈ° μœ„ν•œ κΈ°λŠ₯ μΆ”κ°€
- `GROUP_CONFIRMED_APPOINTMENTS_LOADED` 성곡 μ½”λ“œ μΆ”κ°€ (κ·Έλ£Ή ν™•μ •λœ 약속 쑰회 성곡 응닡)
- `GROUP_ONGOING_APPOINTMENTS_LOADED` 쀑볡 μ„ μ–Έ μˆ˜μ •
- κ·Έλ£Ή κ΄€λ ¨ 응닡 λ©”μ‹œμ§€λ₯Ό λͺ…ν™•ν•˜κ²Œ κ΅¬λΆ„ν•˜κΈ° μœ„ν•œ κΈ°λŠ₯ μΆ”κ°€
- `AppointmentTimeResponse` λ ˆμ½”λ“œ μΆ”κ°€ (μ•½μ†μ˜ λ‚ μ§œ, μ‹œμž‘ μ‹œκ°„, μ’…λ£Œ μ‹œκ°„μ„ μ‘λ‹΅μœΌλ‘œ 전달)
- `of` νŒ©ν† λ¦¬ λ©”μ„œλ“œ μΆ”κ°€ν•˜μ—¬ μΈμŠ€ν„΄μŠ€ 생성 νŽΈμ˜μ„± 제곡
- ν™•μ •λœ 약속 쑰회 응닡에 μ‚¬μš©λ  μ‹œκ°„ κ΄€λ ¨ 정보λ₯Ό μ²˜λ¦¬ν•˜λŠ” DTO κ΅¬ν˜„
- `ConfirmedAppointmentsResponse` λ ˆμ½”λ“œ μΆ”κ°€ (약속 ID, 이름, μΉ΄ν…Œκ³ λ¦¬, μ‹œκ°„ 정보λ₯Ό μ‘λ‹΅μœΌλ‘œ 전달)
- `of` νŒ©ν† λ¦¬ λ©”μ„œλ“œ μΆ”κ°€ν•˜μ—¬ μΈμŠ€ν„΄μŠ€ 생성 νŽΈμ˜μ„± 제곡
- κ·Έλ£Ή ν™•μ •λœ 약속 쑰회 응닡에 ν•„μš”ν•œ 데이터λ₯Ό μ²˜λ¦¬ν•˜λŠ” DTO κ΅¬ν˜„
- `GroupConfirmedAppointmentsResponse` λ ˆμ½”λ“œ μΆ”κ°€ (κ·Έλ£Ή 정보와 ν™•μ •λœ 약속 λͺ©λ‘μ„ μ‘λ‹΅μœΌλ‘œ 전달)
- `of` νŒ©ν† λ¦¬ λ©”μ„œλ“œ μΆ”κ°€ν•˜μ—¬ μΈμŠ€ν„΄μŠ€ 생성 νŽΈμ˜μ„± 제곡
- κ·Έλ£Ή ν™•μ •λœ 약속 쑰회 응닡에 ν•„μš”ν•œ 데이터λ₯Ό μ²˜λ¦¬ν•˜λŠ” DTO κ΅¬ν˜„
- `GroupConfirmedInfoResponse` λ ˆμ½”λ“œ μΆ”κ°€ (κ·Έλ£Ή 이름, ν”„λ‘œν•„ 이미지 URL, κ·Έλ£Ή 멀버 수 정보λ₯Ό μ‘λ‹΅μœΌλ‘œ 전달)
- `of` νŒ©ν† λ¦¬ λ©”μ„œλ“œ μΆ”κ°€ν•˜μ—¬ μΈμŠ€ν„΄μŠ€ 생성 νŽΈμ˜μ„± 제곡
- κ·Έλ£Ή ν™•μ •λœ 약속 정보 쑰회 응닡에 ν•„μš”ν•œ 데이터λ₯Ό μ²˜λ¦¬ν•˜λŠ” DTO κ΅¬ν˜„
- `GroupConfirmedResponseMapper` 클래슀 μΆ”κ°€
- κ·Έλ£Ή 정보 및 ν™•μ •λœ 약속 응닡을 λ³€ν™˜ν•˜λŠ” λ©”μ„œλ“œ κ΅¬ν˜„
  - `toGroupConfirmedInfo`: κ·Έλ£Ή 정보 λ³€ν™˜
  - `toConfirmedAppointmentsResponse`: ν™•μ •λœ 약속 λͺ©λ‘ λ³€ν™˜
  - `toConfirmedAppointmentResponse`: 각 ν™•μ •λœ 약속 응닡 λ³€ν™˜
  - `toAppointmentTimeResponse`: 약속 μ‹œκ°„ λ³€ν™˜
  - `findConfirmedOption`: ν™•μ •λœ 약속 μ˜΅μ…˜ 쑰회 및 μ˜ˆμ™Έ 처리
- κ·Έλ£Ή 및 약속 정보λ₯Ό DTO둜 λ³€ν™˜ν•˜λŠ” μ±…μž„μ„ λ‹΄λ‹Ήν•˜λŠ” μœ ν‹Έ 클래슀 κ΅¬ν˜„
- `getById` λ©”μ„œλ“œλ₯Ό `findById`둜 λ³€κ²½ν•˜μ—¬ Optional을 μ²˜λ¦¬ν•˜λ„λ‘ μˆ˜μ •
- `orElseThrow`λ₯Ό μ‚¬μš©ν•˜μ—¬ 멀버가 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” 경우 μ˜ˆμ™Έ 처리
- μ€‘λ³΅λœ 멀버 쑰회 μ½”λ“œ 정리
- `getById` λ©”μ„œλ“œ μ œκ±°ν•˜κ³ , `findById`λ₯Ό 직접 ν˜ΈμΆœν•˜μ—¬ μ˜ˆμ™Έ 처리 둜직 처리
- μ€‘λ³΅λœ μ½”λ“œ 제거둜 가독성 ν–₯상
… μˆ˜μ • 및 쀑볡 μ½”λ“œ 제거

- `findAllByGroupIdConfirmed` λ©”μ„œλ“œ 쀑볡 제거 및 톡합
- `String status`λ₯Ό `AppointmentStatus`둜 λ³€κ²½ν•˜μ—¬ νƒ€μž… μ•ˆμ „μ„± 확보
- `appointmentStatus`κ°€ `CONFIRMED`인 μ•½μ†λ§Œ ν•„ν„°λ§ν•˜λ„λ‘ μˆ˜μ •
- μ½”λ“œ 가독성 ν–₯상 및 λΆˆν•„μš”ν•œ 쑰건 필터링 제거
- μœ νš¨ν•œ ν•œκΈ€ μΉ΄ν…Œκ³ λ¦¬ μž…λ ₯에 λŒ€ν•΄ μ˜¬λ°”λ₯Έ `AppointmentCategory` λ°˜ν™˜ 확인 (`shouldReturnCorrectCategoryForValidInput`)
- 잘λͺ»λœ μΉ΄ν…Œκ³ λ¦¬ μž…λ ₯에 λŒ€ν•΄ μ˜ˆμ™Έ λ°œμƒ 확인 (`shouldThrowExceptionForInvalidCategory`)
- `null` λ˜λŠ” 빈 λ¬Έμžμ—΄ μž…λ ₯에 λŒ€ν•΄ μ˜ˆμ™Έ λ°œμƒ 확인 (`shouldThrowExceptionForNullOrBlankCategory`)
- ν•œκΈ€ μΉ΄ν…Œκ³ λ¦¬ μ™Έ 단어 μž…λ ₯ μ‹œ μ˜ˆμ™Έ λ°œμƒ ν…ŒμŠ€νŠΈ κ°•ν™”
- `MethodSource`λ₯Ό ν™œμš©ν•˜μ—¬ `null` λ˜λŠ” 빈 λ¬Έμžμ—΄ μž…λ ₯에 λŒ€ν•œ μ˜ˆμ™Έ 처리 확인
- `findConfirmedOptionByAppointmentId(Long appointmentId)` λ©”μ„œλ“œ μΆ”κ°€ (νŠΉμ • 약속에 λŒ€ν•΄ ν™•μ •λœ μ˜΅μ…˜μ„ 쑰회)
- `existsById(Long id)` λ©”μ„œλ“œ κ΅¬ν˜„ (약속 μ˜΅μ…˜ 쑴재 μ—¬λΆ€ 체크)
- ν™•μ •λœ 약속 μ˜΅μ…˜μ„ λ‚ μ§œ κΈ°μ€€μœΌλ‘œ μ΅œμ‹  ν•­λͺ©μ„ λ°˜ν™˜ν•˜λŠ” κΈ°λŠ₯ κ΅¬ν˜„
β€¦νŠΈ κ΅¬ν˜„

- `GroupConfirmedAppointmentsServiceImplTest` 클래슀 μΆ”κ°€
- `성곡 μΌ€μ΄μŠ€`: ν™•μ •λœ 약속 λͺ©λ‘ 정상 쑰회 확인 (`shouldGetConfirmedAppointmentsSuccessfully`)
- `μ‹€νŒ¨ μΌ€μ΄μŠ€`: μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” κ·Έλ£Ήμ—μ„œ 쑰회 μ‹œ μ˜ˆμ™Έ λ°œμƒ 및 ν™•μ •λœ 약속이 없을 경우 빈 λͺ©λ‘ λ°˜ν™˜ 확인
  - `shouldThrowExceptionWhenGroupNotFound`: 그룹이 μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ μ˜ˆμ™Έ λ°œμƒ
  - `shouldReturnEmptyListWhenNoConfirmedAppointments`: ν™•μ •λœ 약속이 없을 경우 빈 λͺ©λ‘ λ°˜ν™˜
- `AppointmentOption` 및 `Appointment` 생성 λ‘œμ§μ„ ν™œμš©ν•˜μ—¬ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ κ΅¬ν˜„
- `MockitoAnnotations.initMocks(this)`둜 Mockito μ΄ˆκΈ°ν™” 둜직 μˆ˜μ •
- `@Mock`으둜 μ„ μ–Έλœ μ˜μ‘΄μ„±(mock 객체)을 λͺ…μ‹œμ μœΌλ‘œ μ΄ˆκΈ°ν™”ν•˜λ„λ‘ μˆ˜μ •
- ν…ŒμŠ€νŠΈ μ½”λ“œμ—μ„œ μ˜μ‘΄μ„± μ£Όμž… 및 Mock 객체 μ„€μ • κ°œμ„ 
[✨feat] ν™•μ •λœ 약속듀 쑰회 API κ΅¬ν˜„
@jsoonworld jsoonworld added πŸ‹ μž₯순 πŸ‹ This issue or pull request already exists 🧬 merge Good for newcomers labels Feb 27, 2025
@jsoonworld jsoonworld requested a review from 0-tae February 27, 2025 15:26
@jsoonworld jsoonworld self-assigned this Feb 27, 2025
@jsoonworld jsoonworld merged commit 9130ad5 into staging Feb 27, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
πŸ‹ μž₯순 πŸ‹ This issue or pull request already exists 🧬 merge Good for newcomers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants