Repository navigation
[Feat] 일정 조율 알림 구현 - #145
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (17)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthrough일정 조율 시작·응답·리마인드·확정 시 알림과 Outbox 저장 흐름을 추가했습니다. 미응답자 리마인드 API를 추가하고, 만남 삭제 응답을 본문 없는 형식으로 변경했습니다. Changes일정 조율 알림
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant MeetingScheduleController
participant MeetingDatePollService
participant MeetingParticipantRepository
participant NotificationService
MeetingScheduleController->>MeetingDatePollService: 미응답자 리마인드 요청
MeetingDatePollService->>MeetingParticipantRepository: 미응답 활성 참가자 조회
MeetingParticipantRepository-->>MeetingDatePollService: 미응답 참가자 목록
MeetingDatePollService->>NotificationService: 리마인드 알림 명령 저장
Merge Risk: ⚪ Minimal · up to The notification and reminder changes are mergeable after normal checks; no actionable merge-blocking issue remains. 🚥 Pre-merge checks | ✅ 2 | ❌ 2 | ❓ 1❌ Failed checks (2 warnings, 1 inconclusive)✅ Passed checks (2 passed)Full details: Linked Issues checkExplanation 직접 연결된 Full details: Out of Scope Changes checkExplanation
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
개요
#39(PR #140)에서 만든 Outbox 기반 푸시 발송 인프라에, 서비스 정책에 정의된 일정 조율 알림 4종을 연결합니다. 네 알림 모두 각 유스케이스 트랜잭션 안에서
NotificationService로 앱 내 알림과 Outbox를 함께 저장하고, 실제 푸시는 기존 Outbox Worker가 비동기로 발송합니다.작업 내용
DATE_POLL_STARTEDPOLL) 만남 생성DATE_POLL_RESPONDEDDATE_POLL_REMINDERMEETING_DATE_CONFIRMEDMeetingNotificationCommands에서 문구와 중복 방지 키를 만듭니다.meeting→notification단방향 의존만 추가했습니다.MeetingService.createPollMeeting().FIXED만남에는 보내지 않습니다.MeetingDatePollService.respondDatePoll(). 방장 위임 후 방장 본인이 응답하면 보내지 않습니다.MeetingService.confirmMeetingDate(). 같은 날짜로 다시 확정한 멱등 요청에는 보내지 않고, 탈퇴한 멤버는 제외합니다.MeetingParticipantRepository.findAllUnrespondedActiveWithUserByMeetingId(). 생성자, 응답 기록이 있는 참여자(빈 배열 응답 포함), 탈퇴한 멤버를 제외하고 사용자까지 fetch join합니다.MeetingDatePollService.remindUnrespondedParticipants(). 만남 row를 잠근 뒤 방장·조율 방식·조율 중 상태를 검증하고, 미응답자가 없으면MEETING-E024를 반환합니다.POST /api/v1/meetings/{meetingId}/date-poll/reminders→204 No Content204응답에CommonResponse본문 스키마가 붙던 문제를 반환 타입을ResponseEntity<Void>로 바꿔 해결했습니다.테스트
MeetingServiceTest: 조율 요청 알림 명령(FIXED만남 제외), 확정 알림 수신자(방장·탈퇴자 제외)와 멱등 재확정MeetingDatePollServiceTest: 응답 알림(방장 본인 응답 제외), 리마인드 명령과 실패 흐름(E018,E024,E020)MeetingRepositoryTest: 미응답 참여자 조회 조건MeetingDatePollReminderIntegrationTest(신규, MySQL): 미응답자에게만 알림·Outbox 저장, 같은 시각 재요청 시 새 알림 저장MeetingScheduleControllerTest:204본문 없음,409 MEETING-E024MeetingOpenApiTest(신규): 리마인드와 만남 삭제의204응답 문서에 본문 스키마가 없는지 검증MeetingDatePollServiceConcurrencyTest: 응답 시 알림이 생기므로 정리 단계에서 알림·Outbox를 먼저 삭제하도록 수정./gradlew build는 실행하지 않았습니다.API 변경
POST /api/v1/meetings/{meetingId}/date-poll/reminders204 No Content(MEETING-S010)400 MEETING-E012,403 MEETING-E018,404 MEETING-E010,409 MEETING-E020,409 MEETING-E024(신규, 미응답자 없음)미응답자 리마인드를 구현 기준으로 갱신했습니다.DB 및 설정 변경
리뷰 시 참고 사항
NotificationService가 MySQL 전용 upsert(ON DUPLICATE KEY UPDATE)를 써서 H2 기반 서비스 테스트에서는 실행되지 않습니다. 해당 테스트에서는NotificationService를@MockitoBean으로 대체하고 전달된 명령을 검증했으며, 실제 저장은 MySQL 통합 테스트로 확인했습니다. Kotlin non-null 매개변수와 Mockito 매처가 충돌해mockingDetails로 호출 인자를 읽었습니다.DATE_POLL_REMINDER:{meetingId}:{요청 시각 ms}:{요청별 UUID}:{recipientUserId}. 요청 시각만으로는 같은 밀리초 재요청이 중복 처리되는 문제가 있어 요청마다 UUID를 추가했습니다.429 MEETING-E025제외). 클라이언트의 요청 중 버튼 비활성화를 전제로 하며, 남용 문제가 생기면 후속 이슈로 추가합니다.E020으로 거절되도록 했습니다.E020메시지("일정 조율 중인 만남만 확정할 수 있습니다.")는 명세대로 재사용해 리마인드 문맥에서는 다소 어색할 수 있습니다.MEETING_PROPOSED(방장에게 여정 제안) 알림은 제안 기능 기획이 정해지지 않아 제외했습니다.204Swagger에 본문 스키마가 붙는 같은 문제가 있습니다(범위 밖).만남 생성 및 일정 조율 API 설계)가 휴지통에 있어202표기를 갱신하지 못했습니다.체크리스트
Summary by CodeRabbit
새 기능
개선 사항