Skip to content

[♻️ Refactor/188] 프로필 수정 범위 제한 및 프로필 이미지 변경 로직 추가#210

Merged
jerryko570 merged 3 commits into
mainfrom
refactor/188/profile-edit-image
Jan 18, 2026
Merged

[♻️ Refactor/188] 프로필 수정 범위 제한 및 프로필 이미지 변경 로직 추가#210
jerryko570 merged 3 commits into
mainfrom
refactor/188/profile-edit-image

Conversation

@jerryko570
Copy link
Copy Markdown
Contributor

@jerryko570 jerryko570 commented Jan 16, 2026

✅ PR 체크리스트

  • 기능 정상 동작
  • 콘솔 에러 없음
  • UI 동작 및 반응형 레이아웃 확인

🔗 이슈 번호

✨ 작업한 내용

image image

1. 내 정보 비밀번호 변경 기능 구현

  • 사용자 정보 수정 API (PATCH /users/me) 연동
  • 비밀번호 선택적 업데이트 (입력 시에만 API에 포함)
  • 닉네임, 프로필 이미지와 함께 통합 관리

2. 타입 정의 및 API 연동

  • UpdateUserRequest 타입: newPassword 필드 추가
  • MyPageFormData 타입: 폼 입력 데이터 관리
  • createUpdatePayload 함수: 비밀번호 입력 여부에 따라 payload 동적 생성

3. 프로필 이미지 전역 동기화 (Context 적용)

  • 프로필 이미지 상태를 Context에서 관리하도록 구조 개선
  • 내 정보 페이지에서 이미지 변경 시 상단 헤더 프로필 이미지까지 즉시 반영
  • 페이지 이동 없이도 동일한 프로필 상태 유지되도록 동기화 처리

4. 에러 핸들링

  • useErrorHandler 커스텀 훅 구현
  • API 에러별 사용자 친화적 메시지 표시
  • 401 Unauthorized 시 로그인 페이지 리다이렉트
  • 이미지 업로드, 프로필 업데이트 에러 분리 처리

💁 리뷰 요청 / 코멘트

💡 참고사항

@jerryko570 jerryko570 self-assigned this Jan 16, 2026
@jerryko570 jerryko570 added the ♻️ Refactor 코드 리팩토링 label Jan 16, 2026
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @jerryko570, 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은 마이페이지의 사용자 프로필 관리 기능을 대폭 개선합니다. 기존 닉네임 및 비밀번호 수정 기능에 더해 프로필 이미지 변경 기능을 추가하고, 이를 위한 API 연동 및 전역 상태 관리 시스템을 구축했습니다. 또한, 폼 처리 로직을 모듈화하고 다양한 API 에러 상황에 대한 체계적인 사용자 피드백을 제공함으로써 사용자 경험과 코드 안정성을 향상시켰습니다.

Highlights

  • 프로필 이미지 변경 기능 추가: 마이페이지에서 프로필 이미지를 업로드하고 변경할 수 있는 기능이 추가되었습니다.
  • 전역 프로필 이미지 동기화: ProfileImageContext를 도입하여 프로필 이미지 상태를 전역적으로 관리하고, 변경 시 헤더 등 다른 컴포넌트에 즉시 반영되도록 개선되었습니다.
  • 마이페이지 폼 로직 리팩토링: 폼 데이터 관리, 유효성 검사, 비밀번호 선택적 업데이트 로직을 전용 훅 (useFormState)으로 분리하여 코드의 가독성과 재사용성을 높였습니다.
  • 강화된 에러 핸들링: useErrorHandler 커스텀 훅을 구현하여 API 응답 코드별 (예: 401, 403, 409, 413, 415) 구체적인 사용자 친화적 에러 메시지를 제공하고, 401 에러 시 로그인 페이지로 자동 리다이렉트됩니다.
  • 프로필 수정 범위 제한: SideMenu의 프로필 이미지는 이제 마이페이지에서만 편집 가능하도록 editable 속성이 추가되었습니다.
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.

@github-actions
Copy link
Copy Markdown

Copy link
Copy Markdown

@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에서 프로필 수정 기능 리팩토링과 이미지 변경 로직 추가 작업을 진행해주셨네요. 전반적으로 코드 구조가 크게 개선되었습니다.

특히 useFormState, useErrorHandler, useProfileImage 등 커스텀 훅을 적극적으로 활용하여 관심사를 분리한 점이 인상적입니다. 덕분에 useMyPageForm 훅이 훨씬 간결해지고 테스트하기 좋은 구조가 되었습니다. 또한, ProfileImageContext를 도입하여 프로필 이미지 상태를 전역으로 관리하고 즉시 UI에 반영하는 등 사용자 경험을 세심하게 고려한 점도 훌륭합니다.

몇 가지 추가 개선 제안을 리뷰 코멘트로 남겼습니다. 주로 보안, 안정성, 일관성에 대한 내용이니 확인해보시면 좋겠습니다. 좋은 코드 감사합니다!

// 401 Unauthorized - 로그인 페이지로 리다이렉트
if (error.status === 401) {
alert('로그인이 필요합니다.');
localStorage.removeItem('accessToken');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

localStorageaccessToken을 저장하고 관리하는 것은 XSS(Cross-Site Scripting) 공격에 취약할 수 있습니다. localStorage는 JavaScript로 쉽게 접근할 수 있기 때문입니다.

보안 강화를 위해 accessToken은 변수와 같이 메모리에 저장하고, 리프레시 토큰은 httpOnly 쿠키에 저장하는 방식을 고려해 보세요. 이는 스크립트를 통한 토큰 탈취 위험을 크게 줄여줍니다.


if (error instanceof ApiError) {
if (error.status === 413) {
alert('이미지 파일 크기가 너무 큽니다. (최대 4MB)');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

이곳에서는 파일 크기 제한을 4MB로 안내하고 있지만, ProfileEditable.tsx 컴포넌트의 클라이언트 측 유효성 검사에서는 5MB(MAX_SIZE)로 설정되어 있습니다. 사용자 경험의 일관성을 위해 두 값을 일치시키는 것이 좋습니다. ProfileEditable.tsxMAX_SIZE를 서버 제한에 맞춰 4 * 1024 * 1024로 수정하는 것을 고려해 보세요.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

프로필 편집 컴포넌트에 등록된 사이즈 제한과 통일하거나 연결해서 재사용하면 좋을거 같아요
얼랏은 토스트 팝업 사용하면 좋을거 같아요

}

// 비밀번호 형식 오류
if (error.status === 400 && error.message?.includes('password')) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

에러 메시지 문자열(error.message?.includes('password'))에 의존하여 로직을 분기하는 방식은 불안정합니다. 백엔드 API의 에러 메시지가 변경되면 이 코드는 오작동할 수 있습니다.

대신 백엔드에서 에러 코드나 에러가 발생한 필드명을 포함한 구조화된 에러 응답을 보내주도록 협의하고, 이를 기반으로 분기하는 것이 더 안정적인 방법입니다. 예를 들어, error.body.field === 'password' 와 같이 확인할 수 있습니다.

References
  1. For robust error handling, use API error codes or dedicated field names for branching logic instead of relying on parsing error message strings.

Copy link
Copy Markdown
Contributor

@sylee86 sylee86 left a comment

Choose a reason for hiding this comment

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

작동 잘되는거 확인하였습니다. 수고하셨습니다.

if (!file.type.startsWith('image/')) return;
if (file.size > MAX_SIZE) {
//TODO 토스트 모달로 알림 통일
alert('파일 크기는 5MB 이하여야 합니다.');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

해당 얼랏 토스트 팝업으로 표현해주실 수 있나요?

@github-actions
Copy link
Copy Markdown

@jerryko570 jerryko570 merged commit 710108a into main Jan 18, 2026
1 check passed
@jerryko570 jerryko570 deleted the refactor/188/profile-edit-image branch January 18, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

♻️ Refactor 코드 리팩토링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[♻️ Refactor] 프로필 수정 범위 제한 및 프로필 이미지 변경 로직 추가

3 participants