Skip to content

Comments

[PC-1809] Feat: 프로필 화면에서 휴면 해제 기능을 사용할 수 있다.#283

Merged
hsw1920 merged 5 commits intomainfrom
feat/PC-1809
Feb 21, 2026
Merged

[PC-1809] Feat: 프로필 화면에서 휴면 해제 기능을 사용할 수 있다.#283
hsw1920 merged 5 commits intomainfrom
feat/PC-1809

Conversation

@hsw1920
Copy link
Collaborator

@hsw1920 hsw1920 commented Feb 21, 2026

🏷️ 티켓 번호

PC-1809

👷🏼‍♂️ 변경 사항

  • DesignSystem Info 색상 추가

    • InfoLight (#F0F6FF), InfoDark (#0C4596) colorset 추가
    • 휴면 상태 안내 섹션에 사용되는 브랜드 색상
  • Profile DORMANT 상태 휴면 해제 섹션 구현

    • GetUserInfoUseCase 통해 사용자 role 확인
    • isDormant 상태일 때 네비게이션바 하단에 휴면 해제 섹션 표시
    • "휴면 해제" 버튼 클릭 시 ActivateUserUseCase 호출
    • 성공 시 매칭 메인 탭으로 이동 및 토스트 표시
  • Swift 6 concurrency 대응

    • NavigationCommandConsumable 프로토콜에 @mainactor 추가
    • 프로토콜을 채택하는 모든 ViewModel이 MainActor 격리 보장
  • Withdraw 모듈 패턴 리팩토링

    • WithdrawViewFactory에서 ViewModel 생성하지 않도록 변경
    • View init에서 UseCase를 받아 ViewModel 생성
    • Profile 모듈과 동일한 패턴으로 통일

💬 참고 사항

  • Swift 6 concurrency 모드에서 @mainactor 격리 요구사항 준수
  • Profile과 Withdraw 모듈 간 의존성 주입 패턴 일관성 확보
  • DORMANT → ACTIVE 전환 시 NavigationCommand 체이닝으로 라우팅 + 토스트 처리

📸 스크린샷(Optional)

Profile DORMANT 상태
Feb-21-2026 17-01-04

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 프로필에서 휴면 계정 상태 표시 및 휴면 계정 활성화 기능 추가
    • 디자인 시스템에 Info Light / Info Dark 색상 변형 추가로 시각적 일관성 향상
  • 개선

    • 프로필 및 내비게이션 흐름 관련 제어가 강화되어 더 일관된 화면 이동 및 상태 처리가 가능해짐

- InfoLight (#F0F6FF), InfoDark (#0C4596) colorset 추가
- Color.swift에 Info 색상 extension 추가
- Swift 6 concurrency 지원을 위해 @mainactor 추가
- 프로토콜을 채택하는 모든 ViewModel이 MainActor에서 실행 보장
- ProfileViewModel에 GetUserInfoUseCase 주입 및 NavigationCommand 시스템 추가
- isDormant 상태 추가 및 getUserRole 메서드 구현
- DORMANT 상태일 때 휴면 해제 섹션 UI 표시
- 휴면 해제 성공 시 매칭 메인 탭으로 이동 및 토스트 표시
- WithdrawViewFactory에서 ViewModel을 직접 생성하지 않도록 변경
- View의 init에서 UseCase를 받아 ViewModel 생성
- Profile 모듈과 동일한 패턴으로 통일
@hsw1920 hsw1920 self-assigned this Feb 21, 2026
@hsw1920 hsw1920 added the ✨ feature 새로운 기능 label Feb 21, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 21, 2026

Walkthrough

프로필에 사용자 정보 조회와 비활성 사용자 활성화 흐름을 추가하고, 디자인 시스템에 infoLight/infoDark 색상 자산과 Color 확장을 도입했습니다. 네비게이션용 NavigationCommandConsumable 프로토콜과 여러 뷰 초기화/의존성 주입 경로가 조정되었습니다.

Changes

Cohort / File(s) Summary
색상 자산
Presentation/DesignSystem/Resources/Colors.xcassets/InfoDark.colorset/Contents.json, Presentation/DesignSystem/Resources/Colors.xcassets/InfoLight.colorset/Contents.json
InfoLight / InfoDark 컬러 자산(Contents.json) 추가. sRGB RGBA 값 및 메타데이터 포함.
색상 API 확장
Presentation/DesignSystem/Sources/Color.swift
ColorShapeStyle where Self == ColorinfoLight/infoDark 접근자 추가.
프로필 뷰 및 팩토리 변경
Presentation/Feature/Profile/Sources/ProfileView.swift, Presentation/Feature/Profile/Sources/ProfileViewFactory.swift, Presentation/Feature/Home/Sources/HomeView.swift
GetUserInfoUseCase 의존성 추가(팩토리/초기화/호출 경로에 전달). HomeView에서 프로필 팩토리 호출에 파라미터 전달 추가.
프로필 뷰모델 업데이트
Presentation/Feature/Profile/Sources/ProfileViewModel.swift
getUserInfoUseCase 주입, isDormant 상태·activateDormantUser 액션·getUserRole/활성화 핸들러 추가. NavigationCommandConsumable 채택 및 navigationCommand 노출 추가.
네비게이션 프로토콜
Presentation/Router/Sources/NavigationCommand.swift
@MainActor 적용 NavigationCommandConsumable 프로토콜 추가 (get/set navigationCommand).
탈퇴(Withdraw) 흐름 재배치
Presentation/Feature/Withdraw/Sources/WithdrawIntro/WithdrawIntroView.swift, .../WithdrawIntroViewModel.swift, .../WithdrawReason/WithdrawReasonView.swift, .../WithdrawViewFactory.swift
WithdrawIntroView 초기화가 뷰모델 주입→유스케이스 직접 주입으로 변경, WithdrawIntroViewModel에 @MainActor 추가, WithdrawReasonView가 무인자 이니셜라이저로 변경 및 팩토리 호출 갱신.
계정 설정 뷰모델
Presentation/Feature/AccountSettings/Sources/AccountSettingsViewModel.swift
@MainActor 애트리뷰트 추가(메인 액터 격리).

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant ProfileView as ProfileView
    participant ProfileVM as ProfileViewModel
    participant GetUserInfoUC as GetUserInfoUseCase
    participant ActivateUC as ActivateUserUseCase
    participant Router as Router

    User->>ProfileView: 화면 진입 (onAppear)
    ProfileView->>ProfileVM: onAppear 트리거

    par parallel
        ProfileVM->>GetUserInfoUC: getUserRole()
        GetUserInfoUC-->>ProfileVM: 역할 및 dormant 상태 응답
        ProfileVM->>ProfileVM: isDormant 업데이트
    and
        ProfileVM->>ProfileVM: unread notifications 조회
    end

    alt isDormant == true
        ProfileView->>User: 비활성 사용자 섹션 노출
        User->>ProfileView: 활성화 버튼 탭
        ProfileView->>ProfileVM: activateDormantUser 액션
        ProfileVM->>ActivateUC: activate 요청
        ActivateUC-->>ProfileVM: 성공 응답
        ProfileVM->>Router: navigationCommand 설정/네비게이션 실행
        Router-->>User: 완료 토스트/화면 전환
    else
        ProfileView->>User: 일반 프로필 표시
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

🪄 refactor

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 주요 변경 사항을 명확히 나타냅니다: 프로필 화면에서 휴면 해제 기능 구현.
Description check ✅ Passed PR 설명이 템플릿 구조를 따르며 변경 사항, 참고 사항, 스크린샷을 포함하고 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/PC-1809

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

Caution

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

⚠️ Outside diff range comments (1)
Presentation/Feature/Withdraw/Sources/WithdrawIntro/WithdrawIntroViewModel.swift (1)

50-52: ⚠️ Potential issue | 🟡 Minor

print(error) — 디버그 로그 잔존

catch 블록에 print(error)만 존재해, 휴면 전환 실패 시 사용자에게 아무런 피드백이 없습니다. 릴리스 빌드에서도 콘솔 출력이 남고, 실제 오류 처리 로직이 없어 사일런트 실패로 이어질 수 있습니다.

🛡️ 오류 처리 개선 제안
    } catch {
-     print(error)
+     // TODO: 오류 상태를 뷰에 노출하거나 구조화된 로깅 사용
+     setNavigationCommand(.none) // 또는 에러 alert 표시
    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Presentation/Feature/Withdraw/Sources/WithdrawIntro/WithdrawIntroViewModel.swift`
around lines 50 - 52, The catch block in WithdrawIntroViewModel currently just
calls print(error); replace this with real error handling: record the error
using your app logger/analytics (e.g., Logger or an analytics.trackError call),
set a user-facing state on WithdrawIntroViewModel (e.g., an `@Published`
errorMessage or showError boolean) so the view can present a localized alert,
and remove any raw console prints so no debug output remains in release builds;
ensure the error is also gracefully handled (fallback flow or noop with user
feedback) in the function where the try/catch occurs.
🧹 Nitpick comments (3)
Presentation/Feature/Withdraw/Sources/WithdrawIntro/WithdrawIntroViewModel.swift (1)

47-49: await MainActor.run { } 불필요 — 제거 가능

WithdrawIntroViewModel 자체가 @MainActor로 선언되어 있으므로, requestDormancy() 역시 Main Actor에서 실행됩니다. await setUserDormantUseCase.execute() 이후 재개(resume)될 때도 Swift 런타임이 자동으로 Main Actor로 돌아오기 때문에, await MainActor.run { } 래핑은 아무 효과가 없습니다.

♻️ 불필요한 MainActor.run 제거 제안
  _ = try await setUserDormantUseCase.execute()
- await MainActor.run {
-   isShowingDormantCompletionAlert = true
- }
+ isShowingDormantCompletionAlert = true
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Presentation/Feature/Withdraw/Sources/WithdrawIntro/WithdrawIntroViewModel.swift`
around lines 47 - 49, The await MainActor.run { isShowingDormantCompletionAlert
= true } wrapper is redundant because WithdrawIntroViewModel is `@MainActor` and
requestDormancy() resumes on the main actor after await
setUserDormantUseCase.execute(); remove the MainActor.run call and assign
isShowingDormantCompletionAlert = true directly inside requestDormancy() (or
ensure requestDormancy() is annotated `@MainActor`) so the property mutation
happens on the main actor without the extra wrapper.
Presentation/Feature/Profile/Sources/ProfileView.swift (1)

77-104: 불필요한 외부 HStack 제거 가능

dormantSection의 바깥쪽 HStack(spacing: 0)은 내부 HStack만을 감싸고 추가적인 레이아웃 역할을 하지 않습니다. .padding(.horizontal, 20).frame(maxWidth: .infinity)를 내부 HStack에 직접 적용하면 불필요한 중첩을 제거할 수 있습니다.

♻️ 중첩 HStack 제거 제안
 private var dormantSection: some View {
-  HStack(spacing: 0) {
-    HStack(spacing: 0) {
-      Text("다른 사람들에게\n프로필이 노출되지 않아요.")
-        .multilineTextAlignment(.leading)
-        .pretendard(.body_S_M)
-        .foregroundStyle(Color.infoDark)
-
-      Spacer()
-
-      Button(
-        action: { viewModel.handleAction(.activateDormantUser) },
-        label: {
-          Text("휴면 해제")
-            .pretendard(.caption_M_M)
-            .foregroundStyle(Color.grayscaleWhite)
-            .padding(.vertical, 8)
-            .padding(.horizontal, 16)
-            .background(RoundedRectangle(cornerRadius: 4).fill(.infoDark))
-        }
-      )
-    }
-    .padding(.all, 14)
-    .background(RoundedRectangle(cornerRadius: 8).fill(.infoLight))
-  }
-  .padding(.horizontal, 20)
-  .frame(maxWidth: .infinity)
+  HStack(spacing: 0) {
+    Text("다른 사람들에게\n프로필이 노출되지 않아요.")
+      .multilineTextAlignment(.leading)
+      .pretendard(.body_S_M)
+      .foregroundStyle(Color.infoDark)
+
+    Spacer()
+
+    Button(
+      action: { viewModel.handleAction(.activateDormantUser) },
+      label: {
+        Text("휴면 해제")
+          .pretendard(.caption_M_M)
+          .foregroundStyle(Color.grayscaleWhite)
+          .padding(.vertical, 8)
+          .padding(.horizontal, 16)
+          .background(RoundedRectangle(cornerRadius: 4).fill(.infoDark))
+      }
+    )
+  }
+  .padding(.all, 14)
+  .background(RoundedRectangle(cornerRadius: 8).fill(.infoLight))
+  .padding(.horizontal, 20)
+  .frame(maxWidth: .infinity)
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Presentation/Feature/Profile/Sources/ProfileView.swift` around lines 77 -
104, The outer HStack in dormantSection is redundant; remove the wrapping
HStack(spacing: 0) and apply the .padding(.horizontal, 20) and .frame(maxWidth:
.infinity) modifiers directly to the remaining inner HStack so layout and
spacing remain unchanged. Locate the dormantSection computed property and delete
the outer container, keeping the inner HStack that contains the Text and Button
(including the Button action viewModel.handleAction(.activateDormantUser)), plus
its .padding(.all, 14) and .background, then add the horizontal padding and
maxWidth frame to that inner HStack.
Presentation/Feature/Profile/Sources/ProfileViewModel.swift (1)

77-80: getUserRole()checkUnreadNotifications()를 병렬 실행으로 개선 가능

두 호출은 서로 독립적인 네트워크 요청이지만 현재 순차 실행됩니다. 별도 Task로 분리하면 두 요청이 동시에 시작되어 화면 반응성이 개선됩니다.

⚡ 병렬 실행 제안
-    Task {
-      await getUserRole()
-      await checkUnreadNotifications()
-    }
+    Task { await getUserRole() }
+    Task { await checkUnreadNotifications() }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Presentation/Feature/Profile/Sources/ProfileViewModel.swift` around lines 77
- 80, Replace the sequential awaits so getUserRole() and
checkUnreadNotifications() run concurrently: inside the existing Task in
ProfileViewModel (or the surrounding async context) start both operations in
parallel (e.g., use `async let userRole = getUserRole()` and `async let unread =
checkUnreadNotifications()` or spawn two separate Tasks) then await both
results, and ensure any state mutations happen on the main actor; also propagate
or handle errors from each call separately so one failure doesn't block the
other.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@Presentation/DesignSystem/Resources/Colors.xcassets/InfoDark.colorset/Contents.json`:
- Around line 1-20: InfoDark and InfoLight assets only define a "universal"
appearance, so add explicit dark-mode variants to each Colors.xcassets
Contents.json (e.g., in InfoDark.colorset/Contents.json and
InfoLight.colorset/Contents.json) by adding an appearances array or extra color
entries with "appearance" : [{"appearance": "luminosity","value":"dark"}] (or
the Xcode equivalent) and supply alternate sRGB color components appropriate for
dark mode; keep the existing universal/light color as the default, ensure keys
like "color-space" and "components" are preserved, and validate the chosen
dark/light pairs meet accessibility contrast requirements.

In `@Presentation/Feature/Withdraw/Sources/WithdrawIntro/WithdrawIntroView.swift`:
- Line 15: The `@State` property viewModel is missing the private access modifier;
change the declaration of viewModel in WithdrawIntroView (the `@State` var
viewModel: WithdrawIntroViewModel) to be private (e.g., `@State` private var
viewModel: WithdrawIntroViewModel) and update any internal references within
WithdrawIntroView accordingly so external code cannot directly mutate the state,
satisfying the private_swiftui_state lint rule.

In `@Presentation/Router/Sources/NavigationCommand.swift`:
- Around line 106-109: The protocol-level `@MainActor` on
NavigationCommandConsumable causes all conformers to be main-actor isolated but
AccountSettingsViewModel currently lacks an explicit `@MainActor`; update
AccountSettingsViewModel to add `@MainActor` alongside its existing `@Observable`
(or alternately remove `@MainActor` from NavigationCommandConsumable if you intend
mixed isolation), and ensure the class still declares conformance to
NavigationCommandConsumable so the navigationCommand property remains correct.

---

Outside diff comments:
In
`@Presentation/Feature/Withdraw/Sources/WithdrawIntro/WithdrawIntroViewModel.swift`:
- Around line 50-52: The catch block in WithdrawIntroViewModel currently just
calls print(error); replace this with real error handling: record the error
using your app logger/analytics (e.g., Logger or an analytics.trackError call),
set a user-facing state on WithdrawIntroViewModel (e.g., an `@Published`
errorMessage or showError boolean) so the view can present a localized alert,
and remove any raw console prints so no debug output remains in release builds;
ensure the error is also gracefully handled (fallback flow or noop with user
feedback) in the function where the try/catch occurs.

---

Duplicate comments:
In
`@Presentation/DesignSystem/Resources/Colors.xcassets/InfoLight.colorset/Contents.json`:
- Around line 1-20: InfoLight.colorset의 Contents.json에 다크 모드 변형(color appearance
for dark) 정의가 빠져있습니다; InfoDark.colorset과 동일한 맥락으로 두 색상이 함께 사용되므로
InfoLight.colorset의 "colors" 배열 항목에 appearance:"dark" 또는
"appearances":[{"appearance":"luminosity","value":"dark"}] 같은 다크 변형을 추가해
주시고(InfoDark.colorset에 사용된 명명·값을 참고), alpha/rgba 값과 색 공간("color-space")이 일치하는지
확인하여 필요 시 두 색상 세트를 동기화하세요.

---

Nitpick comments:
In `@Presentation/Feature/Profile/Sources/ProfileView.swift`:
- Around line 77-104: The outer HStack in dormantSection is redundant; remove
the wrapping HStack(spacing: 0) and apply the .padding(.horizontal, 20) and
.frame(maxWidth: .infinity) modifiers directly to the remaining inner HStack so
layout and spacing remain unchanged. Locate the dormantSection computed property
and delete the outer container, keeping the inner HStack that contains the Text
and Button (including the Button action
viewModel.handleAction(.activateDormantUser)), plus its .padding(.all, 14) and
.background, then add the horizontal padding and maxWidth frame to that inner
HStack.

In `@Presentation/Feature/Profile/Sources/ProfileViewModel.swift`:
- Around line 77-80: Replace the sequential awaits so getUserRole() and
checkUnreadNotifications() run concurrently: inside the existing Task in
ProfileViewModel (or the surrounding async context) start both operations in
parallel (e.g., use `async let userRole = getUserRole()` and `async let unread =
checkUnreadNotifications()` or spawn two separate Tasks) then await both
results, and ensure any state mutations happen on the main actor; also propagate
or handle errors from each call separately so one failure doesn't block the
other.

In
`@Presentation/Feature/Withdraw/Sources/WithdrawIntro/WithdrawIntroViewModel.swift`:
- Around line 47-49: The await MainActor.run { isShowingDormantCompletionAlert =
true } wrapper is redundant because WithdrawIntroViewModel is `@MainActor` and
requestDormancy() resumes on the main actor after await
setUserDormantUseCase.execute(); remove the MainActor.run call and assign
isShowingDormantCompletionAlert = true directly inside requestDormancy() (or
ensure requestDormancy() is annotated `@MainActor`) so the property mutation
happens on the main actor without the extra wrapper.

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.

🧹 Nitpick comments (1)
Presentation/Feature/AccountSettings/Sources/AccountSettingsViewModel.swift (1)

155-179: @MainActor 클래스 내의 async 메서드에서 await MainActor.run { } 호출이 불필요합니다.

클래스에 @MainActor가 선언된 이후, 클래스의 모든 메서드(비동기 포함)는 암묵적으로 @MainActor로 격리됩니다. @MainActor async 함수 내에서는 await 일시 중단 후 재개될 때도 항상 Main Actor 위에서 실행되므로, await MainActor.run { } 래퍼는 중복입니다.

대상 위치:

  • setDormancy: Lines 161-167, 175-178
  • syncAccountSettingsFromUserInfo: Lines 184-186
  • handleConfirmLogoutButton: Lines 241-245, 248-250
♻️ 불필요한 `await MainActor.run` 제거 제안
  private func setDormancy(enabled isEnabled: Bool) async {
    do {
      if isEnabled {
        _ = try await setUserDormantUseCase.execute()
      } else {
        _ = try await activateUserUseCase.execute()
-       await MainActor.run {
-         setNavigationCommand(
-           .setRoute(.home)
-           .withSwitchTab(.home)
-           .withToast(.dormancyDeactivated)
-         )
-       }
+       setNavigationCommand(
+         .setRoute(.home)
+         .withSwitchTab(.home)
+         .withToast(.dormancyDeactivated)
+       )
      }
      await syncAccountSettingsFromUserInfo()
    } catch {
      print(error)
      await syncAccountSettingsFromUserInfo()
    }
    
-   await MainActor.run {
-     state.dormancy.finishUpdate()
-     state.dormancy.hideConfirmAlert()
-   }
+   state.dormancy.finishUpdate()
+   state.dormancy.hideConfirmAlert()
  }
  
  private func syncAccountSettingsFromUserInfo() async {
    do {
      let userInfo = try await getUserInfoUseCase.execute()
-     await MainActor.run {
-       apply(userInfo: userInfo)
-     }
+     apply(userInfo: userInfo)
    } catch {
      print(error)
    }
  }
  func handleConfirmLogoutButton() {
    Task {
      do {
        _ = try await patchLogoutUseCase.execute()
-       await MainActor.run {
-         showLogoutAlert = false
-         clearUserDataPreservingFCMToken()
-         setNavigationCommand(.setRoute(.splash))
-       }
+       showLogoutAlert = false
+       clearUserDataPreservingFCMToken()
+       setNavigationCommand(.setRoute(.splash))
      } catch {
        print(error)
-       await MainActor.run {
-         showLogoutAlert = false
-       }
+       showLogoutAlert = false
      }
    }
  }

Also applies to: 181-190, 237-253

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Presentation/Feature/AccountSettings/Sources/AccountSettingsViewModel.swift`
around lines 155 - 179, The class is already `@MainActor` so remove the redundant
await MainActor.run { ... } wrappers inside the async methods: in setDormancy
remove the MainActor.run blocks that wrap setNavigationCommand(...) and the
final state.dormancy.finishUpdate()/hideConfirmAlert() calls and call those
statements directly; do the same in syncAccountSettingsFromUserInfo and
handleConfirmLogoutButton (remove await MainActor.run and execute the UI/state
updates and navigation directly). Ensure you keep await on any async
useCase.execute()/sync calls but eliminate the unnecessary MainActor.run
invocations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Presentation/Feature/AccountSettings/Sources/AccountSettingsViewModel.swift`:
- Around line 155-179: The class is already `@MainActor` so remove the redundant
await MainActor.run { ... } wrappers inside the async methods: in setDormancy
remove the MainActor.run blocks that wrap setNavigationCommand(...) and the
final state.dormancy.finishUpdate()/hideConfirmAlert() calls and call those
statements directly; do the same in syncAccountSettingsFromUserInfo and
handleConfirmLogoutButton (remove await MainActor.run and execute the UI/state
updates and navigation directly). Ensure you keep await on any async
useCase.execute()/sync calls but eliminate the unnecessary MainActor.run
invocations.

@hsw1920 hsw1920 merged commit c0d3be8 into main Feb 21, 2026
1 check passed
@hsw1920 hsw1920 deleted the feat/PC-1809 branch February 21, 2026 08:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feature 새로운 기능

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant