[feat] 단일 피드 조회 api 개발#135
Conversation
Walkthrough피드 상세 조회 API가 새롭게 추가되었습니다. 이를 위해 컨트롤러, 서비스, 포트, 매퍼, DTO, 에러코드, 스웨거 응답 설명, 그리고 통합 테스트가 생성 및 수정되었습니다. 기존 기능에는 영향이 없으며, 새로운 단일 피드 조회 엔드포인트와 관련 로직이 도입되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant FeedQueryController
participant FeedShowSingleService
participant FeedRepository
participant UserRepository
participant BookRepository
participant Mapper
Client->>FeedQueryController: GET /feeds/{feedId} (userId)
FeedQueryController->>FeedShowSingleService: showSingleFeed(feedId, userId)
FeedShowSingleService->>FeedRepository: findFeedById(feedId)
FeedShowSingleService->>Feed: validateViewPermission(userId)
FeedShowSingleService->>UserRepository: findUserById(creatorId)
FeedShowSingleService->>BookRepository: findBookByIsbn(feed.isbn)
FeedShowSingleService->>FeedShowSingleService: checkSavedAndLiked(feedId, userId)
FeedShowSingleService->>Mapper: toFeedShowSingleResponse(...)
FeedShowSingleService-->>FeedQueryController: FeedShowSingleResponse
FeedQueryController-->>Client: BaseResponse<FeedShowSingleResponse>
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Suggested reviewers
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (5)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/main/java/konkuk/thip/common/exception/code/ErrorCode.java (1)
156-156: HTTP 상태 코드 검토가 필요합니다.비공개 피드 접근 제한은 접근 권한 문제이므로
BAD_REQUEST대신FORBIDDEN이 더 적합할 수 있습니다.BAD_REQUEST는 일반적으로 잘못된 요청 형식을 나타내는 반면,FORBIDDEN은 서버가 요청을 이해했지만 승인을 거부하는 경우에 사용됩니다.- FEED_CAN_NOT_SHOW_PRIVATE_ONE(HttpStatus.BAD_REQUEST, 160008, "비공개 피드는 조회할 수 없습니다."), + FEED_CAN_NOT_SHOW_PRIVATE_ONE(HttpStatus.FORBIDDEN, 160008, "비공개 피드는 조회할 수 없습니다."),src/main/java/konkuk/thip/feed/application/service/FeedShowSingleService.java (1)
34-34: 입력 파라미터 검증 추가를 고려해보세요.
feedId와userId에 대한 null 체크가 없습니다. 잘못된 입력으로 인한 NPE를 방지하기 위해 검증 로직을 추가하는 것이 좋겠습니다.@Override public FeedShowSingleResponse showSingleFeed(Long feedId, Long userId) { + if (feedId == null || userId == null) { + throw new BusinessException(API_BAD_REQUEST); + } + // 1. 단일 피드 조회
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
src/main/java/konkuk/thip/common/exception/code/ErrorCode.java(1 hunks)src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java(1 hunks)src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java(3 hunks)src/main/java/konkuk/thip/feed/adapter/in/web/response/FeedShowSingleResponse.java(1 hunks)src/main/java/konkuk/thip/feed/application/mapper/FeedQueryMapper.java(2 hunks)src/main/java/konkuk/thip/feed/application/port/in/FeedShowSingleUseCase.java(1 hunks)src/main/java/konkuk/thip/feed/application/service/FeedShowSingleService.java(1 hunks)src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSingleApiTest.java(1 hunks)src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSpecificUserApiTest.java(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#113
File: src/main/java/konkuk/thip/recentSearch/adapter/out/persistence/RecentSearchCommandPersistenceAdapter.java:38-44
Timestamp: 2025-07-30T14:05:04.945Z
Learning: seongjunnoh는 코드 최적화 제안에 대해 구체적인 기술적 근거와 효율성 차이를 이해하고 싶어하며, 성능 개선 방식에 대한 상세한 설명을 선호한다.
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#93
File: src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java:49-114
Timestamp: 2025-07-28T16:44:31.224Z
Learning: seongjunnoh는 코드 중복 문제에 대한 리팩토링 제안을 적극적으로 수용하고 함수형 인터페이스를 활용한 해결책을 선호한다.
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#112
File: src/main/java/konkuk/thip/feed/adapter/out/persistence/repository/FeedQueryRepositoryImpl.java:272-272
Timestamp: 2025-07-30T10:44:34.115Z
Learning: seongjunnoh는 피드 커서 페이지네이션에서 LocalDateTime 단일 커서 방식을 선호하며, 복합 키 기반 커서보다 구현 단순성과 성능을 우선시한다.
📚 Learning: commentcontrollertest는 댓글 생성 api의 검증 로직과 예외 상황만을 테스트하는 단위 테스트이며, 성공 케이스는 별도의 통합 테스트(commentcreateapi...
Learnt from: hd0rable
PR: THIP-TextHip/THIP-Server#101
File: src/test/java/konkuk/thip/comment/adapter/in/web/CommentControllerTest.java:118-265
Timestamp: 2025-07-23T17:41:55.507Z
Learning: CommentControllerTest는 댓글 생성 API의 검증 로직과 예외 상황만을 테스트하는 단위 테스트이며, 성공 케이스는 별도의 통합 테스트(CommentCreateAPITest)에서 다룬다.
Applied to files:
src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSingleApiTest.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (19)
src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSpecificUserApiTest.java (1)
42-42: 네이밍 컨벤션 개선을 위한 좋은 변경사항입니다.API 통합 테스트 클래스명에
ApiTest접미사를 추가하여 테스트 유형을 명확히 구분할 수 있게 되었습니다.src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java (1)
172-177: 단일 피드 조회 API에 대한 적절한 에러 코드 그룹핑입니다.관련된 모든 에러 케이스를 포괄적으로 포함하고 있어 API 문서화에 도움이 됩니다.
src/main/java/konkuk/thip/feed/application/port/in/FeedShowSingleUseCase.java (2)
7-7: 메서드 시그니처가 명확하고 적절합니다.파라미터명과 반환 타입이 메서드의 목적을 잘 표현하고 있습니다.
3-3: 아키텍처 의존성 방향 검토가 필요합니다.application.port.in 패키지가 adapter.in.web.response 패키지의 클래스를 import하고 있습니다. 헥사고날 아키텍처에서 application 레이어는 adapter 레이어에 의존하지 않아야 합니다.
Response DTO를 application 레이어 내부로 이동하거나, 도메인 객체를 반환하도록 수정하는 것을 고려해보세요.
⛔ Skipped due to learnings
Learnt from: buzz0331 PR: THIP-TextHip/THIP-Server#78 File: src/main/java/konkuk/thip/user/application/port/out/FollowingQueryPort.java:3-3 Timestamp: 2025-07-14T18:22:56.538Z Learning: THIP 프로젝트에서는 Query API(조회 API)에 한해서는 application 계층에서 adapter.in.web.response 패키지의 response DTO를 직접 참조하는 것을 허용함. 이는 CQRS 아키텍처에서 읽기 전용 작업의 효율성을 위한 팀 컨벤션임.Learnt from: seongjunnoh PR: THIP-TextHip/THIP-Server#43 File: src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java:0-0 Timestamp: 2025-07-03T03:05:05.031Z Learning: THIP 프로젝트에서는 CQRS Port 분리 시 다음 컨벤션을 따름: CommandPort에는 findByXXX를 통해 도메인 엔티티를 찾아오는 메서드를 추가하고, QueryPort에는 조회 API의 response에 해당하는 데이터들을 DB로부터 조회하는 메서드를 추가함.src/main/java/konkuk/thip/feed/application/service/FeedShowSingleService.java (4)
36-39: 비공개 피드 접근 제어 로직이 적절합니다.피드 조회 후 즉시 공개 여부를 확인하여 접근을 제어하는 로직이 올바르게 구현되었습니다.
41-45: 도메인 객체 조회 로직이 명확합니다.피드 작성자와 연관 도서 정보를 적절한 포트를 통해 조회하고 있습니다.
47-51: 사용자 상호작용 상태 확인 로직이 효율적입니다.Set을 사용하여 저장 및 좋아요 상태를 한 번에 조회하고 contains()로 확인하는 방식이 효율적입니다.
53-53: 매퍼를 통한 응답 변환이 적절합니다.도메인 객체들과 상태 플래그를 매퍼를 통해 응답 DTO로 변환하는 방식이 관심사 분리 원칙을 잘 따르고 있습니다.
src/main/java/konkuk/thip/feed/adapter/in/web/response/FeedShowSingleResponse.java (1)
3-21: 레코드 클래스 구조가 잘 설계되었습니다.단일 피드 조회에 필요한 모든 필드가 적절히 포함되어 있고, 불변 객체인 레코드를 사용하여 DTO의 목적에 부합합니다.
src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java (4)
8-8: Swagger 예외 문서화 어노테이션 추가가 좋습니다.새로운 API의 예외 상황에 대한 문서화가 추가되어 API 사용성이 개선됩니다.
12-12: 새로운 UseCase 인터페이스 import가 적절합니다.헥사고날 아키텍처 패턴에 따라 포트 인터페이스를 통한 의존성 주입이 올바르게 구현되었습니다.
30-30: 의존성 주입이 올바르게 구현되었습니다.final 키워드를 사용하여 불변성을 보장하고 기존 패턴과 일관성을 유지합니다.
89-100: 단일 피드 조회 엔드포인트가 잘 구현되었습니다.
- REST API 설계 원칙에 따른 적절한 경로 구조 (
/feeds/{feedId})- Swagger 문서화가 완전함
- 예외 처리 문서화 포함
- 기존 컨트롤러 패턴과 일관성 유지
src/main/java/konkuk/thip/feed/application/mapper/FeedQueryMapper.java (3)
3-9: 필요한 도메인 객체 import가 적절히 추가되었습니다.새로운 매핑 기능에 필요한 도메인 클래스들이 정확히 import되었습니다.
63-79: 단일 피드 응답 매핑이 완전하고 정확합니다.
- 모든 필드가 명시적으로 매핑되어 명확함
- DateUtil을 사용한 일관된 날짜 포맷팅
- 도메인 객체에서 DTO로의 적절한 변환
- MapStruct 어노테이션 사용이 올바름
82-99: 헬퍼 메서드들이 방어적으로 잘 구현되었습니다.
- null 체크로 NullPointerException 방지
- Stream API를 활용한 효율적인 변환
- 빈 배열 반환으로 일관된 동작 보장
- 메서드명이 목적을 명확히 표현
src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSingleApiTest.java (3)
77-112: 성공 케이스 테스트가 포괄적으로 잘 구현되었습니다.
- 필요한 모든 테스트 데이터 설정이 완전함
- 피드 저장/좋아요 상태 검증 포함
- JSON 응답 필드들의 정확한 검증
- 태그와 컨텐츠 URL 배열 검증까지 포함
116-137: 비공개 피드 접근 제한 테스트가 적절합니다.비공개 피드에 대한 접근 제한과 적절한 에러 메시지 반환을 정확히 검증합니다. 보안 요구사항이 올바르게 테스트되었습니다.
62-73: 데이터 정리 순서 검증 완료
postLike,savedFeed,content,feedTag등 Feed를 참조하는 모든 엔티티가feedJpaRepository.deleteAllInBatch()호출 이전에 삭제되고 있습니다.- 따라서 외래키 제약 조건 충돌 없이 안전하게 삭제됩니다.
| @Override | ||
| public FeedShowSingleResponse showSingleFeed(Long feedId, Long userId) { | ||
| // 1. 단일 피드 조회 | ||
| Feed feed = feedCommandPort.getByIdOrThrow(feedId); |
There was a problem hiding this comment.
p2: 근데 혹시 피드 상세조회시에 피드를 작성한 게시자라면 비공개 글이라도 조회할수 있지않나요 ?? feed.validateCreateComment 처럼 피드의 도메인 내의 함수를 사용하여 로직 수정하시면 될 것같습니다! 만약 아니더라도 서비스에서 예외처리 대신 비공개 피드 조회에 대한 예외는 도메인 내에서 처리하는게 더 자연스러울 것 같습니다!
There was a problem hiding this comment.
요즘 정신이 오락가락 하네요ㅎ 꼼꼼한 리뷰 감사드립니다! 수정하겠습니다
| Set<Long> savedFeedIds = savedQueryPort.findSavedFeedIdsByUserIdAndFeedIds(Set.of(feedId), userId); | ||
| Set<Long> likedFeedIds = postLikeQueryPort.findPostIdsLikedByUser(Set.of(feedId), userId); |
| DUPLICATED_FEEDS_IN_COLLECTION(HttpStatus.INTERNAL_SERVER_ERROR, 160005, "중복된 피드가 존재합니다."), | ||
| FEED_ALREADY_SAVED(HttpStatus.BAD_REQUEST, 160006, "사용자가 이미 저장한 피드입니다."), | ||
| FEED_NOT_SAVED_CANNOT_DELETE(HttpStatus.BAD_REQUEST, 160007, "사용자가 저장하지 않은 피드는 저장삭제 할 수 없습니다."), | ||
| FEED_CAN_NOT_SHOW_PRIVATE_ONE(HttpStatus.BAD_REQUEST, 160008, "비공개 피드는 조회할 수 없습니다."), |
There was a problem hiding this comment.
이것도 비공개 게시글일 시 작성사가 조회하는 것이라면 필요없는 코드일 것같습니다!
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/main/java/konkuk/thip/feed/domain/Feed.java (1)
165-172: 피드 조회 권한 검증 로직이 올바르게 구현되었습니다.공개 피드는 모든 사용자가 조회 가능하고, 비공개 피드는 작성자만 조회 가능하도록 하는 비즈니스 로직이 정확히 구현되었습니다. JavaDoc 문서화도 적절합니다.
다만 null 안전성을 고려해볼 수 있습니다:
userId가 null일 경우를 고려한 방어적 코딩을 추가할 수 있습니다:
public void validateViewPermission(Long userId) { + if (userId == null) { + throw new BusinessException(FEED_CAN_NOT_SHOW_PRIVATE_ONE); + } if (!isPublic && !creatorId.equals(userId)) { throw new BusinessException(FEED_CAN_NOT_SHOW_PRIVATE_ONE); } }src/test/java/konkuk/thip/feed/domain/FeedTest.java (1)
1-62: 포괄적이고 잘 구조화된 단위 테스트입니다.validateViewPermission 메서드의 모든 시나리오를 적절히 테스트하고 있습니다:
- 공개 피드 조회 (성공)
- 비공개 피드 작성자 조회 (성공)
- 비공개 피드 타인 조회 (실패)
테스트 메서드명이 한국어로 명확하게 작성되어 있고, 헬퍼 메서드를 통한 테스트 데이터 생성도 적절합니다.
null userId에 대한 엣지 케이스 테스트를 추가할 수 있습니다:
@Test @DisplayName("userId가 null인 경우 비공개 피드 조회 시 예외가 발생한다.") void validateViewPermission_exception_when_null_userId() throws Exception { //given Feed privateFeed = makeFeedWithPublicStatus(false); //when //then assertThatThrownBy(() -> privateFeed.validateViewPermission(null)) .isInstanceOf(BusinessException.class) .hasMessage(FEED_CAN_NOT_SHOW_PRIVATE_ONE.getMessage()); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/main/java/konkuk/thip/common/exception/code/ErrorCode.java(1 hunks)src/main/java/konkuk/thip/feed/application/service/FeedShowSingleService.java(1 hunks)src/main/java/konkuk/thip/feed/domain/Feed.java(2 hunks)src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSingleApiTest.java(1 hunks)src/test/java/konkuk/thip/feed/domain/FeedTest.java(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/main/java/konkuk/thip/common/exception/code/ErrorCode.java
- src/main/java/konkuk/thip/feed/application/service/FeedShowSingleService.java
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#113
File: src/main/java/konkuk/thip/recentSearch/adapter/out/persistence/RecentSearchCommandPersistenceAdapter.java:38-44
Timestamp: 2025-07-30T14:05:04.945Z
Learning: seongjunnoh는 코드 최적화 제안에 대해 구체적인 기술적 근거와 효율성 차이를 이해하고 싶어하며, 성능 개선 방식에 대한 상세한 설명을 선호한다.
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#93
File: src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java:49-114
Timestamp: 2025-07-28T16:44:31.224Z
Learning: seongjunnoh는 코드 중복 문제에 대한 리팩토링 제안을 적극적으로 수용하고 함수형 인터페이스를 활용한 해결책을 선호한다.
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#112
File: src/main/java/konkuk/thip/feed/adapter/out/persistence/repository/FeedQueryRepositoryImpl.java:272-272
Timestamp: 2025-07-30T10:44:34.115Z
Learning: seongjunnoh는 피드 커서 페이지네이션에서 LocalDateTime 단일 커서 방식을 선호하며, 복합 키 기반 커서보다 구현 단순성과 성능을 우선시한다.
📚 Learning: thip 프로젝트에서 record와 vote는 room에 속하지만 feed는 room에 속하지 않는 구조이며, 댓글 작성 시 record/vote에 대해서만 사용자가 해당 room...
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#101
File: src/main/java/konkuk/thip/comment/application/service/CommentCreateService.java:36-39
Timestamp: 2025-07-26T06:09:00.850Z
Learning: THIP 프로젝트에서 Record와 Vote는 Room에 속하지만 Feed는 Room에 속하지 않는 구조이며, 댓글 작성 시 Record/Vote에 대해서만 사용자가 해당 Room의 참가자인지 검증이 필요하다.
Applied to files:
src/main/java/konkuk/thip/feed/domain/Feed.java
🧬 Code Graph Analysis (1)
src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSingleApiTest.java (1)
src/test/java/konkuk/thip/common/util/TestEntityFactory.java (1)
TestEntityFactory(33-304)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (5)
src/main/java/konkuk/thip/feed/domain/Feed.java (1)
4-4: 새로운 import 추가가 적절합니다.BusinessException import가 새로운 validateViewPermission 메서드에서 사용되기 위해 적절히 추가되었습니다.
src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSingleApiTest.java (4)
40-73: 통합 테스트 설정이 적절하고 포괄적입니다.Spring Boot 테스트 설정과 MockMvc 사용이 적절하며, @AfterEach에서 모든 관련 테이블을 정리하여 테스트 격리를 보장하고 있습니다. 다수의 Repository 의존성은 복잡해 보이지만 피드 도메인의 연관관계를 고려할 때 필요한 설정입니다.
75-112: 공개 피드 조회 테스트가 상세하고 정확합니다.테스트 데이터 설정이 현실적이며, 응답 검증이 매우 상세합니다:
- 피드 기본 정보 (ID, 작성자, ISBN)
- 컨텐츠 URL 목록
- 저장/좋아요 상태
- 태그 목록
TestEntityFactory를 활용한 테스트 데이터 생성도 적절합니다.
114-137: 비공개 피드 접근 제한 테스트가 정확합니다.비공개 피드에 대한 타인의 접근을 적절히 차단하고, 올바른 에러 코드와 메시지를 반환하는지 검증하고 있습니다. 도메인 레벨의 권한 검증 로직이 API 레벨까지 올바르게 전파되는 것을 확인할 수 있습니다.
139-161: 피드 작성자의 비공개 피드 조회 테스트가 적절합니다.작성자가 자신의 비공개 피드를 조회할 수 있는 시나리오를 간결하게 테스트하고 있습니다. 성공 케이스에 대한 핵심 검증(피드 ID 일치)이 포함되어 있습니다.
| } | ||
|
|
||
| @Test | ||
| @DisplayName("피드 작성자는 비공개 피드를 단일 조회할 수 있다.") |
| // List<Content> → String[] 변환 | ||
| default String[] mapContentList(List<Content> contentList) { | ||
| if (contentList == null) { | ||
| return new String[0]; | ||
| } | ||
| return contentList.stream() | ||
| .map(Content::getContentUrl) | ||
| .toArray(String[]::new); | ||
| } | ||
|
|
||
| // List<Tag> → String[] 변환 | ||
| default String[] mapTagList(List<Tag> tagList) { | ||
| if (tagList == null) { | ||
| return new String[0]; | ||
| } | ||
| return tagList.stream() | ||
| .map(Tag::getValue) | ||
| .toArray(String[]::new); | ||
| } |
There was a problem hiding this comment.
p3: 사용되지 않는 메서드 같은데 지우는게 좋을 것 같습니다!
There was a problem hiding this comment.
아하 명시하지 않아도 MapStruct가 내부적으로 사용하나 보네요. 찾아보니 메서드 이름이 map[SourceType] 형식이라 명시적으로 매핑하지 않아도 찾을 수 있다고 합니다!
다만, 어떤 매핑 함수가 사용되는지 명시되어 있으면 더 좋을 것 같아서 제가 ReactionQueryMapper에서 했던 것처럼 다음과 같이 수정해보면 어떨지 제안드립니다!!
- 변환 메서드에
@Named추가
import org.mapstruct.Named;
@Named("mapContentList")
default String[] mapContentList(List<Content> contentList) {
if (contentList == null) return new String[0];
return contentList.stream().map(Content::getContentUrl).toArray(String[]::new);
}
@Named("mapTagList")
default String[] mapTagList(List<Tag> tagList) {
if (tagList == null) return new String[0];
return tagList.stream().map(Tag::getValue).toArray(String[]::new);
}@Mapping에서 qualifiedByName으로 명시
@Mapping(target = "contentUrls", source = "feed.contentList", qualifiedByName = "mapContentList")
@Mapping(target = "tagList", source = "feed.tagList", qualifiedByName = "mapTagList")
FeedShowSingleResponse toFeedShowSingleResponse(
Feed feed,
User feedCreator,
Book book,
boolean isSaved,
boolean isLiked
);| Set<Long> savedFeedIds = savedQueryPort.findSavedFeedIdsByUserIdAndFeedIds(Set.of(feedId), userId); | ||
| Set<Long> likedFeedIds = postLikeQueryPort.findPostIdsLikedByUser(Set.of(feedId), userId); |

#️⃣ 연관된 이슈
📝 작업 내용
단일 피드 조회 api 를 개발하였습니다
📸 스크린샷
💬 리뷰 요구사항
FeedQueryDto 를 활용하여 QueryDSL 로 여러 테이블을 join하여 response 를 구성할까 하다가, service 에서 필요한 도메인들을 조회한 후 queryMapper 에서 이를 엮어서 response dto를 반환하도록 하였습니다.
필터링, 페이징, 정렬이 필요한 조회로직이 아니므로 service 에서 도메인을 조회하도록 구현하였습니다!
📌 PR 진행 시 이러한 점들을 참고해 주세요
Summary by CodeRabbit
신규 기능
버그 수정
테스트