-
Notifications
You must be signed in to change notification settings - Fork 1
[LNK-26] 상세 피드 조회 시 이전 다음 피드 id 추가 #74
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
The head ref may contain hidden characters: "feat/LNK-26-Leenk-\uC0C1\uC138-\uD53C\uB4DC-\uC870\uD68C-\uC2DC-\uC774\uC804-\uB2E4\uC74C-\uD53C\uB4DC-id-\uCD94\uAC00"
Changes from all commits
7424f5a
7844ffc
b2490b5
58f591a
74953fc
023ac09
37d227c
72650e9
e77485f
a3ee1cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package leets.leenk.domain.feed.application.dto.response; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import lombok.Builder; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Builder | ||
| @Schema(description = "피드 네비게이션 응답 (커서 기반 페이지네이션)") | ||
| public record FeedNavigationResponse( | ||
| @Schema(description = "현재 피드 상세 정보") | ||
| FeedDetailResponse current, | ||
|
|
||
| @Schema(description = "이전 피드 목록 (최신순)") | ||
| List<FeedDetailResponse> prevFeeds, | ||
|
|
||
| @Schema(description = "다음 피드 목록 (최신순)") | ||
| List<FeedDetailResponse> nextFeeds, | ||
|
|
||
| @Schema(description = "더 이전 피드 존재 여부", example = "true") | ||
| boolean hasMorePrev, | ||
|
|
||
| @Schema(description = "더 다음 피드 존재 여부", example = "true") | ||
| boolean hasMoreNext | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,13 +3,16 @@ | |
| import leets.leenk.domain.feed.application.exception.FeedNotFoundException; | ||
| import leets.leenk.domain.feed.domain.entity.Feed; | ||
| import leets.leenk.domain.feed.domain.repository.FeedRepository; | ||
| import leets.leenk.domain.feed.domain.service.dto.FeedNavigationResult; | ||
| import leets.leenk.domain.user.domain.entity.User; | ||
| import leets.leenk.domain.user.domain.entity.UserBlock; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.data.domain.PageRequest; | ||
| import org.springframework.data.domain.Pageable; | ||
| import org.springframework.data.domain.Slice; | ||
| import org.springframework.stereotype.Service; | ||
|
|
||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
| @Service | ||
|
|
@@ -35,4 +38,68 @@ public Slice<Feed> findAll(Pageable pageable, List<UserBlock> blockedUser) { | |
| public Slice<Feed> findAllByUser(User user, Pageable pageable) { | ||
| return feedRepository.findAllByUserAndDeletedAtIsNull(user, pageable); | ||
| } | ||
|
|
||
| /** | ||
| * 이전 피드 조회 (더 최신) - hasMore 정보 포함 | ||
| * ASC로 조회한 결과를 최신순(DESC)으로 역정렬하여 반환 | ||
| * 한 번의 쿼리로 피드 목록과 추가 피드 존재 여부를 함께 반환 | ||
| */ | ||
| public FeedNavigationResult findPrevFeedsWithHasMore(Feed currentFeed, List<UserBlock> blockedUsers, int size) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이전 피드를 조회하는 찾을 때 반드시 이전에 만들어진 모든 피드를 반환해야하는건가요? 즉, 어느 한 피드를 조회할 경우 이전 피드와 다음 피드가 함께 조회되며 만약 이전 피드를 조회하면 그 피드의 바로 이전 피드와 바로 다음 피드(처음에 얘기한 '어느 한 피드'가 곧 '바로 다음 피드'가 되겠죠?)가 같이 조회되도록 하는 것입니다.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 입력한 값(여기서는 size가 되겟죠) (기본값은 1) 만큼만 조회해서 위아래로 붙여서 반환하고 있습니다!
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 넵 알겠습니다!! 확인했습니다!! |
||
| List<Long> blockedUserIds = extractBlockedUserIds(blockedUsers); | ||
|
|
||
| // size+1 개를 조회하여 hasMore 판단 | ||
| Pageable pageable = PageRequest.of(0, size + 1); | ||
| List<Feed> feeds = feedRepository.findPrevFeeds( | ||
| currentFeed.getCreateDate(), | ||
| blockedUserIds.isEmpty() ? null : blockedUserIds, | ||
| pageable | ||
| ); | ||
|
|
||
| // hasMore 판단 | ||
| boolean hasMore = feeds.size() > size; | ||
|
|
||
| // size보다 많으면 잘라내기 | ||
| if (hasMore) { | ||
| feeds = feeds.subList(0, size); | ||
| } | ||
|
|
||
| // ASC로 조회했으므로 최신순으로 역정렬 | ||
| Collections.reverse(feeds); | ||
|
|
||
| return new FeedNavigationResult(feeds, hasMore); | ||
| } | ||
|
|
||
| /** | ||
| * 다음 피드 조회 (더 오래된) - hasMore 정보 포함 | ||
| * DESC로 조회하므로 그대로 반환 | ||
| * 한 번의 쿼리로 피드 목록과 추가 피드 존재 여부를 함께 반환 | ||
| */ | ||
| public FeedNavigationResult findNextFeedsWithHasMore(Feed currentFeed, List<UserBlock> blockedUsers, int size) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 마찬가지로 다음 피드를 조회하는 찾을 때 반드시 이후에 만들어진 모든 피드를 반환해야하는건가요? |
||
| List<Long> blockedUserIds = extractBlockedUserIds(blockedUsers); | ||
|
|
||
| // size+1 개를 조회하여 hasMore 판단 | ||
| Pageable pageable = PageRequest.of(0, size + 1); | ||
| List<Feed> feeds = feedRepository.findNextFeeds( | ||
| currentFeed.getCreateDate(), | ||
| blockedUserIds.isEmpty() ? null : blockedUserIds, | ||
| pageable | ||
| ); | ||
|
|
||
| // hasMore 판단 | ||
| boolean hasMore = feeds.size() > size; | ||
|
|
||
| // size보다 많으면 잘라내기 | ||
| if (hasMore) { | ||
| feeds = feeds.subList(0, size); | ||
| } | ||
|
|
||
| return new FeedNavigationResult(feeds, hasMore); | ||
| } | ||
|
|
||
| private List<Long> extractBlockedUserIds(List<UserBlock> blockedUsers) { | ||
| return blockedUsers.stream() | ||
| .map(UserBlock::getBlocked) | ||
| .map(User::getId) | ||
| .toList(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package leets.leenk.domain.feed.domain.service.dto; | ||
|
|
||
| import leets.leenk.domain.feed.domain.entity.Feed; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| /** | ||
| * 피드 네비게이션 조회 결과 | ||
| * 조회된 피드 목록과 추가 피드 존재 여부를 함께 반환 | ||
| */ | ||
| public record FeedNavigationResult( | ||
| List<Feed> feeds, | ||
| boolean hasMore | ||
| ) { | ||
| } |
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.
컬렉션 파라미터에 null을 넘겨 즉시 실패합니다
FeedGetService.findPrevFeedsWithHasMore/findNextFeedsWithHasMore에서 차단 사용자가 없을 때blockedUserIds.isEmpty() ? null : blockedUserIds로 이 쿼리를 호출합니다. 하지만 Hibernate 6에서는 컬렉션 파라미터에null을 바인딩하는 순간IllegalArgumentException: Collection parameter value must not be null가 발생하여 대부분의 사용자(차단 목록이 비어 있음)에게 네비게이션 API가 바로 500을 뱉게 됩니다. 파라미터를 절대 null로 보내지 않도록 하고(빈 리스트 그대로 전달하거나 분기하여 다른 쿼리를 호출), 필요하다면 이 조건을 단순화해주세요.예시 수정:
(필요하다면 빈 리스트일 때는 조건 자체를 생략하는 전용 쿼리로 분기해도 됩니다.) 이 수정이 없으면 네비게이션 기능이 정상 동작하지 않습니다.
Also applies to: 46-54
🤖 Prompt for AI Agents