Skip to content

Conversation

@casper-jr
Copy link
Member

@casper-jr casper-jr commented Oct 4, 2025

🚀 이슈번호

✏️ 변경사항

  • 내 정보 조회, 내 정보 수정 화면을 하나로 합치는 리팩토링 수행
    • 기존의 내 정보 수정 화면 삭제
  • 내 정보 조회 기능 구현
  • 내 정보 수정 기능 구현
  • 동아리 추가 화면으로 이동 시에 진입점이 회원가입 후 이동, 내 정보 수정 화면인지에 따른 네비게이션 분기처리
    • Route에서 파라미터를 통해 처리
  • 닉네임 수정 시에 줄바꿈이 되지 않도록 수정, 실제 요청시에는 앞뒤의 공백을 자르도록 구현

📷 스크린샷

Android

Screen_Recording_20251004_212026_WhosInClient.mp4

iOS

2025-10-04.21.21.22.mov

✍️ 사용법

🎸 기타

  • 기존에 내 정보 조회/ 수정 화면이 따로 분리되어 있었는데, 상태에 따라서 한 화면에서 로직을 처리하는 것이 좋을 것 같아서 논의하고 합치게 되었습니다

Summary by CodeRabbit

  • 신기능

    • 마이페이지에서 내정보 조회/수정 기능 추가(닉네임 조회·수정, 동아리 목록 관리)
    • 서버 연동 추가: 내정보 조회 및 업데이트 API 연동
  • 변경 사항

    • 별도 “내 정보 수정” 화면 제거하고 마이페이지에 편집 통합
    • 편집 모드에서만 동아리 추가/삭제 UI 노출
    • 뒤로가기/편집 완료 시 상태 갱신 및 네비게이션 흐름 개선(가입 흐름 vs 마이페이지 복귀 분기)

@casper-jr casper-jr self-assigned this Oct 4, 2025
@casper-jr casper-jr added FEAT 기능 개발 REFACTOR 기능을 건드리지 않는 리팩토링 OK Merge 완료된 PR labels Oct 4, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 4, 2025

Walkthrough

네비게이션 라우트 변경(ClubCodeInput에 파라미터 추가, UpdateMyInfo 제거), NavGraph 분기 로직 업데이트, 마이페이지 화면/뷰모델 전면 개편(조회/수정 로직 연동, 편집 모드), 클럽 컴포넌트 편집 모드 도입, EditMyInfo 화면 삭제, 내 정보 조회/수정용 DTO 및 원격/레포지토리 메서드 추가.

Changes

Cohort / File(s) Summary
Navigation API
composeApp/src/commonMain/kotlin/org/whosin/client/core/navigation/Route.kt
ClubCodeInput를 data object → data class ClubCodeInput(val returnToMyPage: Boolean = false)로 변경. UpdateMyInfo 라우트 제거.
Nav Graph updates
composeApp/src/commonMain/kotlin/org/whosin/client/core/navigation/WhosInNavGraph.kt
toRouteClubCodeInput 파라미터 디코딩 및 backStackEntry 처리. returnToMyPage에 따라 완료 후 navigateUp() 또는 navigate(Home) + popUpTo(AuthGraph) 로 분기. MyPage의 Edit 흐름을 제거하고 완료 시 ClubCodeInput(returnToMyPage = true)로 연결.
DTOs (request/response)
.../data/dto/request/UpdateMyInfoRequestDto.kt, .../data/dto/response/MyInfoResponseDto.kt, .../data/dto/response/UpdateMyInfoResponseDto.kt
내 정보 조회/수정 응답 및 수정 요청 DTO 신규 추가. @Serializable@SerialName 매핑 적용.
Remote + Repository
.../data/remote/RemoteMemberDataSource.kt, .../data/repository/MemberRepository.kt
getMyInfo() (GET users/myPage) 및 updateMyInfo(...) (PATCH users/myPage/update) 추가. 응답/에러 바디 파싱(ErrorResponseDto) 처리 및 ApiResult 반환. 레포는 데이터소스에 위임.
My Page UI overhaul
.../presentation/mypage/MyPageScreen.kt, .../presentation/mypage/MyPageViewModel.kt, .../presentation/mypage/component/MyClubComponent.kt
화면을 uiState(StateFlow) 기반으로 전환. 편집 모드 토글, 닉네임 편집/저장, 클럽 목록/삭제 연동. MyClubComponent/MyClubItem에 isEditable 추가로 삭제 아이콘 및 추가 버튼 조건부 렌더링.
Removed screen
.../presentation/mypage/EditMyInfoScreen.kt
EditMyInfo 화면 및 미리보기 프리뷰 전면 삭제.

Sequence Diagram(s)

sequenceDiagram
  actor U as User
  participant S as MyPageScreen
  participant VM as MyPageViewModel
  participant R as MemberRepository
  participant DS as RemoteMemberDataSource
  participant API as HTTP_API

  U->>S: 화면 진입
  S->>VM: getMyInfo()
  VM->>R: getMyInfo()
  R->>DS: GET users/myPage
  DS->>API: HTTP GET
  API-->>DS: 200 + MyInfoResponseDto / Error
  DS-->>R: ApiResult
  R-->>VM: ApiResult
  VM-->>S: uiState 업데이트 (nickname, clubs)
Loading
sequenceDiagram
  actor U as User
  participant S as MyPageScreen
  participant VM as MyPageViewModel
  participant R as MemberRepository
  participant DS as RemoteMemberDataSource
  participant API as HTTP_API

  U->>S: 저장 버튼(편집 완료)
  S->>VM: updateMyInfo(nickname, clubs)
  VM->>R: updateMyInfo(...)
  R->>DS: PATCH users/myPage/update
  DS->>API: HTTP PATCH + UpdateMyInfoRequestDto
  API-->>DS: 200 + UpdateMyInfoResponseDto / Error
  DS-->>R: ApiResult
  R-->>VM: ApiResult
  alt 성공
    VM->>VM: getMyInfo() 재호출 -> uiState 갱신
  else 실패
    VM-->>S: uiState.errorMessage 설정
  end
Loading
sequenceDiagram
  participant MP as MyPage
  participant NAV as NavGraph
  participant CC as ClubCodeInput

  MP->>NAV: Route.ClubCodeInput(returnToMyPage=true)
  NAV->>CC: 화면 진입
  CC-->>NAV: 완료
  NAV->>MP: navigateUp()

  Note over NAV: 회원가입 흐름 (기본값 false)
  MP->>NAV: Route.ClubCodeInput() (returnToMyPage=false)
  NAV->>CC: 화면 진입
  CC-->>NAV: 완료
  NAV->>NAV: navigate(Home) + popUpTo(AuthGraph)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • Nico1eKim
  • ikseong00
  • alswlekk

Poem

닉네임 고치고, 클럽을 지우고
라우트는 묻지, "돌아갈래?"라고
true면 뒤로, false면 홈으로 쓱—
API에 PATCH 한 번, uiState 반짝
마이페이지, 이제 더 내 것 같아 ✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed PR 제목 “[Feat] 내 정보 조회/수정 화면 기능 구현”은 변경사항의 핵심인 내 정보 조회와 수정 화면 기능을 한 문장으로 간결하게 잘 요약하고 있어 적절합니다.
Linked Issues Check ✅ Passed 이 PR은 닉네임 변경 API 연결, 동아리 삭제 API 연결, 동아리 추가 화면 네비게이션 분기 처리 및 화면 인터랙션 마무리 등 이슈 #29의 모든 TODO 항목을 충족하고 있어 linked issue 요구사항을 완전히 이행합니다.
Out of Scope Changes Check ✅ Passed 제안된 변경사항은 내 정보 조회·수정 기능 구현과 관련된 네비게이션, DTO 및 UI 리팩토링에 한정되어 있어 linked issue #29의 범위를 벗어나는 불필요한 수정이 없습니다.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eaf42c3 and 9028f91.

📒 Files selected for processing (1)
  • composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/MyPageViewModel.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/MyPageViewModel.kt
⏰ 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: ios-build

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.

Copy link

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6fb514 and eaf42c3.

📒 Files selected for processing (11)
  • composeApp/src/commonMain/kotlin/org/whosin/client/core/navigation/Route.kt (1 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/core/navigation/WhosInNavGraph.kt (3 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/data/dto/request/UpdateMyInfoRequestDto.kt (1 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/data/dto/response/MyInfoResponseDto.kt (1 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/data/dto/response/UpdateMyInfoResponseDto.kt (1 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/data/remote/RemoteMemberDataSource.kt (2 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/data/repository/MemberRepository.kt (1 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/EditMyInfoScreen.kt (0 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/MyPageScreen.kt (4 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/MyPageViewModel.kt (1 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/component/MyClubComponent.kt (5 hunks)
💤 Files with no reviewable changes (1)
  • composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/EditMyInfoScreen.kt
🧰 Additional context used
🧬 Code graph analysis (3)
composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/MyPageScreen.kt (2)
composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/component/MyPageTopAppBar.kt (1)
  • MyPageTopAppBar (19-29)
composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/component/MyPageButton.kt (1)
  • MyPageButton (18-39)
composeApp/src/commonMain/kotlin/org/whosin/client/core/navigation/WhosInNavGraph.kt (1)
composeApp/src/commonMain/kotlin/org/whosin/client/presentation/auth/clubcode/ClubCodeInputScreen.kt (1)
  • ClubCodeInputScreen (51-298)
composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/component/MyClubComponent.kt (1)
composeApp/src/commonMain/kotlin/ui/theme/Type.kt (1)
  • pretendardFontFamily (14-38)
🪛 detekt (1.23.8)
composeApp/src/commonMain/kotlin/org/whosin/client/data/remote/RemoteMemberDataSource.kt

[warning] 65-65: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)


[warning] 103-103: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

⏰ 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). (2)
  • GitHub Check: ios-build
  • GitHub Check: android-build
🔇 Additional comments (1)
composeApp/src/commonMain/kotlin/org/whosin/client/core/navigation/WhosInNavGraph.kt (1)

119-126: 분기 처리 깔끔합니다. 신규 파라미터로 두 경로를 명확히 나눠서 플로우가 훨씬 선명해졌어요.

Comment on lines +130 to +139
onClick = {
if (uiState.isEditable) {
viewModel.updateMyInfo(uiState.nickname.trim(), uiState.clubs)
}
viewModel.toggleEditMode()
},
text = stringResource(
if (uiState.isEditable) Res.string.complete_edit
else Res.string.edit_my_information
),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

편집 완료 버튼이 실패해도 편집 모드를 종료합니다

지금 로직은 버튼을 누르면 API 성공 여부와 상관없이 toggleEditMode()가 실행되어 편집 모드가 바로 해제됩니다. 요청이 실패해도 사용자가 편집 상태를 잃어버려 수정 내용을 다시 입력해야 하는 문제가 생겨요. 아래처럼 성공 시에만 편집 모드를 종료하도록 분리해 주세요.

-            onClick = {
-                if (uiState.isEditable) {
-                    viewModel.updateMyInfo(uiState.nickname.trim(), uiState.clubs)
-                }
-                viewModel.toggleEditMode()
-            },
+            onClick = {
+                if (uiState.isEditable) {
+                    viewModel.updateMyInfo(uiState.nickname.trim(), uiState.clubs)
+                } else {
+                    viewModel.toggleEditMode()
+                }
+            },

위 수정과 함께 updateMyInfo 성공 분기에서 isEditable을 false로 내려주면 자연스러운 플로우가 완성됩니다.

📝 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
onClick = {
if (uiState.isEditable) {
viewModel.updateMyInfo(uiState.nickname.trim(), uiState.clubs)
}
viewModel.toggleEditMode()
},
text = stringResource(
if (uiState.isEditable) Res.string.complete_edit
else Res.string.edit_my_information
),
onClick = {
if (uiState.isEditable) {
viewModel.updateMyInfo(uiState.nickname.trim(), uiState.clubs)
} else {
viewModel.toggleEditMode()
}
},
text = stringResource(
if (uiState.isEditable) Res.string.complete_edit
else Res.string.edit_my_information
),
🤖 Prompt for AI Agents
In
composeApp/src/commonMain/kotlin/org/whosin/client/presentation/mypage/MyPageScreen.kt
around lines 130-139, the onClick currently calls viewModel.updateMyInfo(...)
then unconditionally viewModel.toggleEditMode(), which exits edit mode even if
the update fails; change the flow so toggleEditMode() is only invoked after a
successful update (remove the unconditional call), and instead handle edit-mode
state in the ViewModel by having updateMyInfo report success/failure (via
callback/State/Result) and set isEditable = false on success so the UI exits
edit mode only when the API call succeeds.

@casper-jr casper-jr merged commit cb97b91 into WhosInRoom:develop Oct 4, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

FEAT 기능 개발 OK Merge 완료된 PR REFACTOR 기능을 건드리지 않는 리팩토링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[API] 내 정보 수정하기 구현

1 participant