refactor: 기사님 상세 구조 개선 및 사용자 역할별 액션 분리 - #53
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough이 PR은 이사 상세 페이지의 리뷰 UI를 분리하고, 지정 흐름을 Changes이사 상세 페이지 변경
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Customer
participant MoverDetailView
participant useMoverDesignation
participant DesignationMutation
Customer->>MoverDetailView: 지정 CTA 클릭
MoverDetailView->>useMoverDesignation: 요청 핸들러 실행
useMoverDesignation->>DesignationMutation: 지정 mutation 호출
DesignationMutation-->>useMoverDesignation: 성공 결과 반환
useMoverDesignation-->>MoverDetailView: 성공 모달 상태 반환
MoverDetailView-->>Customer: 성공 모달 표시
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/components/mover/detail/MoverDetailView.tsx (1)
87-92: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win고정 레이아웃 값을 디자인 토큰으로 대체하세요.
pb-[110px],lg:pb-[150px],lg:w-[766px]는 컴포넌트에 직접 지정된 값입니다. 기존 spacing 또는 layout 토큰을 사용하세요. 적절한 토큰이 없으면 의미 있는 토큰을 정의한 뒤 사용하세요.As per path instructions,
색상·간격·radius는 src/styles/tokens.theme.css의 디자인 토큰을 사용해야 합니다.🤖 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/components/mover/detail/MoverDetailView.tsx` around lines 87 - 92, MoverDetailView의 레이아웃에서 직접 지정한 pb-[110px], lg:pb-[150px], lg:w-[766px] 값을 제거하고 src/styles/tokens.theme.css의 기존 spacing/layout 디자인 토큰으로 교체하세요. 적절한 토큰이 없으면 의미가 드러나는 토큰을 tokens.theme.css에 정의한 뒤 해당 토큰을 사용하고, DetailHeroBanner 및 주변 flex 레이아웃 동작은 유지하세요.Sources: Coding guidelines, Path instructions
src/components/mover/detail/MoverDetailProfile.tsx (1)
121-141: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
FavoriteSummary의 props 타입에 이름을 붙여 주세요.
{ detail: MoverDetail }인라인 타입 대신FavoriteSummaryProps같은 명명된interface를 정의해 주세요. 다른 컴포넌트(MoverDetailProfileProps)와 동일한 규칙을 따르게 됩니다.♻️ 제안하는 리팩터
-function FavoriteSummary({ detail }: { detail: MoverDetail }) { +interface FavoriteSummaryProps { + detail: MoverDetail; +} + +function FavoriteSummary({ detail }: FavoriteSummaryProps) {As per path instructions, "Props 는
interface XxxProps형태로 명확히 정의합니다."🤖 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/components/mover/detail/MoverDetailProfile.tsx` around lines 121 - 141, FavoriteSummary의 인라인 props 타입을 제거하고, detail: MoverDetail을 포함하는 명명된 FavoriteSummaryProps interface를 정의한 뒤 컴포넌트 props 타입으로 사용하세요. 기존 렌더링 동작과 MoverDetailProfileProps의 명명 규칙은 유지하세요.Source: Path instructions
🤖 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/components/mover/detail/MoverDetailProfile.tsx`:
- Around line 60-67: showFavoriteAction이 false인 분기에서 찜 요약을 감싸는 div에
role="group"을 추가하세요. 기존 aria-label인 `현재 찜 ${detail.favoriteCount}개`는 유지해 보조공학이
비활성 찜 요약을 이름 있는 그룹으로 인식하도록 하고, FavoriteSummary 렌더링은 변경하지 마세요.
---
Nitpick comments:
In `@src/components/mover/detail/MoverDetailProfile.tsx`:
- Around line 121-141: FavoriteSummary의 인라인 props 타입을 제거하고, detail: MoverDetail을
포함하는 명명된 FavoriteSummaryProps interface를 정의한 뒤 컴포넌트 props 타입으로 사용하세요. 기존 렌더링 동작과
MoverDetailProfileProps의 명명 규칙은 유지하세요.
In `@src/components/mover/detail/MoverDetailView.tsx`:
- Around line 87-92: MoverDetailView의 레이아웃에서 직접 지정한 pb-[110px], lg:pb-[150px],
lg:w-[766px] 값을 제거하고 src/styles/tokens.theme.css의 기존 spacing/layout 디자인 토큰으로
교체하세요. 적절한 토큰이 없으면 의미가 드러나는 토큰을 tokens.theme.css에 정의한 뒤 해당 토큰을 사용하고,
DetailHeroBanner 및 주변 flex 레이아웃 동작은 유지하세요.
🪄 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: 23da9d20-8619-457e-8537-6af2d1bffe64
📒 Files selected for processing (10)
src/components/common/DetailHeroBanner.tsxsrc/components/estimate/detail/EstimateDetailLayout.tsxsrc/components/mover/detail/MoverDetailProfile.tsxsrc/components/mover/detail/MoverDetailReviews.tsxsrc/components/mover/detail/MoverDetailShare.tsxsrc/components/mover/detail/MoverDetailView.tsxsrc/components/mover/detail/MoverRatingSummary.tsxsrc/components/mover/detail/MoverReviewList.tsxsrc/hooks/useMoverDesignation.tssrc/hooks/useMoverDetail.ts
juengseulki
left a comment
There was a problem hiding this comment.
📋 PR 리뷰
👍 좋았던 점
- 기사님 상세 조회의 인증 복구, 사용자별 Query Scope 확인, 초기 로딩과 404 판별을
useMoverDetail로 이동해 화면 컴포넌트의 상태 의존성을 줄였습니다. - 사용자 Scope가 확정되기 전에는 상세 Query를 실행하지 않도록 기존 optional API 캐시 정책을 유지했습니다.
- 활성 견적 요청 조회, CTA 계산, 실패 후 재조회, 지정 요청 Mutation과 모달 상태를
useMoverDesignation으로 분리해 지정 견적 요청의 흐름을 한곳에서 관리하도록 정리했습니다. - 활성 견적 요청 API를 인증된 CUSTOMER에게만 호출하도록 제한해 비회원·MOVER·역할 미확정 사용자의 불필요한 고객 전용 API 호출을 방지했습니다.
비회원에게는 기존 로그인 안내 흐름을 유지하고, MOVER에게는 고객 전용 액션을 숨기면서 공유와 공개 정보 조회는 유지했습니다. - MOVER에게 찜 개수는 읽기 전용으로 제공하고 접근성 레이블까지 추가해 인터랙션 여부를 명확하게 구분했습니다.
- 평균 별점과 분포를
MoverRatingSummary, 리뷰 목록을MoverReviewList로 분리해MoverDetailReviews가 조회 상태와 페이지네이션 조합에 집중하도록 개선했습니다. - 카카오 공유 데이터 가공을
MoverDetailShare내부로 이동해MoverDetailView가 화면 데이터를 전달하는 역할만 담당하도록 정리했습니다. - 견적 상세와 기사님 상세에서 함께 사용하는 히어로 배너를
DetailHeroBanner로 공통화해 실제 사용 범위와 이름을 일치시켰습니다. - 큰
MoverDetailView에서 인증 Store, API 오류 타입, 활성 요청 Query, CTA 계산과 모달 상태가 제거되어 상세 화면의 조합 구조가 훨씬 읽기 쉬워졌습니다.
🔍 확인 및 제안
한 가지 가벼운 제안으로는 DetailHeroBanner.tsx의 주석이 아직 “견적 상세 히어로 배너”로 남아 있어, 공통화된 현재 역할에 맞게 “상세 페이지 공통 히어로 배너” 정도로 함께 수정하면 이름과 설명이 더 일관될 것 같습니다. 기능상 문제는 아닙니다.
전체적으로 기존 동작을 유지하면서 기사님 상세의 조회, 역할, 지정 견적, 리뷰, 공유 책임을 깔끔하게 분리한 리팩토링이었습니다. 수고하셨습니다! 😊
To Reviewer 질문에 대한 답변드립니다!
현재 MOVER의 기사님 찾기와 기사님 상세 접근 정책이 확정되지 않은 상황에서는,
공개 페이지 접근은 허용하되 CUSTOMER 전용 데이터 변경 액션만 차단하는 현재 방식이
가장 안전한 기본값으로 보입니다.
기사님 목록과 상세에는 공개 프로필, 서비스 정보, 리뷰 등 MOVER가 확인해도 문제가 없는
정보가 포함되어 있고 공유 기능도 공개 기능에 해당하므로, 정책 확정 전부터 페이지 전체를
차단할 필요는 크지 않아 보입니다. 추후 서비스 정책상 MOVER의 기사 검색 자체를 막기로
결정된다면 그때 Route Guard를 추가하고, Hook의 CUSTOMER 검증은 최종 방어선으로
그대로 유지하는 방향이 좋을 것 같습니다.
역할별 액션도 코드상 다음과 같이 구분되어 있는 것을 확인했습니다.
- 비회원: 기사 상세 조회 및 공유 가능, 찜·지정 요청 클릭 시 로그인 안내
- CUSTOMER: 찜 등록·해제, 지정 견적 요청, 활성 견적 요청 조회 가능
- MOVER: 기사 상세 조회 및 공유 가능, 찜 개수만 읽기 전용으로 표시하며 고객 전용 액션은 숨김
- 역할 미확정 사용자: 고객 전용 API와 액션 모두 차단
useActiveEstimateRequest()도 isCustomerLoggedIn인 경우에만 활성화되어 있어
MOVER나 역할 미확정 사용자에게 고객 전용 API가 호출되지 않는 흐름이 적절해 보였습니다.
상세 조회의 상태 처리도 기존 흐름을 유지하고 있습니다.
인증 hydrate와 세션 확인, 사용자별 Scope 확정 및 Query 초기 로딩을
isInitialLoading으로 묶어 기존처럼 스켈레톤을 표시하고,
MOVER_NOT_FOUND 또는 404는 별도 Not Found 상태로,
그 외 오류는 재시도 가능한 Error Panel로 분기하고 있었습니다.
리뷰 UI는 평균 별점·별점 분포를 MoverRatingSummary,
리뷰 항목을 MoverReviewList로 옮겼지만 조회 데이터와
페이지네이션 조건은 MoverDetailReviews에 그대로 유지되어 있어
기존 별점 분포, 리뷰 목록, 페이지 전환 동작에도 영향이 없어 보였습니다.
공통 히어로 배너의 위치와 이름도 현재 구조가 적절해 보입니다.
견적 상세와 기사님 상세에서 함께 사용하며 showProfile을 통해
프로필 포함·배너 전용 모드를 모두 지원하므로,
components/common/DetailHeroBanner가 기존 EstimateDetailHero보다
실제 책임을 더 정확하게 표현한다고 생각합니다.
다만 컴포넌트 내부 주석에 남아 있는 “견적 상세 히어로 배너” 표현도
공통 역할에 맞게 함께 수정하면 이름과 문서가 더 일관될 것 같습니다.
- DetailHeroBanner로 이름을 변경하고, common 폴더로 이동
2027647 to
d79f9fc
Compare
📋 작업 내용
기사님 상세 페이지에 집중되어 있던 조회 상태, 지정 견적 요청, 역할별 액션, 리뷰 및 공유 로직을 각각의 hook과 컴포넌트로 분리했습니다.
견적 상세와 기사님 상세에서 함께 사용하는 히어로 배너도 공통 컴포넌트로 이동했습니다.
🔥 변경 사항
상세 조회 상태 캡슐화
useMoverDetail내부로 이동했습니다.MoverDetailView에서 Zustand 인증 상태와 API 오류 타입에 대한 직접적인 의존성을 제거했습니다.지정 견적 요청 로직 분리
useMoverDesignation으로 분리했습니다.MoverDetailView가 상세 화면 조합과 상태별 UI 렌더링에 집중하도록 정리했습니다.사용자 역할별 상세 액션 분리
리뷰 UI 컴포넌트 분리
MoverRatingSummary로 분리했습니다.MoverReviewList로 분리했습니다.MoverDetailReviews에는 리뷰 조회, 로딩·오류·빈 상태 및 페이지네이션 조합만 남겼습니다.공유 책임 정리
MoverDetailShare내부로 이동했습니다.MoverDetailView는 기사 이름, 찜 수, 프로필 이미지 등 화면 데이터만 전달하도록 변경했습니다.상세 히어로 배너 공통화
EstimateDetailHero를 공통 상세 히어로 배너 컴포넌트로 변경하고 공통 컴포넌트 영역으로 이동했습니다.접근성 개선 (리뷰 반영)
role="group"을 추가해aria-label의 현재 찜 개수가 스크린리더에 전달되도록 수정 (components/mover/detail/MoverDetailProfile.tsx)✅ 체크리스트
📷 스크린샷 (선택)
UI 디자인 변경 사항이 없어 생략했습니다.
💬 To Reviewer
Summary by CodeRabbit
새로운 기능
개선 사항