Skip to content

[feat] 엔티티 멘션 검색 API 무한스크롤 페이지네이션 지원 - #120

Merged
You-Hyuk merged 9 commits into
developfrom
feat/#119-mention-search-infinite-scroll
Sep 16, 2026
Merged

You-Hyuk merged 9 commits into
developfrom
feat/#119-mention-search-infinite-scroll

Conversation

@You-Hyuk

@You-Hyuk You-Hyuk commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

관련 이슈

Closes #119


변경 개요

FE에서 게시글 작성 시 엔티티 멘션 자동완성 드롭다운을 무한 스크롤 방식으로 전환하면서(frontend-46 세션 요청) BE 검색 API에 페이지네이션이 필요해졌다. GET /api/mentions/searchpage 파라미터를 추가하고 limit 기본값을 20으로 올려, 응답을 프로젝트 표준 페이지네이션 포맷(PageResponse)으로 통일했다.

동시에 게시글 통합 검색(GET /api/search)에 최소 검색어 길이(2자) 검증을 추가해 한 글자 검색으로 인한 광범위 조회를 막았다.

변경사항

파일 변경 내용
MentionController.java page 파라미터 추가, limit 기본값 10 → 20, 응답 타입 ListPageResponse
MentionService.java CONCERT/ARTIST/RELEASE 검색을 Page 기반으로 전환, ARTIST/RELEASE에 id 오름차순 정렬 적용
ConcertRepository.java searchByTitleForMention 반환 타입 ListPage, countQuery 추가, startDate DESC, id DESC tie-breaker
SearchController.java Swagger 400 응답 설명 갱신 (2자 미만 케이스 추가)
PostService.java 게시글 통합 검색어 trim 후 2자 미만이면 InvalidInputException
SecurityConfig.java /api/entities/** permitAll 추가
MentionServiceTest.java, MentionControllerTest.java, PostServiceTest.java 신규 시그니처·검증 케이스 반영

주요 구현 내용

무한 스크롤은 페이지 간 결과 중복·누락 없이 안정적으로 이어져야 하므로, 정렬 기준이 없던 ARTIST/RELEASE 검색에 id 오름차순을, 이미 startDate 정렬이 있던 CONCERT 검색에는 id를 tie-breaker로 추가해 동일 정렬 키를 가진 레코드 간 순서를 고정했다. 단, ArtistRepository/ReleaseGroupRepository의 검색 메서드는 ArtistService/ReleaseService에서도 자체 정렬 조건으로 재사용되므로, 리포지토리 쿼리 자체에는 정렬을 넣지 않고 MentionService가 전달하는 Pageable에만 정렬을 실었다.


테스트

  • 로컬 실행 확인
  • 단위 테스트 추가/수정
  • 예외 케이스 확인

리뷰어 참고사항

  • base 브랜치를 develop으로 지정했습니다 (이 저장소는 main이 아닌 develop으로 병합하는 구조 — #116 post-board PR도 develop에 머지됨).
  • /api/entities/** permitAll 추가와 게시글 검색 최소 길이 검증은 이슈 [feat] 엔티티 멘션 검색 API 무한스크롤 지원 (limit 기본값 20 변경) #119(멘션 페이지네이션)와 직접 관련은 없지만, 별도 이슈 없이 진행 중이던 작업이라 같은 브랜치/PR에 포함했습니다.

코드 리뷰

변경사항 요약

멘션 검색 API(MentionController/MentionService)를 limit 단건 조회에서 page 기반 페이지네이션(PageResponse)으로 전환했고, ConcertRepository.searchByTitleForMentionListPage 반환으로 바꾸며 countQuery와 id tie-breaker를 추가했다. 별개로 PostService.search에 최소 검색어 길이 검증을, SecurityConfig/api/entities/** permitAll을 추가했다. 테스트 3개 파일이 함께 갱신되었다.


✅ 특이사항 없음. 변경사항이 깔끔하게 구현되었습니다.

Summary by CodeRabbit

  • New Features

    • Mention search now supports paginated results for infinite scrolling, with up to 20 items per page.
    • Track entities can now be searched, mentioned, and included in relevant post searches.
    • Track results may display their associated release information.
    • Entity lookup endpoints are publicly accessible for GET requests.
  • Bug Fixes

    • Search queries are trimmed and must contain at least two characters.
    • Results now maintain consistent ordering for matching dates or titles.
  • Documentation

    • Updated API documentation for pagination and search-query requirements.

You-Hyuk and others added 2 commits September 15, 2026 16:11
trim 후 2자 미만이면 InvalidInputException을 던지도록 PostService.search()에 검증 추가.
엔티티 조회 API(/api/entities/**)를 SecurityConfig permitAll에 추가.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JNjhau1bE58LegkwKtPBq2
FE 무한스크롤 전환에 맞춰 GET /api/mentions/search에 page 파라미터를 추가하고
limit 기본값을 10 -> 20으로 변경. 응답을 프로젝트 표준 PageResponse
({content, page, size, totalElements, totalPages}) 형식으로 변경.

- ConcertRepository.searchByTitleForMention: List -> Page 반환, countQuery 추가,
  startDate DESC + id DESC tie-breaker로 페이지 간 정렬 안정성 확보
- MentionService: ARTIST/RELEASE 검색에 id 오름차순 정렬을 적용해 동일한 이유로 안정성 확보
- MentionController/Service 테스트를 새 시그니처에 맞게 갱신, 페이지 파라미터 전달과
  정렬 적용을 검증하는 케이스 추가

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JNjhau1bE58LegkwKtPBq2
@You-Hyuk You-Hyuk added the Feat ✨ 새 기능 추가 label Sep 15, 2026
@You-Hyuk You-Hyuk self-assigned this Sep 15, 2026
@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 4378ef35-c128-46c5-aa3b-9c0c270e1f4b

📥 Commits

Reviewing files that changed from the base of the PR and between dd2ed5d and 6a71b2f.

📒 Files selected for processing (15)
  • src/main/java/com/Coming/Backend/post/dto/EntityCardResponse.java
  • src/main/java/com/Coming/Backend/post/dto/PostEntityTagResponse.java
  • src/main/java/com/Coming/Backend/post/entity/EntityType.java
  • src/main/java/com/Coming/Backend/post/repository/PostRepository.java
  • src/main/java/com/Coming/Backend/post/service/EntityLookupService.java
  • src/main/java/com/Coming/Backend/post/service/MentionService.java
  • src/main/java/com/Coming/Backend/release/repository/ReleaseGroupRepository.java
  • src/main/java/com/Coming/Backend/release/repository/TrackRepository.java
  • src/test/java/com/Coming/Backend/post/controller/MentionControllerTest.java
  • src/test/java/com/Coming/Backend/post/repository/PostRepositoryTest.java
  • src/test/java/com/Coming/Backend/post/service/EntityLookupServiceTest.java
  • src/test/java/com/Coming/Backend/post/service/MentionServiceTest.java
  • src/test/java/com/Coming/Backend/post/service/PostServiceTest.java
  • src/test/java/com/Coming/Backend/release/repository/ReleaseGroupRepositoryTest.java
  • src/test/java/com/Coming/Backend/release/repository/TrackRepositoryTest.java

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Mention search now supports page-based PageResponse results for concerts, artists, releases, and tracks. TRACK cards include release-group data. Search queries are trimmed and require at least two characters. Entity GET endpoints are publicly accessible.

Changes

Mention search pagination and contracts

Layer / File(s) Summary
Paginated search contracts
src/main/java/com/Coming/Backend/concert/repository/ConcertRepository.java, src/main/java/com/Coming/Backend/release/repository/ReleaseGroupRepository.java, src/main/java/com/Coming/Backend/release/repository/TrackRepository.java, src/main/java/com/Coming/Backend/post/dto/*
Mention-search repositories return paginated results with count queries and stable ordering. Entity card responses include releaseGroupId.
Paginated mention search flow
src/main/java/com/Coming/Backend/post/controller/MentionController.java, src/main/java/com/Coming/Backend/post/service/MentionService.java, src/test/java/com/Coming/Backend/post/controller/MentionControllerTest.java, src/test/java/com/Coming/Backend/post/service/MentionServiceTest.java
The endpoint accepts page and limit, returns PageResponse<EntityCardResponse>, and adds TRACK search support. Tests verify pagination metadata, requested page values, and artist sorting.
TRACK lookup and post search support
src/main/java/com/Coming/Backend/post/entity/EntityType.java, src/main/java/com/Coming/Backend/post/service/EntityLookupService.java, src/main/java/com/Coming/Backend/post/repository/PostRepository.java, src/test/java/com/Coming/Backend/post/repository/PostRepositoryTest.java, src/test/java/com/Coming/Backend/post/service/EntityLookupServiceTest.java, src/test/java/com/Coming/Backend/post/service/PostServiceTest.java
The TRACK entity type resolves cards with artist, release-group, and thumbnail data. Missing release groups produce title-only cards. Post queries match track titles and track tags associated with releases.
Search validation and access
src/main/java/com/Coming/Backend/post/service/PostService.java, src/main/java/com/Coming/Backend/post/controller/SearchController.java, src/main/java/com/Coming/Backend/common/config/SecurityConfig.java, src/test/java/com/Coming/Backend/post/service/PostServiceTest.java
Search queries are trimmed and rejected when shorter than two characters. API documentation reflects this validation. GET /api/entities/** is permitted without authentication.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant MentionController
  participant MentionService
  participant TrackRepository
  participant EntityLookupService
  Client->>MentionController: Request TRACK mention page
  MentionController->>MentionService: Pass type, query, page, and limit
  MentionService->>TrackRepository: Request paginated track matches
  TrackRepository-->>MentionService: Return Page<Track>
  MentionService->>EntityLookupService: Build track cards
  EntityLookupService-->>MentionService: Return cards with release-group data
  MentionService-->>MentionController: Return PageResponse<EntityCardResponse>
  MentionController-->>Client: Return paginated JSON
Loading

Merge Risk: ⚪ Minimal · up to 6a71b

No concrete merge-blocking issue was established from the supplied evidence.

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning #119의 페이지네이션, 기본 limit=20, PageResponse<EntityCardResponse>, Repository Page<T> 반환, 정렬 tie-breaker, TRACK 카드와 releaseGroupId, 게시글·태그·릴리즈 연계, 테스트 및 Swagger 변경은 변경 요약에서 확인됩니다. 그러나 #119가 요구한 `spe… spec/api/posts.md를 갱신하십시오. 멘션 검색 응답을 {content, page, size, totalElements, totalPages} 형식의 PageResponse<EntityCardResponse>로 설명하고 해당 문서 변경을 PR에 포함하십시오.
Out of Scope Changes check ⚠️ Warning #119의 범위에는 멘션 검색 페이지네이션과 TRACK 멘션의 게시글·태그·릴리즈 연계가 포함됩니다. PostService.search의 일반 게시글 검색어 trim 및 2자 미만 검증은 TRACK 연계와 무관합니다. SecurityConfig의 모든 GET /api/entities/** 공개 허용도 #119의 멘션 검색 API 요구에 포함되지 … 일반 게시글 검색어 검증과 /api/entities/** 접근 정책 변경을 별도 PR로 분리하거나 제거하십시오. 이 PR에는 #119 구현에 직접 필요한 변경과 관련 테스트·문서만 유지하십시오.
Docstring Coverage ⚠️ Warning Docstring coverage is 9.46% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 74 functions across 20 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: infinite-scroll pagination support for the entity mention search API.
Full details: Linked Issues check

Explanation

#119의 페이지네이션, 기본 limit=20, PageResponse&lt;EntityCardResponse&gt;, Repository Page&lt;T&gt; 반환, 정렬 tie-breaker, TRACK 카드와 releaseGroupId, 게시글·태그·릴리즈 연계, 테스트 및 Swagger 변경은 변경 요약에서 확인됩니다. 그러나 #119가 요구한 spec/api/posts.md의 기존 배열 응답 설명을 페이지네이션 형식으로 갱신한 변경은 확인되지 않습니다.

Full details: Out of Scope Changes check

Explanation

#119의 범위에는 멘션 검색 페이지네이션과 TRACK 멘션의 게시글·태그·릴리즈 연계가 포함됩니다. PostService.search의 일반 게시글 검색어 trim 및 2자 미만 검증은 TRACK 연계와 무관합니다. SecurityConfig의 모든 GET /api/entities/** 공개 허용도 #119의 멘션 검색 API 요구에 포함되지 않습니다. SearchController 설명 변경은 이 별도 검색 검증을 반영한 변경입니다.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#119-mention-search-infinite-scroll

Warning

Git: CodeRabbit could not clone the repository, so clone-backed analysis was skipped and this review may be incomplete. Verify repository clone access, such as SSH credentials, before requesting another full review. If clone access is intentionally unavailable, use path_filters to narrow the review scope.


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

Comment @coderabbitai help to get the list of available commands.

You-Hyuk and others added 7 commits September 15, 2026 17:06
트랙 멘션 도입을 위한 준비 작업. 트랙이 속한 앨범 id를 응답에 실어
FE가 앨범 상세 페이지로 링크를 구성할 수 있게 한다. TRACK 외 타입은
당분간 null을 반환한다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JNjhau1bE58LegkwKtPBq2
ConcertRepository.searchByTitleForMention과 동일한 패턴으로 트랙명
부분 일치 검색을 추가한다. 기존 LIKE 쿼리들과 달리 ESCAPE '\' 절을
명시해 서비스 레이어의 와일드카드 이스케이프가 실제로 동작하도록
했다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JNjhau1bE58LegkwKtPBq2
앨범(RELEASE) 단위로만 지원되던 음악 멘션에 트랙 단위를 추가한다.
MentionService.searchTracks()가 트랙명으로 검색하고,
EntityLookupService.toTrackCardsById()가 트랙 → 앨범 → 아티스트를
배치 조회해 카드(제목=트랙명, 부제=아티스트·앨범명, releaseGroupId=
FE 링크 구성용)로 변환한다. 앨범 참조가 끊긴 트랙(FK 제약 없음)은
제목만 채운 카드로 안전하게 대체한다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JNjhau1bE58LegkwKtPBq2
PostRepository.searchPosts()가 ARTIST/CONCERT/RELEASE 태그된
게시글만 이름으로 찾을 수 있었다. TRACK 태그 조건을 동일한 형태로
추가해, 트랙이 멘션된 게시글도 트랙명으로 검색되게 한다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JNjhau1bE58LegkwKtPBq2
TRACK 멘션 카드(EntityCardResponse)에는 releaseGroupId가 채워지지만,
게시글 상세·목록의 entityTags(PostEntityTagResponse)에는 반영되지 않아
게시글 하단 태그 칩에서 트랙 앨범으로 딥링크할 수 없었다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JNjhau1bE58LegkwKtPBq2
트랙 앵커가 앨범 상세 페이지로 귀결되는 구조라, RELEASE 백링크 조회 시
해당 릴리즈에 속한 트랙이 태그된 게시글도 함께 노출되도록 findByEntityTag 확장

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JNjhau1bE58LegkwKtPBq2
TRACK이 별도 멘션 타입으로 분리된 이후에도 RELEASE 멘션 검색이 내부
트랙명까지 매칭해, 검색어와 무관해 보이는 앨범이 노출되는 문제가 있었다.
멘션 전용 쿼리(searchByTitleForMention)를 추가해 릴리즈 제목만 매칭하도록
분리하고, 기존 searchReleases(트랙/아티스트명 포함 매칭)는 일반 릴리즈
목록 API에서 그대로 사용한다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JNjhau1bE58LegkwKtPBq2
@You-Hyuk
You-Hyuk merged commit 67869f0 into develop Sep 16, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feat ✨ 새 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 엔티티 멘션 검색 API 무한스크롤 지원 (limit 기본값 20 변경)

1 participant