Skip to content

Comments

[Refactor] hooks 리팩토링 PR에 대한 추가수정#1063

Merged
seongwon030 merged 5 commits intodevelop-fefrom
refactor/#1057-tantack-refactoring-MOA-532
Jan 18, 2026
Merged

[Refactor] hooks 리팩토링 PR에 대한 추가수정#1063
seongwon030 merged 5 commits intodevelop-fefrom
refactor/#1057-tantack-refactoring-MOA-532

Conversation

@seongwon030
Copy link
Member

@seongwon030 seongwon030 commented Jan 18, 2026

#️⃣연관된 이슈

ex) #이슈번호, #이슈번호

📝작업 내용

1. API 응답 형식 처리 개선

문제: 백엔드에서 일관되지 않은 응답 형식 반환

  • Wrapped 형식: { data: {...} }
  • Unwrapped 형식: { clubId, message }

해결: handleResponse 함수에서 두 형식 모두 처리하도록 개선

2. useUpdateApplicationStatus 훅 사용

  • 수동 API 호출 대신 훅 사용으로 중복된 invalidateQueries 로직 제거

3. CustomDropDown Storybook options

하드코딩된 OPTIONS 대신 args.options 사용하여 Storybook Controls에서 옵션 변경 시 UI에 즉시 반영되도록 수정

중점적으로 리뷰받고 싶은 부분(선택)

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

ex) 메서드 XXX의 이름을 더 잘 짓고 싶은데 혹시 좋은 명칭이 있을까요?

논의하고 싶은 부분(선택)

논의하고 싶은 부분이 있다면 작성해주세요.

🫡 참고사항

Summary by CodeRabbit

Summary by CodeRabbit

릴리스 노트

  • 버그 수정

    • API 응답 처리의 안정성과 예외 처리 범위를 개선했습니다.
    • 애플리케이션 상태 업데이트 흐름에서 문제를 해결하고 오류 처리 알림을 정비했습니다.
  • 개선

    • 일부 API 호출이 빈 결과를 안전하게 반환하도록 유연성을 높였습니다.
    • 스토리북 구성에서 옵션 데이터가 외부 인수로 동적으로 반영되도록 변경했습니다.
    • 표시용 에러 메시지를 소폭 수정했습니다.

✏️ Tip: You can customize this high-level summary in your review settings.

- wrapped({ data: {...} })와 unwrapped({ clubId, message })
응답 형식을 모두 처리하도록 handleResponse 수정
- 하드코딩된 OPTIONS 대신 args.options 사용하여
Storybook Controls에서 옵션 변경 시 UI에 즉시 반영되도록 수정
- detail -> description
- 수동 API 호출 대신 훅 사용으로 중복된 invalidateQueries 로직 제거
@vercel
Copy link

vercel bot commented Jan 18, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
moadong Ready Ready Preview, Comment Jan 18, 2026 0:07am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 18, 2026

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: Invalid regex pattern for base branch. Received: "**" at "reviews.auto_review.base_branches[0]"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

응답 처리 제네릭화 및 안전한 데이터 언래핑 추가, 여러 API 함수들의 반환타입을 undefined 허용으로 조정, Storybook 옵션 소스 변경, 로깅 문구 수정, Application 상태 업데이트를 mutation 훅으로 전환하는 리팩토링입니다.

Changes

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

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 ⚠️ Warning 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.

❤️ Share

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

@seongwon030 seongwon030 changed the title [Refactor] [Refactor] hooks 리팩토링 PR에 대한 추가수정 Jan 18, 2026
@seongwon030 seongwon030 requested a review from suhyun113 January 18, 2026 10:38
Copy link
Contributor

@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: 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>

Copy link
Collaborator

@suhyun113 suhyun113 left a comment

Choose a reason for hiding this comment

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

수고하셨습니다ㅏ!!

- handleResponse 제네릭 타입 도입
- null/undefined 데이터 검증 강화
- API 함수 반환 타입 명시
Copy link
Contributor

@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: 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))는 loginundefined를 반환할 때 런타임 에러가 발생합니다. 호출부에서 반환값이 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)를 사용하면 의도가 더 명확해질 수 있습니다. totalCount0인 경우에도 ||는 올바르게 동작하지만, ??가 더 정확한 의미를 전달합니다.

♻️ Nullish coalescing 사용 제안
     return {
-      clubs: data.clubs || [],
-      totalCount: data.totalCount || 0,
+      clubs: data.clubs ?? [],
+      totalCount: data.totalCount ?? 0,
     };

@seongwon030 seongwon030 merged commit 4b1ba6c into develop-fe Jan 18, 2026
3 checks passed
@seongwon030 seongwon030 deleted the refactor/#1057-tantack-refactoring-MOA-532 branch January 18, 2026 12:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants