Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,11 @@ public AlbumInfoResponse getAlbumInfo(User user, String code) {

albumValidator.validateAlbumParticipant(album, user);

return PhotoMapper.toAlbumInfoResponse(album);
User maker = userAlbumRepository.findMakerByAlbumId(album.getId(), Role.MAKER)
.map(UserAlbum::getUser)
.orElseThrow(() -> new AlbumException(AlbumErrorCode.USER_NOT_MAKER));

return AlbumMapper.toAlbumInfoResponse(album, maker);
}

public List<AlbumBest4CutResponse> getAlbumBest4Cut(User user, String code) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.List;

@Component
@RequiredArgsConstructor
public class AlbumValidator {

private static final ZoneOffset KST_ZONE = ZoneOffset.of("+09:00");
private final AlbumRepository albumRepository;
private final UserAlbumRepository userAlbumRepository;

Expand All @@ -37,7 +39,7 @@ public void validateAlbumCreation(AlbumCreationRequest request) {
throw new AlbumException(AlbumErrorCode.ALBUM_EVENT_DATE_REQUIRED);
}

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.

throw new AlbumException(AlbumErrorCode.ALBUM_EVENT_DATE_INVALID);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ public record AlbumInfoResponse(
@Schema(description = "생성자 ID", example = "1")
Long makerId,

@Schema(description = "생성자 이름", example = "주정빈")
String name,

@Schema(description = "앨범 제목", example = "김수한무거북이")
String title,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,18 @@ public static AlbumBest4CutResponse toBest4CutResponse(Photo photo, String thumb
.isLiked(isLiked)
.build();
}

public static AlbumInfoResponse toAlbumInfoResponse(Album album, User user) {
return AlbumInfoResponse.builder()
.title(album.getTitle())
.makerId(album.getMakerId())
.name(user.getName())
.themeEmoji(album.getThemeEmoji())
.participant(album.getParticipant())
.currentParticipant(album.getCurrentParticipant())
.eventDate(album.getEventDate())
.currentPhotoCnt(album.getCurrentPhotoCount())
.expiredAt(album.getExpiredAt())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,14 @@ Slice<Album> findClosedAlbumsByUserId(
@Param("status") Album.AlbumStatus status,
Pageable pageable
);

@Query("""
SELECT ua
FROM UserAlbum ua
JOIN FETCH ua.user
WHERE ua.album.id = :albumId
AND ua.role = :role
""")
Optional<UserAlbum> findMakerByAlbumId(@Param("albumId") Long albumId, @Param("role") Role role);

}
20 changes: 13 additions & 7 deletions src/main/java/com/cheeeese/global/util/S3Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

public class S3Util {

private static final String PREFIX = "say-cheeeese/";

public static String extractObjectKey(String imageUrl) {
if (imageUrl == null) {
throw new NullPointerException("image url is null");
Expand All @@ -13,14 +15,19 @@ public static String extractObjectKey(String imageUrl) {
try {
URI uri = new URI(imageUrl);
String path = uri.getPath();

if (path != null && !path.isBlank()) {
return path.startsWith("/") ? path.substring(1) : path;
}
} catch (URISyntaxException e) {
if (path.startsWith("/")) {
path = path.substring(1);
}

}
if (imageUrl.startsWith("album/")) {
return imageUrl;
if (path.startsWith(PREFIX)) {
path = path.substring(PREFIX.length());
}

return path;
}
} catch (URISyntaxException ignored) {
}
return imageUrl;
}
Expand All @@ -40,7 +47,6 @@ public static String extractFileName(String imageUrl) {
if (underscoreIdx >= 0 && underscoreIdx < fileName.length() - 1) {
fileName = fileName.substring(underscoreIdx + 1);
}

return fileName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,6 @@ public static PhotoDetailResponse toPhotoDetailResponse(
.build();
}

public static AlbumInfoResponse toAlbumInfoResponse(Album album) {
return AlbumInfoResponse.builder()
.title(album.getTitle())
.makerId(album.getMakerId())
.themeEmoji(album.getThemeEmoji())
.participant(album.getParticipant())
.currentParticipant(album.getCurrentParticipant())
.eventDate(album.getEventDate())
.currentPhotoCnt(album.getCurrentPhotoCount())
.expiredAt(album.getExpiredAt())
.build();
}

public static PhotoLikedUserResponse.PhotoLiker toPhotoLiker(User user, String profileImageUrl, boolean isMe, Role role) {
return PhotoLikedUserResponse.PhotoLiker.builder()
.name(user.getName())
Expand Down
20 changes: 10 additions & 10 deletions src/main/java/com/cheeeese/user/domain/type/ProfileImageType.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@

@Getter
public enum ProfileImageType {
P1("profile/signup_profile_1.jpg"),
P2("profile/signup_profile_2.jpg"),
P3("profile/signup_profile_3.jpg"),
P4("profile/signup_profile_4.jpg"),
P5("profile/signup_profile_5.jpg"),
P6("profile/signup_profile_6.jpg"),
P7("profile/signup_profile_7.jpg"),
P8("profile/signup_profile_8.jpg"),
P9("profile/signup_profile_9.jpg"),
P10("profile/signup_profile_10.jpg");
P1("profile/sign_up_profile_1.jpg"),
P2("profile/sign_up_profile_2.jpg"),
P3("profile/sign_up_profile_3.jpg"),
P4("profile/sign_up_profile_4.jpg"),
P5("profile/sign_up_profile_5.jpg"),
P6("profile/sign_up_profile_6.jpg"),
P7("profile/sign_up_profile_7.jpg"),
P8("profile/sign_up_profile_8.jpg"),
P9("profile/sign_up_profile_9.jpg"),
P10("profile/sign_up_profile_10.jpg");

private final String path;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ public record UserProfileImageResponse(
[
{
"imageCode": "P5",
"profileImageUrl": "https://say-cheese-profile.edge.naverncp.com/profile/signup_profile_5.jpg"
"profileImageUrl": "https://say-cheese-profile.edge.naverncp.com/profile/sign_up_profile_5.jpg"
},
{
"imageCode": "P6",
"profileImageUrl": "https://say-cheese-profile.edge.naverncp.com/profile/signup_profile_6.jpg"
"profileImageUrl": "https://say-cheese-profile.edge.naverncp.com/profile/sign_up_profile_6.jpg"
}
]
"""
Expand All @@ -36,7 +36,7 @@ public record ProfileImageOpt(

@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
) {}
Expand Down