Skip to content

[refactor] CD CRUD 알파테스트 및 리팩토링#121

Merged
hansololiviakim merged 12 commits intodevelopfrom
refactor/#120/cd-crud
Oct 25, 2025
Merged

[refactor] CD CRUD 알파테스트 및 리팩토링#121
hansololiviakim merged 12 commits intodevelopfrom
refactor/#120/cd-crud

Conversation

@hansololiviakim
Copy link
Member

@hansololiviakim hansololiviakim commented Oct 25, 2025

🛰️ 관련 이슈


✨ 주요 변경 사항

1️⃣ 마이페이지 /tracklist → /mycd 라우팅 시 url 형식 수정
2️⃣ 미사용 mock 파일 제거
3️⃣ 마이페이지 /tracklist에서 뒤로가기 시 마이페이지 tab 선택 상태값 복원
4️⃣ 스티커 렌더링 y좌표 위치 상세 조정
5️⃣ /customize step3 버튼 폰트, pc 배경 중 로고 사이즈 수정
6️⃣ /customize step2 테마 버튼 리스트 마우스 드래그 스크롤 기능 추가
7️⃣ 트랙리스트 수정 시 이전 데이터가 잠시 노출되던 현상 수정


🗯️ PR 포인트

  • @maylh 가현님 내 cd + 비공개 상태일때는 마이페이지 /tracklist → /mycd 넘어가서 재생 가능해야할 것 같은데 해당 부분 확인 부탁드립니다!

🚀 알게된 점

▪️ cd 수정 후 재편집 시 이전 데이터 잠시 노출되던 문제

  • 상황: cd 수정 후 재편집 시, step1에서 캐시된 트랙리스트가 화면에 표시되고 수정된 트랙리스트로 출력되지 않았음
  • 원인: refetchOnMount: 'always' 옵션으로 refetch는 수행되지만, React Query가 네트워크 응답 전에 캐시된 데이터를 즉시 렌더링하기 때문
  • 해결방법: isFetching 상태를 함께 체크하여 refetch 중에는 로딩 상태를 유지하도록 처리함
  • 결과: 캐시된 이전 데이터가 화면에 노출되지 않고, 항상 최신 데이터 기준으로 렌더링됨

▪️ 마이페이지 탭 state가 유지되던 문제

  • 상황: 마이페이지 /tracklist → 뒤로가기를 클릭해 /mypage로 넘어갈 때 navigate state를 전달해 이전 tab값을 기억하도록 했는데, state값이 계속 남아있어 다른 페이지를 이동하더라도 해당 tab 값이 유지되는 상황 발생
  • 원인: navigate의 state 값이 React Router의 history.state에 남아 세션 내에서 계속 유지되기 때문
  • 해결방법: 마이페이지 진입 시 탭 복원 후 navigate(location.pathname, { replace: true, state: null })을 호출해 state 초기화
  • 결과: 탭 선택값이 한 번만 복원되고, 이후에는 다른 페이지 이동 시에도 state가 남지 않아 정상 동작
  • 참고: session storage를 사용하지 않은 이유는 해당 케이스 외에는 tab 클릭값을 기억해야 할 이유가 없었기 때문

📖 참고 자료 (선택)

  • 없음

Summary by CodeRabbit

  • 새로운 기능

    • 테마 목록 드래그 스크롤 추가
    • 탭 복원으로 이전 선택 상태 유지
  • 버그 수정

    • 로딩 상태 처리 개선(isLoading/isFetching 통합)
    • 트랙 재생 및 편집 네비게이션 동작 정교화
    • 리스트 레이아웃 워핑 개선
  • 스타일

    • 로고 높이 제약 제거
    • 버튼 타이포그래피 및 입력 패딩 조정
    • 스티커 위치 1px 상향 조정
  • 기타

    • 사용되지 않는 모의 데이터 파일 삭제

@hansololiviakim hansololiviakim self-assigned this Oct 25, 2025
@hansololiviakim hansololiviakim added the HIGH 빠르게 처리해야 하는 높은 우선순위 label Oct 25, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 25, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

마이페이지 및 마이CD 관련 UI와 내비게이션 흐름을 다듬고, 드래그-스크롤 훅을 추가했으며 로딩 상태 지표(isFetching)를 반영하도록 수정하고 일부 모의(mock) 데이터 파일을 삭제했습니다. 또한 CD 스티커 위치와 입력/로고 스타일 소량 조정이 포함됩니다.

Changes

Cohort / File(s) 변경 요약
모의 데이터 제거
src/pages/mypage/mock/likeUser.json, src/pages/mypage/mock/myPlaylist.json, src/pages/mypage/mock/playlistLinks.json
정적 mock JSON 파일들 삭제
로딩/쿼리 상태 업데이트
src/entities/playlist/model/useMyCd.ts, src/pages/mypage/ui/customize/index.tsx, src/pages/mypage/ui/main/components/MyCdList.tsx, src/pages/mypage/ui/main/components/MyLikedCdList.tsx
useQuery 관련 isFetching 도입 및 컴포넌트에서 `isLoading
드래그 스크롤 추가
src/shared/lib/useDragScroll.ts, src/pages/mypage/ui/customize/step2/index.tsx
마우스 기반 드래그-스크롤 훅 추가 및 테마 리스트에 적용 (ref 연결)
내비게이션 상태 전달 변경
src/pages/mycd/index.tsx, src/pages/mypage/ui/tracklist/index.tsx, src/pages/mypage/ui/main/index.tsx
편집 내비게이션에서 쿼리 → location.state로 cdId 전달; 트랙 재생 경로를 쿼리 id → 경로 기반 id로 변경(조건부 ?type=LIKE); 마운트 시 location.state.prevSelectedTab 통해 탭 복원 및 상태 초기화
UI/스타일 소소 변경
src/App.tsx, src/shared/ui/Cd.tsx, src/shared/ui/Input.tsx, src/pages/mypage/ui/customize/step1/index.tsx, src/pages/mypage/ui/customize/step3/index.tsx
로고 컨테이너 첫 자식 이미지의 고정 높이 제거; CD 스티커 top을 1px 상향; 입력 컴포넌트 padding 조정; 장르 드롭다운 패딩/배경/폰트 변경; CTA 버튼 타이포그래피 변경

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MyPage
    participant Location as LocationState
    participant Tabs

    User->>MyPage: /mypage 접근
    MyPage->>Location: useLocation 읽기
    alt prevSelectedTab 존재
        Location-->>MyPage: { prevSelectedTab }
        MyPage->>Tabs: 탭 복원(setTab(prevSelectedTab))
        MyPage->>Location: navigate(replace, state cleared)
    else
        MyPage->>Tabs: 기본 탭 유지
    end
    Tabs-->>User: 마이페이지 렌더링
Loading
sequenceDiagram
    participant User
    participant ThemeList
    participant Hook as useDragScroll
    participant Container

    User->>ThemeList: mousedown
    ThemeList->>Hook: start drag (record pos)
    User->>ThemeList: mousemove
    Hook->>Container: update scrollLeft
    User->>ThemeList: mouseup / mouseleave
    Hook->>Hook: stop drag, cleanup
    Container-->>User: 스크롤 반영
Loading
sequenceDiagram
    participant User
    participant Tracklist
    participant Router

    User->>Tracklist: 재생 클릭 (item)
    Tracklist->>Router: navigate(`/mycd/${id}${type==='LIKE' ? '?type=LIKE' : ''}`)
    Router-->>User: mycd 페이지로 이동
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • 주의 필요 파일/영역:
    • src/entities/playlist/model/useMyCd.tsisFetching/placeholderData 추가로 인한 로딩/데이터 상태 일관성 확인
    • src/pages/mypage/ui/tracklist/index.tsxsrc/pages/mycd/index.tsx — 경로 기반 ID와 location.state 방식의 내비게이션 호환성 검증
    • src/shared/lib/useDragScroll.ts — 이벤트 리스너 등록/해제 및 브라우저 호환성 검토

Possibly related PRs

Suggested reviewers

  • maylh

Poem

🐰 탭을 기억해, 스티커를 한 픽셀 위로 옮기고
손끝으로 테마를 쓱쓱 끌어내리네 ✨
mock 파일은 안녕, 로딩은 똑똑해졌네
CD 정리의 알파테스트, 달려볼까? 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed PR 제목 "[refactor] CD CRUD 알파테스트 및 리팩토링"은 변경사항의 전반적인 범위와 목적을 잘 반영하고 있습니다. 제목은 이 PR이 CD CRUD 기능 관련 리팩토링과 알파테스트 작업임을 명확히 전달합니다. 다만 7가지의 구체적인 변경사항(라우팅 수정, mock 파일 제거, 탭 상태 복원, UI 조정 등)을 모두 담기는 어려우므로, 이 정도 수준의 포괄적 제목은 적절합니다.
Out of Scope Changes Check ✅ Passed 모든 변경사항이 이슈 #120의 "CD 관련 기능 전반 리팩토링" 범위 내에서 타당해 보입니다. 라우팅 수정, 상태 관리 이슈, mock 파일 정리, React Query 캐싱 문제 해결은 명백히 CD CRUD 워크플로우와 관련 있고, UI 조정(스티커 위치, 버튼 폰트, 로고 크기), 드래그 스크롤 기능 추가도 모두 CD 커스터마이징 및 표시 단계의 개선으로서 알파테스트 중 발견된 개선사항으로 볼 수 있습니다.
Description Check ✅ Passed PR 설명은 템플릿의 대부분의 섹션을 충실히 작성했습니다. 관련 이슈(#120), 주요 변경 사항(7가지 항목), PR 포인트, 알게된 점(이전 데이터 노출 문제와 탭 상태 유지 문제에 대한 상세한 설명)이 모두 포함되어 있습니다. 테스트 방법/체크리스트 섹션이 누락되어 있으나, 이는 해당 작업이 알파테스트 단계라는 컨텍스트에서 비필수 항목으로 볼 수 있습니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/#120/cd-crud

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35cdb77 and 594fe0a.

📒 Files selected for processing (8)
  • src/entities/playlist/model/useMyCd.ts (4 hunks)
  • src/pages/mycd/index.tsx (1 hunks)
  • src/pages/mypage/ui/customize/index.tsx (1 hunks)
  • src/pages/mypage/ui/customize/step1/index.tsx (1 hunks)
  • src/pages/mypage/ui/main/components/MyCdList.tsx (1 hunks)
  • src/pages/mypage/ui/main/components/MyLikedCdList.tsx (3 hunks)
  • src/pages/mypage/ui/tracklist/index.tsx (2 hunks)
  • src/shared/ui/Input.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

**/*.{ts,tsx,js,jsx}: ## 1. 일반적인 코딩 컨벤션

포맷팅

  • .prettierrc 설정에 따라 포맷팅 확인
  • 들여쓰기: 2칸 스페이스
  • 최대 줄 길이: 100자
  • 세미콜론 사용 안함
  • 따옴표: 작은따옴표 사용
  • 괄호 안 공백: 있음
  • 화살표 함수 괄호: 항상 사용
  • 줄바꿈: LF 사용

네이밍 컨벤션

  • 컴포넌트: PascalCase (예: UserProfile)
  • 유틸리티/훅/변수: camelCase (예: getUserData, useUserInfo)
  • 상수: UPPER_SNAKE_CASE (예: API_BASE_URL)
  • 이미지 파일: kebab-case (예: user-profile-icon.png)

주석 사용

  • 복잡한 로직에만 주석 추가
  • 불필요한 주석 지양 (코드로 설명 가능한 것)
  • TODO/FIXME 형식: // TODO: 설명 - 작성자

가독성

  • 매직 넘버 지양, 의미있는 상수 사용
  • 함수는 하나의 책임만 가지도록 작성 (최대 20줄 권장)
  • 중첩 깊이 최소화 (3단계 이하 권장)

2. React 모범 사례

컴포넌트 작성

  • 최신 React hooks 사용 권장
  • 컴포넌트는 단일 책임 원칙 준수
  • Presentational/Container 컴포넌트 분리
  • 성능 최적화: memo, useCallback, useMemo 적절히 사용
  • 대용량 리스트는 가상화 라이브러리 사용 고려

상태 관리

  • Zustand와 Tanstack Query를 일관되게 사용
  • 상태 구조는 정규화된 형태로 관리
  • 에러 처리: Error Boundary와 try-catch 또는 onError 콜백 활용

3. 스타일링

Styled Components

  • Styled Components 일관되게 사용
  • 스타일드 컴포넌트명은 의미있게 작성
  • 동적 스타일링은 props나 CSS 변수 활용
  • 테마 시스템 활용하여 글로벌 스타일 관리
  • 재사용 가능한 스타일은 mixin이나 확장으로 관리
  • CSS 포맷팅 가독성 유지
  • 사용하지 않는 스타일이나 중복 스타일 제거

4. Vite 및 빌드 최적화

  • 모듈 import 최적화 (tree-shaking 고려)
  • 환경변수는 .env 파일로 관리
  • vite.config.ts에서 빌드 성능 튜닝 (sourcemap 설정, 플러그인 최적화 등)

5. 아키텍처 및 개발 환경

폴더 구조

  • Feature-Sliced Design (FSD) 구조 준수
  • 레이어별 참조 규칙 엄격히 적용

타입스크립트

  • strict 모드 사용
  • 타입 명시적으로 작성 (any 사용 지양)
  • path alias (@/_) 절대 경로 import 사용

Git 훅

  • Husky 설정으로 pre-commit, commit-msg 린팅 확인

6. 기타 가이드라인

  • 충분한 근거와 함께 리뷰 제공
  • 정보 검증 후 답변
  • 간결하고 명확한 응답
  • 필요시 추가 컨텍스트 요청
  • 검증되지 않은 주장 지양
  • 가능한 경우 출처 명시
  • 별도 언급 없으면 JavaScript 기준
  • 한국어로 응답
  • 대부분 브라우저에서 지원하는 ES6+ 기능 활용
  • 코드 리뷰를 통한 유지보수성 향상에 적극 활용

Files:

  • src/pages/mypage/ui/main/components/MyCdList.tsx
  • src/pages/mypage/ui/main/components/MyLikedCdList.tsx
  • src/pages/mypage/ui/tracklist/index.tsx
  • src/shared/ui/Input.tsx
  • src/entities/playlist/model/useMyCd.ts
  • src/pages/mycd/index.tsx
  • src/pages/mypage/ui/customize/step1/index.tsx
  • src/pages/mypage/ui/customize/index.tsx
🧬 Code graph analysis (4)
src/pages/mypage/ui/main/components/MyCdList.tsx (1)
src/entities/playlist/model/useMyCd.ts (1)
  • useMyCdList (11-18)
src/pages/mypage/ui/main/components/MyLikedCdList.tsx (1)
src/entities/playlist/model/useMyCd.ts (1)
  • useMyLikedCdList (20-27)
src/pages/mypage/ui/customize/step1/index.tsx (1)
src/shared/styles/theme.ts (1)
  • theme (3-122)
src/pages/mypage/ui/customize/index.tsx (1)
src/entities/playlist/model/useMyCd.ts (1)
  • useMyCdActions (29-68)
🔇 Additional comments (10)
src/pages/mypage/ui/customize/step1/index.tsx (1)

396-408: 스타일 정제가 잘 적용되었습니다.

GenreDropdown의 패딩, 배경색, 폰트 스타일 조정이 일관성 있게 적용되었습니다. 테마 시스템의 body2-normal 폰트를 사용하여 다른 UI 요소들과 통일성을 유지하고 있습니다.

src/entities/playlist/model/useMyCd.ts (1)

29-68: isFetching 상태 노출이 적절합니다.

useMyCdActions에서 isFetching을 반환하여 컴포넌트에서 백그라운드 리페칭 중임을 감지할 수 있도록 했습니다. 이는 로딩 UI 처리를 더 정확하게 만듭니다.

src/shared/ui/Input.tsx (1)

113-123: 불필요한 패딩 제거가 적절합니다.

StyledInput에서 padding: 0을 명시하여 InputContainer의 패딩만 사용하도록 정리했습니다. 중복 패딩을 방지하고 레이아웃 제어를 명확하게 만드는 좋은 리팩토링입니다.

src/pages/mypage/ui/customize/index.tsx (1)

48-59: 로딩 상태 처리가 정확하게 구현되었습니다.

isFetching 플래그를 추가하고 isLoading || isFetching 조건으로 로딩 상태를 체크하여, 백그라운드 리페칭 중에도 로딩 UI가 표시되도록 했습니다. Loading 컴포넌트에 조합된 값을 전달하여 이전 리뷰의 피드백을 정확히 반영했습니다.

src/pages/mycd/index.tsx (1)

196-208: 네비게이션 패턴 개선이 적절합니다.

쿼리 파라미터 대신 location.state를 사용하여 cdId를 전달하도록 변경한 것은 URL을 깔끔하게 유지하고, 일시적인 네비게이션 데이터를 처리하는 더 나은 방식입니다. 목적지 컴포넌트와도 잘 연계되어 있습니다.

src/pages/mypage/ui/main/components/MyCdList.tsx (1)

19-22: 로딩 상태 처리 패턴이 일관되게 적용되었습니다.

isFetching 플래그를 활용하여 백그라운드 리페칭 중에도 로딩 UI가 표시되도록 했습니다. 다른 컴포넌트들과 동일한 패턴을 사용하여 일관성을 유지하고 있습니다.

src/pages/mypage/ui/main/components/MyLikedCdList.tsx (2)

36-64: 로딩 상태와 에러 처리가 적절합니다.

isFetching 플래그를 포함하여 로딩 상태를 정확히 체크하고, isLoading || isFetching 조건으로 백그라운드 리페칭 중에도 적절한 로딩 UI를 보여줍니다. 전체 코드베이스에서 일관된 패턴을 유지하고 있습니다.


124-137: 레이아웃 개선이 좋습니다.

flex-wrap: wrap을 추가하여 아이템들이 반응형으로 줄바꿈되도록 했습니다. 다양한 화면 크기에서 더 나은 사용자 경험을 제공합니다.

src/pages/mypage/ui/tracklist/index.tsx (2)

54-54: RESTful URL 구조로 개선되었습니다.

경로 파라미터를 사용하여 /mycd/${playlistId} 형식으로 변경하고, 필요한 경우에만 ?type=LIKE 쿼리 파라미터를 추가하도록 구현했습니다. RESTful API 디자인 원칙에 더 부합하며 URL 구조가 명확해졌습니다.


114-133: 네비게이션 상태 관리가 개선되었습니다.

뒤로가기 시 prevSelectedTab 상태를 전달하여 마이페이지에서 탭 선택 상태를 복원할 수 있도록 했으며, 편집 버튼은 본인의 CD일 때만 조건부 렌더링하여 접근 제어를 명확히 했습니다. PR 목표였던 탭 상태 복원 기능이 잘 구현되었습니다.


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 and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @hansololiviakim, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 CD CRUD 기능의 알파 테스트 단계에서 발견된 여러 개선 사항과 버그 수정, 그리고 전반적인 리팩토링을 포함합니다. 사용자 경험을 향상시키기 위한 UI/UX 조정, 데이터 처리 로직 개선, 그리고 코드베이스 정리를 통해 애플리케이션의 안정성과 사용성을 높이는 데 중점을 두었습니다.

Highlights

  • 마이페이지 라우팅 개선: /tracklist에서 /mycd로 이동 시 URL 형식을 /mycd/:id 형태로 변경했습니다.
  • 미사용 Mock 데이터 제거: 더 이상 사용되지 않는 likeUser.json, myPlaylist.json, playlistLinks.json mock 파일을 삭제하여 코드베이스를 정리했습니다.
  • 마이페이지 탭 상태 복원: /tracklist에서 뒤로가기 시 마이페이지의 이전에 선택된 탭 상태를 정확히 복원하도록 수정했습니다.
  • 스티커 렌더링 위치 조정: CD 스티커의 Y축 렌더링 위치를 미세 조정하여 시각적 정확도를 높였습니다.
  • UI 요소 스타일 개선: /customize step3 버튼의 폰트와 PC 배경 로고 크기를 조정하여 일관된 UI를 제공합니다.
  • 드래그 스크롤 기능 추가: /customize step2의 테마 버튼 리스트에 마우스 드래그 스크롤 기능을 추가하여 사용자 경험을 향상시켰습니다.
  • 트랙리스트 데이터 노출 문제 해결: 트랙리스트 수정 시 이전 데이터가 잠시 보이는 문제를 isFetching 상태를 활용하여 해결했습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이번 PR은 CD CRUD 관련 알파 테스트 피드백을 반영하고 전반적인 리팩토링을 진행한 것으로 보입니다. 사용하지 않는 mock 파일을 제거하고, 마이페이지의 상태 유지 로직을 개선했으며, CD 편집 시 데이터 로딩 문제를 해결하는 등 여러 개선 사항이 포함되어 있습니다. 특히 드래그 스크롤 커스텀 훅 추가와 같이 사용자 경험을 향상시키기 위한 노력도 돋보입니다. 몇 가지 코드 개선 제안을 포함하여 리뷰를 남겼습니다. 전반적으로 좋은 변경이라고 생각합니다.

@github-actions
Copy link

github-actions bot commented Oct 25, 2025

🎵 Storybook Link 🎵
🔗 https://689dbb45f8d09aea7832eeb1-fnuwnsejqs.chromatic.com/

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/shared/ui/Cd.tsx (1)

98-98: 매직 넘버 대신 상수화 고려

1픽셀 오프셋 조정이 의도적인 것으로 보이지만, -1이라는 매직 넘버가 코드에 직접 하드코딩되어 있습니다. 이 값이 특정한 목적(예: 스티커 렌더링 정렬 보정)을 가지고 있다면 상수로 정의하거나 주석으로 설명하는 것이 좋습니다.

다음과 같이 개선할 수 있습니다:

+// 스티커 Y좌표 렌더링 보정값
+const STICKER_Y_OFFSET = 1
+
 <img
   key={`${cdItemId}-${xCoordinate}-${yCoordinate}`}
   src={src}
   alt="cd-sticker"
   style={{
     position: 'absolute',
     left: xCoordinate * ratio,
-    top: yCoordinate * ratio - 1,
+    top: yCoordinate * ratio - STICKER_Y_OFFSET,
     width: width * ratio,
     height: height * ratio,
     transform: `scale(${scale}) rotate(${angle}rad)`,
     transformOrigin: 'top left',
     pointerEvents: 'none',
   }}
 />
src/shared/lib/useDragScroll.ts (1)

3-36: 드래그 스크롤 훅 구현 검토 및 개선 제안

전반적으로 드래그 스크롤 기능이 잘 구현되었습니다. 다만 몇 가지 개선 사항을 제안합니다.

1. 마우스 커서 스타일 추가

드래그 가능 영역임을 시각적으로 표시하기 위해 커서 스타일을 변경하는 것이 좋습니다:

 const down = (e: MouseEvent) => {
   isDown = true
+  if (el) el.style.cursor = 'grabbing'
   startX = e.pageX - el.offsetLeft
   scrollLeft = el.scrollLeft
 }
-const leave = () => (isDown = false)
-const up = () => (isDown = false)
+const leave = () => {
+  isDown = false
+  if (el) el.style.cursor = 'grab'
+}
+const up = () => {
+  isDown = false
+  if (el) el.style.cursor = 'grab'
+}

그리고 초기 설정:

 useEffect(() => {
   const el = ref.current
   if (!el) return
+  
+  el.style.cursor = 'grab'

   let startX = 0

2. 사용자 선택(user-select) 방지

드래그 중 텍스트가 선택되는 것을 방지하기 위해:

 const down = (e: MouseEvent) => {
+  e.preventDefault()
   isDown = true
   startX = e.pageX - el.offsetLeft
   scrollLeft = el.scrollLeft
 }

3. 접근성 고려사항

현재 마우스 이벤트만 지원하는데, 키보드 네비게이션이나 터치 이벤트 지원을 고려해야 합니다. 특히 모바일에서도 사용될 수 있는 컴포넌트라면 터치 이벤트 추가를 검토하세요:

const touchDown = (e: TouchEvent) => {
  isDown = true
  startX = e.touches[0].pageX - el.offsetLeft
  scrollLeft = el.scrollLeft
}

const touchMove = (e: TouchEvent) => {
  if (!isDown) return
  e.preventDefault()
  el.scrollLeft = scrollLeft - (e.touches[0].pageX - el.offsetLeft - startX)
}

el.addEventListener('touchstart', touchDown)
el.addEventListener('touchmove', touchMove, { passive: false })
el.addEventListener('touchend', up)
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ce46506 and 35cdb77.

📒 Files selected for processing (12)
  • src/App.tsx (0 hunks)
  • src/entities/playlist/model/useMyCd.ts (2 hunks)
  • src/pages/mypage/mock/likeUser.json (0 hunks)
  • src/pages/mypage/mock/myPlaylist.json (0 hunks)
  • src/pages/mypage/mock/playlistLinks.json (0 hunks)
  • src/pages/mypage/ui/customize/index.tsx (1 hunks)
  • src/pages/mypage/ui/customize/step2/index.tsx (4 hunks)
  • src/pages/mypage/ui/customize/step3/index.tsx (1 hunks)
  • src/pages/mypage/ui/main/index.tsx (3 hunks)
  • src/pages/mypage/ui/tracklist/index.tsx (2 hunks)
  • src/shared/lib/useDragScroll.ts (1 hunks)
  • src/shared/ui/Cd.tsx (1 hunks)
💤 Files with no reviewable changes (4)
  • src/pages/mypage/mock/likeUser.json
  • src/App.tsx
  • src/pages/mypage/mock/playlistLinks.json
  • src/pages/mypage/mock/myPlaylist.json
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

**/*.{ts,tsx,js,jsx}: ## 1. 일반적인 코딩 컨벤션

포맷팅

  • .prettierrc 설정에 따라 포맷팅 확인
  • 들여쓰기: 2칸 스페이스
  • 최대 줄 길이: 100자
  • 세미콜론 사용 안함
  • 따옴표: 작은따옴표 사용
  • 괄호 안 공백: 있음
  • 화살표 함수 괄호: 항상 사용
  • 줄바꿈: LF 사용

네이밍 컨벤션

  • 컴포넌트: PascalCase (예: UserProfile)
  • 유틸리티/훅/변수: camelCase (예: getUserData, useUserInfo)
  • 상수: UPPER_SNAKE_CASE (예: API_BASE_URL)
  • 이미지 파일: kebab-case (예: user-profile-icon.png)

주석 사용

  • 복잡한 로직에만 주석 추가
  • 불필요한 주석 지양 (코드로 설명 가능한 것)
  • TODO/FIXME 형식: // TODO: 설명 - 작성자

가독성

  • 매직 넘버 지양, 의미있는 상수 사용
  • 함수는 하나의 책임만 가지도록 작성 (최대 20줄 권장)
  • 중첩 깊이 최소화 (3단계 이하 권장)

2. React 모범 사례

컴포넌트 작성

  • 최신 React hooks 사용 권장
  • 컴포넌트는 단일 책임 원칙 준수
  • Presentational/Container 컴포넌트 분리
  • 성능 최적화: memo, useCallback, useMemo 적절히 사용
  • 대용량 리스트는 가상화 라이브러리 사용 고려

상태 관리

  • Zustand와 Tanstack Query를 일관되게 사용
  • 상태 구조는 정규화된 형태로 관리
  • 에러 처리: Error Boundary와 try-catch 또는 onError 콜백 활용

3. 스타일링

Styled Components

  • Styled Components 일관되게 사용
  • 스타일드 컴포넌트명은 의미있게 작성
  • 동적 스타일링은 props나 CSS 변수 활용
  • 테마 시스템 활용하여 글로벌 스타일 관리
  • 재사용 가능한 스타일은 mixin이나 확장으로 관리
  • CSS 포맷팅 가독성 유지
  • 사용하지 않는 스타일이나 중복 스타일 제거

4. Vite 및 빌드 최적화

  • 모듈 import 최적화 (tree-shaking 고려)
  • 환경변수는 .env 파일로 관리
  • vite.config.ts에서 빌드 성능 튜닝 (sourcemap 설정, 플러그인 최적화 등)

5. 아키텍처 및 개발 환경

폴더 구조

  • Feature-Sliced Design (FSD) 구조 준수
  • 레이어별 참조 규칙 엄격히 적용

타입스크립트

  • strict 모드 사용
  • 타입 명시적으로 작성 (any 사용 지양)
  • path alias (@/_) 절대 경로 import 사용

Git 훅

  • Husky 설정으로 pre-commit, commit-msg 린팅 확인

6. 기타 가이드라인

  • 충분한 근거와 함께 리뷰 제공
  • 정보 검증 후 답변
  • 간결하고 명확한 응답
  • 필요시 추가 컨텍스트 요청
  • 검증되지 않은 주장 지양
  • 가능한 경우 출처 명시
  • 별도 언급 없으면 JavaScript 기준
  • 한국어로 응답
  • 대부분 브라우저에서 지원하는 ES6+ 기능 활용
  • 코드 리뷰를 통한 유지보수성 향상에 적극 활용

Files:

  • src/pages/mypage/ui/tracklist/index.tsx
  • src/pages/mypage/ui/customize/index.tsx
  • src/shared/lib/useDragScroll.ts
  • src/shared/ui/Cd.tsx
  • src/entities/playlist/model/useMyCd.ts
  • src/pages/mypage/ui/customize/step3/index.tsx
  • src/pages/mypage/ui/customize/step2/index.tsx
  • src/pages/mypage/ui/main/index.tsx
🧬 Code graph analysis (4)
src/pages/mypage/ui/customize/index.tsx (1)
src/entities/playlist/model/useMyCd.ts (1)
  • useMyCdActions (27-66)
src/pages/mypage/ui/customize/step3/index.tsx (1)
src/shared/styles/theme.ts (1)
  • theme (3-122)
src/pages/mypage/ui/customize/step2/index.tsx (1)
src/shared/lib/useDragScroll.ts (1)
  • useDragScroll (3-36)
src/pages/mypage/ui/main/index.tsx (1)
src/pages/mypage/types/mypage.ts (1)
  • MYPAGE_TAB_TYPE (3-3)
🔇 Additional comments (6)
src/pages/mypage/ui/tracklist/index.tsx (2)

54-54: LGTM! 네비게이션 로직 개선

쿼리 파라미터 대신 경로 기반 ID를 사용하는 방향으로 변경되었으며, isFromMyCdList 조건에 따라 선택적으로 ?type=LIKE 쿼리를 추가하는 로직이 적절합니다.


115-122: LGTM! 탭 상태 복원 로직 정상 작동

prevSelectedTab 상태를 통해 마이페이지로 돌아갈 때 이전 탭 위치를 복원하는 로직이 올바르게 구현되었습니다. isFromMyCdList 조건에 따라 like 또는 null을 전달하는 로직도 적절합니다.

이 변경사항은 src/pages/mypage/ui/main/index.tsx의 탭 복원 로직과 잘 연동됩니다.

src/pages/mypage/ui/customize/step3/index.tsx (1)

125-125: LGTM! 버튼 타이포그래피 개선

버튼 폰트를 label (13px/18px)에서 body2-normal (14px/20px)로 변경하여 가독성이 향상되었습니다.

src/pages/mypage/ui/customize/index.tsx (1)

51-55: LGTM! 캐시 렌더링 문제 해결

isFetching 상태를 추가하여 React Query의 캐시 데이터가 잠시 노출되는 문제를 해결했습니다. refetchOnMount: 'always' 옵션과 함께 사용할 때 네트워크 응답을 기다리는 동안 로딩 상태를 유지하는 올바른 접근 방식입니다.

PR 설명에 언급된 "트랙리스트 수정 시 이전 데이터가 잠시 노출되던 현상" 해결에 기여합니다.

src/pages/mypage/ui/customize/step2/index.tsx (1)

26-26: LGTM! 드래그 스크롤 기능 추가

테마 리스트에 마우스 드래그로 스크롤할 수 있는 기능이 올바르게 구현되었습니다. useDragScroll 훅을 임포트하고, themeListRef를 생성하여 ThemeListContainer에 연결하는 구조가 적절합니다.

Also applies to: 44-44, 56-56, 941-941

src/entities/playlist/model/useMyCd.ts (1)

34-34: LGTM! 로딩 상태 지표 개선

isFetching 상태를 추가로 노출하여 React Query 캐시 렌더링 문제를 해결할 수 있게 되었습니다. 이 변경사항은 src/pages/mypage/ui/customize/index.tsx에서 사용되어 이전 데이터가 잠시 노출되는 문제를 방지합니다.

Also applies to: 61-61

@hansololiviakim hansololiviakim merged commit ee382a2 into develop Oct 25, 2025
3 of 4 checks passed
@hansololiviakim hansololiviakim deleted the refactor/#120/cd-crud branch November 7, 2025 13:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

HIGH 빠르게 처리해야 하는 높은 우선순위

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[refactor] CD CRUD 알파테스트 및 리팩토링

2 participants