-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] 어르신 일괄 등록 API 연동 #134 #138
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
Conversation
- postElderBulk() 추가 - postElderHealthInfoBulk() 추가
- 현재는 postElderBulk()만 구현된 상태 - TODO: postElderHealthInfoBulk()
…edicare-Call/Medicare-Call-Android into feat/elder-api-bulk-#134
Walkthrough일괄 등록(elders/bulk, elders/health-info/bulk) API 연동을 위해 DTO·Service·Repository를 추가·분리했고, 로그인(어르신 정보/건강 정보) UI를 StateFlow 기반 ViewModel과 불변 상태+콜백 컴포넌트로 재구성했습니다. 일부 import 경로 및 기본값·nullability가 조정되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as 사용자
participant InfoS as LoginElderInfoScreen
participant VM as LoginElderViewModel
participant Repo as ElderRegisterRepository
participant API as ElderRegisterService
participant BE as Backend
U->>InfoS: 어르신 정보 입력/추가/선택
InfoS->>VM: updateElder*(필드)
VM->>VM: elderUiState 업데이트 (StateFlow emit)
U->>InfoS: 다음(일괄 등록)
InfoS->>VM: postElderBulk()
VM->>Repo: postElderBulk(elderList)
Repo->>API: POST /elders/bulk (ElderBulkRegisterRequestDto)
API->>BE: 요청 전달
BE-->>API: 200 + 응답 리스트
API-->>Repo: Response(body)
Repo-->>VM: Result<ElderBulkRegisterResponseDto>
VM->>VM: UI state에 id 동기화
VM-->>InfoS: 상태 업데이트(완료)
sequenceDiagram
autonumber
actor U as 사용자
participant MedS as LoginElderMedInfoScreen
participant VM as LoginElderViewModel
participant Repo as ElderRegisterRepository
participant API as ElderRegisterService
participant BE as Backend
U->>MedS: 질병/약/메모 입력, 시간 선택
MedS->>VM: addDisease/addMedication/selectMedicationTime 등
VM->>VM: elderHealthUiState 업데이트 (StateFlow emit)
U->>MedS: 다음(건강정보 일괄 등록)
MedS->>VM: postElderHealthInfoBulk()
VM->>Repo: postElderHealthInfoBulk(healthList)
Repo->>API: POST /elders/health-info/bulk (ElderBulkHealthInfoRequestDto)
API->>BE: 요청 전달
BE-->>API: 200 OK
API-->>Repo: Response(OK)
Repo-->>VM: Result<Unit>
VM-->>MedS: 완료 신호(상태 갱신)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (11)
app/src/main/java/com/konkuk/medicarecall/ui/feature/settings/screen/MyDetailScreen.kt (1)
47-47: 불필요한 null 체크 제거 가능
isMale이Boolean으로 변경되어 null이 될 수 없으므로, 113번 라인의isMale != null체크와 117번 라인의isMale == true체크는 이제 불필요합니다. 간소화해도 좋을 것 같아요.- && isMale != null- val gender = if (isMale == true) GenderType.MALE else GenderType.FEMALE + val gender = if (isMale) GenderType.MALE else GenderType.FEMALEAlso applies to: 113-113, 117-117
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderChip.kt (1)
41-45: InteractionSource null 사용 개선 권장
clickable수정자에서interactionSource = null을 사용하는 것은 최신 Compose에서 권장되지 않습니다.remember { MutableInteractionSource() }를 사용하는 것이 좋습니다.+import androidx.compose.foundation.interaction.MutableInteractionSource.clickable( indication = null, - interactionSource = null, + interactionSource = remember { MutableInteractionSource() }, onClick = onClick, ),.clickable( indication = null, - interactionSource = null, + interactionSource = remember { MutableInteractionSource() }, onClick = { onRemove() }, ),Also applies to: 66-69
app/src/main/java/com/konkuk/medicarecall/data/dto/response/ElderBulkRegisterResponseDto.kt (1)
6-28: 응답 DTO 명확성 개선 제안 (이름 충돌/가독성)response 패키지의 ElderInfo 명칭이 request 쪽의 ElderInfo(동일 개념의 이름)을 연상시켜 혼동 소지가 있습니다. 응답 모델임을 드러내도록 이름을 구체화하면 유지보수성이 좋아집니다. 또한 guardianId/guardianName 등 필드가 항상 존재하는지 백엔드 스펙을 한 번만 확인 부탁드립니다(없을 수 있으면 nullable 권장).
예시:
-typealias ElderBulkRegisterResponseDto = List<ElderInfo> +typealias ElderBulkRegisterResponseDto = List<ElderInfoResponse> -@Serializable -data class ElderInfo( +@Serializable +data class ElderInfoResponse( ... )app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/screen/LoginElderMedInfoScreen.kt (2)
60-64: selectedIndex 범위 가드 필요uiState.elderHealthList[selectedIndex] 직접 접근은 초기 로딩/동기화 지연 시 IndexOutOfBounds 위험이 있습니다. 사용 전 범위 체크 또는 coerceIn 적용을 권장합니다. 또한 collectAsState 대신 collectAsStateWithLifecycle 사용을 고려해 수명주기 안전성을 높이세요.
예시:
val selected = uiState.selectedIndex.coerceIn(0, (uiState.elderHealthList.size - 1).coerceAtLeast(0)) if (uiState.elderHealthList.isEmpty()) return@Box // 이후 selected 사용
92-96: scrollState 변수가 섀도잉됨(이름 충돌) → 의도치 않은 스크롤 상태 전달 가능외부의 verticalScroll용 scrollState와 내부 Row의 horizontalScroll용 scrollState가 동일 이름으로 섀도잉됩니다. 아래처럼 명시적으로 분리해 혼동/버그를 방지하고, DefaultDropdown에는 외부 content scrollState를 전달하세요.
- val scrollState = rememberScrollState() + val chipRowScrollState = rememberScrollState() - Row(Modifier.horizontalScroll(scrollState)) { + Row(Modifier.horizontalScroll(chipRowScrollState)) { ... } - DefaultDropdown(..., scrollState, { ... }) + DefaultDropdown(..., scrollState /* 바깥 content 스크롤 상태 유지 */, { ... })Also applies to: 181-189
app/src/main/java/com/konkuk/medicarecall/data/repositoryimpl/ElderRegisterRepositoryImpl.kt (3)
65-85: Enum 매핑의 !! 제거(명확한 실패 메시지로 디버깅 용이)displayName → enum 변환에서
!!는 모模호한 NPE를 야기합니다. requireNotNull로 명시적 메시지를 주면 장애 분석이 쉬워집니다.- relationship = RelationshipType.entries.find { it.displayName == elderData.relationship }!!.name, - residenceType = ElderResidenceType.entries.find { it.displayName == elderData.livingType }!!.name, + relationship = requireNotNull( + RelationshipType.entries.find { it.displayName == elderData.relationship } + ) { "Unknown relationship: ${elderData.relationship}" }.name, + residenceType = requireNotNull( + ElderResidenceType.entries.find { it.displayName == elderData.livingType } + ) { "Unknown residenceType: ${elderData.livingType}" }.name,
87-109: elderId/notes 변환의 NPE 위험 제거bulk health-info 요청 생성 시
elderHealthData.id!!및 notes 매핑의!!.name이 실패 지점을 만듭니다. 사전 검증으로 실패를 명확히 하세요.- elderId = elderHealthData.id!!, + elderId = requireNotNull(elderHealthData.id) { "elderHealthData.id is null" }, - notes = elderHealthData.notes.map { note -> - HealthIssueType.entries.find { it.displayName == note }!!.name - }, + notes = elderHealthData.notes.map { note -> + requireNotNull(HealthIssueType.entries.find { it.displayName == note }) { + "Unknown health note: $note" + }.name + },
65-79: 대용량 bulk 요청 최적화: Retrofit 2.12 withStreaming() 고려일괄 등록/건강정보는 페이로드가 커질 수 있습니다. Retrofit 2.12.0의 withStreaming()이 직렬화 시점을 I/O 쓰레드로 미루어 UI 스레드 부하를 낮춥니다. DI의 Retrofit 빌더에서 사용을 검토해 주세요.
예: Gson 기준
Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create().withStreaming()) .build()Based on learnings
Also applies to: 87-106
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/screen/LoginElderInfoScreen.kt (2)
68-75: 수명주기 대응 수집으로 변경 권장UI 상태 수집은 collectAsStateWithLifecycle이 안전합니다. 화면 전환/백그라운드 시 불필요 수집을 줄입니다.
- val uiState by loginElderViewModel.elderUiState.collectAsState() + val uiState by loginElderViewModel.elderUiState.collectAsStateWithLifecycle()
209-236: 휴대폰 번호 검증 강화 제안startsWith("010")만으로는 유효성 보장이 약합니다. 숫자 11자리 및 패턴 검사까지 포함하세요.
- else if (!uiState.eldersList.filter { it.phoneNumber.isNotEmpty() } - .all { it.phoneNumber.startsWith("010") }) + else if (!uiState.eldersList.filter { it.phoneNumber.isNotEmpty() } + .all { it.phoneNumber.length == 11 && it.phoneNumber.all(Char::isDigit) && it.phoneNumber.startsWith("010") })app/src/main/java/com/konkuk/medicarecall/ui/common/component/MedicationItem.kt (1)
138-153: 추가 후 선택 시간 초기화 누락(주석과 동작 불일치)주석은 “입력 필드와 선택된 시간 초기화”라고 되어 있으나, 실제로는 입력만 초기화됩니다. 선택 시간도 해제해 UX 일관성을 맞추는 것을 권장합니다.
selectedList.forEach { time -> onAddMedication(time, inputText) } -// 사용성 개선: 약 추가 후 입력 필드와 선택된 시간 초기화 -onTextChange("") +// 사용성 개선: 약 추가 후 입력 필드와 선택된 시간 초기화 +onTextChange("") +selectedList.forEach { time -> + // onSelectTime이 토글이라면 여러 번 호출하여 선택 해제 + onSelectTime(time) +}또한 동일 약물 중복 추가를 방지하려면 상위 상태에서 시간대별 List에 contains 체크를 추가하는 것도 고려해 주세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
app/src/main/java/com/konkuk/medicarecall/MainActivity.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/data/api/ElderRegisterService.kt(2 hunks)app/src/main/java/com/konkuk/medicarecall/data/dto/request/ElderBulkHealthInfoRequestDto.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/data/dto/request/ElderBulkRegisterRequestDto.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/data/dto/response/ElderBulkRegisterResponseDto.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/data/repository/ElderRegisterRepository.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/data/repositoryimpl/ElderRegisterRepositoryImpl.kt(2 hunks)app/src/main/java/com/konkuk/medicarecall/navigation/NavGraph.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/ui/common/component/DiseaseNamesItem.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/ui/common/component/GenderToggleButton.kt(2 hunks)app/src/main/java/com/konkuk/medicarecall/ui/common/component/MedicationItem.kt(5 hunks)app/src/main/java/com/konkuk/medicarecall/ui/feature/login/info/viewmodel/LoginViewModel.kt(6 hunks)app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/LoginElderViewModel.kt(0 hunks)app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderChip.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderInputForm.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/screen/LoginElderInfoScreen.kt(6 hunks)app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/screen/LoginElderMedInfoScreen.kt(3 hunks)app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/viewmodel/LoginElderHealthUiState.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/viewmodel/LoginElderUiState.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/viewmodel/LoginElderViewModel.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/ui/feature/settings/screen/ElderDetailScreen.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/ui/feature/settings/screen/MyDetailScreen.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/ui/model/ElderData.kt(1 hunks)app/src/main/java/com/konkuk/medicarecall/ui/model/ElderHealthData.kt(1 hunks)
💤 Files with no reviewable changes (1)
- app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/LoginElderViewModel.kt
🧰 Additional context used
🧬 Code graph analysis (6)
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderChip.kt (1)
app/src/main/java/com/konkuk/medicarecall/ui/theme/Theme.kt (1)
MediCareCallTheme(38-60)
app/src/main/java/com/konkuk/medicarecall/ui/common/component/DiseaseNamesItem.kt (2)
app/src/main/java/com/konkuk/medicarecall/ui/common/component/ChipItem.kt (1)
ChipItem(22-52)app/src/main/java/com/konkuk/medicarecall/ui/common/component/AddTextField.kt (1)
AddTextField(20-66)
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/screen/LoginElderMedInfoScreen.kt (6)
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/info/component/LoginBackButton.kt (1)
LoginBackButton(17-37)app/src/main/java/com/konkuk/medicarecall/ui/common/component/DiseaseNamesItem.kt (1)
DiseaseNamesItem(17-69)app/src/main/java/com/konkuk/medicarecall/ui/common/component/MedicationItem.kt (1)
MedicationItem(60-155)app/src/main/java/com/konkuk/medicarecall/ui/common/component/ChipItem.kt (1)
ChipItem(22-52)app/src/main/java/com/konkuk/medicarecall/ui/common/component/CTAButton.kt (1)
CTAButton(22-78)app/src/main/java/com/konkuk/medicarecall/ui/common/component/DefaultSnackBar.kt (1)
DefaultSnackBar(17-37)
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/screen/LoginElderInfoScreen.kt (4)
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/info/component/LoginBackButton.kt (1)
LoginBackButton(17-37)app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderChip.kt (1)
ElderChip(24-77)app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderInputForm.kt (1)
ElderInputForm(27-120)app/src/main/java/com/konkuk/medicarecall/ui/common/component/DefaultSnackBar.kt (1)
DefaultSnackBar(17-37)
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderInputForm.kt (3)
app/src/main/java/com/konkuk/medicarecall/ui/common/component/DefaultTextField.kt (1)
DefaultTextField(18-64)app/src/main/java/com/konkuk/medicarecall/ui/common/component/GenderToggleButton.kt (1)
GenderToggleButton(21-87)app/src/main/java/com/konkuk/medicarecall/ui/common/component/DefaultDropDown.kt (1)
DefaultDropdown(41-175)
app/src/main/java/com/konkuk/medicarecall/ui/common/component/MedicationItem.kt (1)
app/src/main/java/com/konkuk/medicarecall/ui/common/component/AddTextField.kt (1)
AddTextField(20-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: ci-build
🔇 Additional comments (17)
app/src/main/java/com/konkuk/medicarecall/MainActivity.kt (1)
43-43: Import 경로 업데이트 확인됨.
LoginElderViewModel의 패키지 경로가viewmodel하위로 변경되었습니다. 코드 구조 개선을 위한 리팩토링으로 보이며, 기능상 문제는 없습니다.app/src/main/java/com/konkuk/medicarecall/ui/feature/login/info/viewmodel/LoginViewModel.kt (2)
50-50: 성별 상태를 non-nullable로 변경.
isMale이Boolean?에서Boolean(기본값true)로 변경되었습니다. UI 컴포넌트와의 일관성을 위한 개선이며, nullable 처리를 제거하여 코드가 단순해졌습니다.
70-72: 콜백 시그니처 업데이트 확인됨.
onGenderChanged가 non-nullableBoolean을 받도록 변경되어isMale상태 변경과 일치합니다.app/src/main/java/com/konkuk/medicarecall/ui/model/ElderHealthData.kt (1)
5-10: 기본값 추가로 인스턴스 생성 간소화.
ElderHealthData의 모든 필드에 기본값이 추가되어ElderHealthData()로 빈 인스턴스를 생성할 수 있습니다. 일괄 등록 플로우에서 유용하게 활용될 것으로 보입니다.app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/viewmodel/LoginElderHealthUiState.kt (1)
1-12: 새로운 UI 상태 클래스 추가.
LoginElderHealthUiState는 어르신 건강 정보 일괄 등록 플로우를 위한 UI 상태를 관리합니다. 기본값이 적절하게 설정되어 있으며,elderHealthList의 초기 값으로 빈ElderHealthData()인스턴스를 포함하고 있습니다.app/src/main/java/com/konkuk/medicarecall/data/dto/request/ElderBulkHealthInfoRequestDto.kt (1)
1-30: 일괄 건강 정보 제출을 위한 DTO 추가.
ElderBulkHealthInfoRequestDto는POST elders/health-info/bulk엔드포인트를 위한 요청 DTO입니다. 중첩된HealthInfo와MedicationSchedule클래스가 적절히 정의되어 있으며,@Serializable및@SerialName애노테이션이 올바르게 적용되었습니다.app/src/main/java/com/konkuk/medicarecall/ui/common/component/GenderToggleButton.kt (2)
22-25: 성별 토글 버튼 시그니처 간소화.
isMale파라미터가Boolean?에서Boolean(기본값true)로 변경되고,onGenderChange콜백도 non-nullableBoolean을 받도록 업데이트되었습니다. Nullable 처리 제거로 코드가 단순해졌습니다.
36-60: 조건부 로직 간소화.
isMale이 non-nullable이 되어 조건부 스타일링 로직이 단순해졌습니다.if (isMale)및if (!isMale)체크가 명확하며, null 처리가 불필요해졌습니다.app/src/main/java/com/konkuk/medicarecall/navigation/NavGraph.kt (1)
43-43: Import 경로 업데이트 확인됨.
LoginElderViewModel의 패키지 경로가viewmodel하위로 변경되었습니다.MainActivity.kt와 동일한 리팩토링이며, 기능상 문제는 없습니다.app/src/main/java/com/konkuk/medicarecall/ui/feature/settings/screen/ElderDetailScreen.kt (1)
65-65: 성별 상태를 non-nullable로 변경.
isMale이mutableStateOf<Boolean?>에서mutableStateOf<Boolean>로 변경되어 nullable 처리가 제거되었습니다.gender값(이미Boolean)으로 초기화되며, UI 컴포넌트와의 일관성이 개선되었습니다.app/src/main/java/com/konkuk/medicarecall/ui/model/ElderData.kt (1)
6-6: 기본값 추가 확인
gender에 기본값true를 추가하여ElderData()생성을 간소화했습니다. 편의성 향상에 도움이 되네요.app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/viewmodel/LoginElderUiState.kt (1)
1-8: 새로운 UI 상태 클래스 확인어르신 로그인 플로우를 위한 깔끔한 상태 홀더입니다. 구조와 기본값이 잘 정의되어 있네요.
app/src/main/java/com/konkuk/medicarecall/data/dto/request/ElderBulkRegisterRequestDto.kt (1)
1-26: Bulk 등록 DTO 확인일괄 등록을 위한 DTO 구조가 명확하고 직렬화 매핑도 잘 되어 있습니다.
app/src/main/java/com/konkuk/medicarecall/data/api/ElderRegisterService.kt (1)
3-7: Bulk 엔드포인트 추가 확인일괄 등록 및 건강 정보 bulk 엔드포인트가 깔끔하게 추가되었습니다. Retrofit 설정도 적절하네요.
Also applies to: 26-34
app/src/main/java/com/konkuk/medicarecall/data/repository/ElderRegisterRepository.kt (1)
3-3: Bulk 작업으로 마이그레이션 확인기존 단일 등록 방식에서 bulk 작업으로 깔끔하게 전환되었습니다. 인터페이스 설계가 명확하네요.
Also applies to: 9-10
app/src/main/java/com/konkuk/medicarecall/ui/common/component/DiseaseNamesItem.kt (1)
18-24: 콜백 기반 상태 관리로 리팩터링 확인내부 상태를 제거하고 불변 props와 콜백으로 외부화한 것이 단방향 데이터 흐름 패턴에 잘 맞습니다. 깔끔한 리팩터링이네요.
Also applies to: 52-67
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/screen/LoginElderInfoScreen.kt (1)
115-118: 항목 삭제 시 선택 인덱스 일관성 확인 요청마지막 항목을 삭제할 때만
selectElder(selectedIndex - 1)을 호출합니다. 중간/첫 항목 삭제 시 선택 인덱스가 유효하게 보정되는지 ViewModel 로직을 한 번만 확인 부탁드립니다(경계값 이슈 예방).
| Column( | ||
| verticalArrangement = Arrangement.Center, | ||
| ) { | ||
| Column( | ||
| verticalArrangement = Arrangement.Center | ||
| ) { | ||
| DefaultTextField( | ||
| value = loginElderViewModel.nameList[index], | ||
| onValueChange = { loginElderViewModel.onNameChanged(index, it) }, | ||
| category = "이름", | ||
| placeHolder = "이름" | ||
| ) | ||
| Spacer(Modifier.height(20.dp)) | ||
| DefaultTextField( | ||
| loginElderViewModel.dateOfBirthList[index], | ||
| { input -> | ||
| val filtered = input.filter { it.isDigit() }.take(8) | ||
| loginElderViewModel.onDOBChanged(index, filtered) | ||
| }, | ||
| category = "생년월일", | ||
| placeHolder = "YYYY / MM / DD", | ||
| keyboardType = KeyboardType.Number, | ||
| visualTransformation = DateOfBirthVisualTransformation(), | ||
| maxLength = 8 | ||
| DefaultTextField( | ||
| value = elderData.name, | ||
| onValueChange = { input -> | ||
| onNameChanged(input) | ||
| }, | ||
| category = "이름", | ||
| placeHolder = "이름", | ||
| textFieldModifier = if (nameFocusRequester != null) | ||
| Modifier.focusRequester(nameFocusRequester) | ||
| else Modifier, | ||
| ) | ||
| Spacer(Modifier.height(20.dp)) | ||
| DefaultTextField( | ||
| elderData.birthDate, | ||
| { input -> | ||
| val filtered = input.filter { it.isDigit() }.take(8) | ||
| onBirthDateChanged(filtered) | ||
| }, | ||
| category = "생년월일", | ||
| placeHolder = "YYYY / MM / DD", | ||
| keyboardType = KeyboardType.Number, | ||
| visualTransformation = DateOfBirthVisualTransformation(), | ||
| maxLength = 8, | ||
| ) | ||
| Spacer(Modifier.height(20.dp)) | ||
| Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { | ||
| Text( | ||
| "성별", | ||
| color = MediCareCallTheme.colors.gray7, | ||
| style = MediCareCallTheme.typography.M_17, | ||
| ) | ||
| Spacer(Modifier.height(20.dp)) | ||
| Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { | ||
| Text( | ||
| "성별", | ||
| color = MediCareCallTheme.colors.gray7, | ||
| style = MediCareCallTheme.typography.M_17 | ||
| ) | ||
|
|
||
| GenderToggleButton(loginElderViewModel.isMaleBoolList[index]) { | ||
| loginElderViewModel.onGenderChanged( | ||
| index, it | ||
| ) | ||
| } | ||
| GenderToggleButton(elderData.gender) { | ||
| onGenderChanged(it) | ||
| } | ||
| Spacer(Modifier.height(20.dp)) | ||
| DefaultTextField( | ||
| loginElderViewModel.phoneNumberList[index], | ||
| { input -> | ||
| val filtered = input.filter { it.isDigit() }.take(11) | ||
| loginElderViewModel.onPhoneNumberChanged(index, filtered) | ||
| }, | ||
| category = "휴대폰 번호", | ||
| placeHolder = "010-1234-5678", | ||
| keyboardType = KeyboardType.Number, | ||
| visualTransformation = PhoneNumberVisualTransformation(), | ||
| maxLength = 11 | ||
| ) | ||
| Spacer(Modifier.height(20.dp)) | ||
| } | ||
| Spacer(Modifier.height(20.dp)) | ||
| DefaultTextField( | ||
| elderData.phoneNumber, | ||
| { input -> | ||
| val filtered = input.filter { it.isDigit() }.take(11) | ||
| onPhoneNumberChanged(filtered) | ||
| }, | ||
| category = "휴대폰 번호", | ||
| placeHolder = "010-1234-5678", | ||
| keyboardType = KeyboardType.Number, | ||
| visualTransformation = PhoneNumberVisualTransformation(), | ||
| maxLength = 11, | ||
| ) | ||
| Spacer(Modifier.height(20.dp)) | ||
|
|
||
|
|
||
| DefaultDropdown( | ||
| enumList = RelationshipType.entries.map { it.displayName } | ||
| .toList(), | ||
| placeHolder = "관계 선택하기", | ||
| category = "어르신과의 관계", | ||
| scrollState, | ||
| { loginElderViewModel.onRelationshipChanged(index, it) }, | ||
| loginElderViewModel.relationshipList[index] | ||
| ) | ||
| DefaultDropdown( | ||
| enumList = RelationshipType.entries.map { it.displayName } | ||
| .toList(), | ||
| placeHolder = "관계 선택하기", | ||
| category = "어르신과의 관계", | ||
| scrollState, | ||
| { onRelationshipChange(it) }, | ||
| elderData.relationship, | ||
| ) | ||
|
|
||
|
|
||
| Spacer(Modifier.height(20.dp)) | ||
| Spacer(Modifier.height(20.dp)) | ||
|
|
||
| DefaultDropdown( | ||
| enumList = ElderResidenceType.entries.map { it.displayName } | ||
| .toList(), | ||
| placeHolder = "거주방식을 선택해주세요", | ||
| category = "어르신 거주 방식", | ||
| scrollState, | ||
| { loginElderViewModel.onLivingTypeChanged(index, it) }, | ||
| loginElderViewModel.livingTypeList[index] | ||
| ) | ||
| DefaultDropdown( | ||
| enumList = ElderResidenceType.entries.map { it.displayName } | ||
| .toList(), | ||
| placeHolder = "거주방식을 선택해주세요", | ||
| category = "어르신 거주 방식", | ||
| scrollState, | ||
| { onLivingTypeChanged(it) }, | ||
| elderData.livingType, | ||
| ) | ||
|
|
||
| Spacer(Modifier.height(20.dp)) | ||
| } | ||
| } | ||
| if (!isExpanded) { | ||
| Box( | ||
| Modifier | ||
| .fillMaxWidth() | ||
| .figmaShadow(MediCareCallTheme.shadow.shadow03) | ||
| .clip( | ||
| RoundedCornerShape(14.dp) | ||
| ) | ||
| .background(MediCareCallTheme.colors.white) | ||
| .clickable { loginElderViewModel.expandedFormIndex = index } | ||
| ) { | ||
| Column( | ||
| Modifier.padding(16.dp), | ||
| verticalArrangement = Arrangement.spacedBy(8.dp) | ||
| ) { | ||
| Row( | ||
| Modifier.fillMaxWidth(), | ||
| horizontalArrangement = Arrangement.SpaceBetween | ||
| ) { | ||
| Text( | ||
| "${loginElderViewModel.nameList[index]} 님", | ||
| color = MediCareCallTheme.colors.gray8, | ||
| style = MediCareCallTheme.typography.SB_18 | ||
| ) | ||
| Text( | ||
| "삭제하기", | ||
| color = MediCareCallTheme.colors.negative, | ||
| style = MediCareCallTheme.typography.R_14, | ||
| modifier = Modifier.clickable( | ||
| indication = null, | ||
| interactionSource = null, | ||
| onClick = { | ||
| loginElderViewModel.elders-- | ||
| loginElderViewModel.expandedFormIndex = 0 | ||
| } | ||
| ) | ||
| ) | ||
| } | ||
| Text( | ||
| loginElderViewModel.phoneNumberList[index].replaceFirst( | ||
| Regex("(\\d{3})(\\d{4})(\\d{4})"), | ||
| "$1-$2-$3" | ||
| ), | ||
| color = MediCareCallTheme.colors.gray4, | ||
| style = MediCareCallTheme.typography.R_14 | ||
| ) | ||
| } | ||
| } | ||
| Spacer(Modifier.height(30.dp)) | ||
| Spacer(Modifier.height(20.dp)) |
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.
🛠️ Refactor suggestion | 🟠 Major
modifier 파라미터를 실제 레이아웃에 적용해주세요.
modifier를 기본값과 함께 공개 API로 받지만 Column에 전달하지 않아 외부에서 주입한 수정자가 전혀 반영되지 않습니다. 이로 인해 레이아웃 배치/패딩 조정이 불가능해집니다. 루트 Column 혹은 적절한 래퍼에 modifier = modifier를 적용하도록 반영해주세요.
- Column(
- verticalArrangement = Arrangement.Center,
- ) {
+ Column(
+ modifier = modifier,
+ verticalArrangement = Arrangement.Center,
+ ) {🤖 Prompt for AI Agents
In
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderInputForm.kt
around lines 40 to 118, the composable accepts a modifier parameter but never
applies it to the UI, so external layout/padding adjustments are ignored; update
the root Column (or an appropriate wrapper Column) to include modifier =
modifier (or combine with existing modifiers using modifier.then(...)) so the
passed-in modifier is applied to the layout.
| DefaultDropdown( | ||
| enumList = RelationshipType.entries.map { it.displayName } | ||
| .toList(), | ||
| placeHolder = "관계 선택하기", | ||
| category = "어르신과의 관계", | ||
| scrollState, | ||
| { onRelationshipChange(it) }, | ||
| elderData.relationship, | ||
| ) | ||
|
|
||
|
|
||
| Spacer(Modifier.height(20.dp)) | ||
| Spacer(Modifier.height(20.dp)) | ||
|
|
||
| DefaultDropdown( | ||
| enumList = ElderResidenceType.entries.map { it.displayName } | ||
| .toList(), | ||
| placeHolder = "거주방식을 선택해주세요", | ||
| category = "어르신 거주 방식", | ||
| scrollState, | ||
| { loginElderViewModel.onLivingTypeChanged(index, it) }, | ||
| loginElderViewModel.livingTypeList[index] | ||
| ) | ||
| DefaultDropdown( | ||
| enumList = ElderResidenceType.entries.map { it.displayName } | ||
| .toList(), | ||
| placeHolder = "거주방식을 선택해주세요", | ||
| category = "어르신 거주 방식", | ||
| scrollState, | ||
| { onLivingTypeChanged(it) }, | ||
| elderData.livingType, | ||
| ) |
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.
named 인자 뒤에 위치 인자 사용으로 컴파일 실패합니다.
DefaultDropdown 호출부에서 category = ... 이후에 scrollState, { ... }, elderData.relationship을 위치 인자로 넘기고 있는데, Kotlin에서는 named 인자를 사용한 뒤에 positional 인자를 섞을 수 없습니다. 현재 코드는 빌드 단계에서 Mixing named and positioned arguments is not allowed 컴파일 오류가 발생합니다. 모든 인자를 명시적으로 이름 붙여 호출하도록 수정해주세요.
- DefaultDropdown(
- enumList = RelationshipType.entries.map { it.displayName }
- .toList(),
- placeHolder = "관계 선택하기",
- category = "어르신과의 관계",
- scrollState,
- { onRelationshipChange(it) },
- elderData.relationship,
- )
+ DefaultDropdown(
+ enumList = RelationshipType.entries.map { it.displayName }.toList(),
+ placeHolder = "관계 선택하기",
+ category = "어르신과의 관계",
+ scrollState = scrollState,
+ onOptionSelect = { onRelationshipChange(it) },
+ value = elderData.relationship,
+ )아래 거주 방식 드롭다운도 동일하게 수정이 필요합니다.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| DefaultDropdown( | |
| enumList = RelationshipType.entries.map { it.displayName } | |
| .toList(), | |
| placeHolder = "관계 선택하기", | |
| category = "어르신과의 관계", | |
| scrollState, | |
| { onRelationshipChange(it) }, | |
| elderData.relationship, | |
| ) | |
| Spacer(Modifier.height(20.dp)) | |
| Spacer(Modifier.height(20.dp)) | |
| DefaultDropdown( | |
| enumList = ElderResidenceType.entries.map { it.displayName } | |
| .toList(), | |
| placeHolder = "거주방식을 선택해주세요", | |
| category = "어르신 거주 방식", | |
| scrollState, | |
| { loginElderViewModel.onLivingTypeChanged(index, it) }, | |
| loginElderViewModel.livingTypeList[index] | |
| ) | |
| DefaultDropdown( | |
| enumList = ElderResidenceType.entries.map { it.displayName } | |
| .toList(), | |
| placeHolder = "거주방식을 선택해주세요", | |
| category = "어르신 거주 방식", | |
| scrollState, | |
| { onLivingTypeChanged(it) }, | |
| elderData.livingType, | |
| ) | |
| DefaultDropdown( | |
| enumList = RelationshipType.entries.map { it.displayName }.toList(), | |
| placeHolder = "관계 선택하기", | |
| category = "어르신과의 관계", | |
| scrollState = scrollState, | |
| onOptionSelect = { onRelationshipChange(it) }, | |
| value = elderData.relationship, | |
| ) | |
| Spacer(Modifier.height(20.dp)) | |
| DefaultDropdown( | |
| enumList = ElderResidenceType.entries.map { it.displayName } | |
| .toList(), | |
| placeHolder = "거주방식을 선택해주세요", | |
| category = "어르신 거주 방식", | |
| scrollState, | |
| { onLivingTypeChanged(it) }, | |
| elderData.livingType, | |
| ) |
🤖 Prompt for AI Agents
In
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderInputForm.kt
around lines 95–116, the DefaultDropdown calls mix named and positional
arguments which causes the compiler error; change the remaining positional
arguments after category to named arguments as well (e.g., pass scrollState =
scrollState, the change lambda as its named parameter, and the selected value as
its named parameter) for both the relationship and living-type dropdowns so all
arguments are consistently named.
| loginElderViewModel.initElderHealthData() | ||
| loginElderViewModel.postElderBulk() | ||
| navController.navigate(Route.LoginElderMedInfoScreen.route) | ||
| } | ||
| }, | ||
| modifier.padding(bottom = 20.dp) | ||
| modifier.padding(bottom = 20.dp), | ||
| ) |
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.
일괄 등록 네트워크 결과 처리 및 네비게이션 순서
postElderBulk() 결과를 확인하지 않고 즉시 이동하면 실패 시 UX가 깨집니다. 비동기 실행으로 성공 시에만 이동하고, 실패는 스낵바로 안내하는 패턴을 권장합니다. 또한 진행 중 중복 클릭 방지(loading state)도 고려해 주세요.
간단 예시:
coroutineScope.launch {
runCatching { loginElderViewModel.postElderBulk() }
.onSuccess { navController.navigate(Route.LoginElderMedInfoScreen.route) }
.onFailure { snackBarState.showSnackbar("등록에 실패했어요. 잠시 후 다시 시도해 주세요.") }
}🤖 Prompt for AI Agents
In
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/screen/LoginElderInfoScreen.kt
around lines 239-245, the code calls loginElderViewModel.postElderBulk() and
immediately navigates away, which ignores the async network result; change this
to launch a coroutine, set a loading flag to prevent duplicate clicks, await
postElderBulk() and only navigate on success, on failure show a snackbar with a
friendly message and clear/reset the loading state; ensure exceptions from
postElderBulk are caught (e.g., runCatching or try/catch) so failures are
handled and UI restored.
| CTAButtonType.GREEN, | ||
| "다음", | ||
| { | ||
| coroutineScope.launch { | ||
| loginElderViewModel.createElderHealthDataList() | ||
| loginElderViewModel.updateAllElders() | ||
| loginElderViewModel.updateAllEldersHealthInfo() | ||
| loginElderViewModel.postElderAndHealth() | ||
| delay(200L) | ||
| loginElderViewModel.postElderHealthInfoBulk() | ||
| navController.navigate(Route.SetCall.route) { | ||
| popUpTo(Route.LoginElderInfoScreen.route) { | ||
| inclusive = true | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| Modifier.padding(top = 30.dp, bottom = 20.dp) | ||
| Modifier.padding(top = 30.dp, bottom = 20.dp), | ||
| ) |
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.
일괄 건강정보 전송 실패 처리 및 중복 클릭 방지
postElderHealthInfoBulk() 호출 후 실패 케이스가 처리되지 않아 실패해도 다음 화면으로 이동할 수 있습니다. runCatching/try-catch로 오류를 스낵바로 안내하고, 진행 중에는 버튼 비활성화(loading state)로 중복 전송도 막아주세요.
간단 예시:
coroutineScope.launch {
runCatching { loginElderViewModel.postElderHealthInfoBulk() }
.onSuccess {
navController.navigate(Route.SetCall.route) { popUpTo(Route.LoginElderInfoScreen.route) { inclusive = true } }
}
.onFailure {
snackBarState.showSnackbar("저장에 실패했어요. 잠시 후 다시 시도해 주세요.")
}
}🤖 Prompt for AI Agents
In
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/screen/LoginElderMedInfoScreen.kt
around lines 191–204, the call to loginElderViewModel.postElderHealthInfoBulk()
does not handle failures and allows immediate navigation (and duplicate
submissions) on click; wrap the network call in runCatching or try/catch, only
call navController.navigate(...) on success, show a snackbar with a friendly
error message on failure, and prevent duplicate clicks by disabling the CTA
button while a ViewModel-backed loading flag is true (or set a local loading
state) so the button is disabled and shows a loading indicator until the call
completes. Ensure the ViewModel exposes or updates a loading state around
postElderHealthInfoBulk() (or return a Result) so the composable can observe it
and toggle the button enabled/disabled state accordingly.
| fun removeElder(index: Int) { | ||
| _elderUiState.update { state -> | ||
| state.copy( | ||
| eldersList = state.eldersList.filterIndexed { i, _ -> i != index }, | ||
| ) | ||
| } | ||
| } |
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.
삭제 이후 selectedIndex 범위가 무너집니다.
removeElder가 리스트에서 항목만 제거하고 selectedIndex를 갱신하지 않아, 마지막 항목을 지운 직후 selectedIndex가 리스트 크기 이상을 가리키게 됩니다. 이후 다른 업데이트 함수에서 eldersList[state.selectedIndex]처럼 접근하면 IndexOutOfBoundsException이 발생합니다. 삭제 후에는 selectedIndex를 min(삭제된 인덱스, 새 리스트 마지막 인덱스) 형태로 재조정하거나, 리스트가 비면 0으로 초기화하는 처리가 필요합니다.
fun removeElder(index: Int) {
_elderUiState.update { state ->
- state.copy(
- eldersList = state.eldersList.filterIndexed { i, _ -> i != index },
- )
+ val updatedList = state.eldersList.filterIndexed { i, _ -> i != index }
+ state.copy(
+ eldersList = updatedList,
+ selectedIndex = updatedList.indices.lastOrNull()?.coerceAtMost(state.selectedIndex.coerceAtMost(updatedList.lastIndex)) ?: 0,
+ )
}
}🤖 Prompt for AI Agents
In
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/viewmodel/LoginElderViewModel.kt
around lines 111 to 117, removeElder currently only removes the item and leaves
selectedIndex unchanged which can point past the end of the new list; after
filtering the eldersList compute the newSelected = if (newList.isEmpty()) 0 else
min(index, newList.lastIndex) (ensure non-negative) and include selectedIndex =
newSelected in the state.copy so selectedIndex is clamped to the valid range
after deletion.
librawish808
left a comment
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.
LGTM
ikseong00
left a comment
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.
#139 PR 이랑 겹치는 부분이 많이 있군요 잘 짜신 것 같습니다
| fun ElderChip( | ||
| name: String, | ||
| selected: Boolean, | ||
| onRemove: () -> Unit, | ||
| onClick: () -> Unit, | ||
| ) { |
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.
재사용성을 위해서 Modifier 넘겨줘야 할 것 같습니다!
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.
반영했습니다 !
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.
9970b36 사진에 있는 오른쪽 커밋 해시 긁어서 복사해서 넣는 방법도 있어요!
나중에 참고하면 좋을 것 같습니당
| LazyRow(horizontalArrangement = Arrangement.spacedBy(10.dp)) { | ||
|
|
||
| itemsIndexed(uiState.eldersList) { index, it -> | ||
| ElderChip( | ||
| name = it.name, | ||
| selected = index == selectedIndex, | ||
| onRemove = { | ||
| if (selectedIndex == uiState.eldersList.size - 1) | ||
| loginElderViewModel.selectElder(selectedIndex - 1) | ||
| loginElderViewModel.removeElder(index) | ||
| }, | ||
| onClick = { loginElderViewModel.selectElder(index) }, | ||
| ) | ||
|
|
||
| } | ||
| } |
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.
👍
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: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderChip.kt(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderChip.kt (1)
app/src/main/java/com/konkuk/medicarecall/ui/theme/Theme.kt (1)
MediCareCallTheme(38-60)
| painter = painterResource(id = R.drawable.ic_close), | ||
| contentDescription = "remove", | ||
| modifier = Modifier | ||
| .size(16.dp) | ||
| .clickable( | ||
| indication = null, | ||
| interactionSource = null, | ||
| onClick = { onRemove() }, | ||
| ), |
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.
삭제 아이콘 터치 영역이 너무 좁습니다
현재 Icon 에 Modifier.size(16.dp) 뒤에 clickable 을 바로 붙여서 실제 터치 영역이 16dp에 불과합니다. 최소 44~48dp 권장 최소 터치 사이즈보다 크게 부족해 고령 사용자가 버튼을 누르기 매우 어렵고 접근성도 저해됩니다. Box/IconButton 등을 활용해 여유 패딩을 두거나, clip + padding 순서를 조정해서 터치 영역을 확장해주세요. 동시에 stringResource(R.string.xxx_remove) 형태로 콘텐츠 설명도 지역화해주면 좋겠습니다.
🤖 Prompt for AI Agents
In
app/src/main/java/com/konkuk/medicarecall/ui/feature/login/senior/component/ElderChip.kt
around lines 63 to 71, the remove icon's clickable area is constrained to 16.dp
because clickable is applied directly after Modifier.size(16.dp); expand the
touch target to at least 44.dp by moving the clickable to a parent container
(e.g., wrap the Icon in a Box or use IconButton) or apply a larger size/padding
before clickable (ensure clip is applied after padding if needed), add
sufficient padding so the visible icon remains 16.dp but the touchable area
meets accessibility guidelines, and replace the hardcoded contentDescription
with a localized stringResource(R.string.xxx_remove).
|
@librawish808 @alswlekk |
|
확인하였습니다 좋습니다! |
alswlekk
left a comment
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.
LGTM !
| fun postElderBulk() { | ||
| viewModelScope.launch { | ||
| elderRegisterRepository.registerElderAndHealth( | ||
| elders = elderUiState.value.eldersList.size, | ||
| elderInfoList = elderUiState.value.eldersList, | ||
| elderHealthInfo = elderHealthUiState.value.elderHealthList, | ||
| ) | ||
| .onSuccess { | ||
| Log.d("httplog", "어르신 및 건강정보 전부 등록 성공!") | ||
| elderRegisterRepository.postElderBulk(elderUiState.value.eldersList) | ||
| .onSuccess { response -> | ||
| _elderUiState.update { state -> | ||
| state.copy( | ||
| eldersList = state.eldersList.mapIndexed { index, elderData -> | ||
| elderData.copy(id = response[index].id) | ||
| }, | ||
| ) | ||
| } | ||
| _elderHealthUiState.update { state -> | ||
| state.copy( | ||
| elderHealthList = state.elderHealthList.mapIndexed { index, healthData -> | ||
| healthData.copy(id = response[index].id) | ||
| }, | ||
| ) | ||
| } | ||
| } | ||
| .onFailure { exception -> | ||
| Log.e("httplog", "어르신 정보 or 건강정보 등록 실패: ${exception.message}") | ||
| when (exception) { | ||
| is HttpException -> { | ||
| Log.e("httplog", "어르신 일괄등록 실패: ${exception.code()}, ${exception.message()}") | ||
| } | ||
| } |
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.
일괄처리 코드 깔끔하게 잘 작성하신 거 같아요 !
🔗 관련 이슈
📙 작업 설명
POSTelders/bulk API 연동POSTelders/health-info/bulk 연동Summary by CodeRabbit