-
Notifications
You must be signed in to change notification settings - Fork 0
feat: cheese4cutPhoto 엔티티 추가 및 스케줄러 기능 구현 변경 #58
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
Conversation
- 확정된 사진 4장 제공
Walkthrough앨범 만료 메커니즘을 Redis TTL에서 ZSET 기반 시스템으로 재구조화하고, Cheese4cut 엔티티를 List photoIds에서 매핑된 Cheese4cutPhoto 엔티티 관계로 전환하며, 유저 인증 컨텍스트를 Cheese4cut 서비스에 추가합니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Scheduler as AlbumExpirationScheduler
participant Service as AlbumExpirationService
participant Redis as AlbumExpirationRedisRepository
participant Repo as AlbumRepository<br/>PhotoRepository
participant C4Service as Cheese4cutService
Scheduler->>Redis: getExpiredAlbumIds()
Redis-->>Scheduler: expiredAlbumIds: Set<Long>
loop for each expiredAlbumId
Scheduler->>Service: expire(expiredAlbumId)
Service->>Repo: Album findById(expiredAlbumId)
Service->>Repo: Photo findAllByIdInOrderByLikesDescCreatedDesc(topPhotoIds)
Service->>Service: 검증: 모든 Photo 존재 확인
alt photos exist
Service->>C4Service: toEntity(album, orderedPhotos)
C4Service-->>Service: Cheese4cut with photos
Service->>Repo: Cheese4cut save(cheese4cut)
Service->>Repo: Album updateStatus(expiredAlbumId, EXPIRED)
else missing photos
Service->>Service: 경고 로깅 및 중단
end
Scheduler->>Redis: unregister(expiredAlbumId)
end
sequenceDiagram
participant Client
participant Controller as Cheese4cutController
participant Service as Cheese4cutService
participant Repo as Cheese4cutRepository<br/>PhotoRepository
participant Mapper as Cheese4cutMapper
participant CDN as CdnUrlResolver
Client->>Controller: GET /api/cheese4cut/{code}<br/>(with Authentication)
Controller->>Service: getCheese4cutByAlbumCode(authentication, code)
Service->>Service: extractUser(authentication)
Service->>Repo: Cheese4cut findByAlbumCode(code)
alt final Cheese4cut exists
Service->>Repo: cheese4cut.getPhotos()
loop for each Cheese4cutPhoto
Service->>CDN: 이미지 URL 해석
Service->>Mapper: toFinalPhotoInfo(photoId, cdnUrl, photoRank)
end
Service->>Mapper: toFinalResponse(photos: List<FinalPhotoInfo>)
Service-->>Controller: Cheese4cutFinalResponse
else preview only
Service->>Repo: UserAlbum findByAlbumId(albumId) → myRole
Service->>Repo: getOrderedPhotos(topPhotoIds)
loop for each Photo
Service->>CDN: 이미지 URL 해석
Service->>Mapper: toPreviewPhotoInfo(photoId, cdnUrl, photoRank)
end
Service->>Mapper: toPreviewResponse(photos, likes, participants, myRole)
Service-->>Controller: Cheese4cutPreviewResponse
end
Controller-->>Client: CommonResponse<Cheese4cutResponse>
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 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 |
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.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/main/java/com/cheeeese/album/infrastructure/persistence/AlbumExpirationRedisRepository.java (1)
18-19: 타임존 설정을 하드코딩하지 않도록 개선을 권장합니다.
KST_ZONE이ZoneOffset.of("+09:00")로 하드코딩되어 있습니다. 타임존은 애플리케이션 설정에서 관리하거나 시스템 기본값을 사용하는 것이 유지보수성과 유연성 측면에서 더 좋습니다.설정 파일에서 타임존을 관리하도록 개선할 수 있습니다:
- private static final ZoneOffset KST_ZONE = ZoneOffset.of("+09:00"); + @Value("${application.timezone.offset:+09:00}") + private String timezoneOffset; + + private ZoneOffset getZoneOffset() { + return ZoneOffset.of(timezoneOffset); + }그리고 사용처에서
KST_ZONE대신getZoneOffset()을 호출하도록 변경:- long expirationMillis = expiredAt.toInstant(KST_ZONE).toEpochMilli(); + long expirationMillis = expiredAt.toInstant(getZoneOffset()).toEpochMilli();
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
src/main/java/com/cheeeese/album/application/AlbumExpirationScheduler.java(1 hunks)src/main/java/com/cheeeese/album/application/AlbumExpirationService.java(4 hunks)src/main/java/com/cheeeese/album/application/AlbumService.java(4 hunks)src/main/java/com/cheeeese/album/domain/Album.java(0 hunks)src/main/java/com/cheeeese/album/infrastructure/persistence/AlbumExpirationRedisRepository.java(1 hunks)src/main/java/com/cheeeese/album/infrastructure/persistence/AlbumRepository.java(1 hunks)src/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java(6 hunks)src/main/java/com/cheeeese/cheese4cut/domain/Cheese4cut.java(2 hunks)src/main/java/com/cheeeese/cheese4cut/domain/Cheese4cutPhoto.java(1 hunks)src/main/java/com/cheeeese/cheese4cut/dto/response/Cheese4cutFinalResponse.java(1 hunks)src/main/java/com/cheeeese/cheese4cut/dto/response/Cheese4cutPreviewResponse.java(3 hunks)src/main/java/com/cheeeese/cheese4cut/infrastructure/mapper/Cheese4cutMapper.java(2 hunks)src/main/java/com/cheeeese/cheese4cut/presentation/Cheese4cutController.java(2 hunks)src/main/java/com/cheeeese/cheese4cut/presentation/swagger/Cheese4cutSwagger.java(2 hunks)src/main/java/com/cheeeese/photo/infrastructure/persistence/PhotoRepository.java(2 hunks)
💤 Files with no reviewable changes (1)
- src/main/java/com/cheeeese/album/domain/Album.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-31T13:17:52.523Z
Learnt from: dahyun24
Repo: Say-Cheeeese/BE PR: 35
File: src/main/java/com/cheeeese/photo/application/PhotoService.java:46-52
Timestamp: 2025-10-31T13:17:52.523Z
Learning: In src/main/java/com/cheeeese/photo/application/PhotoService.java, the getRecentThumbnailUrls method intentionally returns only the first thumbnail URL when photos.size() < 5, rather than returning all available thumbnails. This is according to product requirements: 0 photos → empty list, 1-4 photos → single thumbnail (most recent), 5 photos → all 5 thumbnails.
Applied to files:
src/main/java/com/cheeeese/photo/infrastructure/persistence/PhotoRepository.javasrc/main/java/com/cheeeese/album/application/AlbumExpirationService.javasrc/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java
🧬 Code graph analysis (2)
src/main/java/com/cheeeese/album/application/AlbumExpirationService.java (1)
src/main/java/com/cheeeese/cheese4cut/infrastructure/mapper/Cheese4cutMapper.java (1)
Cheese4cutMapper(16-92)
src/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java (1)
src/main/java/com/cheeeese/cheese4cut/infrastructure/mapper/Cheese4cutMapper.java (1)
Cheese4cutMapper(16-92)
🔇 Additional comments (15)
src/main/java/com/cheeeese/photo/infrastructure/persistence/PhotoRepository.java (1)
108-116: 새로운 정렬 메서드가 잘 구현되었습니다.
findAllByIdInOrderByLikesDescCreatedDesc메서드가 좋아요 수, 생성일, ID를 기준으로 3단계 정렬을 제공하여 결정적(deterministic)인 결과를 보장합니다.isDeleted = FALSE필터도 적절히 포함되어 있습니다.src/main/java/com/cheeeese/album/infrastructure/persistence/AlbumExpirationRedisRepository.java (1)
24-36: ZSET 기반 만료 추적 구현이 효율적입니다.TTL 기반에서 ZSET 기반으로 마이그레이션하여 성능이 개선되었습니다. Unix timestamp를 score로 사용하는 방식이 적절하며,
ZADD명령을 올바르게 사용하고 있습니다.src/main/java/com/cheeeese/cheese4cut/presentation/swagger/Cheese4cutSwagger.java (1)
77-80: 인증 파라미터 추가가 기존 클라이언트에 미치는 영향을 확인하세요.
getCheese4cut메서드에Authentication파라미터가 추가되었습니다. 이 변경사항이 기존에 인증 없이 호출하던 클라이언트에게 영향을 주지 않는지 확인이 필요합니다. 엔드포인트가 선택적 인증(optional authentication)을 지원하는지, 아니면 필수 인증(required authentication)으로 변경되었는지 명확히 해야 합니다.다음 사항을 확인해주세요:
- 이 엔드포인트가 익명 사용자도 접근 가능한지 (Spring Security 설정 확인)
- 기존 클라이언트가 인증 토큰 없이 호출하는 경우가 있는지
- 역할(myRole)이 null일 수 있는 경우를 서비스 레이어에서 처리하는지
src/main/java/com/cheeeese/album/application/AlbumExpirationScheduler.java (2)
19-19: 스케줄러 폴링 간격이 10배 증가했습니다. 비즈니스 요구사항을 확인하세요.
fixedDelay가 1000L(1초)에서 10000L(10초)로 변경되어 앨범 만료 처리가 최대 10초까지 지연될 수 있습니다. 이 변경이 비즈니스 요구사항에 부합하는지 확인이 필요합니다. 만료 후 즉시 처리가 중요한 경우 더 짧은 간격을 고려해야 합니다.다음 사항을 확인해주세요:
- 앨범 만료 처리에 최대 10초 지연이 허용되는지
- 이 변경이 성능 최적화를 위한 것인지
- Redis ZSET 조회 비용이 높아서 폴링 간격을 늘린 것인지
28-33: 에러 처리 개선이 잘 되었습니다.개별 앨범 만료 처리 실패 시 try-catch로 감싸서 다른 앨범 처리가 중단되지 않도록 했습니다. 로그도 적절하게 남기고 있어 장애 추적이 용이합니다.
src/main/java/com/cheeeese/album/infrastructure/persistence/AlbumRepository.java (1)
42-44: 불필요한 업데이트를 방지하는 조건이 잘 구현되었습니다.
updateStatus메서드에a.status <> :status조건을 추가하여 상태가 이미 동일한 경우 불필요한 데이터베이스 쓰기를 방지합니다. 이는 좋은 성능 최적화 패턴입니다.src/main/java/com/cheeeese/cheese4cut/presentation/Cheese4cutController.java (1)
32-38: 인증 파라미터 전달이 일관되게 구현되었습니다.컨트롤러가 Swagger 인터페이스와 일치하게
Authentication파라미터를 받아서 서비스 레이어로 전달하고 있습니다. 구현이 정확합니다.src/main/java/com/cheeeese/album/application/AlbumService.java (1)
62-82: 만료 시간 일관성이 잘 유지되고 있습니다.
expiredAt을 한 번만 생성하여 앨범 엔티티 생성과 Redis 등록에 동일한 타임스탬프를 사용하고 있습니다. 이는 데이터 일관성을 보장하고LocalDateTime.now()를 여러 번 호출할 때 발생할 수 있는 미세한 시간차를 방지합니다. 7일 만료 정책도 PR 요구사항과 일치합니다.src/main/java/com/cheeeese/cheese4cut/dto/response/Cheese4cutPreviewResponse.java (2)
22-25: 역할 기반 응답을 위한 필드 추가가 적절합니다.
myRole필드를 추가하여 사용자의 역할(MAKER/GUEST)에 따라 프론트엔드에서 다른 UI를 표시할 수 있게 되었습니다. Schema 어노테이션도 명확하게 작성되었습니다.
35-38: 사진 순위 정보 제공이 유용합니다.
photoRank필드를 추가하여 좋아요 TOP 4 사진의 순위(1~4)를 명시적으로 제공합니다. 클라이언트가 정렬 로직을 구현할 필요 없이 순위 정보를 바로 사용할 수 있어 좋습니다.src/main/java/com/cheeeese/album/application/AlbumExpirationService.java (1)
64-75: 포토 누락 방지 처리 좋습니다.ID 목록을 기반으로 순서를 복원하고 null 검사를 통해 잘못된 치즈네컷 생성 가능성을 사전에 차단한 점이 인상적입니다.
src/main/java/com/cheeeese/cheese4cut/domain/Cheese4cutPhoto.java (1)
45-47: 양방향 연관관계 설정 👍
assignToCheese4cut으로 owning side를 확실히 묶어 일관된 연관관계가 유지되도록 한 설계가 좋습니다.src/main/java/com/cheeeese/cheese4cut/dto/response/Cheese4cutFinalResponse.java (1)
14-29: 최종 응답 스키마 확장 👍
FinalPhotoInfo레코드로 ID와 순위를 명시적으로 내려주니 소비 측에서 해석이 훨씬 쉬워졌습니다.src/main/java/com/cheeeese/cheese4cut/domain/Cheese4cut.java (1)
29-45: Cheese4cutPhoto 컬렉션 매핑이 깔끔합니다.
@OneToMany와orphanRemoval조합으로 사진 엔티티 생명주기가 자연스럽게 정리된 점이 좋습니다.src/main/java/com/cheeeese/cheese4cut/infrastructure/mapper/Cheese4cutMapper.java (1)
51-65: 정렬 보존된 Cheese4cut 생성 좋습니다.IntStream을 활용해 원본 순서를 그대로 유지하면서
Cheese4cutPhoto를 구성해photoRank관리가 분명해졌습니다.
src/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java
Show resolved
Hide resolved
zyovn
left a comment
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.
🧀🧀🧀🧀🧀🧀🧀🧀🧀🧀🧀🧀🧀
수고하셧습니다
🔗 연관된 이슈
🚀 변경 유형
📝 작업 내용
[작업한 내용]
📸 스크린샷
💬 리뷰 요구사항
📜 리뷰 규칙
Reviewer는 아래 P5 Rule을 참고하여 리뷰를 진행합니다.
P5 Rule을 통해 Reviewer는 Reviewee에게 리뷰의 의도를 보다 정확히 전달할 수 있습니다.
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선 사항