Skip to content

Conversation

@zyovn
Copy link
Member

@zyovn zyovn commented Nov 17, 2025

🔗 연관된 이슈

🚀 변경 유형

  • ✨ 기능 추가 (feature)
  • 🐛 버그 수정 (fix)
  • 📝 문서 변경 (docs)
  • ♻️ 리팩토링 (refactor)
  • 🧪 테스트 추가 / 수정 (test)
  • ⚙️ 설정 변경 (chore)

📝 작업 내용

  • 사진 프로필 이미지 화질 오류 (cdn 캐시 오류)
  • 앨범 생성 KST, UTC 관련 오류

💬 리뷰 요구사항

📜 리뷰 규칙

Reviewer는 아래 P5 Rule을 참고하여 리뷰를 진행합니다.
P5 Rule을 통해 Reviewer는 Reviewee에게 리뷰의 의도를 보다 정확히 전달할 수 있습니다.

  • P1: 꼭 반영해주세요 (Comment)
  • P2: 적극적으로 고려해주세요 (Comment)
  • P3: 웬만하면 반영해 주세요 (Comment)
  • P4: 반영해도 좋고 넘어가도 좋습니다 (Approve)
  • P5: 그냥 사소한 의견입니다 (Approve)

Summary by CodeRabbit

  • 신규 기능

    • 앨범 상세 응답에 제작자 이름(name) 필드가 추가되어 앨범의 제작자 정보가 더 잘 표시됩니다.
  • 버그 수정

    • 기본 프로필 이미지 경로 표기 오류가 수정되어 올바른 기본 프로필 이미지가 일관되게 표시됩니다.
    • 앨범 이벤트 날짜 검증이 한국 표준시(KST)를 기준으로 동작하도록 변경되어 시간대 관련 날짜 오류를 방지합니다.
    • 이미지 URL/경로 처리 로직이 개선되어 외부 저장소 경로 변형으로 인한 이미지 표시 문제를 줄였습니다.

@zyovn zyovn self-assigned this Nov 17, 2025
@zyovn zyovn added the 🐛bug Something isn't working label Nov 17, 2025
@zyovn zyovn linked an issue Nov 17, 2025 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Nov 17, 2025

Walkthrough

앨범 정보 조회가 메이커(MAKER) 사용자 조회를 포함하도록 변경되었고(메이커 미존재 시 예외), AlbumInfoResponse에 메이커 이름 필드가 추가되었습니다. AlbumValidator의 이벤트 날짜 검증은 한국 표준시(KST, +09:00)로 고정되었고, 프로필 이미지 경로 문자열과 S3 URL 추출 로직 일부가 수정되었습니다. PhotoMapper의 album→응답 매핑 메서드는 삭제되었습니다.

Changes

코호트 / 파일(s) 변경 요약
앨범 정보 조회 — 메이커 포함
src/main/java/com/cheeeese/album/application/AlbumService.java
getAlbumInfo에서 기존 PhotoMapper 경로 대신 userAlbumRepository.findMakerByAlbumId(..., Role.MAKER)로 메이커(User)를 조회하고 AlbumMapper.toAlbumInfoResponse(album, maker)를 사용하도록 변경. 메이커 부재 시 AlbumException(USER_NOT_MAKER) 발생
응답 모델 확장 & 매퍼 추가
src/main/java/com/cheeeese/album/dto/response/AlbumInfoResponse.java, src/main/java/com/cheeeese/album/infrastructure/mapper/AlbumMapper.java
AlbumInfoResponse에 String name 필드 추가. AlbumMapper에 toAlbumInfoResponse(Album, User) 신규 메서드 추가하여 메이커 이름 포함 응답 구성
유저-앨범 리포지토리 조회 추가
src/main/java/com/cheeeese/album/infrastructure/persistence/UserAlbumRepository.java
Optional<UserAlbum> findMakerByAlbumId(Long albumId, Role role) 쿼리 메서드 추가(사용자 조인패치 및 role 필터)
앨범 매핑 제거
src/main/java/com/cheeeese/photo/infrastructure/mapper/PhotoMapper.java
toAlbumInfoResponse(Album) 공용 매핑 메서드 삭제
날짜 검증(KST)
src/main/java/com/cheeeese/album/application/validator/AlbumValidator.java
ZoneOffset +09:00 상수 추가 및 LocalDate.now()LocalDate.now(KST_ZONE)로 변경하여 이벤트 날짜 검증을 KST 기준으로 수행
프로필 이미지 경로 문자열 변경
src/main/java/com/cheeeese/user/domain/type/ProfileImageType.java, src/main/java/com/cheeeese/user/dto/response/UserProfileImageResponse.java
P1~P10 등 프로필 이미지 경로 리터럴에서 profile/signup_profile_*.jpgprofile/sign_up_profile_*.jpg로 문자열 수정 (예시 URL 업데이트 포함)
S3 URL/객체키 정규화
src/main/java/com/cheeeese/global/util/S3Util.java
PREFIX = "say-cheeeese/" 상수 추가. extractObjectKey에서 선행 슬래시 제거, PREFIX 일치 시 제거하고 정상화된 객체 키 반환하도록 로직 재구성(기존 album/ 경로 특화 분기 제거)

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client as 클라이언트
    participant AlbumService as AlbumService
    participant UserAlbumRepo as UserAlbumRepository
    participant AlbumMapper as AlbumMapper
    participant ClientResp as 클라이언트응답
    rect rgba(203,232,255,0.35)
    note right of UserAlbumRepo: 신규/변경된 흐름: 메이커 조회 및 메이커 기반 매핑
    end

    Client->>AlbumService: getAlbumInfo(albumId)
    AlbumService->>UserAlbumRepo: findMakerByAlbumId(albumId, Role.MAKER)
    alt maker found
        UserAlbumRepo-->>AlbumService: UserAlbum (with User)
        AlbumService->>AlbumMapper: toAlbumInfoResponse(album, makerUser)
        AlbumMapper-->>AlbumService: AlbumInfoResponse (name 포함)
        AlbumService-->>ClientResp: 200 OK (AlbumInfoResponse)
    else maker not found
        UserAlbumRepo-->>AlbumService: empty
        AlbumService-->>ClientResp: 오류 (USER_NOT_MAKER)
    end
Loading
sequenceDiagram
    autonumber
    participant Client as 클라이언트
    participant AlbumService as AlbumService
    participant Validator as AlbumValidator
    rect rgba(220,247,200,0.35)
    note right of Validator: 변경: KST_ZONE(ZoneOffset +09:00) 사용
    end

    Client->>AlbumService: 앨범 생성 요청 (eventDate)
    AlbumService->>Validator: validate(eventDate)
    Validator->>Validator: now = LocalDate.now(KST_ZONE)
    alt eventDate < now
        Validator-->>AlbumService: validation fail
        AlbumService-->>Client: 오류 응답
    else
        Validator-->>AlbumService: validation pass
        AlbumService-->>Client: 생성 성공
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • 추가로 주의해야 할 파일/영역:
    • src/main/java/com/cheeeese/album/application/AlbumService.java: 메이커 조회 예외 처리와 기존 호출 경로 제거로 인한 영향 범위 확인
    • src/main/java/com/cheeeese/album/dto/response/AlbumInfoResponse.java 및 매퍼 변경: 소비자(프론트/다른 서비스) 호환성 확인
    • src/main/java/com/cheeeese/album/infrastructure/persistence/UserAlbumRepository.java: 쿼리 성능·조인패치 의도 확인
    • src/main/java/com/cheeeese/global/util/S3Util.java: URL/객체키 정규화 변경이 CDN/저장소 키와 일치하는지 검증
    • src/main/java/com/cheeeese/photo/infrastructure/mapper/PhotoMapper.java: 삭제된 매핑 사용처(호출자) 존재 여부 확인

Possibly related PRs

Suggested reviewers

  • dahyun24

Poem

🐰
아침 햇살 따라 KST로 뛰고,
메이커 이름도 소중히 담았네.
경로도 반짝 고쳐두었으니,
토끼가 깡충 뛰며 속삭입니다: 잘했어! 🥕🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive PR 제목이 여러 변경사항(프로필 이미지 경로, 앨범 조회 로직, KST 시간대, S3 경로 정규화 등)을 포괄하는 일반적인 표현으로 작성되어 있어 구체적인 주요 변경사항을 명확히 나타내지 못함. 제목을 보다 구체적으로 개선하여 주요 변경사항을 명시하기를 권장합니다(예: 'fix: KST 시간대 적용 및 프로필 이미지 경로 수정' 또는 'fix: 앨범 생성 및 프로필 이미지 관련 QA 이슈 해결').
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/#74-qa

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9724618 and 9e49955.

📒 Files selected for processing (6)
  • src/main/java/com/cheeeese/album/application/AlbumService.java (1 hunks)
  • src/main/java/com/cheeeese/album/dto/response/AlbumInfoResponse.java (1 hunks)
  • src/main/java/com/cheeeese/album/infrastructure/mapper/AlbumMapper.java (1 hunks)
  • src/main/java/com/cheeeese/album/infrastructure/persistence/UserAlbumRepository.java (1 hunks)
  • src/main/java/com/cheeeese/global/util/S3Util.java (2 hunks)
  • src/main/java/com/cheeeese/photo/infrastructure/mapper/PhotoMapper.java (0 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/com/cheeeese/photo/infrastructure/mapper/PhotoMapper.java
🧰 Additional context used
🧬 Code graph analysis (1)
src/main/java/com/cheeeese/album/application/AlbumService.java (1)
src/main/java/com/cheeeese/album/infrastructure/mapper/AlbumMapper.java (1)
  • AlbumMapper (14-170)
🔇 Additional comments (6)
src/main/java/com/cheeeese/global/util/S3Util.java (2)

10-33: 경로 정규화 로직이 잘 구현되었습니다

CDN 캐시 오류 수정을 위한 경로 정규화 로직이 적절합니다:

  • 선행 슬래시 제거
  • 프리픽스 제거
  • 예외 처리 및 폴백

8-9: PREFIX 값은 정확하며 설계가 의도적입니다

S3Util의 PREFIX("say-cheeeese/")는 정확하고 설계가 의도적입니다. Photo 엔티티는 imageUrl(원본)과 thumbnailUrl(썸네일)을 별도 필드로 관리하며, extractObjectKey는 photo.getImageUrl()만 처리합니다. CdnUrlResolver의 다양한 프리픽스("say-cheeeese/", "say-cheeeese-thumbnail/", "say-cheeeese-profile/")는 각각 다른 리소스 타입을 위한 것이고, S3Util은 원본 이미지 다운로드 용도로만 사용되므로 "say-cheeeese/"만 필요합니다.

src/main/java/com/cheeeese/album/dto/response/AlbumInfoResponse.java (1)

15-16: 생성자 이름 필드 추가 확인

앨범 정보 응답에 생성자 이름을 추가한 것은 적절한 개선사항입니다. 필드 위치와 Swagger 문서화도 잘 되어 있습니다.

src/main/java/com/cheeeese/album/infrastructure/mapper/AlbumMapper.java (1)

157-169: 매퍼 메서드가 올바르게 구현되었습니다

toAlbumInfoResponse 메서드가 Album과 User 정보를 적절히 매핑하고 있습니다. 모든 필드가 올바르게 설정되어 있으며, 빌더 패턴 사용도 일관적입니다.

src/main/java/com/cheeeese/album/application/AlbumService.java (1)

207-211: 메이커 정보 조회 로직이 적절합니다

앨범 생성자 정보를 포함하도록 변경한 것은 적절합니다. findMakerByAlbumId가 JOIN FETCH를 사용하므로 추가 쿼리로 인한 성능 문제는 없을 것으로 보입니다. 메이커를 찾지 못했을 때의 예외 처리도 명확합니다.

src/main/java/com/cheeeese/album/infrastructure/persistence/UserAlbumRepository.java (1)

77-84: 쿼리 메서드가 효율적으로 구현되었습니다

findMakerByAlbumId 메서드가 JOIN FETCH를 사용하여 User 정보를 즉시 로딩하므로 N+1 쿼리 문제가 발생하지 않습니다. 쿼리 로직과 반환 타입이 적절합니다.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d9c95c2 and 11f4ca6.

📒 Files selected for processing (2)
  • src/main/java/com/cheeeese/album/application/validator/AlbumValidator.java (2 hunks)
  • src/main/java/com/cheeeese/user/domain/type/ProfileImageType.java (1 hunks)
🔇 Additional comments (1)
src/main/java/com/cheeeese/album/application/validator/AlbumValidator.java (1)

18-18: LGTM! 타임존 처리를 위한 적절한 import입니다.

서울 시간대를 명시적으로 사용하기 위해 ZoneId를 import한 것은 올바른 접근입니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/cheeeese/user/dto/response/UserProfileImageResponse.java (1)

39-39: Swagger 예시 문자열 불일치 수정 필요

Line 39의 @Schema 예시가 여전히 이전 경로 형식(signup_profile_5.jpg)을 사용하고 있습니다. Lines 17, 21에서 수정한 것과 동일하게 sign_up_profile_5.jpg로 업데이트해야 합니다.

다음 diff를 적용하여 예시를 일관되게 수정하세요:

             @Schema(
                     description = "프로필 이미지의 CDN URL",
-                    example = "https://say-cheese-profile.edge.naverncp.com/profile/signup_profile_5.jpg"
+                    example = "https://say-cheese-profile.edge.naverncp.com/profile/sign_up_profile_5.jpg"
             )
             String profileImageUrl
♻️ Duplicate comments (1)
src/main/java/com/cheeeese/album/application/validator/AlbumValidator.java (1)

27-27: KST 타임존 상수 정의 개선 확인

KST 타임존 상수를 정의한 것은 좋은 개선입니다. 다만, 이전 리뷰에서 지적된 것처럼 이 상수를 공통 유틸 클래스로 이동하여 Album.isExpired(), AlbumService, AlbumQueryService, PhotoService 등 코드베이스 전체에서 일관되게 사용하는 것이 좋습니다.

현재는 이 클래스에만 국한된 변경이므로 점진적 개선으로 볼 수 있지만, 향후 리팩토링을 통해 전사적으로 타임존 처리를 통일하는 것을 권장합니다.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 11f4ca6 and 3733d95.

📒 Files selected for processing (2)
  • src/main/java/com/cheeeese/album/application/validator/AlbumValidator.java (2 hunks)
  • src/main/java/com/cheeeese/user/dto/response/UserProfileImageResponse.java (1 hunks)
🔇 Additional comments (3)
src/main/java/com/cheeeese/album/application/validator/AlbumValidator.java (2)

44-44: KST 기준 날짜 검증 로직 개선 승인

이벤트 날짜 검증에 KST 타임존을 명시적으로 적용한 것은 올바른 수정입니다. 이를 통해 한국 표준시 기준으로 일관된 날짜 비교가 가능합니다.


79-81: 업로드 권한 검증 메서드 추가 승인

validateUploadPermission 메서드를 통해 업로드 권한을 명시적으로 검증하는 로직이 추가되었습니다. 기존 validateAlbumParticipant 메서드를 재사용하여 적절히 구현되었습니다.

src/main/java/com/cheeeese/user/dto/response/UserProfileImageResponse.java (1)

17-22: 프로필 이미지 URL 경로 수정 승인

CDN 캐시 오류 해결을 위해 프로필 이미지 URL 경로를 signup_profile에서 sign_up_profile로 수정한 것이 올바릅니다. 이는 실제 CDN에 저장된 파일명과 일치하도록 하는 필수적인 수정입니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/main/java/com/cheeeese/album/application/validator/AlbumValidator.java (1)

25-25: KST_ZONE 상수를 공통 클래스로 분리하는 것을 권장합니다.

AlbumExpirationRedisRepository에도 동일한 KST_ZONE 상수가 존재하여 중복이 발생하고 있습니다. 타임존 상수를 여러 곳에서 중복 정의하면 유지보수가 어려워집니다.

공통 유틸 클래스(예: TimeZoneConstants 또는 DateTimeUtils)에 KST_ZONE을 정의하고, 이를 AlbumValidatorAlbumExpirationRedisRepository 모두에서 참조하도록 리팩토링하는 것을 고려해주세요.

예시:

// com.cheeeese.common.util.TimeZoneConstants
public final class TimeZoneConstants {
    public static final ZoneOffset KST_ZONE = ZoneOffset.of("+09:00");
    
    private TimeZoneConstants() {
        throw new UnsupportedOperationException();
    }
}

그런 다음 이 파일에서:

-    private static final ZoneOffset KST_ZONE = ZoneOffset.of("+09:00");
+    private static final ZoneOffset KST_ZONE = TimeZoneConstants.KST_ZONE;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3733d95 and 9724618.

📒 Files selected for processing (2)
  • src/main/java/com/cheeeese/album/application/validator/AlbumValidator.java (2 hunks)
  • src/main/java/com/cheeeese/user/dto/response/UserProfileImageResponse.java (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/com/cheeeese/user/dto/response/UserProfileImageResponse.java
🔇 Additional comments (1)
src/main/java/com/cheeeese/album/application/validator/AlbumValidator.java (1)

18-18: 필요한 import 추가입니다.

KST_ZONE 상수 사용을 위한 필수 import이며, 이전 리뷰에서 언급된 미사용 import들은 정리된 것으로 확인됩니다.

}

if (request.eventDate().isAfter(LocalDate.now())) {
if (request.eventDate().isAfter(LocalDate.now(KST_ZONE))) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

이벤트 날짜 검증에 KST 적용이 올바르게 수정되었습니다.

LocalDate.now(KST_ZONE)를 사용하여 한국 표준시 기준으로 날짜를 비교하도록 변경한 것은 PR 목적에 부합하는 올바른 수정입니다.

다만, 이전 리뷰에서 지적된 대로 Album.isExpired(), AlbumService, AlbumQueryService, PhotoService 등 다른 곳에서도 타임존 없이 LocalDate.now() 또는 LocalDateTime.now()를 사용하는 부분들이 있는지 확인이 필요합니다. 특히 Album.isExpired() 메서드는 우선적으로 동일한 타임존 처리가 적용되어야 합니다.

다음 스크립트로 남아있는 타임존 미지정 케이스를 확인해주세요:


🏁 Script executed:

#!/bin/bash
# 타임존이 지정되지 않은 LocalDate.now() 및 LocalDateTime.now() 사용 확인

echo "=== 타임존 미지정 LocalDate.now() 확인 ==="
rg -n --type=java 'LocalDate\.now\(\)' -C2

echo -e "\n=== 타임존 미지정 LocalDateTime.now() 확인 ==="
rg -n --type=java 'LocalDateTime\.now\(\)' -C2

echo -e "\n=== Album.isExpired() 메서드 확인 ==="
ast-grep --pattern $'class Album {
  $$$
  isExpired($_) {
    $$$
  }
  $$$
}'

Length of output: 7436


타임존 미지정 문제가 여러 곳에서 발견되어 추가 수정이 필요합니다.

이 변경사항은 올바르지만, 검증 결과 다음 핵심 파일들에서도 타임존 없이 LocalDateTime.now()LocalDate.now()를 사용하고 있습니다:

  • Album.java line 66: isExpired() 메서드에서 LocalDateTime.now() 사용
  • AlbumService.java line 75: 앨범 만료 시간 계산에서 LocalDateTime.now().plusDays(7) 사용
  • AlbumQueryService.java lines 52, 67: 활성 앨범 조회 시 LocalDateTime.now() 사용
  • AlbumService.java lines 256-257: 주간 앨범 개수 조회에서 LocalDate.now() 사용

이들은 모두 KST_ZONE을 포함하여 동일하게 수정되어야 데이터 일관성이 보장됩니다.

🤖 Prompt for AI Agents
In src/main/java/com/cheeeese/album/domain/Album.java around line 66,
src/main/java/com/cheeeese/album/application/AlbumService.java around lines 75
and 256-257, and
src/main/java/com/cheeeese/album/application/AlbumQueryService.java around lines
52 and 67, various uses of LocalDateTime.now() and LocalDate.now() lack a
timezone; update each occurrence to use the shared KST_ZONE (e.g.,
LocalDateTime.now(KST_ZONE) or LocalDate.now(KST_ZONE)) so all time computations
and comparisons use the same ZoneId constant, and ensure the KST_ZONE
constant/import is referenced where needed.

Copy link
Contributor

@dahyun24 dahyun24 left a comment

Choose a reason for hiding this comment

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

늦게 봐서 미안~ 수고했어~

@zyovn zyovn merged commit 15fb22c into develop Nov 18, 2025
1 check passed
@zyovn zyovn deleted the fix/#74-qa branch November 18, 2025 12:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: QA에서 발견한 오류 수정

3 participants