[FEAT] 직원 재직 상태 추가#31
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the 요약Walkthrough직원 상태 관리 기능을 전체 스택에 추가합니다. 새로운 EmployeeStatus 열거형, API 엔드포인트, 매퍼, 저장소 메서드, UseCase, ViewModel, 하단시트 UI를 구현했습니다. 기존 직원 편집 UI는 상태 편집과 위치 편집으로 분리됩니다. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant EmployeeListScreen
participant UpdateEmployeeStatusBottomSheet
participant UpdateEmployeeStatusViewModel
participant UpdateEmployeeStatusUseCase
participant UserRepository
participant UserApi
User->>EmployeeListScreen: 직원 상태 편집 클릭
EmployeeListScreen->>UpdateEmployeeStatusBottomSheet: 표시 (ShowStatusBottomSheet)
User->>UpdateEmployeeStatusBottomSheet: 상태 선택 및 확인
UpdateEmployeeStatusBottomSheet->>UpdateEmployeeStatusViewModel: onEvent(EditEmployeeStatus)
UpdateEmployeeStatusViewModel->>UpdateEmployeeStatusUseCase: invoke(employee, workspace)
UpdateEmployeeStatusUseCase->>UserRepository: updateEmployeeStatus()
UserRepository->>UserApi: updateEmployeeStatus(PATCH /user/status/{userId})
UserApi-->>UserRepository: UpdateEmployeeStatusResponseDto
UserRepository-->>UpdateEmployeeStatusUseCase: Result<Employee>
UpdateEmployeeStatusUseCase-->>UpdateEmployeeStatusViewModel: Result<Employee>
rect rgb(200, 150, 255)
UpdateEmployeeStatusViewModel->>UpdateEmployeeStatusViewModel: isSuccess=true
UpdateEmployeeStatusViewModel->>UpdateEmployeeStatusBottomSheet: onStatusUpdated(employee)
end
UpdateEmployeeStatusBottomSheet->>EmployeeListScreen: 하단시트 닫기
EmployeeListScreen->>EmployeeListScreen: 직원 목록 새로고침
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 분 검토 시 주의:
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
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 |
|
@coderabbitai review --force |
|
@Sangyoon98: I'll perform a comprehensive review of the changes in this PR. ✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (3)
app/src/main/java/com/sampoom/android/feature/cart/ui/CartListScreen.kt (1)
34-34: 사용되지 않는 import 제거 필요
androidx.compose.ui.draw.shadowimport가 파일 34번 줄에 추가되었으나, 전체 파일을 검토한 결과 실제로 사용되지 않습니다..shadow()modifier를 사용하는 코드가 없으므로 해당 import를 제거하면 됩니다.app/src/main/java/com/sampoom/android/feature/user/ui/EmployeeListUiState.kt (1)
9-10: 일관성을 위해 trailing comma를 통일하는 것을 고려하세요.Line 9의
selectedEmployee에는 trailing comma가 없고, Line 10의bottomSheetType에는 있습니다. Kotlin 컨벤션에 따라 모든 프로퍼티에 trailing comma를 추가하면 향후 프로퍼티 추가 시 diff가 깔끔해집니다.- val selectedEmployee: Employee? = null, - val bottomSheetType: EmployeeBottomSheetType? = null + val selectedEmployee: Employee? = null, + val bottomSheetType: EmployeeBottomSheetType? = null,app/src/main/java/com/sampoom/android/feature/user/ui/UpdateEmployeeStatusViewModel.kt (1)
73-73: 하드코딩된 문자열을 상수로 추출 권장
"AGENCY"문자열이 하드코딩되어 있습니다. 유지보수성 향상을 위해 상수로 추출하는 것을 권장합니다.companion object에 상수를 추가하세요:
private companion object { private const val TAG = "UpdateEmployeeStatusViewModel" + private const val USER_TYPE_AGENCY = "AGENCY" }그리고 사용처를 수정하세요:
-updateEmployeeStatusUseCase(updateEmployee, "AGENCY") +updateEmployeeStatusUseCase(updateEmployee, USER_TYPE_AGENCY)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (29)
app/src/main/java/com/sampoom/android/core/model/EmployeeStatus.kt(1 hunks)app/src/main/java/com/sampoom/android/core/ui/component/CommonButton.kt(2 hunks)app/src/main/java/com/sampoom/android/core/util/EmployeeStatusToKorean.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/cart/ui/CartListScreen.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/outbound/ui/OutboundListScreen.kt(3 hunks)app/src/main/java/com/sampoom/android/feature/part/ui/PartDetailBottomSheet.kt(3 hunks)app/src/main/java/com/sampoom/android/feature/part/ui/PartListScreen.kt(2 hunks)app/src/main/java/com/sampoom/android/feature/part/ui/PartScreen.kt(4 hunks)app/src/main/java/com/sampoom/android/feature/user/data/mapper/UserMappers.kt(3 hunks)app/src/main/java/com/sampoom/android/feature/user/data/remote/api/UserApi.kt(2 hunks)app/src/main/java/com/sampoom/android/feature/user/data/remote/dto/EmployeeDto.kt(2 hunks)app/src/main/java/com/sampoom/android/feature/user/data/remote/dto/UpdateEmployeeStatusRequestDto.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/data/remote/dto/UpdateEmployeeStatusResponseDto.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/data/repository/UserRepositoryImpl.kt(3 hunks)app/src/main/java/com/sampoom/android/feature/user/domain/model/Employee.kt(2 hunks)app/src/main/java/com/sampoom/android/feature/user/domain/repository/UserRepository.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/domain/usecase/UpdateEmployeeStatusUseCase.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/ui/EditEmployeeBottomSheet.kt(4 hunks)app/src/main/java/com/sampoom/android/feature/user/ui/EditEmployeeViewModel.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/ui/EmployeeBottomSheetType.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/ui/EmployeeListScreen.kt(10 hunks)app/src/main/java/com/sampoom/android/feature/user/ui/EmployeeListUiEvent.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/ui/EmployeeListUiState.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/ui/EmployeeListViewModel.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/ui/UpdateEmployeeStatusBottomSheet.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/ui/UpdateEmployeeStatusUiEvent.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/ui/UpdateEmployeeStatusUiState.kt(1 hunks)app/src/main/java/com/sampoom/android/feature/user/ui/UpdateEmployeeStatusViewModel.kt(1 hunks)app/src/main/res/values/strings.xml(1 hunks)
🔇 Additional comments (37)
app/src/main/java/com/sampoom/android/feature/part/ui/PartListScreen.kt (3)
8-8: LGTM! 필요한 import 추가Spacer와 width 사용을 위한 import가 올바르게 추가되었습니다.
Also applies to: 13-13
257-258: LGTM! 시각적 간격 개선수량 정보와 chevron 아이콘 사이에 8.dp 간격을 추가하여 카드 레이아웃의 시각적 균형을 개선했습니다.
262-262: LGTM! 의미적으로 올바른 색상 사용Chevron 아이콘의 tint를
disableColor()에서textSecondaryColor()로 변경하여 클릭 가능한 요소에 더 적합한 색상을 사용하도록 개선했습니다.app/src/main/java/com/sampoom/android/feature/outbound/ui/OutboundListScreen.kt (2)
100-102: LGTM!modifier 포맷팅이 개선되어 가독성이 향상되었습니다.
204-204: 버튼 variant 변경이 적절하지만 PR 범위와 무관합니다.
ButtonVariant.Error에서ButtonVariant.Secondary로 변경한 것은 주문 버튼의 의미에 더 적합합니다. Error variant는 일반적으로 삭제와 같은 위험한 작업에 사용되므로, Secondary variant가 더 적절합니다.그러나 이 변경 사항은 PR 제목 "[FEAT] 직원 재직 상태 추가"와 관련이 없어 보입니다. 이 변경이 의도적으로 포함된 것인지 확인이 필요합니다.
app/src/main/java/com/sampoom/android/feature/part/ui/PartDetailBottomSheet.kt (1)
206-217: 버튼 variant 변경이 적절합니다.출고 추가 버튼의 variant를
Error에서Secondary로 변경한 것은 의미적으로 올바른 개선입니다. 출고 추가는 오류나 위험한 작업이 아니므로 중립적인 Secondary variant가 더 적합합니다.다만, 이 파일은 부품(Part) 관련 기능인데 PR 제목이 "직원 재직 상태 추가"인 점이 의아합니다. 이 변경사항이 해당 PR에 포함된 이유를 확인해주세요.
app/src/main/java/com/sampoom/android/feature/part/ui/PartScreen.kt (1)
15-15: UI 일관성 개선이 적절합니다셰브론 아이콘의 색상을
disableColor()에서textSecondaryColor()로 변경하고 8dp 간격을 추가한 것은 좋은 개선입니다. 이러한 변경사항은PartItemCard와SearchPartItem간의 시각적 일관성을 높이며, 다른 파일의 유사한 업데이트와도 정렬됩니다.Also applies to: 524-524, 649-655
app/src/main/java/com/sampoom/android/core/ui/component/CommonButton.kt (1)
85-95: Secondary 버튼의 색상 대비와 의미적 명확성을 검증하세요.Secondary 버튼이 filled tonal 스타일에서
Main300.copy(alpha = 0.3f)배경과Main500테두리를 가진 outlined 스타일로 변경되었습니다. 다음을 확인하세요:
WCAG 색상 대비: Main500 텍스트(#8080FF)와 Main300 0.3 알파 배경(#B3B3FF)의 조합이 흰색/어두운 배경에서 WCAG AA 기준(4.5:1)을 충족하는지 검증하세요. 특히 밝은 배경에서 충분한 명도 대비가 있는지 확인하세요.
Outlined 변형과의 의미적 구분: Secondary와 Outlined 변형의 시각적 차이가 명확한지 확인하세요. 두 변형이 모두 Main500 테두리와 contentColor를 사용한다면, 사용자가 의도를 구분할 수 있어야 합니다.
비활성화 상태:
disabledContainerColor가 명시적으로 설정되어 있는지 확인하고, 의도한 동작이 맞는지 검증하세요.app/src/main/java/com/sampoom/android/core/model/EmployeeStatus.kt (1)
1-7: LGTM!EmployeeStatus enum이 명확하게 정의되어 있으며, 각 상태에 대한 한글 주석이 이해를 돕습니다. 구현이 깔끔하고 올바릅니다.
app/src/main/java/com/sampoom/android/feature/user/data/remote/dto/UpdateEmployeeStatusResponseDto.kt (1)
1-8: LGTM!UpdateEmployeeStatusResponseDto가 올바르게 정의되어 있습니다. DTO 레이어에서 employeeStatus를 String으로 처리하는 것은 적절하며, 도메인 레이어에서 EmployeeStatus enum으로 매핑될 것으로 예상됩니다.
app/src/main/java/com/sampoom/android/feature/user/data/remote/dto/EmployeeDto.kt (2)
3-3: LGTM!EmployeeStatus import가 적절하게 추가되었습니다.
15-15: LGTM!employeeStatus 필드가 nullable로 추가되어 기존 데이터와의 호환성을 유지할 수 있습니다. 적절한 구현입니다.
app/src/main/java/com/sampoom/android/core/util/EmployeeStatusToKorean.kt (1)
1-10: LGTM!employeeStatusToKorean 함수가 명확하게 구현되어 있습니다. null 처리와 기본값 반환이 적절하며, 각 상태에 대한 한글 매핑이 올바릅니다.
app/src/main/java/com/sampoom/android/feature/user/ui/EditEmployeeViewModel.kt (1)
32-35: LGTM!bindLabel 함수에서 deleteEmployee 파라미터가 제거된 것은 직원 상태 편집과 위치 편집을 분리하는 리팩토링의 일부로 적절합니다. 변경사항이 PR의 목적과 일치합니다.
app/src/main/java/com/sampoom/android/feature/user/ui/EmployeeBottomSheetType.kt (1)
1-6: LGTM!EmployeeBottomSheetType enum이 명확하게 정의되어 있습니다. STATUS와 EDIT 두 가지 바텀시트 타입을 구분하기에 적절한 구조입니다.
app/src/main/java/com/sampoom/android/feature/user/data/remote/dto/UpdateEmployeeStatusRequestDto.kt (1)
1-5: LGTM!UpdateEmployeeStatusRequestDto가 올바르게 정의되어 있습니다. 간단하고 명확한 구조로 API 요청에 적합합니다.
app/src/main/java/com/sampoom/android/feature/user/ui/EmployeeListUiEvent.kt (1)
8-9: LGTM! 깔끔한 이벤트 분리재직 상태 변경과 직급 편집을 별도 이벤트로 분리한 것은 관심사의 명확한 분리를 제공하며 코드 가독성과 유지보수성을 향상시킵니다.
app/src/main/java/com/sampoom/android/feature/user/ui/EmployeeListViewModel.kt (1)
43-44: LGTM! 명확한 상태 관리각 바텀시트 타입에 따라 적절히 상태를 업데이트하고 있으며, 불변성을 유지하는
copy()를 사용하여 안전하게 구현되었습니다.app/src/main/java/com/sampoom/android/feature/user/domain/repository/UserRepository.kt (1)
14-14: LGTM! 일관성 있는 메서드 시그니처새로운
updateEmployeeStatus메서드가 기존editEmployee메서드와 동일한 패턴을 따르고 있어 일관성이 유지됩니다.app/src/main/java/com/sampoom/android/feature/user/data/remote/api/UserApi.kt (1)
40-45: LGTM! RESTful한 API 엔드포인트 설계새로운
updateEmployeeStatus엔드포인트가 기존 API 패턴과 일관성을 유지하며, 상태 업데이트에 적합한PATCH메서드를 사용하고 있습니다.app/src/main/java/com/sampoom/android/feature/user/ui/UpdateEmployeeStatusUiState.kt (1)
1-10: LGTM! 표준 UI 상태 패턴
UpdateEmployeeStatusUiState가 일반적인 UI 상태 관리 패턴을 따르고 있으며, 로딩, 성공, 에러 상태를 명확하게 관리합니다.app/src/main/java/com/sampoom/android/feature/user/domain/model/Employee.kt (1)
3-3: 모든 Employee 생성 코드가 새로운employeeStatus필드로 올바르게 업데이트되었습니다.검증 결과:
- 매퍼 함수 (UserMappers.kt): 3개 모두 employeeStatus 포함 ✓
- EditEmployeeResponseDto.toModel(): EmployeeStatus.ACTIVE로 설정
- UpdateEmployeeStatusResponseDto.toModel(): 응답값으로 설정
- EmployeeDto.toModel(): nullable 처리 후 ACTIVE로 기본값 설정
- 저장소 직접 생성 (UserRepositoryImpl.kt): 2개 모두 employeeStatus 포함 ✓
- editEmployee (line 119): 기존 employee의 employeeStatus 유지
- updateEmployeeStatus (line 153): 업데이트된 employeeStatus 적용
- 테스트: Employee 인스턴스 생성 없음
app/src/main/res/values/strings.xml (1)
122-126: 삭제된 문자열 참조 검증 완료 - 문제 없음검증 결과, 코드베이스에서
employee_delete와employee_edit문자열에 대한 참조가 없으므로 안전하게 삭제되었습니다. 새로운 문자열 리소스(employee_edit_edited,employee_edit_status_edited등)가 코드에서 올바르게 사용 중입니다.app/src/main/java/com/sampoom/android/feature/user/data/mapper/UserMappers.kt (1)
65-77: 상태 문자열 파싱 기본값 처리 👍서버가 알 수 없는 문자열을 내려보내더라도
EmployeeStatus.ACTIVE로 안전하게 폴백하도록 구성하신 덕분에 매핑 안정성이 좋아졌습니다.app/src/main/java/com/sampoom/android/feature/user/domain/usecase/UpdateEmployeeStatusUseCase.kt (1)
7-11: UseCase 위임 구조가 간결합니다Repository에 그대로 위임해 책임 경계가 명확해졌네요. 추가 로직이 없어 테스트와 유지보수 측면에서도 좋습니다.
app/src/main/java/com/sampoom/android/feature/user/ui/EditEmployeeBottomSheet.kt (1)
57-62: 성공 시 콜백 전달 흐름이 명확합니다업데이트 성공 시 부모 콜백을 먼저 호출하고 곧바로 상태를 초기화한 뒤 시트를 닫는 순서라 사이드이펙트가 생길 여지가 거의 없어 보여요. 좋습니다.
app/src/main/java/com/sampoom/android/feature/user/ui/UpdateEmployeeStatusUiEvent.kt (1)
6-9: UI 이벤트 세분화가 명확합니다초기화·편집·닫기 시나리오가 각각의 이벤트로 분리돼 뷰모델 상태 전이가 훨씬 읽기 쉬워졌습니다.
app/src/main/java/com/sampoom/android/feature/user/ui/UpdateEmployeeStatusBottomSheet.kt (3)
48-51: 직원 변경 시 상태 초기화 로직 확인
selectedStatus는 42번 줄에서 이미employee.employeeStatus로 초기화되는데, 50번 줄에서 다시 같은 값으로 설정하고 있습니다. 42번 줄의 초기값만으로 충분하지만,employee객체가 변경될 때 상태를 동기화하는 용도라면 현재 구조가 적절합니다.
57-63: 성공 처리 로직 확인됨상태 업데이트 성공 시 콜백 호출 → 상태 초기화 → 바텀시트 닫기 순서가 적절합니다.
107-113: 버튼 활성화 조건이 적절함로딩 중이 아니고 상태가 변경되었을 때만 버튼이 활성화되어 불필요한 API 호출을 방지합니다.
app/src/main/java/com/sampoom/android/feature/user/ui/EmployeeListScreen.kt (4)
88-94: 바텀시트 상태 관리 로직 확인됨
selectedEmployee와bottomSheetType두 조건을 모두 확인하여 바텀시트를 제어하는 로직이 적절합니다.
231-265: 바텀시트 분기 처리가 잘 구현됨상태 편집과 직급 편집을 별도 바텀시트로 분리하고, 각각 업데이트 후 목록을 새로고침하여 데이터 일관성을 유지하고 있습니다.
283-298: 직원 카드 UI 개선 확인됨직원 이름과 재직 상태를 수평으로 배치하여 정보를 명확하게 표시하고 있습니다.
346-362: 버튼 역할 재정의가 적절함삭제 버튼을 상태 편집 버튼으로 변경하고 variant를 Outlined로 조정하여, 편집 버튼과 시각적으로 구분하고 있습니다.
app/src/main/java/com/sampoom/android/feature/user/ui/UpdateEmployeeStatusViewModel.kt (3)
37-61: 이벤트 처리 로직이 명확함Initialize, EditEmployeeStatus, Dismiss 이벤트를 적절하게 처리하고 상태를 업데이트하고 있습니다.
85-96: 오류 처리가 포괄적으로 구현됨서버 메시지 추출 → 예외 메시지 확인 → 기본 오류 레이블 순으로 fallback하는 로직이 적절합니다.
100-102: 상태 초기화 함수 확인됨성공 상태와 오류를 초기화하는 간단하고 명확한 함수입니다.
📝 Summary
직원 재직 상태 추가
🙏 Question & PR point
📬 Reference
Summary by CodeRabbit
릴리스 노트
새로운 기능
UI/UX 개선