feat : 구간 재생 준비 API 연동 - #136
Conversation
|
Warning Review limit reached
Next review available in: 56 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough트랙 좋아요 등록·삭제, 장소 트랙 상세 조회, 재생 준비 조회 API와 React Query 훅을 추가했습니다. 핀 카드와 상세 화면을 서버 데이터에 연결하고, 곡 상세 화면에 실제 재생 정보를 표시합니다. Changes트랙 API 및 핀 기능 연동
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant PinDetailPage
participant usePutLikedTrack
participant likedTrackCache
participant trackApi
User->>PinDetailPage: 좋아요 버튼 클릭
PinDetailPage->>usePutLikedTrack: placeTrackId 전달
usePutLikedTrack->>likedTrackCache: 좋아요 상태와 개수 낙관적 갱신
usePutLikedTrack->>trackApi: 좋아요 등록 요청
trackApi-->>usePutLikedTrack: 응답 반환
usePutLikedTrack->>likedTrackCache: 관련 쿼리 무효화
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
src/api/track.ts (2)
49-65: 🗄️ Data Integrity & Integration | 🔵 Trivial장소 ID와 좌표가 하드코드되어 있습니다.
주석은 이미 이 상태를 인지하고 "추후에 수정 필요"라고 명시합니다.
placeId는 URL 경로에2로 고정되어 있습니다. 실제 사용자 위치나 선택된 장소를 반영하도록 나중에 교체해야 합니다.주석에 적힌 기본 좌표값(
latitude: 37.5665, longitude: 126.978)도usePlaceTrack.ts의 실제 기본값(37.5350918,127.0531533)과 다릅니다. 자세한 내용은 통합 코멘트를 참고하십시오.이 작업을 진행할 해결책을 생성해 드릴까요? 아니면 별도 이슈로 등록해 드릴까요?
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/api/track.ts` around lines 49 - 65, Update getPlaceTracks so the URL uses the caller’s selected placeId instead of the hardcoded 2, adding placeId to the function input and passing it into the path. Replace any hardcoded coordinate defaults associated with this request using the established defaults from usePlaceTrack.ts, while preserving the existing query parameters and response handling.
51-61: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
sort매개변수 타입을PinSort로 좁히십시오.
getPlaceTracks의sort매개변수는string으로 선언되어 있습니다. 호출부는 항상PinSort값을 전달합니다. 타입을PinSort로 지정하면 잘못된 문자열 전달을 컴파일 시점에 막을 수 있습니다.♻️ 제안하는 타입 변경
import type { searchTracksResponse, GetLikedTracksResponse, GetPlaceTracksResponse, PutLikedTracksResponse, GetPlaceTrackDetailResponse, GetPlaybackPreparationsResponse, } from '`@/features/pin/types`'; +import type { PinSort } from '`@/features/pin/types`'; export async function getPlaceTracks( page: string, size: number, latitude: number, longitude: number, - sort: string, + sort: PinSort, ): Promise<GetPlaceTracksResponse> {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/api/track.ts` around lines 51 - 61, Change the sort parameter type in the getPlaceTracks function signature from string to PinSort to enforce type safety at compile time and prevent invalid values from being passed, ensuring the function only accepts the valid PinSort enum values that callers actually use.src/features/pin/queries/usePlaceTrack.ts (1)
14-21: 🗄️ Data Integrity & Integration | 🔵 Trivial기본 좌표가 하드코드되어 있고,
src/api/track.ts의 주석과 값이 다릅니다.
latitude와longitude의 기본값이37.5350918,127.0531533으로 고정되어 있습니다.src/api/track.ts의 주석은37.5665,126.978을 예시로 듭니다. 두 값이 일치하지 않습니다.실제 사용자 위치를 사용할 계획이라면 이 기본값은 임시 상태입니다. 자세한 내용은 통합 코멘트를 참고하십시오.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/pin/queries/usePlaceTrack.ts` around lines 14 - 21, The default latitude and longitude values in the usePlaceTrack function parameters are hardcoded and do not match the example coordinates documented in src/api/track.ts, creating inconsistency between the function defaults and the API documentation. Update the default values for the latitude parameter (currently 37.5350918) and longitude parameter (currently 127.0531533) in the UsePlaceTrackParams destructuring to align with the documented example values from src/api/track.ts (37.5665 and 126.978 respectively).src/features/pin/queries/likedTrackCache.ts (1)
1-98: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win낙관적 업데이트/롤백 로직에 테스트가 없습니다.
prepareLikedTrackMutation,rollbackLikedTrackMutation,setPlaceTrackLiked,removeLikedTrackFromList는 순수 함수에 가깝고QueryClient만 모킹하면 테스트하기 쉽습니다. 이 로직은 좋아요 상태와 카운트를 낙관적으로 변경하고 실패 시 되돌리는 핵심 경로입니다. 회귀가 발생하면 캐시 상태가 실제 서버 상태와 어긋나 사용자에게 잘못된 좋아요 상태를 보여줄 수 있습니다.단위 테스트 작성을 도와드릴까요?
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/pin/queries/likedTrackCache.ts` around lines 1 - 98, Add unit tests for the cache mutation functions prepareLikedTrackMutation, rollbackLikedTrackMutation, setPlaceTrackLiked, and removeLikedTrackFromList. Mock the QueryClient and verify each function correctly updates or reverts the cache state. Cover the core optimistic update paths: preparing and storing snapshot data, restoring data during rollback, updating like status and counts in place track queries, and removing tracks from liked track queries. Include tests for edge cases such as undefined or missing data to ensure cache consistency is maintained.src/features/pin/types.ts (1)
104-108: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Pin타입 정의와pinCount설명이 실제 사용과 다릅니다.주석은
pinCount를 "UI 전용 옵션"이라고 설명합니다.PinListSheet는usePlaceTrack의PlaceTrack데이터로Pin을 생성합니다(src/features/pin/components/PinListSheet.tsx:120-145참고).PlaceTrack은pinCount를 실제 API 필드로 포함합니다. 이 경우pinCount는 UI 전용 값이 아니라 서버 응답값입니다.
Pin이LikedTrack을 기반으로 정의된 것도 오해를 일으킵니다.Pin은 실제로LikedTrack출처와PlaceTrack출처를 모두 표현합니다. 타입을 두 출처의 공통 필드로 직접 선언하면 의도가 더 명확해집니다.♻️ 제안하는 타입 정의
-/** PinCard — 찜한 곡 API와 동일 shape (+ UI 전용 옵션) */ -export type Pin = LikedTrack & { - pinCount?: number; - liked?: boolean; - pinId?: string; -}; +/** + * PinCard — 찜한 곡(LikedTrack) 또는 장소별 곡(PlaceTrack) 데이터를 함께 표현합니다. + * pinCount는 PlaceTrack 출처일 때만 존재하는 실제 API 필드입니다. + */ +export type Pin = TrackBase & { + placeTrackId: number; + likeCount: number; + pinCount?: number; + liked?: boolean; + pinId?: string; +};🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/pin/types.ts` around lines 104 - 108, The JSDoc comment for the Pin type incorrectly describes pinCount as a UI-only option, but pinCount is actually an API field from PlaceTrack data when Pin is created in PinListSheet. Additionally, extending LikedTrack is misleading since Pin represents data from both LikedTrack and PlaceTrack sources. Update the JSDoc comment to clarify that Pin combines fields from both API sources, and consider restructuring the Pin type definition to directly declare the common fields from both LikedTrack and PlaceTrack rather than extending only LikedTrack, making the dual-source nature of the type explicit.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/features/pin/components/PinListSheet.tsx`:
- Around line 120-138: Update the PlaceInfo model and toPlaceInfo conversion to
include latitude and longitude from selectedMapPlace.coordinates, then pass
those coordinates from PinListSheet to usePlaceTrack so its query key and
results react to the selected place instead of using fixed defaults.
In `@src/pages/PinDetailPage.tsx`:
- Line 87: Update the registration-count text in PinDetailPage so it is a
complete standalone sentence when no count is displayed; replace the incomplete
“명이 등록” wording with the appropriate full Korean message while preserving the
surrounding layout and styling.
---
Nitpick comments:
In `@src/api/track.ts`:
- Around line 49-65: Update getPlaceTracks so the URL uses the caller’s selected
placeId instead of the hardcoded 2, adding placeId to the function input and
passing it into the path. Replace any hardcoded coordinate defaults associated
with this request using the established defaults from usePlaceTrack.ts, while
preserving the existing query parameters and response handling.
- Around line 51-61: Change the sort parameter type in the getPlaceTracks
function signature from string to PinSort to enforce type safety at compile time
and prevent invalid values from being passed, ensuring the function only accepts
the valid PinSort enum values that callers actually use.
In `@src/features/pin/queries/likedTrackCache.ts`:
- Around line 1-98: Add unit tests for the cache mutation functions
prepareLikedTrackMutation, rollbackLikedTrackMutation, setPlaceTrackLiked, and
removeLikedTrackFromList. Mock the QueryClient and verify each function
correctly updates or reverts the cache state. Cover the core optimistic update
paths: preparing and storing snapshot data, restoring data during rollback,
updating like status and counts in place track queries, and removing tracks from
liked track queries. Include tests for edge cases such as undefined or missing
data to ensure cache consistency is maintained.
In `@src/features/pin/queries/usePlaceTrack.ts`:
- Around line 14-21: The default latitude and longitude values in the
usePlaceTrack function parameters are hardcoded and do not match the example
coordinates documented in src/api/track.ts, creating inconsistency between the
function defaults and the API documentation. Update the default values for the
latitude parameter (currently 37.5350918) and longitude parameter (currently
127.0531533) in the UsePlaceTrackParams destructuring to align with the
documented example values from src/api/track.ts (37.5665 and 126.978
respectively).
In `@src/features/pin/types.ts`:
- Around line 104-108: The JSDoc comment for the Pin type incorrectly describes
pinCount as a UI-only option, but pinCount is actually an API field from
PlaceTrack data when Pin is created in PinListSheet. Additionally, extending
LikedTrack is misleading since Pin represents data from both LikedTrack and
PlaceTrack sources. Update the JSDoc comment to clarify that Pin combines fields
from both API sources, and consider restructuring the Pin type definition to
directly declare the common fields from both LikedTrack and PlaceTrack rather
than extending only LikedTrack, making the dual-source nature of the type
explicit.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: d5f41076-1d6a-4de1-8215-89423490c5a9
📒 Files selected for processing (17)
src/api/track.tssrc/features/pin/components/PinCard.tsxsrc/features/pin/components/PinListSheet.tsxsrc/features/pin/components/SortTabs.tsxsrc/features/pin/data/mockPinSearchPlaces.tssrc/features/pin/queries/likedTrackCache.tssrc/features/pin/queries/useDeleteLikedTrack.tssrc/features/pin/queries/useGetPlaybackPreparations.tssrc/features/pin/queries/useLikeTrack.tssrc/features/pin/queries/usePlaceTrack.tssrc/features/pin/queries/usePlaceTrackDetail.tssrc/features/pin/queries/usePutLikedTrack.tssrc/features/pin/types.tssrc/pages/MapPage.tsxsrc/pages/MyPlimapPage.tsxsrc/pages/PinDetailPage.tsxsrc/pages/SongDetailPage.tsx
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/pages/SongDetailPage.tsx (2)
150-152: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
songId를 숫자로 검증한 후 조회를 시작하세요.현재 호출은 라우트 문자열을 그대로 훅에 전달합니다.
songId가abc이면Number(songId)가 유효하지 않은 값이 됩니다. 양의 정수인 경우에만 훅을 활성화하거나, 잘못된 경로에 대한 오류 화면을 표시하세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/pages/SongDetailPage.tsx` around lines 150 - 152, Validate songId in SongDetailPage before invoking useGetPlaybackPreparations, converting it to a positive integer and only enabling the hook for valid values. Prevent invalid route strings such as “abc” from reaching the query, and show the existing invalid-route error state when validation fails.
150-160: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win로딩 및 오류 상태에서 30초 대체값을 노출하지 마세요.
song이 없을 때 로딩과 오류를 구분하지 않고durationSec에 30초를 사용합니다. 이 상태에서는 제목, 아티스트, 앨범 이미지도 비어 있을 수 있습니다. API 오류 시 사용자는 잘못된 재생 시간과 불완전한 화면을 봅니다. 성공한song이 있을 때만durationSec을 계산하고, 로딩 및 오류 화면을 별도로 렌더링하세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/pages/SongDetailPage.tsx` around lines 150 - 160, Update SongDetailPage around useGetPlaybackPreparations and durationSec so the 30-second fallback is not used when song is unavailable. Render distinct loading and API-error states before the main detail UI, and calculate durationSec only after a successful song response using its durationMs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/pages/SongDetailPage.tsx`:
- Around line 150-152: Validate songId in SongDetailPage before invoking
useGetPlaybackPreparations, converting it to a positive integer and only
enabling the hook for valid values. Prevent invalid route strings such as “abc”
from reaching the query, and show the existing invalid-route error state when
validation fails.
- Around line 150-160: Update SongDetailPage around useGetPlaybackPreparations
and durationSec so the 30-second fallback is not used when song is unavailable.
Render distinct loading and API-error states before the main detail UI, and
calculate durationSec only after a successful song response using its
durationMs.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 654dd5cc-cb07-464a-9a64-4f66da913adf
📒 Files selected for processing (1)
src/pages/SongDetailPage.tsx
변경 내용
POST /api/v1/tracks/playback-preparations구간 재생 준비 API 연동useGetPlaybackPreparations훅 추가SongDetailPage에서 mock 곡 정보를 API 응답(제목, 아티스트, 앨범 이미지, 재생 시간 등)으로 교체관련 이슈
Closes #135
변경 사항
테스트
스크린샷 (UI 변경시)
2026-07-31.10.37.33.mov
체크리스트
pnpm format)pnpm lint:fix)코드 품질 확인
PR 제출 전에 다음 명령어를 실행하여 코드 품질을 확인해주세요:
Summary by CodeRabbit
새로운 기능
개선