You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
scripts/sql/mail-reservation-queries.sql — 범용 쿼리 5개를 특정 이메일 하드코딩 쿼리 2개로 전면 교체. PR 설명에 전혀 언급 없음.
🔴 크리티컬 이슈
1. getPendingReservationStatuses에서 특권 유저의 OAuth 상태 체크 로직 버그
// MailService.kt:67-101fungetPendingReservationStatuses(userId:Long): List<PendingMailReservationStatus> {
val user = userReader.readById(userId) // 특권 유저 (본인)...
val reservations = mailReservationReader.readAllBefore(now) // 전체 팀원 예약 포함return reservations.map { reservation ->...
val (failureErrorCode, failedAt) =try {
// ⚠️ 항상 현재 로그인한 특권 유저(user.id!!)의 토큰만 체크
oauth2Service.refreshOAuth2TokenBeforeExpiry(user.id!!, OAuth2Type.GOOGLE, 10L)
특권 유저가 타 팀원의 예약 목록을 조회하면, 각 예약의 failureErrorCode는 예약 발신자의 OAuth 상태가 아닌 특권 유저 본인의 토큰 상태를 기준으로 반환됩니다. 즉, 팀원 A의 토큰이 만료되어도 특권 유저의 토큰이 유효하면 failureErrorCode = null로 반환되어 실제 장애 상황을 숨기게 됩니다.
// MemberPrivacyService.kt:50-57val activeMembers = memberReader.readAllActive() // 전체 활성 멤버 메모리 로드val teamEmails =
activeMembers
.asSequence()
.filter { member -> member.parts.any { part -> part.id !=null&& myPartIds.contains(part.id) } }
일반 유저 요청마다 전체 활성 멤버를 메모리에 올려 Kotlin 레벨에서 필터링합니다. 멤버 수가 증가할수록 선형적으로 성능이 저하됩니다. memberReader에 readAllActiveByPartIds(partIds: Set<Long>) 같은 파트 필터링 쿼리를 추가하는 것이 바람직합니다.
비특권 유저의 경우 isPrivilegedUser와 getActiveTeamMemberEmails 모두 내부적으로 userReader.readById(userId)를 호출하여 동일한 유저 정보를 최소 2회 이상 DB 조회합니다. isPrivilegedUser도 getMemberPartIds를 간접 호출하여 memberReader.readByEmailOrNull이 2회 이상 호출될 수 있습니다.
glen.urssu@gmail.com이 실제 계정 이메일로 추정되며, 소스 코드에 하드코딩된 채 공개 레포지토리에 커밋되어 있습니다. 실제 사용 예제라면 'your_email@example.com'과 같은 플레이스홀더로 대체를 권장합니다.
또한 기존 SQL 파일에는 범용 쿼리(전체 조회, 건수 확인, 미발송/스케줄러 누락 케이스 등) 5개가 있었는데, 이번 PR에서 특정 이메일 하드코딩 쿼리 2개로 완전히 교체되었습니다. 기존 범용 쿼리들이 삭제된 의도가 PR 설명에 없어 의도적인 변경인지 확인이 필요합니다.
5. updateMailReservation/cancelMailReservation 권한 정책 불일치 (의도적이면 OK)
getUserMailReservation은 팀원도 조회 가능하게 확장되었지만, updateMailReservation과 cancelMailReservation은 여전히 소유자만 가능합니다. 의도적인 설계라면 PR 설명이나 주석에 명시하는 것을 권장합니다.
6. retryReservation의 권한 로직은 변경되지 않음
retryReservation은 소유자 이메일만 체크하는 기존 방식 유지 (MailService.kt:136-138). 팀원 재전송 여부의 정책적 판단이 필요합니다.
📋 테스트 케이스 검토
테스트 케이스
PR 설명 기재 여부
구현 여부
일반 유저: 자기 메일 예약 조회
✅
✅ (line:86)
같은 팀 유저: 타 팀원 단건 조회
✅
✅ (line:596)
특권 유저: 전체 예약 목록 반환
✅
✅ (line:635)
특권 유저의 단건 조회 테스트
❌ 미기재
❌ 미구현
getPendingReservationStatuses 권한 분기 테스트
❌ 미기재
❌ 미구현
요약
PR 설명에 기재된 핵심 기능 변경사항은 코드와 전반적으로 일치합니다. 다만:
크리티컬: getPendingReservationStatuses에서 특권 유저 조회 시 OAuth 상태 체크 대상이 잘못됨 (실제 버그)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
개요
주요 변경 사항
권한/팀 로직 강화
MemberPrivacyService에getActiveTeamMemberEmails(userId)추가메일 예약 조회 범위 확장
MailService.getPendingReservationStatusesisPrivilegedUser == true) → 전체 예약(readAllBefore)getActiveTeamMemberEmails기반senderEmail IN (...)조회MailService.getUserMailReservationsreadAll)readAllBySenderEmailsMailService.getUserMailReservationsenderEmailAddress가 팀 이메일 목록에 포함되면 접근 허용MailReservationAccessDeniedException발생저장소 계층 확장
JpaMailReservationRepository/MailReservationRepository/MailReservationReader에senderEmails IN (...)기반 조회 메서드 추가<= time,BETWEEN from AND to)이 있는 버전까지 지원테스트
MailServiceTest에서 다음 케이스 추가/보완getActiveTeamMemberEmails기반으로 자기 메일이 조회되는지 검증./gradlew test) 통과 확인변경 의도
📎 Issue 번호
closed #281