Skip to content

Conversation

@dmp100
Copy link
Contributor

@dmp100 dmp100 commented Nov 13, 2025

ISSUE

❗ WORK DESCRIPTIONAdd commentMore actions

  • 로그아웃, 회원탈퇴 API 연동후 모달뜨고 로그인화면으로 돌아가도록 작업했습니다
  • CICD 문법 에러난것도 수정했습니다

📸 SCREENSHOT

2025-11-13.18.23.08.mov
image

📢 TO REVIEWERS

  • 리플효과 안되어있는거는 추후에 찾아서 적용할께요,,

Summary by CodeRabbit

  • New Features
    • Added account logout functionality with confirmation dialog
    • Added account withdrawal/deletion feature with confirmation dialog
    • Expanded device preset support with new device models while removing restricted legacy presets

@dmp100 dmp100 added feature ✨ 기능 구현 mod 🎉 큰 단위의 코드 수정 규현 🐻 규현 전용 라벨 labels Nov 13, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 13, 2025

Walkthrough

This PR introduces logout and account withdrawal functionality by adding new authentication DTOs, service endpoints, repository methods, view model functions, and UI dialogs with confirmation flows across the authentication and profile layers.

Changes

Cohort / File(s) Summary
CI/CD Configuration
.github/workflows/ci-cd.yml
Whitespace/indentation adjustments in YAML environment variable definitions; no functional logic changes.
Device Presets
.idea/caches/deviceStreaming.xml
Added OnePlus OP5552L1 (api=35) and Samsung a26x (api=36) device presets; removed numerous legacy/EULA-restricted device entries.
Authentication DTOs
app/src/main/java/com/hsLink/hslink/data/dto/request/auth/LogoutRequestDto.kt,
app/src/main/java/com/hsLink/hslink/data/dto/request/auth/WithdrawRequestDto.kt,
app/src/main/java/com/hsLink/hslink/data/dto/response/auth/WithdrawResponseDto.kt
Added three new serializable data classes for logout and withdrawal requests/responses carrying refreshToken and account deletion metadata.
Service Layer
app/src/main/java/com/hsLink/hslink/data/service/login/AuthService.kt
Added logout() (POST) and withdraw() (DELETE) suspend functions to AuthService with corresponding request/response types.
Repository Interfaces
app/src/main/java/com/hsLink/hslink/domain/repository/AuthRepository.kt
Added logout() and withdraw() suspend function signatures to the domain repository interface.
Repository Implementation
app/src/main/java/com/hsLink/hslink/data/repositoryimpl/AuthRepositoryImpl.kt
Implemented logout() and withdraw() methods with token validation, service calls, token clearing on success, and error handling.
UI Components & Screens
app/src/main/java/com/hsLink/hslink/presentation/mypage/component/career/ConfirmDialog.kt,
app/src/main/java/com/hsLink/hslink/presentation/mypage/screen/main/MypageScreen.kt
Added reusable ConfirmDialog composable; updated MypageScreen to wire logout/withdraw callbacks, display confirmation dialogs, and handle navigation on success.
View Model
app/src/main/java/com/hsLink/hslink/presentation/mypage/viewmodel/MypageViewModel.kt
Added AuthRepository dependency, three new state flows (logoutSuccess, withdrawSuccess, isAuthLoading), and logout()/withdraw() methods with state management.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as MypageScreen
    participant VM as MypageViewModel
    participant Repo as AuthRepository
    participant Service as AuthService
    participant API as Backend API
    participant Store as TokenDataStore

    User->>UI: Click logout/withdraw button
    UI->>UI: Show ConfirmDialog
    User->>UI: Confirm action
    UI->>VM: Call logout() or withdraw()
    VM->>VM: Set isAuthLoading = true
    VM->>Repo: Call logout() or withdraw()
    Repo->>Store: Read refresh token
    alt Token exists
        Repo->>Service: Call logout/withdraw with token
        Service->>API: POST/DELETE request
        API-->>Service: Response
        alt Success
            Repo->>Store: Clear tokens
            Repo-->>VM: Return Result.success()
            VM->>VM: Set logoutSuccess/withdrawSuccess = true
            VM->>VM: Set isAuthLoading = false
            VM-->>UI: Success state emitted
            UI->>UI: Navigate to login
        else Failure
            VM->>VM: Set error message
            VM->>VM: Set isAuthLoading = false
            VM-->>UI: Error state emitted
        end
    else No token
        Repo-->>VM: Return Result.failure()
        VM->>VM: Set isAuthLoading = false
        VM-->>UI: Error state emitted
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • AuthRepositoryImpl.kt: Review token validation logic, error propagation, and state management for logout/withdraw flows.
  • MypageScreen.kt: Verify dialog state management, navigation flow on success/failure, and proper passing of authentication loading state to UI.
  • MypageViewModel.kt: Confirm repository integration, state flow initialization, and consistency of success/error handling across logout and withdraw operations.
  • Cross-layer coherence: Ensure DTO contracts, service method signatures, and repository implementations align end-to-end.

Possibly related PRs

  • PR #27: Modifies AuthService and AuthRepositoryImpl authentication layer with DTO updates, directly overlapping with logout/withdraw service integration.
  • PR #29: Adds TokenDataStore and token persistence on login, foundational to the token reading/clearing logic in logout/withdraw implementations.
  • PR #19: Updates MyPage UI and related dialog components, shares the same presentation layer modifications for MypageScreen and dialog handling.

Poem

🐰 A logout hops, a withdraw springs,
Tokens cleared on swift wings,
Dialogs confirm what users choose,
No data left—just smooth goodbyes to lose! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Out of Scope Changes check ❓ Inconclusive Device preset changes in .idea/caches/deviceStreaming.xml and CI/CD whitespace adjustments appear unrelated to issue #36. Clarify if these changes are intentional scope expansions or should be addressed separately.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main changes: logout implementation, account withdrawal, and CI/CD error fixes.
Description check ✅ Passed The description covers key requirements: logout/withdrawal API integration with modal and login redirect, CI/CD fixes, screenshots and notes.
Linked Issues check ✅ Passed All coding requirements from issue #36 are implemented: logout/withdrawal API integration with modals and login redirect via DTOs, service methods, and UI components.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#36-Logout

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.

@dmp100 dmp100 merged commit 788788d into develop Nov 13, 2025
4 of 5 checks passed
@dmp100 dmp100 self-assigned this Nov 13, 2025
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

Caution

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

⚠️ Outside diff range comments (1)
.idea/caches/deviceStreaming.xml (1)

1-1002: Remove IDE cache file from version control.

IDE configuration and cache files (.idea/caches/deviceStreaming.xml) should not be committed to the repository. These are auto-generated by IntelliJ IDEA and are user-specific. Additionally, the device preset changes in this file are unrelated to the PR objectives (logout, withdrawal, CICD fixes) and have no impact on the authentication features being implemented.

Action items:

  1. Remove this file from the commit.
  2. Ensure .idea/ is in your .gitignore if not already present:
    .idea/
    *.iml
  3. If already ignored, ensure your git cache is clean: git rm --cached .idea/ (and commit separately if needed).
🧹 Nitpick comments (3)
app/src/main/java/com/hsLink/hslink/presentation/mypage/component/career/ConfirmDialog.kt (3)

21-22: Remove unused imports.

HsLinkButtonSize and HsLinkSelectButton are imported but never used in this file.

Apply this diff:

-import com.hsLink.hslink.core.designsystem.component.HsLinkButtonSize
-import com.hsLink.hslink.core.designsystem.component.HsLinkSelectButton

53-53: Consider using theme color instead of hardcoded value.

The dialog background uses Color.White directly. Consider using a theme color for consistency and to support potential theme variations.

-        containerColor = Color.White, // ← 완전 하얀색 배경
+        containerColor = HsLinkTheme.colors.Common,

75-75: Fixed lineHeight in sp may not scale optimally.

Using sp for lineHeight creates a fixed value that may not scale proportionally with different font sizes. Consider using a relative multiplier or em unit for better text scaling.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55615b8 and 1ae8817.

📒 Files selected for processing (11)
  • .github/workflows/ci-cd.yml (2 hunks)
  • .idea/caches/deviceStreaming.xml (2 hunks)
  • app/src/main/java/com/hsLink/hslink/data/dto/request/auth/LogoutRequestDto.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/dto/request/auth/WithdrawRequestDto.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/dto/response/auth/WithdrawResponseDto.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/repositoryimpl/AuthRepositoryImpl.kt (2 hunks)
  • app/src/main/java/com/hsLink/hslink/data/service/login/AuthService.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/domain/repository/AuthRepository.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/mypage/component/career/ConfirmDialog.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/mypage/screen/main/MypageScreen.kt (5 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/mypage/viewmodel/MypageViewModel.kt (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
app/src/main/java/com/hsLink/hslink/presentation/mypage/screen/main/MypageScreen.kt (1)
app/src/main/java/com/hsLink/hslink/presentation/mypage/component/career/ConfirmDialog.kt (1)
  • ConfirmDialog (41-106)
app/src/main/java/com/hsLink/hslink/presentation/mypage/component/career/ConfirmDialog.kt (2)
app/src/main/java/com/hsLink/hslink/core/designsystem/theme/Theme.kt (1)
  • HsLinkTheme (37-57)
app/src/main/java/com/hsLink/hslink/core/designsystem/component/HsLinkActionButton.kt (1)
  • HsLinkActionButton (37-93)
⏰ 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: build-and-test
🔇 Additional comments (7)
.github/workflows/ci-cd.yml (1)

45-46: LGTM! Environment variable formatting corrected.

The indentation adjustments ensure proper YAML syntax for environment variables. No functional changes to the workflow.

Also applies to: 99-99

app/src/main/java/com/hsLink/hslink/data/dto/response/auth/WithdrawResponseDto.kt (1)

1-10: LGTM! Clean DTO structure.

The WithdrawResponseDto is properly structured with appropriate types and serialization support.

app/src/main/java/com/hsLink/hslink/data/dto/request/auth/LogoutRequestDto.kt (1)

1-9: LGTM! Clean request DTO.

The LogoutRequestDto follows standard patterns and is properly annotated for serialization.

app/src/main/java/com/hsLink/hslink/data/dto/request/auth/WithdrawRequestDto.kt (1)

1-9: LGTM! Clean request DTO.

The WithdrawRequestDto is properly structured with serialization support. While identical to LogoutRequestDto, maintaining separate DTOs provides better type safety and intent clarity.

app/src/main/java/com/hsLink/hslink/domain/repository/AuthRepository.kt (1)

4-4: LGTM! Clean interface additions.

The new logout() and withdraw() methods follow the existing pattern with proper suspend modifiers and Result type wrappers.

Also applies to: 12-13

app/src/main/java/com/hsLink/hslink/data/service/login/AuthService.kt (1)

18-22: Verify response wrapping inconsistency.

The logout endpoint returns Response<Unit> while withdraw returns Response<BaseResponse<WithdrawResponseDto>>. This wrapping inconsistency suggests different backend response structures. Ensure this matches the actual API contract.

app/src/main/java/com/hsLink/hslink/data/repositoryimpl/AuthRepositoryImpl.kt (1)

41-60: LGTM! Well-structured logout implementation.

The logout flow properly validates token presence, handles API responses, clears local tokens on success, and includes appropriate error handling.

Comment on lines +62 to +81
override suspend fun withdraw(): Result<WithdrawResponseDto> {
return try {
val refreshToken = tokenDataStore.refreshToken.first() // ← 수정
if (refreshToken.isNullOrEmpty()) {
return Result.failure(Exception("토큰이 존재하지 않습니다"))
}

val request = WithdrawRequestDto(refreshToken)
val response = authService.withdraw(request)

if (response.isSuccessful && response.body()?.isSuccess == true) {
tokenDataStore.clearTokens()
Result.success(response.body()!!.result)
} else {
Result.failure(Exception(response.body()?.message ?: "계정 탈퇴에 실패했습니다"))
}
} catch (e: Exception) {
Result.failure(e)
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Potential NPE risk with !! operator.

Line 74 uses the !! operator on response.body(), which could throw a NullPointerException even after checking isSuccessful and isSuccess. Although unlikely, HTTP responses can have null bodies in edge cases.

Apply this diff to handle the null case safely:

-            if (response.isSuccessful && response.body()?.isSuccess == true) {
+            val body = response.body()
+            if (response.isSuccessful && body?.isSuccess == true && body.result != null) {
                 tokenDataStore.clearTokens()
-                Result.success(response.body()!!.result)
+                Result.success(body.result)
             } else {
-                Result.failure(Exception(response.body()?.message ?: "계정 탈퇴에 실패했습니다"))
+                Result.failure(Exception(body?.message ?: "계정 탈퇴에 실패했습니다"))
             }
🤖 Prompt for AI Agents
In app/src/main/java/com/hsLink/hslink/data/repositoryimpl/AuthRepositoryImpl.kt
around lines 62 to 81, the code uses response.body()!! at line 74 which can
throw an NPE even after basic success checks; change the logic to safely handle
a null body by first capturing val body = response.body() and then if
(response.isSuccessful && body?.isSuccess == true) return
Result.success(body.result) else return Result.failure(Exception(body?.message
?: "계정 탈퇴에 실패했습니다")); remove the use of !! and ensure every access to body is
null-checked, returning a failure with a clear message when body is null.

Comment on lines +102 to +107
if (logoutSuccess || withdrawSuccess) {
navController.navigateToLogin(
navOptions = NavOptions.Builder()
.setPopUpTo(0, inclusive = true) // ← 모든 백스택 클리어
.build()
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix back stack clearing when navigating to Login

setPopUpTo(0, inclusive = true) never finds a destination with id 0, so nothing is removed from the back stack. After logging out or withdrawing, the user can press Back and land on the previous protected screen, effectively bypassing logout. Point popUpTo at a real destination (e.g., the graph’s start destination) so the entire stack is cleared.

             navController.navigateToLogin(
                 navOptions = NavOptions.Builder()
-                    .setPopUpTo(0, inclusive = true) // ← 모든 백스택 클리어
-                    .build()
+                    .setPopUpTo(navController.graph.startDestinationId, inclusive = true)
+                    .setLaunchSingleTop(true)
+                    .build()
             )
📝 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
if (logoutSuccess || withdrawSuccess) {
navController.navigateToLogin(
navOptions = NavOptions.Builder()
.setPopUpTo(0, inclusive = true) // ← 모든 백스택 클리어
.build()
)
if (logoutSuccess || withdrawSuccess) {
navController.navigateToLogin(
navOptions = NavOptions.Builder()
.setPopUpTo(navController.graph.startDestinationId, inclusive = true)
.setLaunchSingleTop(true)
.build()
)
🤖 Prompt for AI Agents
In
app/src/main/java/com/hsLink/hslink/presentation/mypage/screen/main/MypageScreen.kt
around lines 102 to 107, the call uses setPopUpTo(0, inclusive = true) which
never matches any destination id so the back stack isn’t cleared; change the
popUpTo target to a real destination (for example the nav graph’s start
destination id or the login route id) and keep inclusive = true so all entries
are removed (e.g. use navController.graph.startDestinationId or the login
destination id as the popUpTo value).

@vvan2 vvan2 changed the title Feat/#36 logout, 회원탈퇴, CICD Error [feat/#36] logout, 회원탈퇴, CICD Error Nov 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature ✨ 기능 구현 mod 🎉 큰 단위의 코드 수정 규현 🐻 규현 전용 라벨

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 로그아웃, 회원탈퇴

2 participants