Skip to content

Conversation

@librawish808
Copy link
Collaborator

@librawish808 librawish808 commented Oct 7, 2025

🔗 관련 이슈

📙 작업 설명

문제1: 설정 화면에서 어르신 이름을 변경한 뒤 홈/주간통계로 돌아와도 네임바·드롭다운이 즉시 반영되지 않음.

해결1

  • HomeScreen과 StatisticsScreen에 진입할 때마다 LaunchedEffect를 사용하여 ViewModel의 데이터 새로고침 함수(fetchElderList, refresh)를 호출하도록 수정
  • HomeViewModel 내 fetchElderList 함수를 public으로 변경

-----> 이후 확인해보니,
문제2: 설정에서 이름 변경 후 홈화면으로 이동시 네임바가 빈칸으로 뜨거나 스피너가 오랫동안 돌게되어 다시 수정을 진행했습니다.

해결2
설정에서 저장 시 main 그래프 SavedStateHandle(StateFlow) 기반으로 이벤트를 전달
HomeScreen이 getStateFlow를 구독 → 수신 즉시 homeViewModel의 updatedName 호출
elderInfoList 및 elderName 즉시 변경 및 로딩 플래그 즉시 false
이후 softRefresh로 요약/건강 정보만 재조회 (스피너 없음)

📸 스크린샷 또는 시연 영상 (선택)

<해결1 영상>

Screen_recording_20251006_230301.webm

<해결2 영상>

2.webm

💬 추가 설명 or 리뷰 포인트 (선택)

Summary by CodeRabbit

  • 신기능

    • 상세 정보에서 수정한 보호대상자 이름이 뒤로 돌아올 때 한 번만 즉시 반영되도록 연동(백스택 상태로 전달).
    • 홈/통계 진입 시 관련 데이터 자동 로드 및 화면 생명주기 연동 강화.
  • 개선

    • 홈 화면 데이터 구조를 정보 기반으로 재설계해 선택·표시 정확도 향상 및 드롭다운 목록 개선.
    • 통계 화면에 60초 갱신 스로틀 추가로 중복 요청 감소.
    • 상세 화면에서 네비게이션으로 수정 후 이전 화면으로 돌아가며 상태 전달 및 입력(생년월일/전화번호) 포맷·유효성 보조 추가.

- 홈 화면 진입 시 목록 새로고침을 위해 HomeScreen에서 호출할 수 있도록 private에서 public으로 변경
- 각 화면(HomeScreen, StatisticsScreen) 진입 시 `LaunchedEffect`를 사용하여 ViewModel의 데이터 새로고침 함수를 호출하도록 수정
- 저장 성공 직후 previousBackStackEntry.savedStateHandle에 ELDER_NAME_UPDATED 세팅
- 이후 popBackStack()으로 복귀
- SavedStateHandle.getStateFlow("ELDER_NAME_UPDATED") 구독(StateFlow)
- 값 수신 시 homeViewModel.overrideName(updatedName) 호출
- 수동 새로고침 없이 네임바/드롭다운 즉시 갱신
- 이벤트 처리 후 savedStateHandle.remove("ELDER_NAME_UPDATED")로 중복 실행 방지
- previousBackStackEntry → getBackStackEntry("main")로 변경
- 저장 성공 시 ELDER_NAME_UPDATED를 main.savedStateHandle에 세팅
- popBackStack()으로 복귀
- 홈/주간통계 등 모든 탭에서 즉시 반영 가능
- navController.getBackStackEntry("main")를 parentEntry로 생성
- HomeScreen 호출 시 mainBackStackEntry=parentEntry를 인자로 전달
- main.savedStateHandle의 ELDER_NAME_UPDATED 구독
- overrideName()으로 즉시 반영, 처리 후 remove로 중복 방지
- 목록 지연 시 homeUiState.elderName로 폴백
- overrideName: 스피너 없이 바로 UI 갱신
- softRefresh: 백그라운드로 최신화, timeout/실패에도 화면 유지
- fetchElderList/summary: 어떤 경우든 isLoading=false (finally)
- forceRefresh: onComplete 항상 호출, 목록도 재동기화
@librawish808 librawish808 self-assigned this Oct 7, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 7, 2025

Walkthrough

NavGraph과 화면 시그니처를 확장해 savedStateHandle을 통해 ELDER_NAME_UPDATED 전달을 연결하고, Home/Statistics 진입 시 ViewModel의 목록/통계 갱신을 트리거하도록 했으며 HomeViewModel·StatisticsViewModel에 이름 재정의, 소프트 리프레시, 60초 스로틀링 등 상태·동기화 로직을 추가했다.

Changes

Cohort / File(s) Summary
Repository minor refactor
app/src/main/java/com/konkuk/medicarecall/data/repositoryimpl/ElderIdRepositoryImpl.kt
elderIdsvarval로 변경(참조 불변화). 내부 리스트는 여전히 가변.
Navigation wiring
app/src/main/java/com/konkuk/medicarecall/navigation/NavGraph.kt
NavGraph 호출 포맷(트레일링 콤마) 및 HomeScreenhomeViewModel, mainBackStackEntry 전달; StatisticsScreenhomeViewModel 전달.
Home screen + lifecycle integration
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt
mainBackStackEntry: NavBackStackEntry 인자 추가. savedStateHandle의 ELDER_NAME_UPDATED 관찰해 overrideName 호출 및 상태 초기화. HomeScreenLayout 파라미터를 elderInfoList/selectedElderId로 변경.
HomeViewModel enhancements
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/viewmodel/HomeViewModel.kt
overrideName(newName) 추가, fetchElderList() 공개화, elderNameList: StateFlow<List<String>> 공개 추가, 소프트 리프레시·로딩/동기화 개선(try/finally 등).
Settings -> name update propagation
app/src/main/java/com/konkuk/medicarecall/ui/feature/settings/screen/ElderDetailScreen.kt
PersonalDetailScreennavController: NavController 파라미터 추가. 저장 시 "main" 백스택에 ELDER_NAME_UPDATED 설정 후 popBackStack()으로 복귀. 입력 변환/검증 유틸 임포트 추가.
Statistics screen + throttled refresh
app/src/main/java/com/konkuk/medicarecall/ui/feature/statistics/screen/StatisticsScreen.kt
컴포지션 시 homeViewModel.fetchElderList()statisticsViewModel.refresh() 호출 추가. 현재 이름 결정 로직을 elderInfoList/선택 ID 우선으로 재조정.
StatisticsViewModel throttling
app/src/main/java/com/konkuk/medicarecall/ui/feature/statistics/viewmodel/StatisticsViewModel.kt
lastFetchTime 기반 60초 내 중복 리프레시 차단 추가. 생성자에 EldersHealthInfoRepository 주입, earliest/latest 주간 플래그 계산 보정 및 선택 변경 시 earliestDate 초기화.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as 사용자
  participant Settings as ElderDetailScreen
  participant Nav as NavController
  participant Main as MainBackStackEntry
  participant Home as HomeScreen
  participant HVM as HomeViewModel

  User->>Settings: 어르신 이름 변경 후 저장
  Settings->>Nav: setSavedState("main", ELDER_NAME_UPDATED=newName)
  Settings->>Nav: popBackStack()
  Home->>Main: savedStateHandle[ELDER_NAME_UPDATED] 관찰 (LaunchedEffect)
  Home->>HVM: overrideName(newName)
  HVM-->>Home: UI 상태(이름/목록) 업데이트
  Home->>Main: savedStateHandle.remove(ELDER_NAME_UPDATED)
Loading
sequenceDiagram
  autonumber
  participant Nav as NavGraph
  participant Home as HomeScreen
  participant HVM as HomeViewModel
  participant Stats as StatisticsScreen
  participant SVM as StatisticsViewModel

  Nav->>Home: 진입 (mainBackStackEntry 전달)
  Home->>HVM: fetchElderList()  -- 진입 시
  Home->>HVM: softRefreshCurrentElder() / summary 갱신
  Nav->>Stats: 진입
  Stats->>HVM: fetchElderList()  -- 진입 시
  Stats->>SVM: refresh()  -- 스로틀링 적용
  SVM-->>Stats: 결과 반영 (isLoading, 데이터)
Loading
sequenceDiagram
  autonumber
  participant SVM as StatisticsViewModel

  SVM->>SVM: refresh()
  alt now - lastFetchTime < 60s
    SVM->>SVM: 빠른 종료 (중복 fetch 차단)
  else
    SVM->>SVM: 원격 호출 및 상태 갱신
    SVM->>SVM: lastFetchTime = now
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

refactor

Suggested reviewers

  • alswlekk
  • ikseong00

Poem

작게 바뀐 이름 한 자락, 스택을 건너와,
홈과 통계가 귀 기울여 새 이름을 불러.
리스트는 새로고침 없이도 고요히 갱신되고,
스로틀은 바쁜 호출을 살짝 달래네. 🎈

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning 이 PR은 SavedStateHandle 기반 이벤트 전파와 HomeViewModel의 overrideName 메서드 추가, fetchElderList 공개, StatisticsScreen의 초기 데이터 재호출 구현 등 이슈 #143의 주요 요구사항 대부분을 충족하지만 HomeScreen 진입 시 fetchElderList 호출 여부가 명확하지 않아 일부 요구사항이 누락된 것으로 보입니다. HomeScreen 컴포저블에 진입할 때 HomeViewModel.fetchElderList()를 호출하도록 LaunchedEffect를 추가하여 요구사항을 완전히 충족하도록 보완하세요.
Out of Scope Changes Check ⚠️ Warning Migration과 이슈 #143의 버그 수정 외에도 ElderIdRepositoryImpl의 var→val 변경, NavGraph API 확장, HomeScreen 및 StatisticsScreen 호출부 리팩토링, StatisticsViewModel의 페치 스로틀링 등 이슈 목적과 직접 관련 없는 광범위한 리팩토링과 기능 확장이 포함되어 있습니다. 이슈 #143의 핵심 수정만 남기고 다른 리팩토링이나 설계 변경은 별도 PR로 분리하여 관리하는 것이 좋습니다.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed 설정된 PR 제목은 어르신 이름 변경 반영이라는 주요 변경사항을 간결하고 명확하게 요약하며 불필요한 이모지나 파일 목록 없이 구체적으로 이슈를 지칭하고 있어 적절합니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/elder-name-update-#143

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@librawish808 librawish808 added bug Something isn't working fix labels Oct 7, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt (1)

500-523: 🛠️ Preview 함수 파라미터 업데이트가 필요해요

HomeScreenLayout 시그니처가 elderInfoListselectedElderId를 요구하도록 바뀌었는데, PreviewHomeScreen_Unrecorded는 여전히 기존의 elderNameList 파라미터를 전달하고 있어서 컴파일 오류가 발생합니다. 미리보기에서도 동일한 구조를 사용하도록 리스트와 선택 ID를 만들어 넘겨주세요.

-    val previewNameList = listOf("김옥자", "박막례", "최이순")
+    val previewNameList = listOf("김옥자", "박막례", "최이순")
+    val previewElderInfoList = previewNameList.mapIndexed { index, name ->
+        ElderInfo(
+            id = index + 1,
+            name = name,
+            phoneNumber = "010-0000-${(index + 1).toString().repeat(4)}"
+        )
+    }
+    val previewSelectedId = 1
 ...
-            elderNameList = previewNameList,
+            elderInfoList = previewElderInfoList,
+            selectedElderId = previewSelectedId,
🧹 Nitpick comments (2)
app/src/main/java/com/konkuk/medicarecall/ui/feature/settings/screen/ElderDetailScreen.kt (1)

230-232: 이름 변경 체크 추가 고려

현재는 이름이 실제로 변경되지 않아도 항상 ELDER_NAME_UPDATED 이벤트를 전달합니다. 이는 불필요한 데이터 재조회를 유발할 수 있습니다.

이름이 실제로 변경되었을 때만 이벤트를 전달하도록 개선할 수 있습니다:

+                        if (name != eldersInfoResponseDto.name) {
                             navController.getBackStackEntry("main")
                                 .savedStateHandle["ELDER_NAME_UPDATED"] = name
+                        }
                         navController.popBackStack()
app/src/main/java/com/konkuk/medicarecall/navigation/NavGraph.kt (1)

237-237: trailing comma 일관성 개선 권장

일부 argument list에 trailing comma가 추가됐는데, 파일 전체적으로 일관되게 적용하면 향후 파라미터 추가 시 diff가 깔끔해집니다. 필수는 아니지만 코드 스타일 통일 차원에서 고려해볼 만합니다.

Also applies to: 249-249, 273-273, 281-281, 289-289, 305-305, 313-313, 328-332, 343-344, 359-363, 381-381, 391-391, 465-465

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8272dd2 and 86c484d.

📒 Files selected for processing (4)
  • app/src/main/java/com/konkuk/medicarecall/navigation/NavGraph.kt (15 hunks)
  • app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt (8 hunks)
  • app/src/main/java/com/konkuk/medicarecall/ui/feature/settings/screen/ElderDetailScreen.kt (3 hunks)
  • app/src/main/java/com/konkuk/medicarecall/ui/feature/statistics/screen/StatisticsScreen.kt (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/src/main/java/com/konkuk/medicarecall/navigation/NavGraph.kt (2)
app/src/main/java/com/konkuk/medicarecall/ui/feature/settings/screen/MyDataSettingScreen.kt (1)
  • MyDataSettingScreen (50-206)
app/src/main/java/com/konkuk/medicarecall/ui/feature/settings/screen/ServiceCenterScreen.kt (1)
  • ServiceCenterScreen (23-61)
🪛 GitHub Actions: Android CI
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt

[error] 506-506: Kotlin compilation error: No parameter with name 'elderNameList' found.


[error] 522-522: Kotlin compilation error: No value passed for parameter 'elderInfoList'.


[error] 522-522: Kotlin compilation error: No value passed for parameter 'selectedElderId'.

🔇 Additional comments (9)
app/src/main/java/com/konkuk/medicarecall/ui/feature/statistics/screen/StatisticsScreen.kt (2)

57-60: 초기 데이터 로딩 추가 잘 되었습니다! 👍

화면 진입 시 fetchElderList()refresh()를 호출하여 최신 어르신 목록과 통계 데이터를 가져오는 로직이 깔끔하게 추가되었네요. key1 = true를 사용하여 컴포저블이 컴포지션에 진입할 때마다(화면 이동 후 복귀 시) 실행되므로 PR 목표인 "화면 진입 시마다 최신 데이터 로딩"이 잘 구현되었습니다.

참고로 아래 DisposableEffectON_RESUME과 약간의 중복 가능성이 있지만, 초기 컴포지션과 백그라운드 복귀를 구분하는 용도로 보이므로 의도된 설계로 판단됩니다.


92-96: 어르신 이름 우선순위 로직 개선 좋습니다! 👍

이름 결정 로직의 우선순위를 변경하여 elderInfoList에서 selectedElderId로 찾은 이름을 가장 먼저 사용하도록 수정한 점이 좋네요. 이제 최신 목록 데이터가 우선 반영되므로 이름 변경 사항이 더 빠르게 UI에 나타날 것으로 예상됩니다.

우선순위 흐름:

  1. elderInfoList에서 선택된 ID의 이름
  2. uiState.summary에 포함된 이름 (백업)
  3. 목록의 첫 번째 이름
  4. 기본값 "어르신 통계"

다만 elderInfoListselectedElderId가 서로 다른 시점에 업데이트될 경우 일시적으로 일치하지 않을 가능성이 있으니, 실제 사용 중 이름이 잠깐 깜빡이거나 이상하게 보이는 현상이 있는지 테스트해보시면 좋을 것 같아요.

app/src/main/java/com/konkuk/medicarecall/ui/feature/settings/screen/ElderDetailScreen.kt (3)

29-29: Import 추가 내용 확인 완료!

NavController 및 관련 유틸리티/타입 import들이 코드 전반에 걸쳐 적절하게 사용되고 있습니다.

Also applies to: 36-46


51-57: PersonalDetailScreen 호출부에 navController가 정상으로 전달되고 있습니다
추가 검증 불필요합니다.


230-232: getBackStackEntry("main") 사용 안전

NavGraph.ktnavigation(…, route = "main") 으로 “main” 그래프가 정의되어 있어, 해당 엔트리는 항상 백스택에 존재합니다. 예외 처리 없이 사용해도 문제없습니다.
(이름 변경 여부 체크는 필요 시 선택적 리팩터로 검토 가능)

Likely an incorrect or invalid review comment.

app/src/main/java/com/konkuk/medicarecall/navigation/NavGraph.kt (4)

104-109: 함수 시그니처 업데이트 확인됨

trailing comma 추가는 Kotlin 1.4+ 스타일 가이드에 부합하는 포맷팅 개선입니다.


154-155: navController 파라미터 추가 일관성 양호

여러 화면에 navController 파라미터가 명시적으로 전달되도록 일관되게 업데이트됐네요. 네비게이션 기능이 필요한 화면들에 올바르게 적용됐습니다.

Also applies to: 162-163, 170-171, 178-179, 185-186, 232-233, 243-243, 267-267, 298-298, 322-322, 344-344, 353-353, 400-400, 453-453, 469-469


131-149: HomeScreen 시그니처 확인 완료
HomeScreen 함수에 homeViewModel: HomeViewModel = hiltViewModel()mainBackStackEntry: NavBackStackEntry 파라미터가 정상적으로 추가된 것을 확인했습니다. 변경사항 승인합니다.


198-208: StatisticsScreen 시그니처 검증 완료: homeViewModel: HomeViewModel 파라미터가 포함된 것이 확인되었습니다.

Copy link
Contributor

@ikseong00 ikseong00 left a comment

Choose a reason for hiding this comment

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

👍

Comment on lines 77 to 81
viewModelScope.launch {
_uiState.value = _uiState.value.copy(isLoading = true)
_uiState.value = _uiState.value.copy(isLoading = false)
}
return
Copy link
Contributor

Choose a reason for hiding this comment

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

이거는 무슨 코드인가요 .. ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

이름 변경 시에도 뭔가 리프레시된 것처럼 보여주려던 처리였습니다 해당 부분은 삭제하도록 하겠습니다

Comment on lines +99 to +101
val updatedName by mainBackStackEntry.savedStateHandle
.getStateFlow<String?>("ELDER_NAME_UPDATED", null)
.collectAsStateWithLifecycle()
Copy link
Contributor

Choose a reason for hiding this comment

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

SavedStateHandle 대신에 다른 방법을 쓰는 걸 고안해야 할 것 같습니다

하드코딩 문자열로 주고받을 때 휴먼에러가 발생할 가능성도 있고,
해당 데이터가 백스택에 존재할 지, 존재하지 않을 지 컴파일 타임에 증명할 수가 없어서
코드 복잡도가 증가할 것 같습니다

대체 방안으로는

  • 상단바 전용 ViewModel 을 만들어 id 값을 홀딩, 매번 id 를 가져다 쓰기
  • 레포지토리에서 id 값을 매번 가져다 쓰기

등으로 해서, id 값만 넓은 스코프에서 유지를 하는 게 좋을 것 같아요. 추후 이슈로 하면 될 것 같습니다

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

아하 넵 이해했습니다
해당 개선 내용은 별도 이슈로 만들어두겠습니다. 감사합니다!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt (1)

500-525: Preview 함수 시그니처를 업데이트해야 합니다.

두 번째 Preview 함수가 여전히 구버전 API를 사용하고 있어 컴파일 에러가 발생하고 있습니다.

다음 diff를 적용하여 수정하세요:

 @Preview(showBackground = true, name = "홈 화면 (미기록 상태)", heightDp = 1500)
 @Composable
 fun PreviewHomeScreen_Unrecorded() {
     val unrecordedUiState = HomeUiState(
         isLoading = false,
         elderName = "김옥자",
         balloonMessage = "",
         breakfastEaten = null,
         lunchEaten = null,
         dinnerEaten = null,
         medicines = emptyList(),
         sleep = HomeResponseDto.SleepDto(0, 0),
         healthStatus = "",
         mentalStatus = "",
         glucoseLevelAverageToday = 0
     )
 
-    val previewNameList = listOf("김옥자", "박막례", "최이순")
+    val previewElderInfoList = listOf(
+        ElderInfo(1, "김옥자", "010-1111-1111"),
+        ElderInfo(2, "박막례", "010-2222-2222"),
+        ElderInfo(3, "최이순", "010-3333-3333")
+    )
+    val previewSelectedId = 1
 
     MediCareCallTheme {
         HomeScreenLayout(
             navController = rememberNavController(),
             homeUiState = unrecordedUiState,
-            elderNameList = previewNameList,
+            elderInfoList = previewElderInfoList,
+            selectedElderId = previewSelectedId,
             isRefreshing = false,
             dropdownOpened = false,
             onDropdownClick = {},
             onDropdownDismiss = {},
             onDropdownItemSelected = {},
             onNavigateToMealDetail = {},
             onNavigateToMedicineDetail = {},
             onNavigateToSleepDetail = {},
             onNavigateToStateHealthDetail = {},
             onNavigateToStateMentalDetail = {},
             onNavigateToGlucoseDetail = {},
             snackbarHostState = SnackbarHostState(),
             isLoading = false,
             immediateCall = {},
             onRefresh = {},
             onFabClick = {}
         )
     }
 }
♻️ Duplicate comments (1)
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt (1)

99-108: SavedStateHandle 기반 이벤트 전달 방식.

하드코딩된 문자열 키를 사용한 SavedStateHandle 기반 접근 방식은 컴파일 타임 안전성이 부족하다는 점이 이미 이전 리뷰에서 논의되었습니다. 작성자께서 별도 이슈로 개선할 예정이라고 하셨으니, 현재는 원샷 처리 로직(remove 호출)이 정상 동작하는지만 확인하시면 될 것 같습니다.

🧹 Nitpick comments (3)
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt (1)

174-183: 선택된 어르신 이름 처리 로직.

elderNameList 도출 및 selectedElderName 폴백 체인이 방어적으로 잘 구현되어 있습니다. 다만 폴백 로직이 3단계로 구성되어 있어, 각 단계의 의도를 간단한 주석으로 표시하면 추후 유지보수 시 도움이 될 것 같습니다.

예시:

val selectedElderName =
    // 1. Try to find by selected ID
    elderInfoList.find { it.id == selectedElderId }?.name
        ?.takeIf { it.isNotBlank() }
    // 2. Fallback to cached elderName
        ?: homeUiState.elderName
            .takeIf { it.isNotBlank() }
    // 3. Default placeholder
        ?: "어르신 선택"
app/src/main/java/com/konkuk/medicarecall/ui/feature/statistics/viewmodel/StatisticsViewModel.kt (2)

136-139: 중복 네트워크 호출 가능성 (ignoreLoadingGate=true로 게이트 우회)

refresh에서 ignoreLoadingGate=true로 호출하면, 기존 로딩 중에도 추가 요청이 겹칠 수 있습니다(순서경쟁/불필요 트래픽).

권장 대안 중 하나:

  • 단일 fetchJob을 관리하며 신규 호출 시 이전 잡 cancel 후 최신만 유지.

예시 변경안:

// 상단 필드
import kotlinx.coroutines.Job
private var fetchJob: Job? = null

// 시그니처에서 ignoreLoadingGate 제거(선택)
private fun getWeeklyStatistics(
    elderId: Int,
    startDate: LocalDate
) {
    if (_uiState.value.isLoading) return
    fetchJob?.cancel()
    fetchJob = viewModelScope.launch {
        _uiState.value = _uiState.value.copy(isLoading = true, error = null)
        // ... 기존 로직
    }
}

// 호출부 (refresh)
getWeeklyStatistics(elderId = id, startDate = start)

게이트를 유지하고 싶다면 최소한 refresh에서 ignoreLoadingGate=false로 두어 동시 호출을 방지하는 것도 대안입니다.

Also applies to: 143-143, 82-86


149-156: correctOrder 조회 비용 최적화(캐시 제안)

매 통계 조회마다 eldersHealthInfoRepository를 호출하면 오버헤드가 큽니다. elderId별로 메모리 캐시(Map<Int, List>) 후, 갱신 이벤트에만 invalidate하는 방식을 고려해 주세요.

간단 예시:

private val orderCache = mutableMapOf<Int, List<String>>()

private suspend fun resolveOrder(elderId: Int): List<String> =
    orderCache[elderId] ?: eldersHealthInfoRepository.getEldersHealthInfo()
        .getOrNull()
        ?.firstOrNull { it.elderId == elderId }
        ?.medications
        ?.flatMap { it.value }
        ?.distinct()
        ?.also { orderCache[elderId] = it }
        ?: emptyList()
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 86c484d and 0aea923.

📒 Files selected for processing (2)
  • app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt (9 hunks)
  • app/src/main/java/com/konkuk/medicarecall/ui/feature/statistics/viewmodel/StatisticsViewModel.kt (4 hunks)
🧰 Additional context used
🪛 GitHub Actions: Android CI
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt

[error] 506-506: No parameter with name 'elderNameList' found.


[error] 522-522: No value passed for parameter 'elderInfoList'.


[error] 522-522: No value passed for parameter 'selectedElderId'.

🔇 Additional comments (4)
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt (3)

89-91: LGTM!

ElderInfo 기반 데이터 모델로 전환한 것은 타입 안전성을 높이고 ID 정보를 함께 유지할 수 있어 좋은 개선입니다. State 수집과 HomeScreenLayout 호출이 올바르게 업데이트되었습니다.

Also applies to: 114-115


80-80: LGTM!

SavedStateHandle에 접근하기 위해 mainBackStackEntry 파라미터를 추가한 것이 적절합니다. 이는 99-101번 줄에서 올바르게 활용되고 있습니다.


103-108: overrideName 메서드 구현 검증 완료

overrideName이 elderInfoList, elderName, isLoading을 업데이트하고 softRefreshCurrentElder()로 요약·건강 정보만 재조회하므로 추가 수정 불필요합니다.

app/src/main/java/com/konkuk/medicarecall/ui/feature/statistics/viewmodel/StatisticsViewModel.kt (1)

8-9: EldersHealthInfoRepository는 이미 RepositoryModule에서 @BINDS로 바인딩되어 있습니다. 이 코멘트는 무시하세요.

Likely an incorrect or invalid review comment.

// [수정 1] earliestDate의 초기값을 아주 먼 과거로 설정하여 초기 오류를 방지합니다.
private var earliestDate: LocalDate = LocalDate.MIN

private var lastFetchTime: Long = 0
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

리프레시 스로틀링: 단조 시간 사용 + 강제 갱신 플래그 추가 제안

  • System.currentTimeMillis 기반 측정은 기기 시간 변경에 취약합니다. SystemClock.elapsedRealtime( )로 교체 권장.
  • 최근 60초 내 스로틀로 인해 “이름 변경 직후 최신 반영”이 최대 60초 지연될 수 있습니다. 명시적 갱신 시 우회할 수 있도록 force 플래그 추가를 추천합니다.

적용 예시(diff):

-    private var lastFetchTime: Long = 0
+    private var lastFetchElapsed: Long = 0
@@
-    fun refresh() {
-        val currentTime = System.currentTimeMillis()
-        if (currentTime - lastFetchTime < 60000) {
-            return
-        }
+    fun refresh(force: Boolean = false) {
+        val now = SystemClock.elapsedRealtime()
+        if (!force && now - lastFetchElapsed < THROTTLE_MS) {
+            return
+        }
@@
-            }.onSuccess { (dto, order) ->
-                lastFetchTime = System.currentTimeMillis()
+            }.onSuccess { (dto, order) ->
+                lastFetchElapsed = SystemClock.elapsedRealtime()

추가로 필요한 보일러플레이트(파일 내 임의 위치, 예: 클래스 상단/companion object):

import android.os.SystemClock

companion object {
    private const val THROTTLE_MS = 60_000L
}

사용처 예시:

  • 일반 진입: refresh()
  • 이름 변경 이벤트 등 즉시 반영 필요: refresh(force = true)

Also applies to: 73-79, 160-160

🤖 Prompt for AI Agents
In
app/src/main/java/com/konkuk/medicarecall/ui/feature/statistics/viewmodel/StatisticsViewModel.kt
around lines 52 (and also update usages at 73-79 and 160), replace the current
System.currentTimeMillis-based throttling with SystemClock.elapsedRealtime(),
add a companion constant THROTTLE_MS = 60_000L and import
android.os.SystemClock, and introduce a force: Boolean parameter to the
refresh(...) call so the throttle check becomes: if (!force &&
(SystemClock.elapsedRealtime() - lastFetchTime) < THROTTLE_MS) return; otherwise
perform the refresh and set lastFetchTime = SystemClock.elapsedRealtime();
update all callers (normal entry calls refresh() and immediate-update callers
use refresh(force = true)).

@librawish808
Copy link
Collaborator Author

@alswlekk 코드리뷰 부탁드립니다
그리고 이전 홈화면, 주간통계화면 UI수정사항 PR은 머지했는데 수정할 부분있다면 코멘트 남겨주세요!
바로 반영하겠습니다

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt (1)

99-108: 일회성 이벤트 처리가 올바르게 구현되었습니다.

SavedStateHandle을 통한 이름 업데이트 알림 패턴이 적절히 구현되었습니다. collectAsStateWithLifecycle를 사용해 생명주기를 고려했고, 처리 후 키를 제거해 일회성을 보장하고 있습니다.

다만 하드코딩된 문자열 키("ELDER_NAME_UPDATED") 사용에 대한 우려는 이미 이전 리뷰에서 지적되었고, 별도 이슈로 개선 예정인 것으로 확인됩니다.

🧹 Nitpick comments (2)
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt (2)

89-91: 미사용 상태 수집 제거 권장

elderInfoListselectedElderIdHomeScreenLayout에 전달되어 사용되고 있으나, elderNameList(라인 90)는 수집만 하고 실제로는 전달되지 않습니다. HomeScreenLayout 내부에서 elderInfoList로부터 직접 파생되므로(라인 174-176), 라인 90의 수집은 불필요한 것으로 보입니다.

다음과 같이 미사용 라인을 제거할 수 있습니다:

     val elderInfoList by homeViewModel.elderInfoList.collectAsState()
-    val elderNameList by homeViewModel.elderNameList.collectAsState()
     val selectedElderId by homeViewModel.selectedElderId.collectAsState()

174-183: 이름 해결 로직이 방어적으로 구현되었습니다.

여러 단계의 폴백을 통해 안전하게 이름을 결정하는 로직입니다. remember(elderInfoList)를 사용해 불필요한 재계산을 방지한 점도 좋습니다.

다만 라인 178-183의 폴백 체인이 다소 복잡해 보일 수 있습니다. 가독성을 높이고 싶다면 별도 헬퍼 함수로 추출하는 것을 고려해보세요.

선택적 리팩토링 예시:

private fun resolveElderName(
    elderInfoList: List<ElderInfo>,
    selectedElderId: Int?,
    fallbackName: String
): String {
    return elderInfoList
        .find { it.id == selectedElderId }
        ?.name
        ?.takeIf { it.isNotBlank() }
        ?: fallbackName.takeIf { it.isNotBlank() }
        ?: "어르신 선택"
}

// 사용:
val selectedElderName = resolveElderName(
    elderInfoList,
    selectedElderId,
    homeUiState.elderName
)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0aea923 and 15b229e.

📒 Files selected for processing (1)
  • app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt (10 hunks)
🔇 Additional comments (3)
app/src/main/java/com/konkuk/medicarecall/ui/feature/home/screen/HomeScreen.kt (3)

37-37: 새 import가 적절하게 추가되었습니다.

LaunchedEffect, collectAsStateWithLifecycle, NavBackStackEntry, ElderInfo 모두 코드에서 적절히 사용되고 있습니다.

Also applies to: 51-52, 67-67


155-156: API 시그니처 개선이 적절합니다.

elderNameList: List<String> 대신 elderInfoList: List<ElderInfo>selectedElderId: Int?를 사용하도록 변경한 것은 더 구조화된 데이터 모델을 반영하며 타입 안전성을 향상시킵니다.


450-455: 프리뷰가 새 데이터 모델에 맞게 잘 업데이트되었습니다.

ElderInfo 리스트와 selectedElderId를 사용하도록 프리뷰 데이터가 적절히 수정되었으며, 기록된 상태와 미기록 상태 모두에 대한 프리뷰를 제공하고 있습니다.

Also applies to: 500-504

eldersInfoResponseDto: EldersInfoResponseDto,
detailViewModel: DetailElderInfoViewModel = hiltViewModel()
detailViewModel: DetailElderInfoViewModel = hiltViewModel(),
navController: NavController,
Copy link
Collaborator

Choose a reason for hiding this comment

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

각 스크린에서 navController를 사용하지 않고 직접 함수값을 변수로 넘겨주는 형식으로 수정하기로 얘기했던 거 같은데 확실치 않아서 이와 관련해서는 시험끝나고 회의 때 한 번 얘기해보면 좋을 거 같습니다 !

Copy link
Collaborator Author

@librawish808 librawish808 Oct 9, 2025

Choose a reason for hiding this comment

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

넵 좋습니다 해당내용은 다음 회의 노션에 추가하도록 하겠습니다

Comment on lines +74 to +79
val currentTime = System.currentTimeMillis()
if (currentTime - lastFetchTime < 60000) {

return
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

@librawish808
Copy link
Collaborator Author

@ProtossManse
코드리뷰 부탁드립니다

@librawish808 librawish808 merged commit 5f9d819 into develop Oct 26, 2025
2 checks passed
@librawish808 librawish808 deleted the fix/elder-name-update-#143 branch October 26, 2025 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Fix] 어르신 이름 변경 반영

4 participants