-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WEAV-140] 프로필 수정 - 내 직군 정보 #47
Conversation
Walkthrough이 변경 사항은 Changes
Possibly related PRs
Suggested labels
Warning There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure. 🔧 SwiftLint (0.57.0)OpenApiGenerator/Sources/OpenapiGenerated/Types.swiftThank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
🧹 Outside diff range and nitpick comments (20)
Projects/Features/Home/UnitTest/EditProfileJobOccupationTest.swift (2)
13-17
: 테스트 구조체에 문서화 추가 필요테스트의 목적과 테스트하는 시나리오에 대한 설명을 추가하면 좋을 것 같습니다.
다음과 같이 문서화를 추가해보세요:
+/// 프로필 직군 정보 수정 기능 테스트를 위한 구조체 +/// - state: 직군 선택 상태를 관리하는 모델 +/// - intent: 사용자 인터랙션을 처리하는 인텐트 struct EditProfileJobOccupationTests { let state: EditProfileJobModel let intent: EditProfileJobIntent
18-25
: 다양한 테스트 케이스 추가 필요현재는 기본 mock 데이터만 사용하고 있습니다. 다양한 시나리오를 테스트하기 위해 여러 케이스의 mock 데이터를 추가하면 좋을 것 같습니다.
예를 들어, 다음과 같은 케이스들을 추가해보세요:
- 직군이 선택되지 않은 상태
- 여러 직군이 선택된 상태
- 잘못된 직군 데이터가 있는 상태
Projects/Core/NetworkKit/Sources/ProfileService/ProfileServiceMock.swift (1)
31-35
: Mock 구현의 테스트 커버리지 개선 필요현재 구현은 성공 케이스만 처리하고 있습니다. Mock 객체의 완성도를 높이기 위해 다음 사항들을 고려해주세요:
- 실패 시나리오 테스트를 위한 에러 케이스 추가
- 입력된 UserInfo 데이터 검증
- 테스트에서 호출 여부를 확인할 수 있는 프로퍼티 추가
다음과 같은 개선된 구현을 제안드립니다:
public final class ProfileServiceMock: ProfileServiceProtocol { + public var requestPutUserInfoCallCount = 0 + public var shouldFail = false + public var lastUserInfo: UserInfo? + public func requestPutUserInfo(userInfo: UserInfo) async throws { + requestPutUserInfoCallCount += 1 + lastUserInfo = userInfo + + if shouldFail { + throw NSError(domain: "ProfileServiceMock", code: -1, + userInfo: [NSLocalizedDescriptionKey: "의도된 실패"]) + } print("✅ [ProfileServiceMock] requestPutUserInfo 성공!") return } }Projects/Features/Home/Sources/ProfilePannel/ProfilePannelIntent.swift (1)
33-33
: 문서화 추가 필요프로토콜 메서드의 목적과 사용 방법을 명확히 하기 위해 문서 주석을 추가하는 것이 좋습니다.
다음과 같이 문서화를 추가해보세요:
+ /// 직군 정보 수정 아이콘을 탭했을 때 호출되는 메서드입니다. + /// 사용자를 직군 정보 수정 화면으로 이동시킵니다. func onTapEditJobOccupationIcon()Projects/Features/Home/UnitTest/WidgetUnitTest.swift (1)
Line range hint
1-89
: 프로필 정보 업데이트 관련 테스트 케이스 추가 필요프로필 수정 기능이 추가됨에 따라, 위젯이 업데이트된 프로필 정보와 올바르게 동기화되는지 확인하는 테스트 케이스가 필요합니다.
다음과 같은 테스트 케이스 추가를 제안드립니다:
@Test func updateWidgetAfterProfileChange() async throws { // 프로필 정보 업데이트 let updatedProfile = UserProfile(/* updated profile info */) writeIntent.updateProfile(updatedProfile) // 위젯 상태 검증 #expect(writeState.isProfileUpdated == true) #expect(writeState.widgetContent.contains(updatedProfile.jobInfo)) }Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobModel.swift (2)
17-17
: MARK 주석 형식을 수정해주세요Swift 스타일 가이드에 따라 MARK 주석은 다음과 같은 형식을 따라야 합니다:
// MARK: ...
또는// MARK: - ...
다음과 같이 수정해주세요:
- //MARK: Stateful + // MARK: - Stateful - //MARK: State Properties + // MARK: - State Properties -//MARK: - Actionable +// MARK: - ActionableAlso applies to: 32-32, 60-60
🧰 Tools
🪛 SwiftLint (0.57.0)
[Warning] 17-17: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 17-17: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
28-29
: 에러 처리 방식에 대한 문서화가 필요합니다
showErrorView
와showErrorAlert
의 사용 목적과 차이점을 명확히 하는 문서화가 필요합니다.각 에러 처리 메서드에 다음과 같이 문서 주석을 추가해주세요:
+ /// 전체 화면 에러 표시가 필요한 경우 사용 func showErrorView(error: ErrorModel) { showErrorView = error } + /// 팝업 형태의 에러 알림이 필요한 경우 사용 func showErrorAlert(error: ErrorModel) { showErrorAlert = error }Also applies to: 90-95
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobIntent.swift (3)
16-16
: MARK 주석 형식을 수정해주세요.Swift 코딩 컨벤션에 따라 MARK 주석은 다음과 같은 형식을 따라야 합니다:
-//MARK: - Intent +// MARK: - IntentAlso applies to: 38-38, 57-57
🧰 Tools
🪛 SwiftLint (0.57.0)
[Warning] 16-16: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 16-16: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
23-27
: 의존성 주입 패턴을 개선해주세요.현재
ProfileService.shared
를 기본값으로 사용하고 있는데, 이는 테스트 용이성을 저해할 수 있습니다. 의존성 주입을 통해 더 유연한 구조로 개선하는 것이 좋습니다.init( model: EditProfileJobModelActionable, input: DataModel, - service: ProfileServiceProtocol = ProfileService.shared + service: ProfileServiceProtocol )이렇게 수정하고, 실제 사용하는 곳에서 서비스를 주입하도록 변경하면 테스트가 더 용이해집니다.
60-62
: 빈 메서드에 대한 설명을 추가해주세요.
onAppear()
와task()
메서드가 의도적으로 비어있다면, 그 이유를 문서화하는 것이 좋습니다.+ /// 현재 구현이 필요하지 않은 기본 메서드입니다. func onAppear() {} + /// 현재 구현이 필요하지 않은 기본 메서드입니다. func task() async {}Projects/Features/Home/Sources/Profile/ProfileIntent.swift (2)
Line range hint
98-101
: 에러 처리 개선이 필요합니다현재 구현에서는 refreshMyUserInfo 실패 시 사용자에게 어떠한 피드백도 제공되지 않습니다. 에러 처리를 추가하여 사용자 경험을 개선하는 것이 좋겠습니다.
다음과 같이 개선을 제안드립니다:
func refreshUserInfo() async { - if let userInfo = try? await AppCoordinator.shared.refreshMyUserInfo() { + do { + let userInfo = try await AppCoordinator.shared.refreshMyUserInfo() fetchUserInfo(userInfo) + } catch { + await MainActor.run { + ToastHelper.showErrorMessage("프로필 정보를 불러오는데 실패했습니다") + } } }
Line range hint
116-119
: 도달할 수 없는 코드가 존재합니다
throw
구문 이후의 코드는 실행될 수 없습니다. 이는 디버깅 목적으로 추가된 코드로 보이며, 프로덕션 환경에서는 제거되어야 합니다.다음과 같이 수정해주세요:
func requestDeleteWidget(_ widget: ProfileWidget) async throws { - throw NSError(domain: "33", code: 33) try await profileService.requestDeleteProfileWidget(widgetType: widget.widgetType.toDto) }
Projects/App/Sources/Navigation/NavigationStack.swift (2)
71-81
: 프로필 편집 네비게이션 구현 검토현재 대부분의 서브뷰가
EmptyView()
로 구현되어 있습니다. 이는 아직 구현이 완료되지 않았음을 의미하는 것으로 보입니다. 하지만 PR의 목적이 직군 정보 수정이므로,EditProfileJobView
만 구현된 것은 적절해 보입니다.향후 다른 프로필 편집 기능이 구현될 때를 대비하여, TODO 주석을 추가하는 것이 좋을 것 같습니다.
다음과 같이 TODO 주석을 추가하는 것을 제안합니다:
case .profileImage(let input): + // TODO: ProfileImageEditView 구현 예정 EmptyView() case .jobOccupation(let input): EditProfileJobView(input) case .company(let input): + // TODO: CompanyEditView 구현 예정 EmptyView() case .region(let input): + // TODO: RegionEditView 구현 예정 EmptyView()
83-91
: 이상형 편집 네비게이션 구조 개선 제안현재 모든 이상형 편집 관련 뷰가
EmptyView()
로 구현되어 있습니다. 이는 현재 PR의 범위를 벗어나는 것으로 보입니다.향후 유지보수성을 고려하여 다음과 같은 구조적 개선을 제안드립니다:
- 이상형 편집 관련 네비게이션 로직을 별도의 파일로 분리
- 각 케이스별로 전달되는
userInfo
파라미터의 타입을 명확히 정의- 각 뷰의 구현 우선순위를 주석으로 명시
예시:
// EditDreamPartnerNavigation.swift enum EditDreamPartnerViewType { case ageRange(DreamPartnerAgeInfo) case jobOccupation(DreamPartnerJobInfo) case distance(DreamPartnerDistanceInfo) @ViewBuilder var view: some View { switch self { case .ageRange: // TODO: [P1] 연령대 설정 뷰 구현 EmptyView() // ... 기타 케이스 } } }Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobView.swift (3)
22-34
: 초기화 로직을 더 간단하게 리팩토링하면 좋을 것 같습니다.현재 초기화 로직이 다소 복잡해 보입니다. 컨테이너 설정 부분을 별도의 private 메서드로 분리하면 가독성이 향상될 것 같습니다.
다음과 같이 리팩토링을 제안드립니다:
public init(_ userInfo: UserInfo) { + self._container = StateObject(wrappedValue: Self.createContainer(userInfo)) } + + private static func createContainer(_ userInfo: UserInfo) -> MVIContainer<EditProfileJobIntent.Intentable, EditProfileJobModel.Stateful> { let model = EditProfileJobModel() let intent = EditProfileJobIntent( model: model, input: .init(userInfo: userInfo) ) - let container = MVIContainer( + return MVIContainer( intent: intent as EditProfileJobIntent.Intentable, model: model as EditProfileJobModel.Stateful, modelChangePublisher: model.objectWillChange ) - self._container = StateObject(wrappedValue: container) }
88-90
: pop 네비게이션 로직 검토가 필요합니다.
AppCoordinator.shared
를 직접 사용하는 것은 뷰의 재사용성과 테스트 가능성을 저해할 수 있습니다.네비게이션 로직을 클로저나 콜백으로 전달받는 방식을 고려해보세요:
public struct EditProfileJobView: View { var onDismiss: () -> Void // ... .setPopNavigation { onDismiss() } }
95-99
: 프리뷰를 더 다양한 상태로 테스트할 수 있게 개선하면 좋을 것 같습니다.현재는 기본 상태만 프리뷰하고 있습니다. 다양한 상태의 프리뷰를 추가하면 UI 테스트에 도움이 될 것 같습니다.
#Preview("기본 상태") { NavigationView { EditProfileJobView(.mock) } } #Preview("선택된 상태") { NavigationView { EditProfileJobView(.mockWithSelectedJob) } } #Preview("로딩 상태") { NavigationView { EditProfileJobView(.mockLoading) } }Projects/Core/CommonKit/Sources/Path/PathTypes.swift (2)
91-104
: 들여쓰기 일관성 개선이 필요합니다.switch 문 내부의 들여쓰기가 일관적이지 않습니다. 가독성 향상을 위해 수정이 필요합니다.
다음과 같이 수정을 제안합니다:
case .editProfile(let subView): switch subView { - case .profileImage: return "프로필 이미지 수정" - case .jobOccupation: return "직군 수정" - case .company: return "직장 수정" - case .region: return "활동 지역 수정" + case .profileImage: return "프로필 이미지 수정" + case .jobOccupation: return "직군 수정" + case .company: return "직장 수정" + case .region: return "활동 지역 수정" }
169-180
: 새로운 enum 타입에 대한 개선사항이 있습니다.
Hashable
프로토콜 준수가 필요할 수 있습니다:
SignUpSubViewType
처럼 컬렉션에서 사용하거나 비교 연산이 필요한 경우를 대비하여Hashable
프로토콜을 채택하는 것이 좋습니다.문서화가 누락되었습니다:
- 각 enum과 case에 대한 설명을 추가하면 코드의 가독성과 유지보수성이 향상될 것입니다.
다음과 같은 개선을 제안합니다:
+/// 프로필 수정 화면의 타입을 정의합니다. -public enum EditProfileViewType { +public enum EditProfileViewType: Hashable { case profileImage(UserInfo) case jobOccupation(UserInfo) case company(UserInfo) case region(UserInfo) } +/// 이상형 정보 수정 화면의 타입을 정의합니다. -public enum EditDreamPartnerViewType { +public enum EditDreamPartnerViewType: Hashable { case ageRange(UserInfo) case jobOccupation(UserInfo) case distance(UserInfo) }Projects/Features/Home/Sources/ProfilePannel/ProfilePannelView.swift (1)
201-209
: 편집 아이콘 UI 구현에 대한 개선 제안현재 구현은 기능적으로는 문제가 없으나, 접근성과 사용자 경험을 개선할 수 있습니다.
다음과 같은 개선을 제안드립니다:
if showEditIcon { DesignCore.Images.pencil1.image .resizable() .aspectRatio(contentMode: .fit) .frame(width: 18, height: 18) + .accessibility(label: Text("편집")) + .contentShape(Rectangle()) .onTapGesture { editHandler?() } }개선 사항:
- VoiceOver 사용자를 위한 접근성 레이블 추가
- 터치 영역을 명확히 하기 위한
contentShape
추가
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (16)
OpenApiGenerator/Sources/OpenapiGenerated/Client.swift
(2 hunks)OpenApiGenerator/Sources/OpenapiGenerated/Types.swift
(10 hunks)OpenApiGenerator/Sources/openapi-generator-cli/3days-oas
(1 hunks)Projects/App/Sources/Navigation/NavigationStack.swift
(1 hunks)Projects/Core/CommonKit/Sources/Path/PathTypes.swift
(4 hunks)Projects/Core/NetworkKit/Sources/ProfileService/ProfileService.swift
(2 hunks)Projects/Core/NetworkKit/Sources/ProfileService/ProfileServiceMock.swift
(2 hunks)Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobIntent.swift
(1 hunks)Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobModel.swift
(1 hunks)Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobView.swift
(1 hunks)Projects/Features/Home/Sources/Profile/ProfileIntent.swift
(1 hunks)Projects/Features/Home/Sources/ProfilePannel/ProfilePannelIntent.swift
(2 hunks)Projects/Features/Home/Sources/ProfilePannel/ProfilePannelView.swift
(5 hunks)Projects/Features/Home/UnitTest/EditProfileJobOccupationTest.swift
(1 hunks)Projects/Features/Home/UnitTest/WidgetUnitTest.swift
(1 hunks)Projects/Model/Model/Sources/Auth/Domain/UserInfo.swift
(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- OpenApiGenerator/Sources/openapi-generator-cli/3days-oas
🧰 Additional context used
🪛 SwiftLint (0.57.0)
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobIntent.swift
[Warning] 16-16: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 38-38: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 57-57: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 16-16: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 38-38: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 57-57: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobModel.swift
[Warning] 17-17: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 32-32: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 60-60: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 17-17: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 32-32: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 60-60: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
🔇 Additional comments (17)
Projects/Features/Home/UnitTest/EditProfileJobOccupationTest.swift (1)
9-11
: NetworkKit import의 필요성 검토 필요
현재 테스트 코드에서 NetworkKit을 직접적으로 사용하는 부분이 보이지 않습니다. 불필요한 import인 경우 제거하는 것이 좋습니다.
다음 스크립트를 실행하여 NetworkKit의 사용 여부를 확인해보겠습니다:
Projects/Core/NetworkKit/Sources/ProfileService/ProfileServiceMock.swift (1)
12-12
: Model 모듈 import 추가 확인됨
UserInfo 타입 사용을 위한 Model 모듈 import가 적절히 추가되었습니다.
Projects/Core/NetworkKit/Sources/ProfileService/ProfileService.swift (1)
23-24
: 프로토콜 메서드 선언이 적절합니다!
비동기 처리와 에러 핸들링을 포함한 메서드 시그니처가 잘 정의되어 있습니다.
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobModel.swift (1)
15-56
: 아키텍처 구현이 잘 되었습니다
다음과 같은 점들이 잘 구현되었습니다:
ObservableObject
를 활용한 MVVM 패턴 구현Stateful
과Actionable
프로토콜을 통한 명확한 책임 분리- 상태 관리와 액션 처리의 체계적인 구조화
Also applies to: 61-73
🧰 Tools
🪛 SwiftLint (0.57.0)
[Warning] 17-17: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 32-32: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 17-17: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 32-32: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobIntent.swift (1)
32-34
: 🛠️ Refactor suggestion
옵셔널 처리를 개선해주세요.
JobOccupation(rawValue:)
가 nil을 반환할 수 있는 상황에서 강제 언래핑을 사용하고 있습니다. 안전한 처리를 위해 guard let 또는 if let을 사용하는 것이 좋습니다.
- if let job = JobOccupation(rawValue: input.userInfo.profile.jobOccupationRawValue) {
- model.setSingleSelectedJob(job)
- }
+ guard let job = JobOccupation(rawValue: input.userInfo.profile.jobOccupationRawValue) else {
+ return
+ }
+ model.setSingleSelectedJob(job)
Likely invalid or redundant comment.
Projects/Features/Home/Sources/Profile/ProfileIntent.swift (1)
92-94
: 비동기 처리가 올바르게 구현되었습니다!
Task 래퍼를 사용하여 비동기 작업을 적절하게 처리하고 있습니다.
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobView.swift (1)
9-14
: 필요한 프레임워크들이 잘 임포트되어 있습니다!
필요한 모든 의존성이 명확하게 정의되어 있습니다.
Projects/Core/CommonKit/Sources/Path/PathTypes.swift (1)
29-30
: 새로운 PathType 케이스가 적절히 추가되었습니다!
프로필 수정과 이상형 수정을 위한 새로운 케이스가 기존 코드 스타일과 일관성있게 추가되었습니다.
Projects/Model/Model/Sources/Auth/Domain/UserInfo.swift (2)
16-17
: dreamPartner
속성의 가변성 필요성 검토 필요
프로필의 직군 정보 수정 기능 구현을 위해 profile
을 var
로 변경한 것은 적절해 보입니다. 하지만 dreamPartner
를 가변으로 만든 이유가 불분명합니다. 현재 PR의 범위가 직군 정보 수정에 한정되어 있다면, dreamPartner
는 불변(let
)으로 유지하는 것이 더 안전할 수 있습니다.
66-68
: 잘 구현된 jobOccupationDTO
computed property
Components.Schemas.JobOccupation
으로의 안전한 변환을 제공하는 computed property가 잘 구현되었습니다. 타입 안전성을 보장하면서도 DTO 변환을 깔끔하게 처리하고 있습니다.
Projects/Features/Home/Sources/ProfilePannel/ProfilePannelView.swift (2)
84-88
: 직군 정보 수정 기능 구현이 적절합니다.
직군 정보 수정을 위한 편집 아이콘과 핸들러가 잘 구현되어 있습니다. onTapEditJobOccupationIcon()
을 통해 적절한 네비게이션 처리가 이루어지고 있습니다.
184-186
: 메서드 시그니처 변경이 적절합니다.
horizonIconKeyValueView
메서드에 편집 기능 관련 파라미터가 잘 추가되었습니다. 선택적 매개변수(editHandler
)를 사용하여 하위 호환성도 고려했습니다.
OpenApiGenerator/Sources/OpenapiGenerated/Client.swift (1)
Line range hint 662-675
: HTTP 메소드 변경이 적절해 보입니다.
PATCH에서 PUT으로의 변경은 사용자 정보를 전체적으로 업데이트하는 현재 구현 방식과 잘 맞습니다. PUT은 리소스의 전체 업데이트를 위한 표준 HTTP 메소드이며, 이는 프로필 수정 기능의 의도와 일치합니다.
다음 스크립트를 실행하여 클라이언트 코드에서 이 엔드포인트의 사용을 확인하겠습니다:
✅ Verification successful
Let me gather more information about the implementation details and the request body structure.
Let me check one more detail about the request schema to understand the complete update structure.
PUT 메소드 변경이 적절하며 구현이 올바릅니다.
사용자 정보 업데이트 엔드포인트의 구현을 검토한 결과:
- UpdateMyUserInfoRequest 스키마는 사용자 프로필의 전체 정보(이름, 직군, 회사, 활동 지역)를 포함하고 있습니다
- PATCH에서 PUT으로의 변경은 리소스의 전체 업데이트를 의미하며, 현재 구현된 요청 구조와 일치합니다
- 다른 PATCH 엔드포인트와의 충돌이 없습니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: PUT /users/my 엔드포인트 사용 확인
# Test: 엔드포인트 호출 패턴 검색
rg -A 5 "PUT.*?/users/my"
Length of output: 2672
Script:
#!/bin/bash
# Description: Check the request body structure and related types
# Search for updateMyUserInfo Input/Body type definitions
ast-grep --pattern 'struct Input {
$$$
}'
# Search for any related documentation or comments
rg -B 2 -A 5 "updateMyUserInfo.*?Body"
Length of output: 4364
Script:
#!/bin/bash
# Search for UpdateMyUserInfoRequest schema definition
rg -B 2 -A 10 "UpdateMyUserInfoRequest"
# Also check if there are any PATCH endpoints that might be affected
rg "PATCH.*?/users"
Length of output: 4859
OpenApiGenerator/Sources/OpenapiGenerated/Types.swift (4)
186-187
: [중복 코멘트] HTTP 메서드 변경에 따른 영향 확인 필요
이미 언급된 내용과 같이, 이 부분에서도 updateMyUserInfo
메서드의 HTTP 메서드 변경에 따른 영향 확인이 필요합니다.
Line range hint 2378-2397
: HTTP 메서드 변경에 따른 영향 확인 필요
updateMyUserInfo
오퍼레이션의 정의에서 HTTP 메서드가 PATCH
에서 PUT
으로 변경되었습니다. 이는 API의 동작 방식과 클라이언트 호출에 영향을 줄 수 있으므로, 관련된 모든 부분이 업데이트되었는지 확인해주세요.
53-54
:
HTTP 메서드 변경에 따른 영향 확인 필요
updateMyUserInfo
메서드의 HTTP 메서드가 PATCH
에서 PUT
으로 변경되었습니다. 이 변경은 클라이언트 측의 API 호출에도 영향을 미치므로, 모든 클라이언트 구현부가 해당 변경 사항을 반영하도록 업데이트되었는지 확인해주세요.
다음 스크립트를 실행하여 클라이언트 코드에서 updateMyUserInfo
메서드 호출이 올바르게 업데이트되었는지 확인할 수 있습니다:
591-619
:
필수 필드 변경에 따른 호환성 확인 필요
UpdateMyUserInfoRequest
구조체에서 name
, jobOccupation
, locationIds
필드가 선택적(Optional
)에서 필수적(Non-Optional
)으로 변경되었습니다. 이로 인해 해당 구조체를 사용하는 기존 클라이언트 코드에서 컴파일 오류가 발생할 수 있습니다. 또한, 새로운 필드인 allowSameCompany
가 추가되었습니다.
다음 스크립트를 실행하여 클라이언트 코드에서 UpdateMyUserInfoRequest
초기화 시 필수 필드들이 모두 포함되었는지 확인할 수 있습니다:
✅ Verification successful
Let me search for actual usage of this struct in the codebase to verify the impact.
Let me search specifically in the ProfileService and AuthService where this request is most likely to be used.
Let me check the ProfileService implementation and any other potential usages.
필수 필드 변경이 안전하게 처리되어 있음을 확인했습니다
UpdateMyUserInfoRequest
구조체의 필수 필드 변경과 관련하여 다음 사항들을 확인했습니다:
ProfileService
에서requestPutUserInfo
메서드를 통해UpdateMyUserInfoRequest
를 생성할 때 필수 필드인name
,jobOccupation
,locationIds
를 모두 올바르게 제공하고 있습니다.- 실제 사용처는
EditProfileJobIntent
에서 프로필 수정 시에만 사용되며,UserInfo
모델을 통해 필수 값들이 안전하게 전달됩니다. - 선택적 필드인
companyId
와allowSameCompany
는 필요한 경우에만 설정되도록 구현되어 있습니다.
따라서 필수 필드 변경으로 인한 호환성 문제는 발생하지 않을 것으로 판단됩니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# 'UpdateMyUserInfoRequest' 초기화 시 누락된 필수 필드 확인
rg "UpdateMyUserInfoRequest" -A 10
Length of output: 4389
Script:
#!/bin/bash
# Search for actual usage/initialization of UpdateMyUserInfoRequest
rg -B 3 -A 3 "UpdateMyUserInfoRequest\(" --type swift
# Also search for any imports of OpenapiGenerated to find client code
rg "import.*OpenapiGenerated" --type swift
Length of output: 1282
Script:
#!/bin/bash
# Search in profile and auth related services
rg -B 5 -A 5 "UpdateMyUserInfoRequest" Projects/Core/NetworkKit/Sources/ProfileService/ Projects/Core/NetworkKit/Sources/AuthService/
# Also check the mock implementations
cat Projects/Core/NetworkKit/Sources/ProfileService/ProfileServiceMock.swift
cat Projects/Core/NetworkKit/Sources/AuthService/AuthServiceMock.swift
Length of output: 3141
Script:
#!/bin/bash
# Check ProfileService implementation
cat Projects/Core/NetworkKit/Sources/ProfileService/ProfileService.swift
# Search for any other potential usages of UpdateMyUserInfoRequest in the codebase
rg -B 5 -A 5 "requestPutUserInfo|UpdateMyUserInfoRequest" --type swift
Length of output: 10889
public func requestPutUserInfo(userInfo: UserInfo) async throws { | ||
guard let jobOccupation = userInfo.profile.jobOccupationDTO else { | ||
return | ||
} | ||
let result = try await client.updateMyUserInfo( | ||
.init( | ||
body: .json( | ||
.init( | ||
name: userInfo.name, | ||
jobOccupation: jobOccupation, | ||
locationIds: userInfo.profile.locations.map { $0.id } | ||
) | ||
) | ||
) | ||
) | ||
_ = try result.ok | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
에러 처리 및 유효성 검사가 필요합니다.
현재 구현에서 몇 가지 개선이 필요한 부분이 있습니다:
- jobOccupation이 nil일 때 조용히 리턴하는 것은 호출하는 쪽에서 실패 여부를 알 수 없습니다.
- name이나 locations 같은 필수 필드에 대한 유효성 검사가 없습니다.
다음과 같이 개선하는 것을 제안드립니다:
public func requestPutUserInfo(userInfo: UserInfo) async throws {
guard let jobOccupation = userInfo.profile.jobOccupationDTO else {
- return
+ throw ProfileServiceError.invalidJobOccupation
}
+
+ guard !userInfo.name.isEmpty else {
+ throw ProfileServiceError.invalidName
+ }
+
let result = try await client.updateMyUserInfo(
.init(
body: .json(
추가로 다음 에러 타입도 정의가 필요합니다:
public enum ProfileServiceError: Error {
case invalidJobOccupation
case invalidName
}
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobModel.swift
Show resolved
Hide resolved
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobIntent.swift
Show resolved
Hide resolved
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobView.swift
Show resolved
Hide resolved
case editProfile(EditProfileViewType) | ||
case editDreamPartner(EditDreamPartnerViewType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
네비게이션 스택에서 일부 화면이 EmptyView()
로 구현되어 있습니다
네비게이션 스택에서 새로운 경로들이 모두 처리되고 있지만, 다음 화면들이 아직 EmptyView()
로만 구현되어 있습니다:
editProfile
: profileImage 화면editDreamPartner
: ageRange, jobOccupation 화면
이 화면들의 구현이 필요합니다.
🔗 Analysis chain
새로운 네비게이션 경로의 처리 여부를 확인해주세요.
새로 추가된 프로필 수정 관련 화면들이 네비게이션 스택에서 올바르게 처리되는지 확인이 필요합니다.
Also applies to: 169-180
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# NavigationStack에서 새로운 PathType 케이스들의 처리 여부 확인
# NavigationStack 파일에서 새로운 케이스 처리 확인
rg -A 5 "case [.]editProfile|case [.]editDreamPartner" --type swift
Length of output: 2299
public var companyName: String? | ||
public let jobOccupation: String | ||
public let jobOccupationRawValue: String | ||
public let locations: [LocationModel] | ||
public var jobOccupationRawValue: String | ||
public var locations: [LocationModel] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jobOccupation
과 jobOccupationRawValue
간의 일관성 보장 필요
jobOccupation
은 let
으로 유지되는 반면 jobOccupationRawValue
는 var
로 변경되었습니다. 이로 인해 두 속성 간의 불일치가 발생할 수 있습니다. 다음 두 가지 해결 방안을 고려해보세요:
jobOccupation
을 computed property로 변경jobOccupationRawValue
수정 시jobOccupation
도 함께 업데이트하는 로직 추가
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
🧹 Outside diff range and nitpick comments (15)
Projects/Core/NetworkKit/Sources/ProfileService/ProfileServiceMock.swift (1)
31-35
: Mock 구현이 일관된 패턴을 따르고 있습니다.다음 사항들이 적절하게 구현되었습니다:
- 기존 메서드들과 동일한 형식의 성공 메시지 출력
- ProfileServiceProtocol 요구사항 준수
- async/throws 키워드의 올바른 사용
하나의 개선사항을 제안드립니다:
실제 서비스에서 발생할 수 있는 다양한 시나리오 테스트를 위해 에러 케이스도 추가하는 것이 좋을 것 같습니다. 다음과 같은 구현을 고려해보세요:
public func requestPutUserInfo(userInfo: UserInfo) async throws { + // 테스트를 위한 에러 케이스 추가 + guard userInfo.occupation != "invalid_occupation" else { + throw NetworkError.invalidRequest + } print("✅ [ProfileServiceMock] requestPutUserInfo 성공!") return }Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobModel.swift (4)
17-17
: MARK 주석 형식을 수정해주세요Swift 스타일 가이드라인에 따라 MARK 주석 형식을 수정해야 합니다.
다음과 같이 수정해주세요:
- //MARK: Stateful + // MARK: - Stateful - //MARK: State Properties + // MARK: - State Properties -//MARK: - Actionable +// MARK: - ActionableAlso applies to: 32-32, 60-60
🧰 Tools
🪛 SwiftLint (0.57.0)
[Warning] 17-17: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 17-17: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
37-48
: 검증 로직을 단순화할 수 있습니다현재 검증 로직이 중첩된 조건문으로 인해 복잡해 보입니다. 가독성을 높이기 위해 로직을 단순화하는 것이 좋겠습니다.
다음과 같이 수정하는 것을 제안합니다:
var isValidated: Bool { - if let userInfo, - let singleSelectedJob { - if userInfo.profile.jobOccupationRawValue == singleSelectedJob.rawValue { - return false - } - } else { - return false - } - - return true + guard let userInfo = userInfo, + let singleSelectedJob = singleSelectedJob else { + return false + } + return userInfo.profile.jobOccupationRawValue != singleSelectedJob.rawValue }
28-29
: 에러 처리 방식에 대한 문서화가 필요합니다
showErrorView
와showErrorAlert
의 사용 목적과 차이점을 명확히 하는 문서화가 필요합니다.각 에러 처리 방식에 대해 다음과 같이 문서 주석을 추가해주세요:
// error + /// 화면 전체에 표시되는 에러 뷰를 위한 에러 모델 var showErrorView: ErrorModel? { get } + /// 팝업 형태로 표시되는 에러 알럿을 위한 에러 모델 var showErrorAlert: ErrorModel? { get }Also applies to: 90-99
15-56
: 단위 테스트 추가를 권장합니다상태 관리와 검증 로직이 잘 구현되어 있습니다. 하지만 이러한 비즈니스 로직의 신뢰성을 보장하기 위해 단위 테스트가 필요합니다.
다음 사항들에 대한 테스트 케이스 작성을 권장드립니다:
isValidated
속성의 다양한 조건에 대한 테스트- 에러 상태 관리에 대한 테스트
- 직군 선택 상태 변경에 대한 테스트
테스트 코드 작성을 도와드릴까요?
🧰 Tools
🪛 SwiftLint (0.57.0)
[Warning] 17-17: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 32-32: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 17-17: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 32-32: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobIntent.swift (2)
16-16
: MARK 주석 형식을 수정해주세요Swift 스타일 가이드라인에 따라 MARK 주석 형식을 수정해야 합니다.
다음과 같이 수정해주세요:
-//MARK: - Intent +// MARK: - Intent -//MARK: - Intentable +// MARK: - IntentableAlso applies to: 38-38, 57-57
🧰 Tools
🪛 SwiftLint (0.57.0)
[Warning] 16-16: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 16-16: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
86-91
: 프로필 업데이트 전 유효성 검증을 추가해주세요프로필 정보 업데이트 전에 필수 필드에 대한 유효성 검증이 필요합니다.
다음과 같은 개선을 제안드립니다:
func requestEditProfile(newUserInfo: UserInfo) async throws { - + // 필수 필드 유효성 검증 + guard !newUserInfo.profile.jobOccupationRawValue.isEmpty else { + throw ProfileError.invalidJobOccupation + } + try await profileService.requestPutUserInfo( userInfo: newUserInfo ) }Projects/Features/Home/Sources/Profile/ProfileIntent.swift (1)
Line range hint
124-127
: 심각: 위젯 삭제 기능이 동작하지 않습니다.현재 구현에서 다음과 같은 문제점이 있습니다:
- 하드코딩된 에러가 항상 발생하여 실제 API 호출이 실행되지 않습니다.
- 에러의 domain과 code가 의미 없는 값으로 설정되어 있습니다.
다음과 같이 수정해주세요:
func requestDeleteWidget(_ widget: ProfileWidget) async throws { - throw NSError(domain: "33", code: 33) try await profileService.requestDeleteProfileWidget(widgetType: widget.widgetType.toDto) }
Projects/App/Sources/Navigation/NavigationStack.swift (1)
83-91
: 이상적인 파트너 편집 기능이 구현되지 않았습니다.모든 서브뷰가
EmptyView()
를 반환하고 있습니다. 이는 아직 구현되지 않은 상태를 나타냅니다. PR의 목적이 프로필 수정 기능 구현이므로, 이상적인 파트너 편집 기능은 별도의 PR로 분리하는 것이 좋을 것 같습니다.현재 PR의 범위를 프로필 수정으로 한정하고, 이상적인 파트너 편집 기능은 새로운 PR로 분리하는 것을 제안드립니다.
Projects/Core/CommonKit/Sources/Path/PathTypes.swift (1)
91-104
: 문자열 관리 개선을 고려해보세요.'수정'이라는 단어가 여러 번 반복되고 있습니다. 문자열을 상수로 분리하거나 지역화 파일로 관리하는 것을 고려해보세요.
예시 리팩토링:
+ private enum LocalizedString { + static let edit = "수정" + } case .editProfile(let subView): switch subView { - case .profileImage: return "프로필 이미지 수정" - case .jobOccupation: return "직군 수정" + case .profileImage: return "프로필 이미지 \(LocalizedString.edit)" + case .jobOccupation: return "직군 \(LocalizedString.edit)" // ... 나머지 케이스들도 동일하게 적용Projects/Model/Model/Sources/Auth/Domain/UserInfo.swift (2)
61-61
: 프로필 수정 관련 프로퍼티 변경 승인직무 정보 수정 기능 구현을 위한 적절한 프로퍼티 변경입니다. 다만, 프로퍼티들의 업데이트 로직을 명확히 하기 위해 다음과 같은 개선을 제안드립니다:
public struct UserInfoProfile { + // MARK: - Mutable Properties for Profile Update public var companyName: String? public var jobOccupationRawValue: String public var locations: [LocationModel]
Also applies to: 63-64
66-68
: jobOccupationDTO 계산 프로퍼티 개선 제안계산 프로퍼티의 구현이 간단하고 명확하나, 다음과 같은 개선사항을 고려해보시기 바랍니다:
- 실패 가능한 변환에 대한 로깅 추가
- 잘못된 rawValue 처리를 위한 에러 핸들링
public var jobOccupationDTO: Components.Schemas.JobOccupation? { + // TODO: Add logging for debugging purposes return .init(rawValue: jobOccupationRawValue) }
Projects/Features/Home/Sources/ProfilePannel/ProfilePannelView.swift (1)
201-209
: 접근성 개선을 위한 제안사항이 있습니다.현재 구현은 기능적으로는 문제가 없으나, 다음과 같은 개선사항을 고려해보시면 좋겠습니다:
DesignCore.Images.pencil1
대신 SF Symbols의pencil
아이콘 사용을 고려해보세요.- 고정된 프레임 크기 대신 Dynamic Type을 지원하는 방식으로 수정하면 좋겠습니다.
-DesignCore.Images.pencil1.image - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 18, height: 18) +Image(systemName: "pencil") + .imageScale(.medium) + .font(.body)Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobView.swift (2)
41-41
: 하드코딩된 문자열을 로컬라이즈하세요사용자 인터페이스에 표시되는 문자열은 로컬라이제이션을 통해 관리되어야 합니다. 이를 통해 다국어 지원과 유지 보수성을 향상시킬 수 있습니다.
Also applies to: 73-73, 86-86
85-85
: 키보드로 인한 안전 영역을 무시하지 않는 것이 좋습니다
.ignoresSafeArea(.keyboard)
를 사용하면 키보드로 인해 중요한 UI 요소가 가려질 수 있습니다. 키보드 나타남에 따라 뷰를 자동으로 조정하도록 구현하는 것이 사용자 경험 측면에서 더 좋습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (16)
OpenApiGenerator/Sources/OpenapiGenerated/Client.swift
(2 hunks)OpenApiGenerator/Sources/OpenapiGenerated/Types.swift
(10 hunks)OpenApiGenerator/Sources/openapi-generator-cli/3days-oas
(1 hunks)Projects/App/Sources/Navigation/NavigationStack.swift
(1 hunks)Projects/Core/CommonKit/Sources/Path/PathTypes.swift
(4 hunks)Projects/Core/NetworkKit/Sources/ProfileService/ProfileService.swift
(2 hunks)Projects/Core/NetworkKit/Sources/ProfileService/ProfileServiceMock.swift
(2 hunks)Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobIntent.swift
(1 hunks)Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobModel.swift
(1 hunks)Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobView.swift
(1 hunks)Projects/Features/Home/Sources/Profile/ProfileIntent.swift
(1 hunks)Projects/Features/Home/Sources/ProfilePannel/ProfilePannelIntent.swift
(2 hunks)Projects/Features/Home/Sources/ProfilePannel/ProfilePannelView.swift
(5 hunks)Projects/Features/Home/UnitTest/EditProfileJobOccupationTest.swift
(1 hunks)Projects/Features/Home/UnitTest/WidgetUnitTest.swift
(1 hunks)Projects/Model/Model/Sources/Auth/Domain/UserInfo.swift
(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- OpenApiGenerator/Sources/openapi-generator-cli/3days-oas
🧰 Additional context used
🪛 SwiftLint (0.57.0)
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobIntent.swift
[Warning] 16-16: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 38-38: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 57-57: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 16-16: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 38-38: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 57-57: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobModel.swift
[Warning] 17-17: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 32-32: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 60-60: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 17-17: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 32-32: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 60-60: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
🔇 Additional comments (16)
Projects/Features/Home/UnitTest/EditProfileJobOccupationTest.swift (1)
9-11
: 테스트에 필요한 모듈이 모두 import 되었는지 확인이 필요합니다.
현재 Testing, Home, NetworkKit만 import되어 있습니다. 테스트에서 사용되는 모든 타입들이 이 모듈들에 포함되어 있는지 확인해주세요.
✅ Verification successful
현재 import된 모듈들로 충분합니다.
검증 결과, 테스트에서 사용되는 모든 타입들이 현재 import된 모듈들을 통해 접근 가능합니다:
EditProfileJobModel
,EditProfileJobIntent
는@testable import Home
을 통해 접근 가능합니다 (Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/ 경로에서 확인)ProfileServiceMock
은 테스트 파일 내에서 정의되거나Testing
모듈에서 제공되는 것으로 보입니다NetworkKit
은 서비스 관련 기능을 위해 필요합니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if all required types are available in imported modules
# Search for all custom types used in the test file
rg -o --no-filename '(\w+Model|\w+Intent|\w+Service|\w+Mock)' Projects/Features/Home/UnitTest/EditProfileJobOccupationTest.swift | sort -u | while read type; do
echo "Searching for type: $type"
rg "class $type|struct $type|protocol $type"
done
Length of output: 347
Script:
#!/bin/bash
# Let's check the content of the test file first to understand the types being used
cat Projects/Features/Home/UnitTest/EditProfileJobOccupationTest.swift
# Then search for the implementation of these types in the Home module
echo "Searching for related types in Home module..."
fd . Projects/Features/Home -e swift -E "*Test.swift" --exec rg -l "class|struct|protocol.*(?:EditProfileJob|Intent|Model)"
Length of output: 2347
Projects/Core/NetworkKit/Sources/ProfileService/ProfileServiceMock.swift (1)
12-12
: Model 모듈 import 추가가 적절합니다.
UserInfo 타입을 사용하기 위해 필요한 import문이 올바르게 추가되었습니다.
Projects/Features/Home/Sources/ProfilePannel/ProfilePannelIntent.swift (2)
33-33
: 프로토콜 메서드 선언이 적절합니다.
프로토콜에 직군 정보 수정 아이콘 탭 이벤트를 처리하는 메서드가 잘 정의되어 있습니다.
58-72
: 🛠️ Refactor suggestion
직군 정보 수정 화면 전환 로직 개선이 필요합니다.
현재 구현에서 몇 가지 개선이 필요한 부분이 있습니다:
- userInfo가 없는 경우에 대한 처리가 누락되어 있습니다.
- Task와 MainActor의 중첩 사용이 불필요해 보입니다.
다음과 같이 개선하는 것을 제안드립니다:
func onTapEditJobOccupationIcon() {
- Task {
- await MainActor.run {
- if let userInfo = AppCoordinator.shared.userInfo {
- AppCoordinator.shared.push(
- .editProfile(
- .jobOccupation(
- userInfo
- )
- )
- )
- }
- }
+ guard let userInfo = AppCoordinator.shared.userInfo else {
+ // TODO: 사용자 정보가 없는 경우 에러 처리
+ return
}
+
+ AppCoordinator.shared.push(
+ .editProfile(
+ .jobOccupation(
+ userInfo
+ )
+ )
+ )
}
또한, 다음 사항들도 검토해 주시기 바랍니다:
- 화면 전환 전에 사용자 정보 유효성 검증이 필요한지
- 에러 상황에 대한 사용자 피드백 처리 방안
Projects/Core/NetworkKit/Sources/ProfileService/ProfileService.swift (1)
23-24
: 프로토콜 메서드 선언이 명확합니다!
비동기 처리와 에러 핸들링이 적절하게 구현되어 있습니다.
Projects/Features/Home/UnitTest/WidgetUnitTest.swift (2)
36-36
: 초기 content 값이 nil인 이유에 대한 검증 필요
content: nil
로 초기화하는 것이 의도된 것인지 확인이 필요합니다. 이는 잠재적인 null 참조 문제를 야기할 수 있습니다.
다음 사항들을 확인해주세요:
- nil 상태에서의 위젯 동작 검증
- content가 nil일 때의 예외 처리 로직 검증
36-38
: 🛠️ Refactor suggestion
성공 핸들러에 대한 테스트 케이스 추가 필요
successHandler
가 비어있는 상태로 구현되어 있습니다. 성공 시나리오에 대한 테스트 커버리지가 누락되어 있을 수 있습니다.
다음과 같은 테스트 케이스 추가를 제안드립니다:
- 성공 핸들러 호출 여부 검증
- 성공 시나리오에서의 상태 변화 검증
예시 구현:
@Test func onTapNextButton() async throws {
writeIntent.onTapNextButton(state: writeState)
- // 3초 후 실행
try await Task.sleep(for: .seconds(1))
#expect(writeState.isModalPresented == false)
+ // 성공 핸들러 호출 검증
+ var successHandlerCalled = false
+ writeIntent.input.successHandler = {
+ successHandlerCalled = true
+ }
+ #expect(successHandlerCalled == true)
}
Projects/Features/Home/Sources/Profile/ProfileIntent.swift (1)
92-94
: 비동기 처리가 올바르게 구현되었습니다! 👍
Task를 사용하여 비동기 작업을 적절하게 처리하고 있습니다.
Projects/App/Sources/Navigation/NavigationStack.swift (1)
71-81
: 프로필 편집 기능 구현이 완료되지 않았습니다.
현재 EditProfileJobView
만 구현되어 있고 나머지 뷰들은 EmptyView()
를 반환하고 있습니다. 프로필 이미지, 회사, 지역 정보 수정 기능의 구현 계획을 명확히 해주시기 바랍니다.
구현이 필요한 나머지 뷰들에 대한 기본 구조를 제공해드릴까요?
Projects/Core/CommonKit/Sources/Path/PathTypes.swift (1)
29-30
: 새로운 PathType 케이스가 적절히 추가되었습니다!
프로필 수정과 이상형 수정을 위한 새로운 케이스가 기존 코드 스타일을 잘 따르고 있습니다.
Projects/Model/Model/Sources/Auth/Domain/UserInfo.swift (1)
16-17
: 불변성(Immutability) 변경에 대한 안전성 검토 필요
핵심 사용자 정보를 담고 있는 profile
과 dreamPartner
프로퍼티를 가변(var
)으로 변경하는 것은 프로필 수정 기능을 위해 필요하지만, 예기치 않은 상태 변경의 위험이 있습니다.
다음 사항들을 확인해주세요:
- 상태 변경이 일어나는 시점이 명확한지
- 동시성 관련 이슈는 없는지
- 상태 변경 후 적절한 validation이 이루어지는지
Projects/Features/Home/Sources/ProfilePannel/ProfilePannelView.swift (2)
84-88
: 직군 수정 기능이 적절하게 구현되었습니다!
MVI 패턴을 잘 따르고 있으며, 사용자 인터랙션 처리가 깔끔하게 구현되었습니다.
184-186
: 메서드 시그니처가 적절하게 확장되었습니다!
새로운 파라미터들이 잘 정의되어 있으며, 옵셔널 핸들러의 기본값 처리가 적절합니다.
OpenApiGenerator/Sources/OpenapiGenerated/Client.swift (1)
662-663
: HTTP 메소드 변경에 대한 설계 검토
PATCH에서 PUT으로의 변경이 RESTful 설계 원칙에 부합하는지 확인이 필요합니다. PUT은 리소스의 전체 교체를 의미하므로, 부분 업데이트가 필요한 경우 PATCH가 더 적절할 수 있습니다.
Also applies to: 675-675
✅ Verification successful
Let me gather more information about the API specification and implementation to better understand the HTTP method change.
PUT 메소드 사용이 적절함을 확인
OpenAPI 생성 코드와 ProfileService의 구현을 검토한 결과, PUT 메소드로의 변경이 적절합니다. 해당 엔드포인트는 사용자 정보의 전체 업데이트를 위한 것으로 보이며, 일관되게 PUT으로 구현되어 있습니다.
ProfileService
에서updateMyUserInfo
는 PUT 메소드를 사용하여 구현됨- OpenAPI 스펙에서도
/users/my
엔드포인트가 PUT으로 정의됨 - 전체 코드베이스에서 이 엔드포인트에 대한 PATCH 사용 사례가 발견되지 않음
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: PUT 메소드가 일관되게 사용되는지 확인
# 다른 파일에서 동일한 엔드포인트를 호출하는 부분 검색
# API 호출 패턴 검색
rg -A 3 "users/my.*PATCH|users/my.*PUT" --type swift
# ProfileService 클래스에서 관련 메소드 검색
ast-grep --pattern 'class ProfileService {
$$$
func $_(userInfo: UserInfo) {
$$$
}
$$$
}'
Length of output: 2173
Script:
#!/bin/bash
# Check OpenAPI specification files for the endpoint definition
fd -e yaml -e json . | xargs rg -A 5 "/users/my"
# Look for any related test files or documentation
rg -g "!*.generated.*" -g "!*.gen.*" "updateMyUserInfo" --type swift
Length of output: 4490
OpenApiGenerator/Sources/OpenapiGenerated/Types.swift (2)
Line range hint 2383-2514
: 작업 구조 변경 검토 완료
updateMyUserInfo 작업의 구조가 PUT 메소드에 맞게 적절히 업데이트되었으며, 에러 처리도 기존과 동일하게 잘 유지되어 있습니다.
53-54
: HTTP 메소드 변경에 따른 주의사항
PATCH에서 PUT으로의 변경은 클라이언트 측에서 부분 업데이트가 아닌 전체 리소스 상태를 전송해야 함을 의미합니다. 클라이언트 코드가 이 변경사항을 올바르게 처리하는지 확인이 필요합니다.
Also applies to: 186-187, 2378-2379
✅ Verification successful
PUT 메소드 변경은 적절하게 구현되어 있습니다
코드 검토 결과, PUT 메소드로의 변경이 다음과 같은 이유로 적절하게 구현되어 있음을 확인했습니다:
- 필수 필드인
name
,jobOccupation
,locationIds
가 명확하게 정의되어 있습니다 - 선택적 필드인
companyId
와allowSameCompany
가 옵셔널로 올바르게 처리되어 있습니다 - API 문서에 프로필 정보 전체를 수정하는 엔드포인트임이 명시되어 있습니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify if there are any remaining PATCH references in the codebase
# Check for PATCH references in Swift files
rg -l "PATCH.*?/users/my" --type swift
# Check for PATCH references in API documentation or configuration files
rg -l "PATCH.*?/users/my" --type yaml --type json
Length of output: 92
Script:
#!/bin/bash
# Let's verify the HTTP method change more thoroughly
# Check for any PUT references to /users/my
echo "=== Checking PUT /users/my references ==="
rg "PUT.*?/users/my" --type swift -A 2 -B 2
# Check for any method references to /users/my in yaml/json files
echo "=== Checking API specs for /users/my endpoint ==="
rg "/users/my" --type yaml --type json -A 5 -B 5
# Look for UpdateMyUserInfo related code
echo "=== Checking UpdateMyUserInfo implementation ==="
ast-grep --pattern 'struct UpdateMyUserInfoRequest'
Length of output: 2591
Script:
#!/bin/bash
# Let's check the UpdateMyUserInfoRequest structure to understand the required fields
echo "=== Checking UpdateMyUserInfoRequest structure ==="
rg "struct UpdateMyUserInfoRequest" --type swift -A 20
echo "=== Checking for any documentation about required fields ==="
rg "UpdateMyUserInfoRequest" --type swift -B 5 -A 1 | grep -E "(///|//)"
Length of output: 4843
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobIntent.swift
Show resolved
Hide resolved
Projects/Features/Home/Sources/Profile/EditProfile/EditProfileJob/EditProfileJobIntent.swift
Show resolved
Hide resolved
public enum EditProfileViewType { | ||
case profileImage(UserInfo) | ||
case jobOccupation(UserInfo) | ||
case company(UserInfo) | ||
case region(UserInfo) | ||
} | ||
|
||
public enum EditDreamPartnerViewType { | ||
case ageRange(UserInfo) | ||
case jobOccupation(UserInfo) | ||
case distance(UserInfo) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
새로운 enum들에 Hashable 프로토콜 준수가 필요합니다.
EditProfileViewType
과 EditDreamPartnerViewType
이 다른 enum들처럼 Hashable
을 준수하도록 수정이 필요합니다. 이는 향후 이 타입들을 컬렉션이나 비교 연산에서 사용할 때 필요할 수 있습니다.
다음과 같이 수정해주세요:
- public enum EditProfileViewType {
+ public enum EditProfileViewType: Hashable {
case profileImage(UserInfo)
case jobOccupation(UserInfo)
case company(UserInfo)
case region(UserInfo)
}
- public enum EditDreamPartnerViewType {
+ public enum EditDreamPartnerViewType: Hashable {
case ageRange(UserInfo)
case jobOccupation(UserInfo)
case distance(UserInfo)
}
Committable suggestion skipped: line range outside the PR's diff.
구현사항
스크린샷(선택)
Summary by CodeRabbit
New Features
변경 사항
버그 수정