Conversation
개요사용자 직급 관리 시스템을 문자열에서 강타입 변경 사항
시퀀스 다이어그램sequenceDiagram
participant View as SignUp View
participant ViewModel as ViewModel
participant Repo as Repository
participant Remote as Remote API
participant Local as Local Storage
View->>ViewModel: signUp(user)
ViewModel->>Repo: authenticate(email, password)
Repo->>Remote: login(credentials)
Remote-->>Repo: token + profile
Repo->>Repo: retry block (up to 5 times,<br/>exponential backoff)
Repo->>Remote: getProfile()
alt Success
Remote-->>Repo: profileDTO
Repo->>Repo: toModel() - convert to User
Repo->>Local: saveUser(user)
Repo-->>ViewModel: success
else Retry Exhausted
Repo->>Local: clearTokens()
Repo-->>ViewModel: error
end
sequenceDiagram
participant User as User selects position
participant View as SignUpView
participant State as selectedPosition state
participant ViewModel as ViewModel
User->>View: tap Menu dropdown
View->>View: show UserPosition cases<br/>with displayNameKo
User->>View: select position
View->>State: selectedPosition = UserPosition
View->>ViewModel: updatePosition(pos.rawValue)
View->>View: move focus to email field
예상 코드 리뷰 노력🎯 3 (보통) | ⏱️ ~20분
시
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (1)
59-65: 재시도 가능한 오류만 필터링하는 것을 고려하세요.현재 구현은 모든 오류에 대해 재시도를 수행하는데, 이는 유효성 검사 실패나 404와 같은 재시도 불가능한 오류에도 최대 5번까지 재시도하여 불필요한 지연을 발생시킬 수 있습니다.
다음과 같이 재시도 가능한 오류만 필터링하도록 개선할 수 있습니다:
- profileUser = try await retry(times: 5, initialDelayMs: 300, maxDelayMs: 1500, factor: 1.8) { + profileUser = try await retry( + times: 5, + initialDelayMs: 300, + maxDelayMs: 1500, + factor: 1.8, + shouldRetry: { error in + // 네트워크 오류나 일시적 서버 오류만 재시도 + if let authError = error as? AuthError { + return authError == .invalidResponse + } + return true // 기타 네트워크 오류는 재시도 + } + ) { let profileResponse = try await self.api.getProfile() guard let profileDto = profileResponse.data else { throw AuthError.invalidResponse } return profileDto.toModel() }그리고 retry 함수의 시그니처를 다음과 같이 수정:
private func retry<T>( times: Int = 5, initialDelayMs: UInt64 = 300, maxDelayMs: UInt64 = 1500, factor: Double = 1.8, + shouldRetry: ((Error) -> Bool)? = nil, _ block: @escaping () async throws -> T ) async throws -> T { precondition(times >= 1) var currentDelayMs = initialDelayMs for attempt in 1..<(times) { do { return try await block() } catch { + if let shouldRetry = shouldRetry, !shouldRetry(error) { + throw error + } let ns = currentDelayMs * 1_000_000 try? await Task.sleep(nanoseconds: ns) let next = UInt64(Double(currentDelayMs) * factor) currentDelayMs = min(next, maxDelayMs) } } return try await block() }SampoomManagement/Features/Auth/Domain/Models/User.swift (1)
10-26: UserRole과 UserPosition 간의 중복을 검토하세요.UserRole enum에
staff,seniorStaff,assistantManager등의 케이스가 포함되어 있는데, 이는 새로 추가된 UserPosition enum과 중복됩니다. UserRole은 권한 수준(admin, user, manager)을 나타내고 UserPosition은 조직 내 직급을 나타내야 하는데, 현재 두 개념이 혼재되어 있어 혼란을 야기할 수 있습니다.향후 UserRole을 실제 역할(권한)만 포함하도록 정리하는 것을 고려하세요:
enum UserRole: String, Codable, Equatable { case admin = "ADMIN" case user = "USER" case manager = "MANAGER" var isAdmin: Bool { self == .admin } }SampoomManagement/Features/Auth/UI/SignUpView.swift (1)
16-16: 중복된 nil 초기화를 제거하세요.Optional 변수는 기본적으로 nil로 초기화되므로 명시적인
= nil은 불필요합니다.다음과 같이 수정:
-@State private var selectedPosition: UserPosition? = nil +@State private var selectedPosition: UserPosition?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
SampoomManagement/Features/Auth/Data/Local/Preferences/AuthPreferences.swift(3 hunks)SampoomManagement/Features/Auth/Data/Mappers/AuthMappers.swift(2 hunks)SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift(2 hunks)SampoomManagement/Features/Auth/Domain/Models/User.swift(1 hunks)SampoomManagement/Features/Auth/Domain/Models/UserPosition.swift(1 hunks)SampoomManagement/Features/Auth/UI/SignUpUiState.swift(1 hunks)SampoomManagement/Features/Auth/UI/SignUpView.swift(2 hunks)SampoomManagement/Features/Setting/UI/SettingView.swift(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
SampoomManagement/Features/Auth/UI/SignUpView.swift (1)
SampoomManagement/Features/Auth/UI/SignUpViewModel.swift (1)
updatePosition(35-38)
SampoomManagement/Features/Auth/Data/Local/Preferences/AuthPreferences.swift (1)
SampoomManagement/Features/Auth/Data/Local/Preferences/KeychainManager.swift (2)
save(24-43)get(45-71)
SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (3)
SampoomManagement/Core/Network/AuthRequestInterceptor.swift (1)
retry(56-80)SampoomManagement/Features/Auth/Data/Remote/API/AuthAPI.swift (1)
getProfile(98-105)SampoomManagement/Features/Auth/Data/Mappers/AuthMappers.swift (2)
toModel(11-27)toModel(31-47)
🪛 SwiftLint (0.57.0)
SampoomManagement/Features/Auth/UI/SignUpView.swift
[Warning] 16-16: Initializing an optional variable with nil is redundant
(redundant_optional_initialization)
🔇 Additional comments (8)
SampoomManagement/Features/Auth/Data/Repository/AuthRepositoryImpl.swift (1)
158-180: 재사용 가능한 재시도 헬퍼 구현이 우수합니다.지수 백오프 재시도 로직이 잘 구현되어 있고, 제네릭으로 재사용 가능하도록 설계되었습니다.
SampoomManagement/Features/Setting/UI/SettingView.swift (1)
61-61: 한글 직급명 표시가 올바르게 적용되었습니다.UserPosition enum의 displayNameKo 속성을 활용하여 한글 직급명을 표시하도록 변경된 것이 적절합니다.
SampoomManagement/Features/Auth/Data/Local/Preferences/AuthPreferences.swift (1)
38-38: Enum 직렬화가 올바르게 구현되었습니다.rawValue를 사용한 저장 및 복원 로직이 적절하며, 기존 사용자 데이터에 대한 마이그레이션도
.staff폴백을 통해 안전하게 처리됩니다.Also applies to: 89-89, 105-105
SampoomManagement/Features/Auth/Domain/Models/User.swift (1)
37-37: Position의 타입 변경이 올바르게 적용되었습니다.String에서 UserPosition enum으로의 변경은 타입 안정성과 한글 표시를 제공합니다.
SampoomManagement/Features/Auth/Data/Mappers/AuthMappers.swift (1)
20-20: 매핑 로직이 새로운 enum 타입과 일관되게 업데이트되었습니다.LoginResponseDTO는 임시
.staff값을 사용하고, GetProfileResponseDTO는 rawValue로 안전하게 변환하며 폴백을 제공합니다.Also applies to: 40-40
SampoomManagement/Features/Auth/UI/SignUpUiState.swift (1)
33-33: 기본값을 API 상수와 일치하도록 변경한 것이 적절합니다.한글 문자열 "대리점"에서 영문 상수 "AGENCY"로 변경하여 API와의 일관성을 확보했습니다.
SampoomManagement/Features/Auth/Domain/Models/UserPosition.swift (1)
10-36: UserPosition enum 구현이 우수합니다.타입 안정성, 로컬라이제이션, UI 반복을 위한 적절한 프로토콜 준수가 잘 구현되어 있습니다. rawValue는 서버 API와의 호환성을 보장하고, displayNameKo는 UI 표시를 간소화합니다.
SampoomManagement/Features/Auth/UI/SignUpView.swift (1)
86-121: Menu 기반 직급 선택 UI가 잘 구현되었습니다.TextField를 Menu picker로 교체하여 사전 정의된 직급 선택에 더 적합한 UX를 제공합니다. UserPosition.allCases를 활용한 반복, rawValue 저장, 에러 표시, 포커스 관리가 모두 올바르게 처리되었습니다.
📝 Summary
직급 Enum 변경
🙏 Question & PR point
📬 Reference
Summary by CodeRabbit
릴리스 노트
새 기능
개선사항