Skip to content

[FEAT] 대시보드 UI 구성#18

Merged
Sangyoon98 merged 3 commits intodevfrom
SPM-283
Oct 29, 2025
Merged

[FEAT] 대시보드 UI 구성#18
Sangyoon98 merged 3 commits intodevfrom
SPM-283

Conversation

@Sangyoon98
Copy link
Copy Markdown
Member

@Sangyoon98 Sangyoon98 commented Oct 29, 2025

📝 Summary

🙏 Question & PR point

📬 Reference

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 대시보드 뷰 및 주문 항목 표시 추가(요약 목록, 상세 이동)
    • 주문 항목 UI 컴포넌트 추가
  • 개선 사항

    • 사용자 프로필 확장(직급, 부서, 지점) 및 로그인 흐름에 프로필 병합/보정 추가
    • 인증·토큰 처리 강화(갱신 시 프로필 보존)
    • 입력 필드 제출 동작 지원 추가(submit 라벨·제출 콜백)
  • UI/UX

    • 회원가입 키보드 네비게이션 개선(포커스 이동)
    • 아이콘 추가(금액, 경고)

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 29, 2025

Warning

Rate limit exceeded

@Sangyoon98 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 3 minutes and 25 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 7e5bc8c and fd3127c.

📒 Files selected for processing (3)
  • SampoomManagement/App/ContentView.swift (3 hunks)
  • SampoomManagement/Core/Resources/StringResources.swift (1 hunks)
  • SampoomManagement/Features/Dashboard/UI/DashboardView.swift (1 hunks)

Walkthrough

대시보드 UI를 ViewModel 기반으로 재구성하고, 사용자 프로필에 position/workspace/branch 필드를 추가했으며, CommonTextField에 제출 제어를 도입하고 주문 항목 컴포넌트 및 관련 대시보드 상태·이벤트 파일을 추가했습니다.

Changes

Cohort / File(s) 변경 요약
Content & Dashboard 통합
SampoomManagement/App/ContentView.swift, SampoomManagement/App/Screens/DashboardScreen.swift
ContentView에서 DashboardScreen을 제거하고 DashboardView를 NavigationStack과 DashboardViewModel로 사용하도록 변경; 탭 전환 및 경로(App의 navigationPath) 연동 콜백 추가; 기존 DashboardScreen 파일 삭제
Dashboard UI / VM / State / Event
SampoomManagement/Features/Dashboard/UI/DashboardView.swift, SampoomManagement/Features/Dashboard/UI/DashboardViewModel.swift, SampoomManagement/Features/Dashboard/UI/DashboardUiState.swift, SampoomManagement/Features/Dashboard/UI/DashboardUiEvent.swift
DashboardView(새로운 뷰), DashboardViewModel(데이터 로딩 및 이벤트 처리), DashboardUiState(immutable copy 패턴), DashboardUiEvent(로드/재시도 이벤트) 추가
주문 항목 컴포넌트
SampoomManagement/Core/UI/Components/OrderItem.swift
재사용 가능한 주문 항목 버튼 컴포넌트 추가 (주문 제목, 기관명, 생성일, 상태 표시 및 클릭 콜백)
CommonTextField 제출 제어
SampoomManagement/Core/UI/Components/CommonTextField.swift
submitLabel 및 onSubmit 속성·초기자 추가, SecureField/TextField에 .submitLabel 및 .onSubmit 연결
회원가입 포커스 네비게이션
SampoomManagement/Features/Auth/UI/SignUpView.swift
FocusState 기반 필드 포커스 전환 도입 및 CommonTextField의 submitLabel/onSubmit 사용으로 키보드 내비게이션 개선
인증 모델·매퍼·저장소 변경
SampoomManagement/Features/Auth/Domain/Models/User.swift, SampoomManagement/Features/Auth/Data/Mappers/AuthMappers.swift, SampoomManagement/Features/Auth/Data/Local/Preferences/AuthPreferences.swift, SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift
User 모델에 position/workspace/branch 필드 추가; 매퍼에 프로필 매핑 및 mergeWith 구현; AuthPreferences에 새 필드 저장/복구/삭제 로직 추가; signIn 흐름 변경(토큰 저장 → 프로필 조회 및 병합 → 병합된 사용자 저장, 실패 시 롤백)
Auth API / DTO 변경
SampoomManagement/Features/Auth/Data/Remote/API/AuthAPI.swift, SampoomManagement/Features/Auth/Data/Remote/DTO/GetProfileResponseDTO.swift, SampoomManagement/Features/Auth/Data/Remote/DTO/LoginResponseDTO.swift
AuthAPI에 getProfile() 추가; GetProfileResponseDTO 추가; LoginResponseDTO.userName을 옵셔널로 변경
토큰 갱신 시 사용자 필드 유지
SampoomManagement/Core/Network/TokenRefreshService.swift
TokenRefreshService에서 토큰 갱신 시 기존 user's position/workspace/branch 값을 새 User에 보존하도록 업데이트
새 자산 추가
SampoomManagement/Resources/Assets.xcassets/money.imageset/Contents.json, SampoomManagement/Resources/Assets.xcassets/warning.imageset/Contents.json
money.svg 및 warning.svg 용 Contents.json 추가

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ContentView
    participant DashboardView
    participant DashboardViewModel
    participant GetOrderUseCase

    User->>ContentView: 앱 로드
    ContentView->>DashboardView: DashboardView 표시 (NavigationStack)
    DashboardView->>DashboardViewModel: init(getOrderUseCase)
    DashboardViewModel->>GetOrderUseCase: execute()
    GetOrderUseCase-->>DashboardViewModel: 주문 목록 반환
    DashboardViewModel->>DashboardView: @Published uiState 변경
    DashboardView->>User: 주문 목록 렌더링

    User->>DashboardView: Pull-to-Refresh
    DashboardView->>DashboardViewModel: onEvent(.loadDashboard)
    DashboardViewModel->>GetOrderUseCase: execute()
    DashboardViewModel-->>DashboardView: 업데이트된 uiState
    DashboardView->>User: 화면 갱신
Loading
sequenceDiagram
    participant User
    participant AuthRepositoryImpl
    participant AuthAPI
    participant AuthPreferences
    participant AuthMappers

    User->>AuthRepositoryImpl: signIn(credentials)
    AuthRepositoryImpl->>AuthAPI: login()
    AuthAPI-->>AuthRepositoryImpl: LoginResponseDTO
    AuthRepositoryImpl->>AuthPreferences: 토큰 저장 (access/refresh)
    rect rgb(220,235,255)
      note right of AuthRepositoryImpl: 프로필 조회 및 병합 흐름
      AuthRepositoryImpl->>AuthAPI: getProfile()
      AuthAPI-->>AuthRepositoryImpl: GetProfileResponseDTO
      AuthRepositoryImpl->>AuthMappers: profile.toModel() / mergeWith(...)
      AuthMappers-->>AuthRepositoryImpl: 병합된 User
    end
    AuthRepositoryImpl->>AuthPreferences: 병합된 User 저장
    AuthRepositoryImpl-->>User: 완성된 User 반환
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • 추가 검토 필요 항목:
    • signIn의 프로필 조회 및 실패 시 롤백(토큰/키체인 정합성)
    • User 모델 확장으로 인한 모든 초기화 지점/매퍼 일관성
    • DashboardViewModel의 에러/로딩 상태 처리와 UI 바인딩
    • ContentView에서의 탭 전환 및 navigationPath 조작(주문 상세로 이동) 동작 검증
    • CommonTextField의 submit 동작이 SignUpView의 FocusState 흐름과 충돌 없는지

Possibly related PRs

Suggested reviewers

  • yangjiseonn
  • vivivim
  • Lee-Jong-Jin

Poem

🐰 새 뷰와 VM으로 깡총깡총,
프로필은 늘어나고 키보드는 춤추네,
주문도 항목으로 반짝반짝,
토끼가 기쁜 건 코드가 정돈됐기 때문,
훌쩍—배포 준비 됐어! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.65% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed 제목 "[FEAT] 대시보드 UI 구성"은 변경 세트의 주요 목표를 명확하게 반영하고 있습니다. DashboardView, DashboardViewModel, DashboardUiState, DashboardUiEvent 등 새로운 대시보드 UI 컴포넌트들을 추가하고, ContentView에서 기존 DashboardScreen을 새로운 구현으로 교체하는 것이 핵심 변경사항입니다. 인증 플로우 개선(사용자 정보 필드 확장, 프로필 fetch 추가)과 UI 컴포넌트 개선(CommonTextField, OrderItem, SignUpView)은 모두 대시보드 기능을 지원하기 위한 보조적 변경사항으로 볼 수 있습니다. 제목은 간결하고 구체적이며, 팀원이 커밋 히스토리를 스캔할 때 주요 변경사항을 쉽게 이해할 수 있습니다.

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
Copy Markdown
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

🧹 Nitpick comments (5)
SampoomManagement/Features/Auth/UI/SignUpView.swift (1)

150-155: 마지막 필드가 적절하게 구현되었습니다.

비밀번호 확인 필드에서 .done 레이블을 사용하고 제출 시 키보드를 닫는 것은 적절한 UX 패턴입니다. 사용자가 명시적으로 회원가입 버튼을 눌러 제출하도록 하는 현재 디자인은 실수로 인한 제출을 방지하는 장점이 있습니다.

선택적으로, 마지막 필드에서 자동으로 폼을 제출하려면 다음과 같이 수정할 수 있습니다:

-                    onSubmit: { focusedField = nil }
+                    onSubmit: { 
+                        focusedField = nil
+                        if viewModel.uiState.isValid {
+                            viewModel.submit()
+                        }
+                    }

다만 현재의 명시적 버튼 클릭 방식도 유효한 디자인 선택입니다.

SampoomManagement/Features/Auth/Domain/Models/User.swift (1)

18-20: 프로필 필드의 옵셔널 타입 사용 고려

새로 추가된 position, workspace, branch 필드가 non-optional String으로 정의되었습니다. 하지만 GetProfileResponseDTO에서는 이 필드들이 옵셔널이며, AuthPreferences에서는 누락된 경우 빈 문자열로 기본값 처리하고 있습니다.

"값이 설정되지 않음"과 "빈 문자열"을 구분해야 하는 경우, 이 필드들을 String?으로 변경하는 것을 고려해보세요. 현재 구현은 일관성 있게 빈 문자열 기본값 전략을 사용하고 있지만, 의미적으로 nil이 더 명확할 수 있습니다.

SampoomManagement/Features/Dashboard/UI/DashboardViewModel.swift (1)

30-47: 매직 넘버를 상수로 추출하는 것을 고려해보세요.

Line 36에서 최근 주문 목록을 5개로 제한하는데, 이 값을 상수로 추출하면 유지보수가 더 쉬워집니다.

다음과 같이 리팩토링할 수 있습니다:

 @MainActor
 class DashboardViewModel: ObservableObject {
     @Published var uiState = DashboardUiState()
     
     private let getOrderUseCase: GetOrderUseCase
+    private let maxRecentOrders = 5
     
     init(getOrderUseCase: GetOrderUseCase) {
         self.getOrderUseCase = getOrderUseCase
         loadOrderList()
     }

그리고 사용 부분:

                 let orderList = try await getOrderUseCase.execute()
                 uiState = uiState.copy(
-                    orderList: Array(orderList.items.prefix(5)),
+                    orderList: Array(orderList.items.prefix(maxRecentOrders)),
                     dashboardLoading: false,
                     dashboardError: nil
                 )
SampoomManagement/Features/Dashboard/UI/DashboardView.swift (2)

27-32: TODO 주석을 해결해야 합니다.

역할 기반 직원 버튼 기능이 아직 구현되지 않았습니다.

이 TODO를 추적하기 위한 이슈를 생성하도록 도와드릴까요?


43-46: 임시 로그아웃 버튼을 적절한 위치로 이동하세요.

로그아웃 버튼이 임시로 메인 컨텐츠 영역에 배치되어 있습니다. 일반적으로 설정 화면이나 프로필 메뉴로 이동하는 것이 좋습니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 041e976 and 9b46102.

⛔ Files ignored due to path filters (2)
  • SampoomManagement/Resources/Assets.xcassets/money.imageset/money.svg is excluded by !**/*.svg
  • SampoomManagement/Resources/Assets.xcassets/warning.imageset/warning.svg is excluded by !**/*.svg
📒 Files selected for processing (19)
  • SampoomManagement/App/ContentView.swift (1 hunks)
  • SampoomManagement/App/Screens/DashboardScreen.swift (0 hunks)
  • SampoomManagement/Core/Network/TokenRefreshService.swift (1 hunks)
  • SampoomManagement/Core/UI/Components/CommonTextField.swift (4 hunks)
  • SampoomManagement/Core/UI/Components/OrderItem.swift (1 hunks)
  • SampoomManagement/Features/Auth/Data/Local/Preferences/AuthPreferences.swift (5 hunks)
  • SampoomManagement/Features/Auth/Data/Mappers/AuthMappers.swift (1 hunks)
  • SampoomManagement/Features/Auth/Data/Remote/API/AuthAPI.swift (1 hunks)
  • SampoomManagement/Features/Auth/Data/Remote/DTO/GetProfileResponseDTO.swift (1 hunks)
  • SampoomManagement/Features/Auth/Data/Remote/DTO/LoginResponseDTO.swift (1 hunks)
  • SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (2 hunks)
  • SampoomManagement/Features/Auth/Domain/Models/User.swift (1 hunks)
  • SampoomManagement/Features/Auth/UI/SignUpView.swift (7 hunks)
  • SampoomManagement/Features/Dashboard/UI/DashboardUiEvent.swift (1 hunks)
  • SampoomManagement/Features/Dashboard/UI/DashboardUiState.swift (1 hunks)
  • SampoomManagement/Features/Dashboard/UI/DashboardView.swift (1 hunks)
  • SampoomManagement/Features/Dashboard/UI/DashboardViewModel.swift (1 hunks)
  • SampoomManagement/Resources/Assets.xcassets/money.imageset/Contents.json (1 hunks)
  • SampoomManagement/Resources/Assets.xcassets/warning.imageset/Contents.json (1 hunks)
💤 Files with no reviewable changes (1)
  • SampoomManagement/App/Screens/DashboardScreen.swift
🧰 Additional context used
🧬 Code graph analysis (9)
SampoomManagement/Core/UI/Components/OrderItem.swift (1)
SampoomManagement/Core/Utilities/OrderFormatter.swift (1)
  • buildOrderTitle (11-38)
SampoomManagement/Features/Auth/Data/Local/Preferences/AuthPreferences.swift (3)
SampoomManagement/Features/Auth/Data/Local/Preferences/KeychainManager.swift (3)
  • save (24-43)
  • delete (73-85)
  • get (45-71)
SampoomManagement/Core/Network/TokenRefreshService.swift (1)
  • refreshToken (17-65)
SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (1)
  • refreshToken (89-125)
SampoomManagement/Features/Auth/Data/Remote/API/AuthAPI.swift (1)
SampoomManagement/Core/Network/NetworkManager.swift (1)
  • request (21-59)
SampoomManagement/Features/Dashboard/UI/DashboardViewModel.swift (1)
SampoomManagement/Features/Dashboard/UI/DashboardUiState.swift (1)
  • copy (25-35)
SampoomManagement/Features/Dashboard/UI/DashboardView.swift (1)
SampoomManagement/Features/Dashboard/UI/DashboardViewModel.swift (1)
  • onEvent (23-28)
SampoomManagement/App/ContentView.swift (2)
SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (1)
  • signOut (77-87)
SampoomManagement/Features/Auth/UI/AuthViewModel.swift (1)
  • signOut (40-50)
SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (4)
SampoomManagement/Features/Auth/Data/Remote/API/AuthAPI.swift (2)
  • login (19-33)
  • getProfile (97-104)
SampoomManagement/Features/Auth/Data/Mappers/AuthMappers.swift (3)
  • toModel (11-23)
  • toModel (27-39)
  • mergeWith (43-55)
SampoomManagement/Features/Auth/Data/Local/Preferences/AuthPreferences.swift (2)
  • saveToken (51-61)
  • saveUser (25-49)
SampoomManagement/Core/Network/TokenRefreshService.swift (1)
  • refreshToken (17-65)
SampoomManagement/Features/Auth/Data/Mappers/AuthMappers.swift (2)
SampoomManagement/Core/Network/TokenRefreshService.swift (1)
  • refreshToken (17-65)
SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (1)
  • refreshToken (89-125)
SampoomManagement/Features/Auth/UI/SignUpView.swift (1)
SampoomManagement/Features/Auth/UI/SignUpViewModel.swift (6)
  • updateName (23-26)
  • updateBranch (29-32)
  • updatePosition (35-38)
  • updateEmail (41-44)
  • updatePassword (47-53)
  • updatePasswordCheck (56-59)
🪛 SwiftLint (0.57.0)
SampoomManagement/Features/Dashboard/UI/DashboardView.swift

[Warning] 27-27: TODOs should be resolved (role-based employee button)

(todo)

🔇 Additional comments (25)
SampoomManagement/Resources/Assets.xcassets/warning.imageset/Contents.json (1)

1-12: 검증 완료 - 이슈 없음

SVG 파일(warning.svg)이 올바른 위치에 존재하며, Contents.json에서 정확히 참조되고 있습니다. DashboardView.swift(line 94)에서 해당 자산이 대시보드 UI에 실제로 사용되고 있음이 확인되었습니다. 모든 구조와 참조가 정상입니다.

SampoomManagement/Resources/Assets.xcassets/money.imageset/Contents.json (1)

1-12: 모든 확인 사항 검증 완료 - 코드 승인

Contents.json의 JSON 구조가 정확하며, 참조하는 money.svg 파일이 올바른 위치에 존재합니다. DashboardView.swift의 line 95에서 이 asset이 주문 금액 표시 UI의 iconName으로 실제 사용되고 있음을 확인했습니다. 별도 조치가 필요하지 않습니다.

SampoomManagement/Core/UI/Components/CommonTextField.swift (3)

62-63: 제출 컨트롤 속성이 올바르게 추가되었습니다.

키보드의 return 키 레이블과 제출 동작을 제어하는 새로운 속성들이 명확하게 정의되었습니다. 이는 SignUpView의 포커스 관리 흐름을 지원합니다.


72-74: 초기화 함수가 적절하게 확장되었습니다.

새 파라미터들에 합리적인 기본값이 제공되어 기존 코드와의 호환성이 유지됩니다. .next를 기본 submitLabel로 사용하는 것은 대부분의 폼 필드에 적합한 선택입니다.

Also applies to: 83-84


94-95: 제출 수정자가 일관되게 적용되었습니다.

SecureField와 TextField 모두에 동일한 submitLabel과 onSubmit 수정자가 적용되어, 비밀번호 필드와 일반 텍스트 필드가 통일된 제출 동작을 갖습니다.

Also applies to: 103-104

SampoomManagement/Features/Auth/UI/SignUpView.swift (6)

20-20: 포커스 관리 기반이 올바르게 구축되었습니다.

FocusState와 Field enum을 사용한 키보드 포커스 관리 구조가 명확하게 정의되었습니다. 모든 입력 필드를 포함하며 체계적인 포커스 전환을 가능하게 합니다.

Also applies to: 26-28


52-57: 이름 필드의 포커스 흐름이 올바르게 구현되었습니다.

첫 번째 필드로서 적절하게 구성되었으며, return 키 입력 시 지점 필드로 자연스럽게 전환됩니다. ViewModel과의 연동도 정확합니다.


71-76: 지점 필드가 포커스 체인에 올바르게 통합되었습니다.

이전 필드(이름)로부터 포커스를 받고 다음 필드(직급)로 전환하는 흐름이 정확하게 구현되었습니다.


90-95: 직급 필드가 포커스 체인에 올바르게 통합되었습니다.

지점 필드로부터 포커스를 받고 이메일 필드로 전환하는 흐름이 정확하게 구현되었습니다.


110-115: 이메일 필드가 포커스 체인에 올바르게 통합되었습니다.

직급 필드로부터 포커스를 받고 비밀번호 필드로 전환하는 흐름이 정확하게 구현되었습니다.


130-135: 비밀번호 필드가 포커스 체인에 올바르게 통합되었습니다.

이메일 필드로부터 포커스를 받고 비밀번호 확인 필드로 전환하는 흐름이 정확하게 구현되었습니다.

SampoomManagement/Features/Dashboard/UI/DashboardUiEvent.swift (1)

10-13: LGTM!

대시보드 이벤트 타입이 명확하게 정의되어 있습니다.

SampoomManagement/Features/Auth/Data/Remote/API/AuthAPI.swift (1)

96-104: LGTM!

프로필 조회 API가 기존 패턴을 따라 올바르게 구현되었습니다.

SampoomManagement/Features/Auth/Data/Remote/DTO/GetProfileResponseDTO.swift (1)

10-16: LGTM!

프로필 응답 DTO가 적절하게 정의되어 있습니다. 모든 필드가 옵셔널로 처리되어 API의 유연성을 확보했습니다.

SampoomManagement/Core/Network/TokenRefreshService.swift (1)

51-61: LGTM!

토큰 갱신 시 사용자 프로필 필드(position, workspace, branch)를 올바르게 보존하고 있습니다.

SampoomManagement/Features/Auth/Data/Local/Preferences/AuthPreferences.swift (3)

25-49: LGTM!

새 프로필 필드를 저장하고 실패 시 롤백하는 로직이 올바르게 구현되었습니다.


63-95: LGTM!

프로필 필드가 누락된 경우 빈 문자열로 기본값 처리하는 로직이 적절하며, User 모델의 non-optional 필드 정의와 일관성 있게 구현되었습니다.


124-139: LGTM!

로그아웃 시 새 프로필 필드를 포함한 모든 키를 올바르게 삭제하고 있습니다.

SampoomManagement/Features/Auth/Data/Remote/DTO/LoginResponseDTO.swift (1)

12-12: userName 옵셔널 처리 확인됨

AuthMappers.swifttoModel() 메서드에서 self.userName ?? ""를 사용하여 nil 값을 안전하게 빈 문자열로 처리하고 있습니다. 매퍼가 옵셔널 처리를 올바르게 구현하고 있으므로 추가 조치가 필요하지 않습니다.

SampoomManagement/Core/UI/Components/OrderItem.swift (1)

10-39: 잘 구현되었습니다!

OrderItem 컴포넌트가 깔끔하게 구현되었습니다. 옵셔널 처리와 레이아웃 구성이 적절합니다.

SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (1)

111-114: 토큰 갱신 시 프로필 필드가 올바르게 유지됩니다.

새로운 프로필 필드(position, workspace, branch)가 토큰 갱신 후에도 적절히 보존되고 있습니다.

SampoomManagement/Features/Dashboard/UI/DashboardViewModel.swift (1)

12-21: ViewModel 구조가 깔끔합니다.

@MainActor 사용과 상태 관리 패턴이 적절하게 구현되어 있습니다.

SampoomManagement/Features/Auth/Data/Mappers/AuthMappers.swift (3)

10-24: 로그인 응답 매핑이 적절합니다.

새로운 프로필 필드에 대한 기본값 처리가 적절하며, 옵셔널 처리도 올바릅니다.


26-40: 프로필 응답 매핑이 올바릅니다.

프로필 DTO에 인증 토큰 정보가 없으므로 빈 값으로 설정하고, 나중에 mergeWith 메서드로 병합하는 접근이 적절합니다.


42-56: 병합 로직이 깔끔하게 구현되었습니다.

인증 데이터는 원본에서, 프로필 데이터는 파라미터에서 가져오는 불변 병합 패턴이 올바르게 구현되었습니다.

Comment thread SampoomManagement/App/ContentView.swift
Comment thread SampoomManagement/Features/Dashboard/UI/DashboardUiState.swift
Comment thread SampoomManagement/Features/Dashboard/UI/DashboardView.swift
Comment thread SampoomManagement/Features/Dashboard/UI/DashboardView.swift
Comment thread SampoomManagement/Features/Dashboard/UI/DashboardView.swift
Copy link
Copy Markdown
Member

@CHOOSLA CHOOSLA left a comment

Choose a reason for hiding this comment

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

승인!

Copy link
Copy Markdown

@Lee-Jong-Jin Lee-Jong-Jin left a comment

Choose a reason for hiding this comment

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

승인

Copy link
Copy Markdown

@taemin3 taemin3 left a comment

Choose a reason for hiding this comment

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

확인했습니다

@33Auto-Bot 33Auto-Bot added the ready-to-merge 3명 이상의 리뷰어에게 승인되어 병합 준비가 완료된 PR label Oct 29, 2025
Copy link
Copy Markdown
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

🧹 Nitpick comments (1)
SampoomManagement/Features/Dashboard/UI/DashboardView.swift (1)

32-38: 빈 액션 핸들러들을 구현하거나 TODO 주석으로 표시하세요.

상단 바의 직원 및 설정 버튼(lines 32, 36)과 모든 통계 카드들(lines 90, 93-94, 97-98)이 빈 액션 핸들러 {}를 가지고 있습니다. Line 30에 직원 버튼에 대한 TODO 주석이 있지만, 다른 버튼들에는 구현 계획이 명시되어 있지 않습니다.

향후 작업을 추적하기 위해 각 빈 액션 핸들러에 TODO 주석을 추가하거나, 필요하다면 이슈로 등록하는 것을 고려하세요.

이러한 미구현 기능들을 추적할 이슈를 생성하는 데 도움이 필요하신가요?

Also applies to: 90-99

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b46102 and 7e5bc8c.

📒 Files selected for processing (4)
  • SampoomManagement/App/ContentView.swift (3 hunks)
  • SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (2 hunks)
  • SampoomManagement/Features/Dashboard/UI/DashboardUiState.swift (1 hunks)
  • SampoomManagement/Features/Dashboard/UI/DashboardView.swift (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • SampoomManagement/App/ContentView.swift
🧰 Additional context used
🧬 Code graph analysis (2)
SampoomManagement/Features/Dashboard/UI/DashboardView.swift (1)
SampoomManagement/Features/Dashboard/UI/DashboardViewModel.swift (1)
  • onEvent (23-28)
SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (4)
SampoomManagement/Features/Auth/Data/Remote/API/AuthAPI.swift (2)
  • login (19-33)
  • getProfile (97-104)
SampoomManagement/Features/Auth/Data/Mappers/AuthMappers.swift (3)
  • toModel (11-23)
  • toModel (27-39)
  • mergeWith (43-55)
SampoomManagement/Features/Auth/Data/Local/Preferences/AuthPreferences.swift (3)
  • saveToken (51-61)
  • clear (124-139)
  • saveUser (25-49)
SampoomManagement/Core/Network/TokenRefreshService.swift (1)
  • refreshToken (17-65)
🪛 SwiftLint (0.57.0)
SampoomManagement/Features/Dashboard/UI/DashboardView.swift

[Warning] 30-30: TODOs should be resolved (role-based employee button)

(todo)

🔇 Additional comments (6)
SampoomManagement/Features/Dashboard/UI/DashboardUiState.swift (1)

25-35: 이전 리뷰의 critical issue가 수정되었습니다! 👍

copy 메서드의 dashboardError 파라미터가 이제 nil-coalescing을 사용하여 기존 에러 메시지를 올바르게 보존합니다. 이전 리뷰에서 지적된 문제가 정확히 해결되었습니다.

SampoomManagement/Features/Dashboard/UI/DashboardView.swift (3)

65-85: 이전 리뷰의 하드코딩 문제가 해결되었습니다! 👍

titleSection이 이제 하드코딩된 "가산디지털단지점"과 "홍길동" 대신 workspace, branch, userName 파라미터를 동적으로 사용하고 있습니다. 이전 리뷰에서 지적된 문제가 정확히 수정되었습니다.


131-164: orderListSection의 상태 처리 구현이 우수합니다! 👍

로딩, 에러, 비어있음, 데이터 표시의 네 가지 UI 상태를 모두 적절히 처리하고 있으며, viewModel.uiState와의 바인딩도 올바르게 구현되어 있습니다. ForEach에서 안정적인 식별자(orderId)를 사용하고 있고, 네비게이션 콜백 처리도 깔끔합니다.


104-129: buttonCard 헬퍼 함수가 잘 구현되었습니다.

재사용 가능한 컴포넌트로 깔끔하게 추출되어 있으며, 선택적 테두리 기능과 함께 일관된 디자인 시스템을 사용하고 있습니다. 파라미터 기본값 처리도 적절합니다.

SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (2)

41-84: 이전 리뷰에서 제기된 불완전한 상태 문제가 해결되었습니다.

이전 리뷰에서 제기된 "프로필 조회 실패 시 토큰은 저장되었지만 프로필 정보가 없는 불완전한 상태" 문제가 현재 코드에서 적절히 해결되었습니다:

  • Line 62, 68: 프로필 조회 실패 시 preferences.clear()를 호출하여 저장된 토큰을 롤백합니다.
  • Line 48의 주석: 토큰을 먼저 저장하는 이유(getProfile 호출 시 Authorization 헤더에 필요)가 명확히 설명되어 있습니다.
  • 에러 처리: 각 단계에서 실패 시 적절한 롤백 및 에러 전파가 이루어집니다.

현재 구현은 다음과 같은 견고한 흐름을 제공합니다:

  1. 로그인 → 토큰 저장
  2. 프로필 조회 (실패 시 토큰 롤백)
  3. 데이터 병합
  4. 최종 사용자 정보 저장

선택적 개선 사항: 네트워크 일시적 오류를 대비한 프로필 조회 재시도 로직을 추가하는 것을 고려해볼 수 있습니다.


120-123: 새로운 프로필 필드가 올바르게 전파됩니다.

토큰 갱신 시 position, workspace, branch 필드를 기존 사용자 정보에서 새로운 사용자 객체로 올바르게 복사하고 있습니다. 이는 토큰 갱신 시 프로필 데이터가 손실되지 않도록 보장합니다.

@Sangyoon98 Sangyoon98 merged commit 9f0373f into dev Oct 29, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge 3명 이상의 리뷰어에게 승인되어 병합 준비가 완료된 PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants