Skip to content

[feat] 특정 유저의 피드 전체 조회 api 개발#129

Merged
seongjunnoh merged 8 commits into
developfrom
feat/#121-feed-show-all-of-specific-user
Aug 2, 2025
Merged

[feat] 특정 유저의 피드 전체 조회 api 개발#129
seongjunnoh merged 8 commits into
developfrom
feat/#121-feed-show-all-of-specific-user

Conversation

@seongjunnoh

@seongjunnoh seongjunnoh commented Aug 2, 2025

Copy link
Copy Markdown
Collaborator

#️⃣ 연관된 이슈

closes #121

📝 작업 내용

특정 유저가 작성한 공개 피드 목록을 최신순으로 조회하는 api를 개발하였습니다

  • api 주요 코드
    • FeedShowAllOfUserService
      • "내 피드 조회", "특정 유저의 피드 조회" 를 FeedShowAllOfUserService 클래스에서 메서드로 나누어 수행하도록 구조를 수정하였습니다
      • 특정 유저의 피드 조회를 위해
        1. 해당 유저가 작성한 공개 피드를 조회
        2. 현재 유저(= access token 에서 파싱한 유저) 가 해당 피드를 저장헀는지, 좋아하는지를 판단
          하는 과정을 거쳐 response를 반환합니다
    • FeedQueryRepositoryImpl
      • FeedQueryRepositoryImpl.findSpecificUserFeedsByCreatedAt 메서드를 통해서 [페이징 처리, 최신순 정렬, FeedQueryDto 로의 매핑] 과정을 거치도록 구현하였습니다
      • FeedQueryRepositoryImpl 의 기존 코드와 유사하게 구현하였습니다
    • response dto에 description 추가
      • response dto에 swagger의 @Schema 어노테이션을 활용해 description을 추가하였습니다
      • 로컬 스웨거에서 서술한 description이 잘 나오는 것을 확인했습니다
image
  • 테스트 코드
    • api 통합 테스트 코드를 작성하였습니다
    • 특정 유저가 작성한 공개 피드의 주요 response data가 제대로 나오는지, 페이징 처리가 잘 되는지 등을 테스트 하였습니다

📸 스크린샷

image THIP 포스트맨에 개발한 api request 저장해놓았습니다

💬 리뷰 요구사항

📌 PR 진행 시 이러한 점들을 참고해 주세요

* P1 : 꼭 반영해 주세요 (Request Changes) - 이슈가 발생하거나 취약점이 발견되는 케이스 등
* P2 : 반영을 적극적으로 고려해 주시면 좋을 것 같아요 (Comment)
* P3 : 이런 방법도 있을 것 같아요~ 등의 사소한 의견입니다 (Chore)

Summary by CodeRabbit

  • 신규 기능

    • 특정 사용자가 작성한 공개 피드를 조회할 수 있는 새로운 API 엔드포인트가 추가되었습니다.
    • 특정 사용자의 피드 목록을 페이지네이션 방식으로 조회할 수 있으며, 다음 페이지를 위한 커서와 마지막 페이지 여부를 확인할 수 있습니다.
  • 버그 수정

    • 기존 내 피드 조회 API 설명이 소폭 수정되었습니다.
  • 문서화

    • 일부 API 메서드에 대한 설명이 추가되어 개발자 문서가 보완되었습니다.
  • 테스트

    • 특정 사용자의 피드 조회 기능에 대한 통합 테스트가 추가되었습니다.

@seongjunnoh seongjunnoh linked an issue Aug 2, 2025 that may be closed by this pull request
2 tasks
@coderabbitai

coderabbitai Bot commented Aug 2, 2025

Copy link
Copy Markdown

Walkthrough

특정 유저가 작성한 공개 피드를 페이징 처리하여 전체 조회하는 API가 새로 추가되었습니다. 이를 위해 컨트롤러, 서비스, 포트, 어댑터, 매퍼, 리포지토리 계층에 새로운 메서드 및 DTO가 도입되었으며, 기존 "내 피드 조회" 관련 코드가 통합 및 리팩터링되었습니다. 통합 테스트도 추가되었습니다.

Changes

Cohort / File(s) Change Summary
컨트롤러 및 응답 DTO 추가
src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java, src/main/java/konkuk/thip/feed/adapter/in/web/response/FeedShowByUserResponse.java
특정 유저의 피드 전체 조회용 GET 엔드포인트(/feeds/users/{userId}) 추가 및 응답 DTO(FeedShowByUserResponse) 신설
서비스 및 유스케이스 통합/신설
src/main/java/konkuk/thip/feed/application/service/FeedShowAllOfUserService.java, src/main/java/konkuk/thip/feed/application/port/in/FeedShowAllOfUserUseCase.java, src/main/java/konkuk/thip/feed/application/service/FeedShowMineService.java, src/main/java/konkuk/thip/feed/application/port/in/FeedShowMineUseCase.java
내 피드/특정 유저 피드 조회 통합 유스케이스 및 서비스 신설, 기존 내 피드 조회 유스케이스/서비스 삭제
퍼시스턴스 어댑터 및 리포지토리
src/main/java/konkuk/thip/feed/adapter/out/persistence/FeedQueryPersistenceAdapter.java, src/main/java/konkuk/thip/feed/adapter/out/persistence/repository/FeedQueryRepository.java, src/main/java/konkuk/thip/feed/adapter/out/persistence/repository/FeedQueryRepositoryImpl.java
특정 유저의 피드를 페이징 조회하는 메서드 추가(어댑터, 리포지토리 인터페이스/구현체)
매퍼
src/main/java/konkuk/thip/feed/application/mapper/FeedQueryMapper.java
FeedShowByUserResponse 변환 메서드 추가 및 기존 내 피드 변환 메서드 개선/통합
포트 문서화
src/main/java/konkuk/thip/feed/application/port/out/FeedQueryPort.java
기존 메서드에 JavaDoc 주석 추가(기능적 변화 없음)
테스트
src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSpecificUserTest.java
특정 유저 피드 전체 조회 API의 통합 테스트 신설

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller
    participant Service
    participant FeedQueryPort
    participant SavedFeedPort
    participant LikedPostPort

    Client->>Controller: GET /feeds/users/{userId}?cursor=...
    Controller->>Service: showSpecificUserFeeds(requestUserId, feedOwnerId, cursor)
    Service->>FeedQueryPort: findSpecificUserFeedsByCreatedAt(feedOwnerId, cursor)
    Service->>SavedFeedPort: findSavedFeedIdsByUserId(requestUserId, feedIds)
    Service->>LikedPostPort: findLikedFeedIdsByUserId(requestUserId, feedIds)
    Service->>Service: Map FeedQueryDto + saved/liked info → FeedShowByUserResponse
    Service->>Controller: FeedShowByUserResponse
    Controller->>Client: BaseResponse<FeedShowByUserResponse>
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15-25 minutes

Assessment against linked issues

Objective Addressed Explanation
특정 유저가 작성한 피드들을 페이징 처리하여 전체 조회하는 API 개발 (#121)
Task1, Task2 (#121) Task1, Task2의 구체적 내용이 명시되어 있지 않아 충족 여부를 판단할 수 없음.

Assessment against linked issues: Out-of-scope changes

(해당 변경사항 내에서는 연관 이슈(#121)와 무관한 기능적 코드 변경이 발견되지 않았습니다.)

Suggested labels

🛠️ feat, 👻 성준

Suggested reviewers

  • hd0rable

Poem

🐇
새로운 API가 토끼처럼 점프했네,
유저의 피드 모아모아 한눈에~
커서 타고 페이지도 척척,
공개 피드만 쏙쏙쏙!
테스트도 든든히 자리 잡고,
리뷰어님, 이 변화와 함께
코드밭에 봄이 오길 바라요!
🌱

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#121-feed-show-all-of-specific-user

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java (1)

54-65: 새로운 특정 유저 피드 조회 엔드포인트가 올바르게 구현됨

새로운 API 엔드포인트가 다음과 같이 잘 구현되었습니다:

  • 명확한 Swagger 문서화
  • 적절한 파라미터 어노테이션 사용
  • 기존 엔드포인트와 일관된 패턴

다만 매개변수 명명에 대한 개선 제안이 있습니다.

가독성 향상을 위해 @PathVariable 이름을 더 명확하게 변경하는 것을 고려해보세요:

- @Parameter(description = "해당 유저(= 피드 주인)의 userId 값") @PathVariable("userId") final Long feedOwnerId,
+ @Parameter(description = "해당 유저(= 피드 주인)의 userId 값") @PathVariable("feedOwnerId") final Long feedOwnerId,

그리고 URL 패스도 함께 수정:

- @GetMapping("/feeds/users/{userId}")
+ @GetMapping("/feeds/users/{feedOwnerId}")

이렇게 하면 인증된 사용자의 userId와 피드 소유자의 feedOwnerId를 더 명확히 구분할 수 있습니다.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 90e6fa1 and 4436cb2.

📒 Files selected for processing (12)
  • src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java (4 hunks)
  • src/main/java/konkuk/thip/feed/adapter/in/web/response/FeedShowByUserResponse.java (1 hunks)
  • src/main/java/konkuk/thip/feed/adapter/out/persistence/FeedQueryPersistenceAdapter.java (2 hunks)
  • src/main/java/konkuk/thip/feed/adapter/out/persistence/repository/FeedQueryRepository.java (1 hunks)
  • src/main/java/konkuk/thip/feed/adapter/out/persistence/repository/FeedQueryRepositoryImpl.java (2 hunks)
  • src/main/java/konkuk/thip/feed/application/mapper/FeedQueryMapper.java (2 hunks)
  • src/main/java/konkuk/thip/feed/application/port/in/FeedShowAllOfUserUseCase.java (1 hunks)
  • src/main/java/konkuk/thip/feed/application/port/in/FeedShowMineUseCase.java (0 hunks)
  • src/main/java/konkuk/thip/feed/application/port/out/FeedQueryPort.java (1 hunks)
  • src/main/java/konkuk/thip/feed/application/service/FeedShowAllOfUserService.java (1 hunks)
  • src/main/java/konkuk/thip/feed/application/service/FeedShowMineService.java (0 hunks)
  • src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSpecificUserTest.java (1 hunks)
💤 Files with no reviewable changes (2)
  • src/main/java/konkuk/thip/feed/application/port/in/FeedShowMineUseCase.java
  • src/main/java/konkuk/thip/feed/application/service/FeedShowMineService.java
🧰 Additional context used
🧠 Learnings (3)
📓 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 프로젝트에서는 cqrs port 분리 시 다음 컨벤션을 따름: commandport에는 findbyxxx를 통해 도메인 엔티티를 찾아오는 메서드를 추가하고, querypo...
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로부터 조회하는 메서드를 추가함.

Applied to files:

  • src/main/java/konkuk/thip/feed/application/port/out/FeedQueryPort.java
📚 Learning: thip 프로젝트에서는 query api(조회 api)에 한해서는 application 계층에서 adapter.in.web.response 패키지의 response dto를 직접 ...
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 아키텍처에서 읽기 전용 작업의 효율성을 위한 팀 컨벤션임.

Applied to files:

  • src/main/java/konkuk/thip/feed/application/mapper/FeedQueryMapper.java
  • src/main/java/konkuk/thip/feed/adapter/in/web/response/FeedShowByUserResponse.java
🧬 Code Graph Analysis (1)
src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSpecificUserTest.java (1)
src/test/java/konkuk/thip/common/util/TestEntityFactory.java (1)
  • TestEntityFactory (31-295)
⏰ 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 (21)
src/main/java/konkuk/thip/feed/application/port/out/FeedQueryPort.java (1)

13-27: JavaDoc 주석 추가로 코드 가독성 향상

각 메서드 그룹별로 명확한 목적을 설명하는 JavaDoc 주석이 추가되어 코드의 이해도가 향상되었습니다. 특히 CQRS 패턴에서 Query Port의 역할을 명확히 구분하는 데 도움이 됩니다.

src/main/java/konkuk/thip/feed/adapter/out/persistence/repository/FeedQueryRepository.java (1)

18-18: 새로운 메서드 선언이 기존 패턴과 일관성 있게 추가됨

findSpecificUserFeedsByCreatedAt 메서드가 기존의 다른 피드 조회 메서드들과 동일한 시그니처 패턴(userId, lastCreatedAt, size)을 따라 일관성 있게 추가되었습니다.

src/main/java/konkuk/thip/feed/adapter/out/persistence/FeedQueryPersistenceAdapter.java (2)

56-57: 코드 포맷팅 개선

기존 메서드의 닫는 괄호 포맷팅이 개선되어 코드 일관성이 향상되었습니다.


72-83: 새로운 메서드 구현이 기존 패턴을 올바르게 따름

findSpecificUserFeedsByCreatedAt 메서드가 다음과 같이 올바르게 구현되었습니다:

  • 커서에서 lastCreatedAtsize 추출
  • 리포지토리 메서드 호출
  • createdAt을 기반으로 한 커서 인코딩
  • 기존 메서드들과 동일한 CursorBasedList 구성 패턴

커서 기반 페이지네이션 로직이 일관성 있게 적용되었습니다.

src/main/java/konkuk/thip/feed/adapter/out/persistence/repository/FeedQueryRepositoryImpl.java (2)

199-216: 새로운 특정 유저 피드 조회 메서드가 올바르게 구현됨

findSpecificUserFeedsByCreatedAt 메서드가 기존 패턴을 정확히 따라 구현되었습니다:

  1. ID 목록 조회 → 엔티티 조회 → DTO 변환의 3단계 접근법
  2. 순서 보존을 위한 Map 기반 정렬
  3. priority 정보 없이 DTO 변환 (일관성 유지)

233-247: 보안을 고려한 올바른 필터링 조건

fetchSpecificUserFeedIdsByCreatedAt 헬퍼 메서드가 다음과 같이 올바르게 구현되었습니다:

  • ACTIVE 상태 필터링
  • 특정 유저 ID 필터링
  • isPublic.eq(Boolean.TRUE) 필터링으로 공개 피드만 조회 (중요한 보안 요소)
  • 커서 기반 페이지네이션 및 최신순 정렬

공개 피드만 반환하도록 하는 필터링은 사용자 프라이버시 보호를 위해 필수적입니다.

src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java (2)

8-13: Import 구문 업데이트가 적절함

FeedShowMineUseCaseFeedShowAllOfUserUseCase로 대체하고 새로운 응답 DTO인 FeedShowByUserResponse를 추가하여 리팩터링된 서비스 계층과 올바르게 연동됩니다.


27-27: 통합된 Use Case 사용으로 일관성 향상

feedShowMineUseCase 필드가 FeedShowAllOfUserUseCase 타입으로 변경되어 "내 피드 조회"와 "특정 유저 피드 조회" 기능을 통합적으로 처리할 수 있게 되었습니다.

src/main/java/konkuk/thip/feed/application/port/in/FeedShowAllOfUserUseCase.java (2)

3-4: 아키텍처 계층 분리 원칙 검토 필요

UseCase 인터페이스에서 adapter.in.web.response 패키지의 DTO를 직접 참조하고 있습니다. 일반적으로는 application 계층이 adapter 계층을 의존하지 않아야 하지만, 팀 컨벤션에서 Query API에 한해 허용한다고 학습되어 있으므로 이는 문제없습니다.


6-11: 인터페이스 설계가 명확하고 일관성 있음

두 메서드 모두 cursor 기반 페이징을 지원하며, 메서드명이 직관적이고 파라미터 구성이 일관성 있게 설계되었습니다.

src/main/java/konkuk/thip/feed/application/mapper/FeedQueryMapper.java (2)

36-39: 새로운 매핑 메서드 추가가 적절함

내 피드 조회를 위한 단순 매핑 메서드들이 추가되었습니다. 기존 패턴과 일관성 있게 구현되어 있고, DateUtil.formatBeforeTime을 사용한 날짜 포맷팅도 적절합니다.


41-51: 특정 유저 피드를 위한 매핑 로직이 올바름

저장/좋아요 정보를 포함한 매핑 메서드가 추가되었습니다. savedFeedIds.contains()likedFeedIds.contains() 표현식을 사용한 플래그 설정이 적절하게 구현되어 있습니다.

src/test/java/konkuk/thip/feed/adapter/in/web/FeedShowSpecificUserTest.java (4)

86-157: 포괄적인 통합 테스트 시나리오

특정 유저의 피드 조회 API에 대한 핵심 시나리오들이 잘 구현되어 있습니다:

  • 공개 피드만 조회되는지 확인
  • 저장/좋아요 플래그가 올바르게 설정되는지 검증
  • 최신순 정렬 확인

JDBC를 통한 직접적인 timestamp 조작으로 정렬 테스트를 구현한 것도 효과적입니다.


159-220: 공개 피드 필터링 로직 검증이 철저함

다양한 공개/비공개 피드 조합을 통해 공개 피드만 반환되는지 확인하는 테스트가 잘 구현되어 있습니다. 8개의 피드 중 공개 피드 3개만 반환되는 것을 정확히 검증하고 있습니다.


222-308: 페이징 첫 페이지 로직 검증

12개 피드 중 첫 10개를 반환하고 isLast: false를 설정하는 페이징 로직이 올바르게 테스트되었습니다. 피드 순서도 최신순으로 정확히 검증하고 있습니다.


310-374: 커서 기반 페이징 구현이 정확함

커서를 사용한 다음 페이지 조회 테스트가 잘 구현되어 있습니다. DB에서 실제 timestamp를 조회하여 커서로 사용하는 현실적인 접근 방식이 좋습니다. 마지막 페이지에서 isLast: true를 반환하는 것도 올바르게 검증되었습니다.

src/main/java/konkuk/thip/feed/adapter/in/web/response/FeedShowByUserResponse.java (2)

7-17: 페이징 정보를 포함한 응답 DTO 구조가 적절함

Java record를 사용한 불변 DTO 설계가 좋습니다. feedList, nextCursor, isLast 필드로 페이징 정보가 명확하게 구성되어 있고, Swagger 어노테이션으로 API 문서화도 잘 되어 있습니다.


18-33: 피드 상세 정보 DTO가 포괄적으로 설계됨

피드의 모든 필수 정보(ID, 날짜, 책정보, 콘텐츠, 통계, 사용자별 플래그)가 포함되어 있습니다. isSaved, isLiked 플래그를 통해 요청 사용자의 상호작용 상태도 제공하여 클라이언트에서 UI 상태 관리가 용이할 것입니다.

src/main/java/konkuk/thip/feed/application/service/FeedShowAllOfUserService.java (3)

21-30: 서비스 클래스 구조와 의존성 관리가 적절함

생성자 주입을 통한 의존성 관리, 상수로 정의된 페이지 크기, 그리고 필요한 포트들의 주입이 깔끔하게 구성되어 있습니다.


31-45: 내 피드 조회 로직이 간결하고 명확함

커서 생성 → 피드 조회 → 응답 매핑의 단계별 처리가 명확합니다. @Transactional(readOnly = true) 사용도 적절합니다.


47-73: 특정 유저 피드 조회 로직이 효율적으로 구현됨

특정 유저의 피드를 조회한 후, 요청 유저의 저장/좋아요 정보를 별도로 조회하여 매핑하는 로직이 효율적입니다. Collectors.toUnmodifiableSet()을 사용한 것도 좋은 선택입니다.

피드 ID 추출 → 저장/좋아요 정보 조회 → 매핑의 단계별 처리가 논리적이고 성능 효율적입니다.

@buzz0331 buzz0331 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

수고하셨습니다~~ 사소한 리뷰 몇개 남겨놨습니다!!

Comment on lines +9 to +16
@Schema(description = "조회된 피드 목록")
List<FeedShowByUserResponse.FeedDto> feedList,

@Schema(description = "다음 페이지를 요청할 때 사용할 커서")
String nextCursor,

@Schema(description = "마지막 페이지 여부")
boolean isLast

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

오 저는 response까지는 굳이 필요할 것 같지 않아 설명을 작성하진 않았는데 친절하시네욥 😀

Comment on lines +6 to +11
public interface FeedShowAllOfUserUseCase {

FeedShowMineResponse showMyFeeds(Long userId, String cursor);

FeedShowByUserResponse showSpecificUserFeeds(Long userId, Long feedOwnerId, String cursor);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

Comment on lines +40 to +44
return new FeedShowMineResponse(
feedQueryMapper.toFeedShowMineResponse(result.contents()),
result.nextCursor(),
!result.hasNext()
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

굿굿


@Operation(
summary = "특정 유저 피드 조회",
description = "내가 아닌 다른 유저가 작성한 피드를 전체 조회합니다."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

p3: api 이름을 '특정 유저 공개 피드 조회'라고 하는 것이 어떨까요? 내 피드 조회랑 차이를 두고 싶어서,,

Comment on lines +58 to +65
@GetMapping("/feeds/users/{userId}")
public BaseResponse<FeedShowByUserResponse> showSpecificUserFeeds(
@Parameter(hidden = true) @UserId final Long userId,
@Parameter(description = "해당 유저(= 피드 주인)의 userId 값") @PathVariable("userId") final Long feedOwnerId,
@Parameter(description = "커서 (첫번째 요청시 : null, 다음 요청시 : 이전 요청에서 반환받은 nextCursor 값)")
@RequestParam(value = "cursor", required = false) final String cursor) {
return BaseResponse.ok(feedShowMineUseCase.showSpecificUserFeeds(userId, feedOwnerId, cursor));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

p3: 메서드 네이밍도 처음에 피드 상세보기로 해석이 되어서 showUserPublicFeeds 이런식으로 바꿔보는 것 어떨까요!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/main/java/konkuk/thip/feed/application/service/FeedShowAllOfUserService.java (1)

47-73: 특정 유저 피드 조회 로직이 올바르게 구현되었습니다.

메서드의 단계별 처리 흐름이 명확하고, 스트림을 활용한 함수형 프로그래밍 패턴이 잘 적용되었습니다. Collectors.toUnmodifiableSet() 사용으로 불변성도 보장하고 있습니다.

선택적 개선사항: 다중 DB 호출 최적화 고려

현재 피드 조회, 저장된 피드 조회, 좋아요한 피드 조회를 각각 별도로 수행하고 있습니다. 데이터양이 많아질 경우 성능 최적화를 위해 배치 쿼리나 조인을 활용한 단일 호출로 통합하는 것을 고려해볼 수 있습니다.

// 현재: 3번의 별도 DB 호출
CursorBasedList<FeedQueryDto> result = feedQueryPort.findSpecificUserFeedsByCreatedAt(feedOwnerId, nextCursor);
Set<Long> savedFeedIdsByUser = savedQueryPort.findSavedFeedIdsByUserIdAndFeedIds(feedIds, userId);  
Set<Long> likedFeedIdsByUser = postLikeQueryPort.findPostIdsLikedByUser(feedIds, userId);

// 개선안: 피드 조회 시 저장/좋아요 정보를 함께 조회하는 메서드 추가 고려
// CursorBasedList<EnrichedFeedQueryDto> result = feedQueryPort.findSpecificUserFeedsWithUserPreferences(feedOwnerId, userId, nextCursor);

다만 현재 구현도 충분히 명확하고 유지보수하기 좋으므로, 성능 이슈가 실제로 발생할 때 고려하시면 됩니다.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4436cb2 and c08b77f.

📒 Files selected for processing (3)
  • src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java (5 hunks)
  • src/main/java/konkuk/thip/feed/application/port/in/FeedShowAllOfUserUseCase.java (1 hunks)
  • src/main/java/konkuk/thip/feed/application/service/FeedShowAllOfUserService.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/konkuk/thip/feed/application/port/in/FeedShowAllOfUserUseCase.java
  • src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java
🧰 Additional context used
🧠 Learnings (1)
📓 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 단일 커서 방식을 선호하며, 복합 키 기반 커서보다 구현 단순성과 성능을 우선시한다.
⏰ 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 (2)
src/main/java/konkuk/thip/feed/application/service/FeedShowAllOfUserService.java (2)

21-29: 의존성 구조가 잘 설계되었습니다.

서비스 클래스의 구조가 깔끔하게 구성되어 있고, 필요한 포트들이 적절히 주입되어 있습니다. PAGE_SIZE를 상수로 정의한 것도 좋은 관례입니다.


31-45: 내 피드 조회 로직이 간결하고 효율적입니다.

커서 기반 페이지네이션을 활용한 구현이 기존 학습된 패턴과 일치하며, 트랜잭션 설정도 적절합니다. 코드가 읽기 쉽고 유지보수하기 좋게 작성되었습니다.

@buzz0331 buzz0331 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

굿굿

@seongjunnoh seongjunnoh merged commit f375203 into develop Aug 2, 2025
2 checks passed
@seongjunnoh seongjunnoh deleted the feat/#121-feed-show-all-of-specific-user branch August 2, 2025 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[THIP2025-171] [feat] 특정 유저의 피드 전체 조회 api 개발

2 participants