[Refactor] hooks 리팩토링 PR에 대한 추가수정#1063
Conversation
- wrapped({ data: {...} })와 unwrapped({ clubId, message })
응답 형식을 모두 처리하도록 handleResponse 수정
- 하드코딩된 OPTIONS 대신 args.options 사용하여 Storybook Controls에서 옵션 변경 시 UI에 즉시 반영되도록 수정
- detail -> description
- 수동 API 호출 대신 훅 사용으로 중복된 invalidateQueries 로직 제거
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning
|
| Cohort / File(s) | 변경 사항 |
|---|---|
API 응답 처리 frontend/src/apis/utils/apiHelpers.ts |
handleResponse에 제네릭 <T = unknown> 추가 및 반환 타입을 Promise<T | undefined>로 변경. JSON 결과에서 data 프로퍼티가 있으면 result.data를 언래핑하여 반환하도록 로직 추가. |
API 호출 시 타입/반환 조정 frontend/src/apis/application.ts, frontend/src/apis/auth.ts, frontend/src/apis/club.ts, frontend/src/apis/image.ts |
여러 API 함수들에서 handleResponse<...>를 사용하도록 타입 지정 추가. 일부 공개 함수의 반환 타입에 ` |
스토리북 데이터 소스 frontend/src/components/common/CustomDropDown/CustomDropDown.stories.tsx |
스토리의 옵션/선택 레이블을 로컬 상수 대신 args.options에서 가져오도록 변경. |
로그 메시지 수정 frontend/src/hooks/Queries/useClub.ts |
onError 로그 메시지 변경: "Error updating club detail:" → "Error updating club description:". |
뮤테이션 훅 적용 (상태 업데이트 리팩토링) frontend/src/pages/AdminPage/tabs/ApplicationListTab/ApplicationListTab.tsx |
queryClient 직접 호출 및 수동 캐시 무효화 제거. useUpdateApplicationStatus 뮤테이션 훅을 사용하도록 교체하고, 상태 변경 처리 로직을 해당 훅으로 위임(오류 시 alert, 성공 시 메뉴 닫기). |
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
- [refactor] tanstackQuery 최적화 및 활동사진 컴포넌트 리팩토링 #237: useUpdateClubDescription 관련 변경과 로그/핸들러 차이로 강한 연관성 있음.
- [feature] 지원서 제작/수정/불러오기 API 연결하기 #499: application API 타입·응답 처리 변경과 관련된 타입/구조 조정과 연관성 있음.
Suggested labels
🔨 Refactor, 💻 FE, 📬 API
Suggested reviewers
- lepitaaar
- oesnuj
🚥 Pre-merge checks | ✅ 2 | ❌ 3
❌ Failed checks (1 warning, 2 inconclusive)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Out of Scope Changes check | CustomDropDown.stories.tsx의 Storybook 옵션 변경과 useClubDescription의 로그 메시지 수정은 tanstack query 리팩토링 목표와 직접적 관련성이 명확하지 않아 범위 외 변경으로 보임. | CustomDropDown 스토리북 수정과 로그 메시지 변경이 tanstack query 리팩토링과의 관계를 PR 본문에 명시하거나, 이들 변경을 별도의 PR으로 분리하기를 권장. | |
| Title check | ❓ Inconclusive | PR 제목은 '[Refactor] hooks 리팩토링 PR에 대한 추가수정'로 훅 리팩토링 관련 추가 수정을 언급하나, 실제 변경사항의 핵심(handleResponse 제네릭 타입 도입, API 응답 형식 개선)을 명확하게 반영하지 못함. | 제목을 더 구체적으로 수정하여 주요 변경사항을 명확히 반영하도록 권장. 예: '[Refactor] API 응답 처리 및 useUpdateApplicationStatus 훅 추가' |
| Linked Issues check | ❓ Inconclusive | 연결된 이슈(MOA-532)는 tanstack query 리팩토링을 목표로 하나, 구체적인 코딩 요구사항이 체크리스트 형태로만 존재하고 상세 내용이 제공되지 않아 변경사항과의 정확한 요구사항 매칭이 불가능함. | 연결된 이슈의 체크리스트 항목들을 구체화하고, 변경사항(handleResponse 제네릭, useUpdateApplicationStatus, Storybook 수정)이 각 작업 항목과 어떻게 대응되는지 명시하기를 권장. |
✅ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing touches
- 📝 Generate docstrings
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 @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/src/components/common/CustomDropDown/CustomDropDown.stories.tsx (1)
81-103: options가 비어있을 때 스토리가 깨질 수 있음Line 82, 100에서 args.options가 undefined/null이면 find/map에서 런타임 에러가 납니다. 기본값을 보장해 주세요.
🛠️ 수정 제안
const [isOpen, setIsOpen] = useState(args.open); const [selected, setSelected] = useState(args.selected); + const options = args.options ?? []; const handleSelect = (value: string) => { setSelected(value); args.onSelect(value); }; const onToggleWrapper = (currentOpenState: boolean) => { setIsOpen(!currentOpenState); args.onToggle(!currentOpenState); }; - const selectedLabel = - args.options.find((opt) => opt.value === selected)?.label || '선택하세요'; + const selectedLabel = + options.find((opt) => opt.value === selected)?.label || '선택하세요'; return ( <CustomDropDown {...args} - options={args.options as readonly { label: string; value: string }[]} + options={options as readonly { label: string; value: string }[]} open={isOpen} onToggle={onToggleWrapper} selected={selected as string} onSelect={handleSelect} > @@ - <CustomDropDown.Menu width='150px'> - {args.options.map((option) => ( + <CustomDropDown.Menu width='150px'> + {options.map((option) => ( <CustomDropDown.Item key={option.value} value={option.value}> {option.label} </CustomDropDown.Item> ))} </CustomDropDown.Menu> </CustomDropDown>
frontend/src/pages/AdminPage/tabs/ApplicationListTab/ApplicationListTab.tsx
Show resolved
Hide resolved
- handleResponse 제네릭 타입 도입 - null/undefined 데이터 검증 강화 - API 함수 반환 타입 명시
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
frontend/src/apis/auth.ts (1)
17-31:login함수의 반환 타입에 대한 명확한 처리 필요.
login함수가Promise<LoginResponseData | undefined>로 변경되었으나, 현재 호출부에서undefined케이스를 처리하지 않고 있습니다.frontend/src/pages/AdminPage/auth/LoginTab/LoginTab.tsx:35의 코드(const { accessToken } = await login(userId, password))는login이undefined를 반환할 때 런타임 에러가 발생합니다. 호출부에서 반환값이undefined인지 먼저 검사한 후accessToken을 구조 분해해야 합니다.frontend/src/apis/image.ts (1)
36-50: API 함수들이undefined를 반환할 수 있지만 호출 지점에서 처리하지 않음 - 런타임 에러 위험
coverApi.getUploadUrl(),feedApi.getUploadUrls(),logoApi.getUploadUrl()모두undefined를 반환할 수 있는 타입으로 선언되어 있으나, 호출하는 모든 지점에서undefined체크 없이 즉시 구조분해 할당 또는 배열 접근을 시도합니다:
useClubCover.ts:15-const { presignedUrl, finalUrl } = await coverApi.getUploadUrl(...)useClubImages.ts:31-const feedResArr = await feedApi.getUploadUrls(...)를 직후feedResArr[i].presignedUrl로 접근useClubImages.ts:103-const { presignedUrl, finalUrl } = await logoApi.getUploadUrl(...)API가
undefined를 반환할 경우 런타임 에러가 발생합니다. 호출 지점에undefined처리 로직을 추가하거나, API 함수의 타입 선언을undefined제외로 수정해야 합니다.
🧹 Nitpick comments (1)
frontend/src/apis/club.ts (1)
37-49: 타입 안전성이 향상되었습니다.
handleResponse에 제네릭 타입을 명시하고undefined체크 후 기본값을 제공하는 방식이 적절합니다.
||대신??(nullish coalescing)를 사용하면 의도가 더 명확해질 수 있습니다.totalCount가0인 경우에도||는 올바르게 동작하지만,??가 더 정확한 의미를 전달합니다.♻️ Nullish coalescing 사용 제안
return { - clubs: data.clubs || [], - totalCount: data.totalCount || 0, + clubs: data.clubs ?? [], + totalCount: data.totalCount ?? 0, };
#️⃣연관된 이슈
📝작업 내용
1. API 응답 형식 처리 개선
문제: 백엔드에서 일관되지 않은 응답 형식 반환
해결: handleResponse 함수에서 두 형식 모두 처리하도록 개선
2. useUpdateApplicationStatus 훅 사용
3. CustomDropDown Storybook options
하드코딩된 OPTIONS 대신
args.options사용하여 Storybook Controls에서 옵션 변경 시 UI에 즉시 반영되도록 수정중점적으로 리뷰받고 싶은 부분(선택)
논의하고 싶은 부분(선택)
🫡 참고사항
Summary by CodeRabbit
Summary by CodeRabbit
릴리스 노트
버그 수정
개선
✏️ Tip: You can customize this high-level summary in your review settings.