Skip to content

Conversation

@Chiman2937
Copy link
Member

@Chiman2937 Chiman2937 commented Dec 13, 2025

📝 변경 사항

💡 프로필/마이 페이지 업데이트 API 연결

  • 팔로우 목록 조회를 제외한 모든 user 엔드포인트 api 연결 및 테스트 완료

💡 타입 네이밍 수정

1. Query Parameter:

  • 타입 변수명: *QueryParams
  • ex) UnfollowQueryParams

2. Path Parameter:

  • 타입 변수명: *PathParams
  • ex) GetUserPathParams

3. Body:

  • 타입 변수명: *Payloads
  • ex) UpdateMyImagePayloads

💡 Query Parameter 적용 방식 수정

  • 기존에 API 요청에서 직접 path에 작성하던 방식에서 axios의 params 속성을 지정하는 방식으로 수정

Before

  unfollowUser: async (params: UnfollowParmams) => {
    return api.delete<void>(`/users/unfollow?unFollowNickname=${params.unFollowNickname}`);
  },

After

  unfollowUser: async (params: UnfollowQueryParams) => {
    return api.delete<string>(`/users/unfollow`, {
      params: { unFollowNickname: params.unFollowNickname },
    });
  },

💡 ImageWithFallback 컴포넌트

  • next image 컴포넌트의 src에 유효하지 않은 값이 전달될 때 fallback 이미지를 대신 보여줌
  • 현재 unsplash 이미지로 설정되어있으며 추후 수정 예정

💡 next.config.ts

  • wego s3 버킷 경로 추가

💡 useUser 훅 수정

  • useGetUser: get 요청 후 null값이 들어있는 field에 대해 '' 로 교체하도록 수정

🔗 관련 이슈

Closes #48


🧪 테스트 방법

  • 수동 테스트 검증(로컬 환경)
  • 유닛 테스트 검증
  • 통합 테스트 검증

📸 스크린샷 (선택)

Animation
Animation


📋 체크리스트

  • 관련 문서를 업데이트했습니다 (필요한 경우)
  • 테스트를 추가/수정했습니다 (필요한 경우)
  • Breaking change가 있다면 명시했습니다

💬 추가 코멘트


CodeRabbit Review는 자동으로 실행되지 않습니다.

Review를 실행하려면 comment에 아래와 같이 작성해주세요

@coderabbitai review

Summary by CodeRabbit

  • New Features

    • 이메일·닉네임 중복 확인 기능 추가
    • 프로필 이미지 대체(fallback) 표시 기능 추가
    • 외부(AWS S3) 이미지 호스팅 지원 추가
  • Improvements

    • 프로필 이미지 업로드 및 편집 워크플로 개선(이미지와 정보 분리 업데이트)
    • 알림 설정이 서버와 동기화되도록 개선
    • 프로필 편집 UI의 상태 및 제출 동작 개선

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 13, 2025

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

프로필 관련 API와 훅을 실 API 형태로 재구성하고, 이미지 폴백 컴포넌트 추가 및 프로필 수정의 두 단계 업데이트(프로필 정보 · 이미지)를 도입했으며 알림 토글을 서버 뮤테이션으로 전환했습니다.

Changes

Cohort / File(s) Summary
구성
next.config.ts
AWS S3 호스트 we-go-bucket.s3.ap-northeast-2.amazonaws.com에 대한 remotePatterns 항목 추가.
API 서비스 & 타입
src/api/service/user-service/index.ts, src/types/service/user.ts
사용자 API 엔드포인트 재구성(팔로우/언팔로우, 닉네임/이메일 가용성, 프로필 업데이트/이미지 업로드, 알림 업데이트 쿼리파라미터 등) 및 타입명/필드(rename/add) 변경 (isFollowingisFollow, 여러 Payload/Params 이름 변경·추가).
커스텀 훅들
src/hooks/use-user/*, src/hooks/use-user/index.ts
useUpdateUser, useUserImageUpdate(이전 useDeleteUser), useUpdateMyNotification 등 훅 추가/시그니처 변경 및 useGetUser의 select 변환기 추가; 일부 훅의 리-익스포트 제거.
이미지 유틸 컴포넌트
src/components/ui/image-with-fallback/index.tsx, src/components/ui/index.ts
이미지 에러 시 폴백을 제공하는 ImageWithFallback 컴포넌트 추가 및 UI 배럴에 익스포트 추가.
프로필 편집 컴포넌트
src/components/pages/user/profile/profile-edit-fields/*, src/components/pages/user/profile/profile-edit-modal/index.tsx
필드 모듈들 재내보내기(index.ts), ImageField를 named export로 변경, 모달에서 프로필 정보 업데이트와 이미지 업로드를 분리한 두 단계(mutates) 흐름으로 변경.
프로필 표시 컴포넌트
src/components/pages/user/profile/profile-card/index.tsx
next/image 사용을 ImageWithFallback으로 교체.
마이페이지 관련
src/app/(user)/mypage/page.tsx, src/components/pages/user/mypage/mypage-setting/index.tsx
불필요한 주석 제거(페이지), 로컬 상태 대신 useUpdateMyNotification 뮤테이션으로 알림 토글 처리 변경.
모킹 데이터
src/mock/service/user/user-mock.ts
목 데이터의 사용자 관계 필드명 isFollowingisFollow로 변경.

Sequence Diagram(s)

sequenceDiagram
    actor 사용자
    participant ProfileModal as 프로필 편집 모달
    participant Hook_Update as useUpdateUser
    participant Hook_Image as useUserImageUpdate
    participant API as UserService API
    participant Query as QueryClient

    사용자->>ProfileModal: 폼 제출(프로필 데이터 + 이미지)
    
    rect rgb(200,220,255)
    Note over ProfileModal,Hook_Update: 단계 1 - 프로필 정보 업데이트
    ProfileModal->>Hook_Update: mutate(nextProfileInfo)
    Hook_Update->>API: PATCH /users/profile (payload)
    API-->>Hook_Update: 업데이트된 User 반환
    Hook_Update->>Query: invalidate user queries
    end

    rect rgb(200,255,220)
    Note over ProfileModal,Hook_Image: 단계 2 - 이미지 업로드 (파일 존재 시)
    alt 이미지 파일 있음
        ProfileModal->>Hook_Image: mutate({ file })
        Hook_Image->>API: PATCH /users/profile-image (FormData)
        API-->>Hook_Image: 업데이트된 User 반환
        Hook_Image->>Query: invalidate user queries
    end
    end

    ProfileModal->>사용자: 모달 닫힘 / UI 갱신
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • API 엔드포인트와 타입 네이밍 변경(확인 필요)
  • 프로필 모달의 두 단계 뮤테이션 흐름(동시성·오류 처리 점검)
  • 훅 시그니처 변경에 따른 모든 호출부 일관성 검토
  • ImageWithFallback의 에러·fallback 경로 및 로딩 동작 확인

Suggested reviewers

  • wooktori

Poem

🐰✨ 새 프로필, 깡충깡충 바뀌었네,
이미지 넘어져도 폴백이 살려내네,
정보 먼저, 사진 다음—두 단계로 춤추며,
서버와 속삭여 진짜로 바뀌었지요,
깡총, 축하의 당근 한 조각! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed PR이 연결된 이슈 #48의 '실제 API 요청 환경으로 전환'이라는 목표를 충족하며, 마이페이지 API 3종(프로필 정보, 이미지, 알림 설정)의 연결을 완료하고 있습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 마이페이지 API 연동 및 관련 UI/컴포넌트 개선에 범위 내에 있으며, 불필요한 외부 변경은 없습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed PR 설명이 대부분 완성되었으며 구조적 요구사항을 충족합니다. 필수 섹션(변경 사항, 관련 이슈, 테스트 방법)이 모두 작성되어 있습니다.
Title check ✅ Passed PR 제목은 사용자 엔드포인트 API 연결이라는 주요 변경 사항을 명확하게 요약하고 있으며, 코드 변경 내용과 직접적으로 관련이 있습니다.

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.

@github-actions
Copy link

github-actions bot commented Dec 13, 2025

🎭 Playwright Report

E2E Test가 성공적으로 완료되었습니다.

Test 요약 내용을 확인해주세요.

Status Build Log Updated (UTC)
✅ Ready View Build 2025-12-14 14:42:59

📊 Test Summary

  • ✅ Passed: 9
  • ❌ Failed: 0
  • ⏱️ Duration: 45.2s

📜 Test Details

✅ Passed Tests (9)
  • profile.test.ts (9)
    • [chromium] 비로그인 상태에서 /mypage 접속 시 /login으로 redirect 되는 지 테스트
    • [chromium] 나의 프로필 페이지로 접속 시 /mypage로 /redirect 되는 지 테스트
    • [chromium] 존재하지 않는 프로필 페이지로 접속 시 404 redirect 되는 지 테스트
    • [firefox] 비로그인 상태에서 /mypage 접속 시 /login으로 redirect 되는 지 테스트
    • [firefox] 나의 프로필 페이지로 접속 시 /mypage로 /redirect 되는 지 테스트
    • [firefox] 존재하지 않는 프로필 페이지로 접속 시 404 redirect 되는 지 테스트
    • [webkit] 비로그인 상태에서 /mypage 접속 시 /login으로 redirect 되는 지 테스트
    • [webkit] 나의 프로필 페이지로 접속 시 /mypage로 /redirect 되는 지 테스트
    • [webkit] 존재하지 않는 프로필 페이지로 접속 시 404 redirect 되는 지 테스트

@github-actions
Copy link

github-actions bot commented Dec 13, 2025

🎨 Storybook Report

변경 사항이 없습니다

모든 Story가 이전 빌드와 동일합니다.

Status Storybook Build Log Updated (UTC)
✅ Unchanged View Storybook View Build 2025-12-14 14:43:09

@github-actions
Copy link

github-actions bot commented Dec 13, 2025

📊 Coverage Report

Status Build Log Updated (UTC)
✅ Ready View Build 2025-12-14 14:41:33

📈 #175main에 병합하면 coverage가 0.26% 증가합니다.

Coverage 요약

@@             Coverage Diff             @@
##             main     #175       +/-   ##
===========================================
+ Coverage   35.21%   35.47%    +0.26%     
===========================================
  Files         146      149        +3     
  Lines        5974     6134      +160     
  Branches      234      244       +10     
===========================================
+ Hits         2104     2176       +72     
+ Misses       3870     3958       +88     

영향받은 파일

파일 Coverage 변화
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/api/service/user-service/index.ts 61.19% (-17.07%) ⬇️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/pages/user/profile/profile-edit-fields/index.ts 100.00% (+100.00%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/pages/user/profile/profile-edit-fields/image-field/index.tsx 21.81% (-6.76%) ⬇️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/pages/user/profile/profile-edit-modal/index.tsx 19.13% (-14.20%) ⬇️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/pages/user/profile/profile-info/index.tsx 90.00% (-10.00%) ⬇️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/ui/image-with-fallback/index.tsx 91.66% (+91.66%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/hooks/use-user/use-user-follow/index.ts 71.42% (+38.09%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/hooks/use-user/use-user-image-update/index.ts 41.17% (+41.17%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/hooks/use-user/use-user-unfollow/index.ts 75.00% (+40.00%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/hooks/use-user/use-user-update/index.ts 41.17% (+6.17%) ⬆️

@github-actions
Copy link

github-actions bot commented Dec 13, 2025

🚀 PR Preview Report

Build가 성공적으로 완료되었습니다.

Preview에서 변경사항을 확인하세요.

Status Preview Build Log Updated (UTC)
✅ Ready Visit Preview View Logs 2025-12-14 14:42:44

@Chiman2937
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 13, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/hooks/use-user/use-user-get/index.ts (1)

7-18: The ?? '' defaults in the select transformer are unnecessary; the API returns non-null strings.

The User type and all mock data confirm that profileImage, profileMessage, and mbti are always strings from the API. No consumers check for null to distinguish "unset" vs "empty" state; components render these fields directly. The hook can be simplified by removing the select transformer or documenting why it's defensive.

🧹 Nitpick comments (5)
src/components/pages/user/profile/profile-card/index.tsx (1)

13-19: Consider adding sizes (and confirm eager-loading semantics in the wrapper).

With fill, providing sizes avoids suboptimal image selection; here the container is size-24 (~96px).

 <ImageWithFallback
   className='object-cover'
   alt='프로필 이미지'
   fill
-  loading='eager'
+  sizes='96px'
+  loading='eager'
   src={profileImage}
 />

Also verify whether ImageWithFallback maps to next/image and whether you’d rather use priority for above-the-fold avatars.

src/components/pages/user/mypage/mypage-setting/index.tsx (1)

11-21: Guard against rapid re-clicks (pending state) when toggling notifications.

Consider disabling the button while the mutation is pending (or use optimistic update + rollback). Example:

 export const MyPageSetting = ({ user }: Props) => {
-  const { mutate } = useUpdateMyNotification();
+  const { mutate, isPending } = useUpdateMyNotification();

   return (
     <section className='bg-mono-white flex flex-col gap-3 px-3 py-6'>
       <MyPageToggleButton
         value={user.isNotificationEnabled}
+        disabled={isPending}
         onClick={() => mutate({ isNotificationEnabled: !user.isNotificationEnabled })}
       >
src/hooks/use-user/use-user-update/index.ts (1)

7-15: Good hook signature change; don’t leave onError empty.

At minimum, capture the error for UI/telemetry (even if you don’t toast here).

   const query = useMutation({
     mutationFn: (payload: UpdateMePayload) => API.userService.updateMe(payload),
     onSuccess: (data, _variables, _context) => {
       queryClient.invalidateQueries({ queryKey: userKeys.item(data.userId) });
     },
-    onError: () => {},
+    onError: (error) => {
+      // TODO: route to centralized logger/toast
+      console.error(error);
+    },
   });
src/components/ui/image-with-fallback/index.tsx (1)

24-26: Consider removing unoptimized and document the 'null' string check.

  1. The unoptimized prop disables Next.js image optimization benefits. If this is intentional (e.g., for S3 images already optimized), add a comment explaining why.

  2. The src === 'null' check suggests the API may return a literal "null" string. This is a valid defensive measure, but consider fixing this at the API response transformation layer (e.g., in useGetUser) for cleaner component logic.

-  const imgSrc = error || !src || src === 'null' ? fallbackSrc : src;
+  // Handle cases where API returns "null" as a string instead of null/undefined
+  const imgSrc = error || !src || src === 'null' ? fallbackSrc : src;

-  return <Image {...rest} src={imgSrc} unoptimized onError={() => setError(true)} />;
+  // unoptimized: S3 images are pre-optimized; avoids Next.js re-processing
+  return <Image {...rest} src={imgSrc} unoptimized onError={() => setError(true)} />;
src/hooks/use-user/use-user-image-update/index.ts (1)

7-17: LGTM!

The hook correctly follows the established mutation pattern. The empty onError handler delegates error handling to consumers, which is appropriate since the modal component uses mutateAsync and can handle errors locally.

One optional consideration: you could remove the empty onError callback entirely since it's the default behavior, or add logging for debugging purposes.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 244986d and 6adfb79.

📒 Files selected for processing (16)
  • next.config.ts (1 hunks)
  • src/api/service/user-service/index.ts (1 hunks)
  • src/app/(user)/mypage/page.tsx (0 hunks)
  • src/components/pages/user/mypage/mypage-setting/index.tsx (2 hunks)
  • src/components/pages/user/profile/profile-card/index.tsx (2 hunks)
  • src/components/pages/user/profile/profile-edit-fields/image-field/index.tsx (2 hunks)
  • src/components/pages/user/profile/profile-edit-fields/index.ts (1 hunks)
  • src/components/pages/user/profile/profile-edit-modal/index.tsx (3 hunks)
  • src/components/ui/image-with-fallback/index.tsx (1 hunks)
  • src/components/ui/index.ts (1 hunks)
  • src/hooks/use-user/index.ts (0 hunks)
  • src/hooks/use-user/use-user-get/index.ts (1 hunks)
  • src/hooks/use-user/use-user-image-update/index.ts (1 hunks)
  • src/hooks/use-user/use-user-notification/index.ts (1 hunks)
  • src/hooks/use-user/use-user-update/index.ts (1 hunks)
  • src/types/service/user.ts (2 hunks)
💤 Files with no reviewable changes (2)
  • src/app/(user)/mypage/page.tsx
  • src/hooks/use-user/index.ts
🧰 Additional context used
🧬 Code graph analysis (7)
src/hooks/use-user/use-user-notification/index.ts (3)
src/types/service/user.ts (1)
  • UpdateMyNotiParams (31-33)
src/api/index.ts (1)
  • API (22-22)
src/lib/query-key/query-key-user/index.ts (1)
  • userKeys (1-5)
src/components/ui/image-with-fallback/index.tsx (1)
src/components/ui/index.ts (1)
  • ImageWithFallback (3-3)
src/components/pages/user/profile/profile-edit-fields/image-field/index.tsx (2)
src/lib/utils.ts (1)
  • cn (74-76)
src/components/icon/index.tsx (1)
  • Icon (55-61)
src/components/pages/user/profile/profile-edit-modal/index.tsx (3)
src/hooks/use-user/use-user-update/index.ts (1)
  • useUpdateUser (7-17)
src/hooks/use-user/use-user-image-update/index.ts (1)
  • useUserImageUpdate (7-18)
src/types/service/user.ts (1)
  • UpdateMePayload (21-25)
src/hooks/use-user/use-user-image-update/index.ts (3)
src/types/service/user.ts (1)
  • UpdateMyProfileImagePayload (27-29)
src/api/index.ts (1)
  • API (22-22)
src/lib/query-key/query-key-user/index.ts (1)
  • userKeys (1-5)
src/api/service/user-service/index.ts (2)
src/types/service/user.ts (9)
  • FollowParams (35-37)
  • UpdateMePayload (21-25)
  • User (1-15)
  • UpdateMyProfileImagePayload (27-29)
  • UpdateMyNotiParams (31-33)
  • GetUserParams (17-19)
  • GetNickNameAvailabilityParams (43-45)
  • Availability (39-41)
  • GetEmailAvailabilityParams (47-49)
src/api/core/index.ts (1)
  • api (64-90)
src/components/pages/user/mypage/mypage-setting/index.tsx (2)
src/hooks/use-user/use-user-notification/index.ts (1)
  • useUpdateMyNotification (7-20)
src/components/pages/user/mypage/mypage-setting-button/index.tsx (1)
  • MyPageToggleButton (12-19)
🔇 Additional comments (11)
next.config.ts (1)

25-30: S3 bucket allowlist addition looks correct.

This should unblock next/image remote loading for the WeGo S3 host.

src/components/pages/user/profile/profile-edit-fields/index.ts (1)

1-4: Clean barrel export; improves module boundaries.

src/components/ui/index.ts (1)

1-5: UI export addition is fine (public surface updated).

src/types/service/user.ts (1)

27-49: LGTM!

The type definitions are well-structured. The rename to UpdateMyProfileImagePayload is more descriptive, and the new availability interfaces properly support the nickname/email validation features.

src/components/pages/user/profile/profile-edit-modal/index.tsx (1)

82-84: LGTM!

Good UX improvement with the combined pending state and dynamic button label feedback during submission.

src/components/pages/user/profile/profile-edit-fields/image-field/index.tsx (1)

24-51: LGTM!

The render prop logic correctly handles the empty images case by ensuring a placeholder is always rendered. The ImageWithFallback component will properly display the fallback image when the url is an empty string.

src/api/service/user-service/index.ts (5)

15-18: LGTM!

The follow endpoint implementation is correct. POST method is appropriate for the follow action, and the path parameter will be properly URL-encoded by axios.


20-23: LGTM!

The profile update endpoint correctly uses PATCH for partial updates and passes the payload as the request body.


25-30: LGTM!

The profile image update endpoint correctly handles file uploads using FormData. The implementation follows the standard pattern for multipart/form-data file uploads.


39-42: LGTM!

The user profile retrieval endpoint is correctly implemented with appropriate path parameter handling.


54-57: LGTM!

The unfollow endpoint implementation is correct. DELETE method is appropriate for the unfollow action, and the path parameter will be properly URL-encoded by axios.

Comment on lines 32 to 37
// 4. 알림 설정 변경
updatMyNotification: async (payload: UpdateMyNotiParams) => {
return api.patch<User>(`/users/notification/${payload.isNotificationEnabled}`);
updatMyNotification: async (params: UpdateMyNotiParams) => {
return api.patch<User>(
`/users/notification?isNotificationEnabled=${params.isNotificationEnabled}`,
);
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find and display the target file and relevant context
cat -n src/api/service/user-service/index.ts | head -50

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 1850


🏁 Script executed:

# Search for all usages of the function name (both correct and typo variants)
rg -n 'updatMyNotification|updateMyNotification' --type=ts --type=tsx -C2

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 98


🏁 Script executed:

# Search for all usages of updatMyNotification (the typo version)
rg -n 'updatMyNotification' -C2

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 1011


🏁 Script executed:

# Also search for updateMyNotification to see if it's used anywhere
rg -n 'updateMyNotification' -C2

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 53


🏁 Script executed:

# Check the api core to understand how axios is configured
cat -n src/api/core.ts 2>/dev/null || cat -n src/api/core/index.ts 2>/dev/null || find src/api -name "*core*" -type f

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 3597


Fix function name typo and use proper query parameter handling.

Two issues identified:

  1. Function name has a typo: "updatMyNotification" should be "updateMyNotification"
  2. Query parameters should use axios config instead of string interpolation for consistency and best practices

This change affects at least one call site in src/hooks/use-user/use-user-notification/index.ts (line 10).

Apply this diff:

-  // 4. 알림 설정 변경
-  updatMyNotification: async (params: UpdateMyNotiParams) => {
-    return api.patch<User>(
-      `/users/notification?isNotificationEnabled=${params.isNotificationEnabled}`,
-    );
+  // 4. 알림 설정 변경
+  updateMyNotification: async (params: UpdateMyNotiParams) => {
+    return api.patch<User>('/users/notification', null, {
+      params: { isNotificationEnabled: params.isNotificationEnabled },
+    });
   },

Update the call site in src/hooks/use-user/use-user-notification/index.ts (line 10) to use the corrected function name.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 4. 알림 설정 변경
updatMyNotification: async (payload: UpdateMyNotiParams) => {
return api.patch<User>(`/users/notification/${payload.isNotificationEnabled}`);
updatMyNotification: async (params: UpdateMyNotiParams) => {
return api.patch<User>(
`/users/notification?isNotificationEnabled=${params.isNotificationEnabled}`,
);
},
// 4. 알림 설정 변경
updateMyNotification: async (params: UpdateMyNotiParams) => {
return api.patch<User>('/users/notification', null, {
params: { isNotificationEnabled: params.isNotificationEnabled },
});
},
🤖 Prompt for AI Agents
In src/api/service/user-service/index.ts around lines 32 to 37, rename the
function from "updatMyNotification" to "updateMyNotification" and change the
request to pass query parameters via axios config (use
api.patch<User>('/users/notification', undefined, { params: {
isNotificationEnabled: params.isNotificationEnabled } }) ) instead of string
interpolation; also update the call site in
src/hooks/use-user/use-user-notification/index.ts (around line 10) to call the
new updateMyNotification function name.

Comment on lines 44 to 47
// 6. 닉네임 중복 검사
getNicknameAvailability: async (params: GetNickNameAvailabilityParams) => {
return api.get<Availability>(`/users/nickname/availability?nickname=${params.nickName}`);
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the file structure and the endpoint in question
cat -n src/api/service/user-service/index.ts | head -60

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 2141


🏁 Script executed:

# Search for API endpoint definitions or tests that might show the correct parameter name
rg "nickname.*availability" -i -A 3 -B 3

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 1298


🏁 Script executed:

# Look for similar endpoints to understand the pattern used in the codebase
rg "api\.get.*params:" -A 2 -B 2

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 53


🏁 Script executed:

# Check if there's any API documentation or backend endpoint definition
find . -type f \( -name "*api*" -o -name "*spec*" -o -name "*swagger*" -o -name "*openapi*" \) | grep -E "\.(ts|js|md|json|yaml|yml)$" | head -20

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 53


🏁 Script executed:

# Look for tests related to this endpoint
rg "getNicknameAvailability" -A 5 -B 2

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 661


🏁 Script executed:

# Check the axios configuration to understand default behavior with params
rg "api\.get|axios.*get" -A 2 | head -40

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 1314


🏁 Script executed:

# Look for test files or actual usage of getNicknameAvailability
rg "getNicknameAvailability" -A 5 -B 2

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 661


🏁 Script executed:

# Check the axios/api core configuration
cat -n src/api/core/index.ts 2>/dev/null || find src/api/core -type f -name "*.ts" | head -5

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 3597


🏁 Script executed:

# Look for backend API documentation or OpenAPI spec
find . -type f \( -name "*.md" -o -name "*.json" -o -name "*.yaml" -o -name "*.yml" \) | xargs grep -l "nickname.*availability" 2>/dev/null | head -5

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 53


🏁 Script executed:

# Check if there's environment/config that might specify API endpoint details
find . -type f \( -name ".env*" -o -name "config*" -o -name "*api*config*" \) | head -10

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 84


🏁 Script executed:

# Look for any comments or documentation about the nickname endpoint
rg "nickname" -B 2 -A 2 | grep -E "(api|endpoint|param|query)" | head -20

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 709


🏁 Script executed:

# Look for any integration tests or E2E tests that use this endpoint
find . -type f -name "*.test.*" -o -name "*.spec.*" | xargs grep -l "getNicknameAvailability\|nickname.*availability" 2>/dev/null

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 55


🏁 Script executed:

# Check if there's a backend repository reference or API spec
cat README.md 2>/dev/null | grep -i "api\|backend\|backend-repo" | head -10

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 410


🏁 Script executed:

# Search for actual usage of these functions to see if they work with special characters
rg "getNicknameAvailability|getEmailAvailability" -A 3 -B 3 | head -30

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 909


Missing URL encoding for query parameters.

The nickname query parameter is not URL-encoded. Nicknames containing spaces or special characters (e.g., "John Doe", "user@123") will cause malformed URLs and request failures.

The api.get() function supports passing a config object as the second parameter, which allows axios to properly handle and encode query parameters. Apply this fix:

   // 6. 닉네임 중복 검사
   getNicknameAvailability: async (params: GetNickNameAvailabilityParams) => {
-    return api.get<Availability>(`/users/nickname/availability?nickname=${params.nickName}`);
+    return api.get<Availability>('/users/nickname/availability', {
+      params: { nickname: params.nickName },
+    });
   },

Note: The same issue affects the getEmailAvailability endpoint (line 51) and updatMyNotification endpoint (line 35). Consider applying the same fix pattern to those endpoints as well.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 6. 닉네임 중복 검사
getNicknameAvailability: async (params: GetNickNameAvailabilityParams) => {
return api.get<Availability>(`/users/nickname/availability?nickname=${params.nickName}`);
},
// 6. 닉네임 중복 검사
getNicknameAvailability: async (params: GetNickNameAvailabilityParams) => {
return api.get<Availability>('/users/nickname/availability', {
params: { nickname: params.nickName },
});
},
🤖 Prompt for AI Agents
In src/api/service/user-service/index.ts around lines 44 to 47, the nickname
query parameter is concatenated into the URL without URL-encoding; change the
call to pass query parameters via the api.get second-argument config (use {
params: { nickname: params.nickName } }) so axios encodes them properly; apply
the same pattern to getEmailAvailability (around line 51) and
updatMyNotification (around line 35) to avoid malformed URLs for emails,
nicknames or other special-character values.

Comment on lines 37 to 56
onSubmit: async ({ value }) => {
console.log(value);
const { profileImage, nickName, profileMessage, mbti } = value;

// 프로필 항목 업데이트 조건 체크
const nextProfileInfo: UpdateMePayload = {
...(user.nickName !== value.nickName && { nickName }),
...(user.profileMessage !== value.profileMessage && { profileMessage }),
...(user.mbti !== value.mbti && { mbti }),
};
if (Object.values(nextProfileInfo).length > 0) {
await updateUser(nextProfileInfo);
}

// 이미지 업데이트 조건 체크
const imageFileObject = Object.values(profileImage)[0];
if (imageFileObject) {
await updateUserImage({ file: imageFileObject });
}
close();
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling for failed mutations.

If either updateUser or updateUserImage fails, the modal closes without user feedback. Users won't know their changes weren't saved.

     onSubmit: async ({ value }) => {
       const { profileImage, nickName, profileMessage, mbti } = value;

       // 프로필 항목 업데이트 조건 체크
       const nextProfileInfo: UpdateMePayload = {
         ...(user.nickName !== value.nickName && { nickName }),
         ...(user.profileMessage !== value.profileMessage && { profileMessage }),
         ...(user.mbti !== value.mbti && { mbti }),
       };
-      if (Object.values(nextProfileInfo).length > 0) {
-        await updateUser(nextProfileInfo);
-      }
-
-      // 이미지 업데이트 조건 체크
-      const imageFileObject = Object.values(profileImage)[0];
-      if (imageFileObject) {
-        await updateUserImage({ file: imageFileObject });
+      try {
+        if (Object.keys(nextProfileInfo).length > 0) {
+          await updateUser(nextProfileInfo);
+        }
+
+        // 이미지 업데이트 조건 체크
+        const imageFileObject = Object.values(profileImage)[0];
+        if (imageFileObject) {
+          await updateUserImage({ file: imageFileObject });
+        }
+        close();
+      } catch (error) {
+        // Consider showing a toast notification here
+        console.error('프로필 업데이트 실패:', error);
       }
-      close();
     },
🤖 Prompt for AI Agents
In src/components/pages/user/profile/profile-edit-modal/index.tsx around lines
37 to 56, the submit handler currently awaits updateUser and updateUserImage but
closes the modal regardless of failures; wrap the mutation calls in a try/catch
so errors are caught, show a user-facing error (e.g., toast or set an error
state) when either updateUser or updateUserImage throws, only call close() when
all required updates succeed, and log the error for debugging; ensure both calls
remain awaited and preserve current behavior when there are no errors.

Comment on lines +12 to +16
export const ImageWithFallback = ({
src,
fallbackSrc = 'https://plus.unsplash.com/premium_photo-1738592736106-a17b897c0ab1?q=80&w=1934&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
...rest
}: ImageWithFallbackProps) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use a local fallback image instead of an external URL.

The default fallbackSrc points to an external Unsplash URL, which defeats the purpose of a reliable fallback. If Unsplash is unavailable, rate-limited, or the URL changes, the fallback itself will fail.

Consider using a local placeholder image:

 export const ImageWithFallback = ({
   src,
-  fallbackSrc = 'https://plus.unsplash.com/premium_photo-1738592736106-a17b897c0ab1?q=80&w=1934&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
+  fallbackSrc = '/images/default-profile.png',
   ...rest
 }: ImageWithFallbackProps) => {

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/components/ui/image-with-fallback/index.tsx around lines 12 to 16, the
default fallbackSrc is an external Unsplash URL which is unreliable; replace it
with a local static asset (e.g., import or reference a local placeholder in the
project assets/public folder) and update the component to use that local path as
the default fallbackSrc so the fallback always resolves even if external
services fail.

Comment on lines 7 to 20
export const useUpdateMyNotification = () => {
const queryClient = useQueryClient();
const query = useMutation({
mutationFn: (params: UpdateMyNotiParams) => API.userService.updatMyNotification(params),
onSuccess: (_data, _variables, _context) => {
queryClient.invalidateQueries({ queryKey: userKeys.all });
console.log('요청 성공');
},
onError: () => {
console.log('요청 실패');
},
});
return query;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for both method name variants
echo "=== Searching for updatMyNotification (possible typo) ==="
rg -n --type=ts -C2 '\bupdatMyNotification\b' src || echo "Not found"

echo ""
echo "=== Searching for updateMyNotification (correct spelling) ==="
rg -n --type=ts -C2 '\bupdateMyNotification\b' src || echo "Not found"

echo ""
echo "=== Locating API service definition ==="
fd --type=f -e ts -e tsx | xargs grep -l "userService" | head -10

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 1556


🏁 Script executed:

#!/bin/bash

# Check how common console.log is in hooks
echo "=== Console.log usage in hooks ==="
rg -n "console\.(log|error|warn)" src/hooks --type=ts | head -20

echo ""
echo "=== Console.log pattern in mutations/queries ==="
rg -n "console\.(log|error|warn)" src/api --type=ts | head -20

Repository: WeGo-Together/WeGo_FrontEnd

Length of output: 1737


Consider fixing the typo updatMyNotification in the API service definition and remove console.log in favor of error handling.

The method name updatMyNotification (missing "e") is defined in src/api/service/user-service/index.ts:33 with the same typo, so the hook correctly calls the matching name—no runtime error here. However, the typo should be fixed at the source to follow naming conventions.

Console logging in mutation callbacks is common throughout the codebase, but it's noisy for production. Consider returning success/error state to the caller (via toast or UI feedback) instead. If removing console.log is a priority, apply the change consistently across other hooks using the same pattern.

🤖 Prompt for AI Agents
In src/hooks/use-user/use-user-notification/index.ts lines 7-20, fix the API
method typo and remove noisy console logs: rename the method in
src/api/service/user-service/index.ts from updatMyNotification to
updateMyNotification and update all call sites to
API.userService.updateMyNotification (including this hook), then remove
console.log calls in onSuccess/onError here and instead rely on the mutation's
returned state (or call a passed-in notification/toast handler) while keeping
queryClient.invalidateQueries in onSuccess and handling the error parameter in
onError for downstream handling.

@Chiman2937 Chiman2937 added the Ready For Review! 리뷰 받을 준비가 되었습니다. label Dec 14, 2025
@Chiman2937
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 14, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

♻️ Duplicate comments (4)
src/hooks/use-user/use-user-notification/index.ts (1)

7-21: console.log를 사용자 피드백 메커니즘으로 교체하는 것을 권장합니다.

프로덕션 환경에서는 console.log 대신 토스트 알림이나 mutation 상태를 통해 사용자에게 피드백을 제공하는 것이 좋습니다. 이 패턴은 다른 훅들에서도 동일하게 사용되고 있습니다.

src/components/pages/user/profile/profile-edit-modal/index.tsx (2)

42-61: mutation 실패 시 에러 핸들링을 추가해야 합니다.

현재 updateUser 또는 updateUserImage가 실패하더라도 모달이 닫힙니다. 사용자는 변경사항이 저장되지 않았다는 것을 알 수 없습니다.

다음과 같이 try-catch를 추가하세요:

     onSubmit: async ({ value }) => {
       const { profileImage, nickName, profileMessage, mbti } = value;

       // 프로필 항목 업데이트 조건 체크
       const nextProfileInfo: UpdateMyInfoPayload = {
         ...(user.nickName !== value.nickName && { nickName }),
         ...(user.profileMessage !== value.profileMessage && { profileMessage }),
         ...(user.mbti !== value.mbti && { mbti }),
       };
-      if (Object.keys(nextProfileInfo).length > 0) {
-        await updateUser(nextProfileInfo);
-      }
-
-      // 이미지 업데이트 조건 체크
-      const imageFileObject = Object.values(profileImage)[0];
-      if (imageFileObject) {
-        await updateUserImage({ file: imageFileObject });
+      try {
+        if (Object.keys(nextProfileInfo).length > 0) {
+          await updateUser(nextProfileInfo);
+        }
+
+        // 이미지 업데이트 조건 체크
+        const imageFileObject = Object.values(profileImage)[0];
+        if (imageFileObject) {
+          await updateUserImage({ file: imageFileObject });
+        }
+        close();
+      } catch (error) {
+        console.error('프로필 업데이트 실패:', error);
+        // TODO: 토스트 알림 추가
       }
-      close();
     },

51-53: Object.values() 대신 Object.keys()를 사용해야 합니다.

조건식에서 Object.values(nextProfileInfo).length를 사용하고 있는데, 이는 객체의 값 개수를 확인합니다. 객체가 비어있는지 확인하려면 Object.keys(nextProfileInfo).length를 사용해야 합니다.

다음과 같이 수정하세요:

-      if (Object.values(nextProfileInfo).length > 0) {
+      if (Object.keys(nextProfileInfo).length > 0) {
         await updateUser(nextProfileInfo);
       }
src/api/service/user-service/index.ts (1)

35-40: 쿼리 파라미터를 axios config를 통해 전달하세요.

이전 리뷰에서 지적된 문자열 보간 문제가 여전히 남아있습니다. 다른 메서드들(getNicknameAvailability, getEmailAvailability, unfollowUser)과의 일관성을 위해 axios config 객체를 사용해야 합니다.

다음 diff를 적용하세요:

   // 4. 알림 설정 변경
   updateMyNotification: async (params: UpdateMyNotificationQueryParams) => {
-    return api.patch<User>(
-      `/users/notification?isNotificationEnabled=${params.isNotificationEnabled}`,
-    );
+    return api.patch<User>('/users/notification', null, {
+      params: { isNotificationEnabled: params.isNotificationEnabled },
+    });
   },
🧹 Nitpick comments (4)
src/hooks/use-user/use-user-follow/index.ts (1)

7-20: 훅 패턴 개선이 잘 적용되었습니다. console.log를 제거하는 것을 권장합니다.

파라미터를 mutationFn에서 받는 패턴으로 변경한 것은 적절합니다. 다만 프로덕션 환경에서는 console.log 대신 사용자 피드백(토스트 등)을 제공하거나 mutation의 상태를 반환하는 것이 좋습니다.

src/hooks/use-user/use-user-update/index.ts (1)

14-14: 빈 에러 핸들러를 개선하는 것을 권장합니다.

onError가 빈 핸들러로 구현되어 있어 에러 발생 시 사용자에게 아무런 피드백이 제공되지 않습니다. 최소한 에러 로깅이나 사용자 알림을 추가하는 것이 좋습니다.

다음과 같이 에러 핸들링을 추가할 수 있습니다:

-    onError: () => {},
+    onError: (error) => {
+      console.error('프로필 업데이트 실패:', error);
+      // TODO: 토스트 알림 추가
+    },
src/components/pages/user/profile/profile-edit-modal/index.tsx (1)

37-41: 순차 실행을 병렬 실행으로 개선하는 것을 권장합니다.

TODO 코멘트에서 언급한 대로, 현재 순차적으로 실행되는 두 API 호출을 Promise.all을 사용하여 병렬로 실행하면 성능이 개선됩니다. 단, 두 API가 독립적이고 순서에 의존하지 않는 경우에만 적용하세요.

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

const promises: Promise<any>[] = [];

if (Object.keys(nextProfileInfo).length > 0) {
  promises.push(updateUser(nextProfileInfo));
}

const imageFileObject = Object.values(profileImage)[0];
if (imageFileObject) {
  promises.push(updateUserImage({ file: imageFileObject }));
}

if (promises.length > 0) {
  await Promise.all(promises);
}
src/hooks/use-user/use-user-unfollow/index.ts (1)

7-20: LGTM! follow 훅과 일관된 패턴이 적용되었습니다.

언팔로우 훅이 팔로우 훅과 동일한 패턴으로 잘 구현되었습니다. 다만 다른 훅들과 마찬가지로 console.log를 사용자 피드백으로 교체하는 것을 권장합니다.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6adfb79 and 7034542.

📒 Files selected for processing (12)
  • src/api/service/user-service/index.ts (1 hunks)
  • src/components/pages/user/profile/profile-edit-modal/index.tsx (3 hunks)
  • src/components/pages/user/profile/profile-info/index.tsx (2 hunks)
  • src/components/ui/image-with-fallback/index.tsx (1 hunks)
  • src/hooks/use-user/use-user-follow/index.ts (1 hunks)
  • src/hooks/use-user/use-user-get/index.ts (1 hunks)
  • src/hooks/use-user/use-user-image-update/index.ts (1 hunks)
  • src/hooks/use-user/use-user-notification/index.ts (1 hunks)
  • src/hooks/use-user/use-user-unfollow/index.ts (1 hunks)
  • src/hooks/use-user/use-user-update/index.ts (1 hunks)
  • src/mock/service/user/user-mock.ts (3 hunks)
  • src/types/service/user.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/hooks/use-user/use-user-image-update/index.ts
  • src/components/ui/image-with-fallback/index.tsx
  • src/hooks/use-user/use-user-get/index.ts
🧰 Additional context used
🧬 Code graph analysis (7)
src/hooks/use-user/use-user-notification/index.ts (3)
src/types/service/user.ts (1)
  • UpdateMyNotificationQueryParams (31-33)
src/api/index.ts (1)
  • API (22-22)
src/lib/query-key/query-key-user/index.ts (1)
  • userKeys (1-5)
src/hooks/use-user/use-user-unfollow/index.ts (1)
src/types/service/user.ts (1)
  • UnfollowQueryParams (39-41)
src/hooks/use-user/use-user-update/index.ts (4)
src/hooks/use-user/index.ts (1)
  • useUpdateUser (4-4)
src/types/service/user.ts (1)
  • UpdateMyInfoPayload (21-25)
src/api/index.ts (1)
  • API (22-22)
src/lib/query-key/query-key-user/index.ts (1)
  • userKeys (1-5)
src/components/pages/user/profile/profile-edit-modal/index.tsx (3)
src/hooks/use-user/use-user-update/index.ts (1)
  • useUpdateUser (7-17)
src/hooks/use-user/use-user-image-update/index.ts (1)
  • useUserImageUpdate (7-17)
src/types/service/user.ts (1)
  • UpdateMyInfoPayload (21-25)
src/hooks/use-user/use-user-follow/index.ts (1)
src/types/service/user.ts (1)
  • FollowPathParams (35-37)
src/components/pages/user/profile/profile-info/index.tsx (2)
src/hooks/use-user/use-user-follow/index.ts (1)
  • useFollowUser (7-21)
src/hooks/use-user/use-user-unfollow/index.ts (1)
  • useUnfollowUser (7-20)
src/api/service/user-service/index.ts (1)
src/types/service/user.ts (10)
  • FollowPathParams (35-37)
  • UpdateMyInfoPayload (21-25)
  • User (1-15)
  • UpdateMyImagePayload (27-29)
  • UpdateMyNotificationQueryParams (31-33)
  • GetUserPathParams (17-19)
  • GetNicknameAvailabilityQueryParams (47-49)
  • Availability (43-45)
  • GetEmailAvailabilityQueryParams (51-53)
  • UnfollowQueryParams (39-41)
🪛 Biome (2.1.2)
src/components/pages/user/profile/profile-edit-modal/index.tsx

[error] 87-87: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: chromatic
🔇 Additional comments (12)
src/mock/service/user/user-mock.ts (1)

18-18: LGTM! 타입 정의 변경에 맞춰 필드명이 올바르게 업데이트되었습니다.

isFollowing에서 isFollow로의 필드명 변경이 모든 mock 데이터에 일관되게 적용되었습니다.

Also applies to: 34-34, 50-50

src/components/pages/user/profile/profile-info/index.tsx (2)

15-25: LGTM! 팔로우/언팔로우 로직이 명확하게 구현되었습니다.

새로운 훅들을 사용하여 팔로우/언팔로우 기능이 깔끔하게 구현되었고, 각 액션에 적절한 핸들러가 연결되었습니다.


31-36: LGTM! 타입 변경에 맞춰 올바르게 업데이트되었습니다.

isFollowing에서 isFollow로의 필드명 변경이 UI 렌더링 로직에 일관되게 적용되었습니다.

src/types/service/user.ts (1)

14-14: LGTM! 타입 정의가 일관성 있고 명확하게 개선되었습니다.

타입 이름들이 더 명확해졌고 (PathParams, QueryParams 등), 새로운 인터페이스들이 잘 정의되었습니다. 전체 코드베이스에서 일관되게 사용될 수 있는 좋은 타입 시스템입니다.

Also applies to: 17-19, 21-25, 31-33, 35-53

src/api/service/user-service/index.ts (8)

1-13: 임포트 구성이 올바릅니다.

새로 추가된 타입들이 메서드 시그니처와 일치하며 적절하게 구성되어 있습니다.


23-26: 메서드 구현이 올바릅니다.

프로필 정보 업데이트를 위한 표준 REST 패턴이 적용되었습니다.


28-33: 파일 업로드 구현이 적절합니다.

FormData를 올바르게 생성하고 파일을 첨부하여 이미지 업데이트를 처리하고 있습니다.


42-45: 사용자 조회 구현이 올바릅니다.

경로 파라미터를 사용한 표준 GET 요청 패턴입니다.


47-52: 이전 리뷰 이슈가 해결되었습니다.

닉네임 중복 검사 메서드가 이제 axios config를 통해 쿼리 파라미터를 전달하여 URL 인코딩이 올바르게 처리됩니다.


54-59: 이전 리뷰 이슈가 해결되었습니다.

이메일 중복 검사 메서드가 이제 axios config를 통해 쿼리 파라미터를 전달하여 특수 문자(+, @ 등)가 올바르게 인코딩됩니다.


61-66: 언팔로우 메서드 구현이 적절합니다.

DELETE 요청에서 쿼리 파라미터를 axios config를 통해 전달하는 방식이 올바르게 구현되었습니다.


16-21: 백엔드 API 명세와 일치하는지 확인이 필요합니다.

followUser 메서드가 POST 요청에서 쿼리 파라미터를 사용하고 있습니다. 일반적으로 POST 요청은 요청 바디에 데이터를 전달하지만, 여기서는 쿼리 파라미터(followNickname)를 사용하고 있습니다. unfollowUser(DELETE, 라인 62-65)도 동일한 패턴으로 쿼리 파라미터를 사용하고 있으므로 의도적인 API 설계로 보이지만, 백엔드 API 명세와 실제로 일치하는지 확인하세요.

@Chiman2937 Chiman2937 changed the title [Feat] 마이페이지 업데이트 API 3종 연결 [Feat] 프로필/마이 페이지 API 연결 Dec 14, 2025
@Chiman2937 Chiman2937 changed the title [Feat] 프로필/마이 페이지 API 연결 [Feat] 프로필/마이페이지 API 연결 Dec 14, 2025
@Chiman2937 Chiman2937 changed the title [Feat] 프로필/마이페이지 API 연결 [Feat] user 엔드포인트 API 연결 Dec 14, 2025
Copy link
Contributor

@wooktori wooktori left a comment

Choose a reason for hiding this comment

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

고생하셨습니다!

@Chiman2937 Chiman2937 merged commit c413aaa into main Dec 15, 2025
8 checks passed
@Chiman2937 Chiman2937 deleted the chiyoung-fix/mypage-edit branch December 15, 2025 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready For Review! 리뷰 받을 준비가 되었습니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[프로필 페이지] API 연동작업

4 participants