Skip to content

홈 화면 목표 조회 API 연동#62

Merged
chanho0908 merged 26 commits intodevelopfrom
feat/#60-home-goal-api
Feb 6, 2026
Merged

홈 화면 목표 조회 API 연동#62
chanho0908 merged 26 commits intodevelopfrom
feat/#60-home-goal-api

Conversation

@dogmania
Copy link
Copy Markdown
Contributor

@dogmania dogmania commented Feb 5, 2026

이슈 번호

작업내용

  • 홈 화면 목표 조회 API 통신 로직을 구현했습니다.
  • 목표 조회 이후 상태 처리 로직을 구현했습니다.

결과물

image

리뷰어에게 추가로 요구하는 사항 (선택)

지금 일단 커플 연결이 안되어 있어서 조회되는 건 없지만 통신이 되는 것까지 확인했어요! 그리고 저는 local.properties에 /api/v1을 추가하지 않았는데 구글 로그인 코드 보니까 형은 추가한 거 같더라구요..? 그래서 이걸 일단 맞춰야 할 거 같아요

제가 local.properties에 /api/v1 추가하니까 LoginViewModel에서 Koin 때문에 자꾸 앱이 죽어버려서 지금 어떻게 설정해놓으셨는지 공유해주세요!

@dogmania dogmania requested a review from chanho0908 February 5, 2026 18:58
@dogmania dogmania self-assigned this Feb 5, 2026
@dogmania dogmania added the Feature Extra attention is needed label Feb 5, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 5, 2026

📝 Walkthrough

Walkthrough

이 PR은 홈 화면의 목표(Goal) 조회 기능을 추가합니다. 네트워크 계층에 GoalService 및 DTO(GoalResponse, GoalListResponse, VerificationResponse)와 매퍼가 도입되고 AuthService의 엔드포인트 경로가 조정되었습니다. 도메인 계층에는 Goal, GoalList, GoalVerification 클래스와 RepeatCycle/GoalIconType 변환 유틸이 추가되며 기존 RepeatType은 제거되었습니다. 데이터 계층에는 DefaultGoalRepository와 DI 바인딩, 관련 build 설정 변경이 포함됩니다. UI 쪽에서는 HomeViewModel과 상태가 GoalList를 사용하도록 변경되고 디자인 시스템에 아이콘 리소스와 문자열, 벡터 드로어블이 추가되었습니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive AuthService 엔드포인트 경로 변경(api/v1 접두사 추가)이 #60과의 직접적인 연관성이 불명확하며 기존 코드에 영향을 줄 가능성이 있습니다. AuthService 경로 변경이 기존 로그인 로직에 미치는 영향을 검증하고, 이 변경이 별도 이슈와 관련되었는지 명확히 해주시기 바랍니다.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목 '홈 화면 목표 조회 API 연동'은 주요 변경사항을 명확하게 요약하며, 변경셋의 핵심 기능 구현을 정확하게 설명합니다.
Description check ✅ Passed PR 설명은 작업내용, 결과물, 그리고 구현 과정의 주의사항을 포함하며 변경셋과 관련된 충분한 컨텍스트를 제공합니다.
Linked Issues check ✅ Passed 코드 변경사항은 #60의 모든 기본 요구사항을 충족합니다: Goal DTO, Domain Model, GoalRepository 구현 및 API 통신 로직 완성.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 feat/#60-home-goal-api

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.

Copy link
Copy Markdown

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
feature/main/src/main/java/com/twix/home/HomeViewModel.kt (1)

62-100: ⚠️ Potential issue | 🟠 Major

빠른 날짜 변경 시 이전 응답이 최신 상태를 덮어쓸 위험이 있습니다.

왜: 여러 날짜를 연속으로 선택하면 먼저 보낸 요청이 늦게 도착해, 최신 선택 날짜와 다른 goalList로 상태가 덮일 수 있습니다.
어떻게: 요청 시점의 날짜를 보존하고, 성공 콜백에서 현재 상태와 일치할 때만 상태를 갱신하도록 가드하는 게 안전합니다. 이 방향으로 처리해 보는 건 어떨까요?

🔧 제안 수정
     private fun fetchGoalList() {
         val date = currentState.selectedDate.toString()

         launchResult(
             block = { goalRepository.fetchGoalList(date = date) },
-            onSuccess = { goalList -> reduce { copy(goalList = goalList) } },
+            onSuccess = { goalList ->
+                if (currentState.selectedDate.toString() != date) return@onSuccess
+                reduce { copy(goalList = goalList) }
+            },
             onError = {
                 emitSideEffect(HomeSideEffect.ShowToast(R.string.toast_goal_fetch_failed, ToastType.ERROR))
             },
         )
     }
🤖 Fix all issues with AI agents
In
`@core/network/src/main/java/com/twix/network/model/response/goal/model/VerificationResponse.kt`:
- Line 12: The date format comment for the uploadedAt property in
VerificationResponse (field: uploadedAt) is ambiguous using "yyyy-mm-dd"; update
the comment to use uppercase months ("yyyy-MM-dd") to avoid confusion with
minutes, e.g., change the inline comment next to uploadedAt in
VerificationResponse.kt to "yyyy-MM-dd".

In `@core/network/src/main/java/com/twix/network/service/AuthService.kt`:
- Around line 11-16: AuthService and GoalService include the "/api/v1" prefix in
their Retrofit endpoints (e.g., googleLogin in AuthService) while
OnboardingService endpoints omit it, causing potential duplicate
"/api/v1/api/v1" when BASE_URL contains the version; decide which single-source
strategy to use and make endpoints consistent: either remove "/api/v1" from all
service interface paths (AuthService, GoalService, OnboardingService) if
BASE_URL will include "/api/v1", or remove the version from BASE_URL and add
"/api/v1" to every service endpoint (including OnboardingService) so all
interfaces use the same versioned prefix. Ensure you update the service methods
(e.g., AuthService.googleLogin and corresponding GoalService/OnboardingService
methods) accordingly and update any docs/config to reflect the chosen strategy.
🧹 Nitpick comments (7)
core/design-system/src/main/res/drawable/ic_unchecked_you.xml (1)

1-18: 하드코딩된 색상값 사용에 대해 검토해 주세요.

현재 #ffffff, #C6C6C6 등 색상값이 직접 하드코딩되어 있습니다. 디자인 시스템의 일관성을 위해 가능하다면 color resource를 참조하는 것이 좋습니다.

다만, Vector Drawable에서 theme attribute(?attr/)나 color resource 참조는 API 레벨 제약이 있을 수 있으므로, 프로젝트의 minSdk와 디자인 시스템 정책에 따라 판단해 주세요.

참고로, "unchecked" 상태를 표현하기 위해 체크마크를 흰색 배경에 흰색으로 그려 보이지 않게 하는 방식은 이해했습니다. 다른 ic_checked_*, ic_unchecked_* 아이콘들과 일관된 스타일인지도 함께 확인해 보시면 좋겠습니다.

core/design-system/src/main/res/drawable/ic_checked_me.xml (1)

9-10: 하드코딩된 색상이 다크 모드를 지원하지 않습니다.

#171717#ffffff가 직접 지정되어 있어 다크 모드에서 아이콘이 제대로 표시되지 않을 수 있습니다. 예를 들어, 다크 모드 배경에서 #171717 원이 거의 보이지 않을 수 있습니다.

디자인 시스템의 테마 속성이나 색상 리소스를 사용하는 것이 좋습니다:

  • ?attr/colorOnSurface 또는 @color/... 형태의 참조 사용
  • 필요시 night 리소스 디렉토리에 별도 버전 추가

다크 모드 지원이 현재 스코프에 포함되지 않는다면, 추후 대응을 위해 이슈로 트래킹해주세요.

Also applies to: 15-16

core/network/src/main/java/com/twix/network/service/GoalService.kt (1)

8-11: date 포맷 계약을 KDoc로 명시하면 좋습니다

왜 문제인지: 현재 String만으로는 호출 측이 yyyy-MM-dd인지, 타임존 포함인지 헷갈릴 수 있어 잘못된 요청이 발생할 수 있습니다.
어떻게 개선: 간단한 KDoc로 기대 포맷을 명시해 주세요.

📝 예시
 interface GoalService {
     `@GET`("api/v1/goals")
     suspend fun fetchGoals(
+        /**
+         * `@param` date 서버가 기대하는 날짜 형식: yyyy-MM-dd (ISO-8601)
+         */
         `@Query`("date") date: String,
     ): GoalListResponse
 }
domain/src/main/java/com/twix/domain/repository/GoalRepository.kt (1)

6-8: date를 String으로 노출하면 포맷 불일치 위험이 있습니다.

도메인 레이어가 문자열 포맷에 의존하면 호출부마다 포맷이 달라져 API 실패나 캐시 불일치가 생길 수 있습니다. 날짜를 표현하는 타입(도메인 전용 타입 등)으로 받고, 데이터 레이어에서 API 포맷으로 변환하는 방식이 더 안전하지 않을까요?

🔧 제안 변경 예시
 interface GoalRepository {
-    suspend fun fetchGoalList(date: String): AppResult<GoalList>
+    suspend fun fetchGoalList(date: LocalDate): AppResult<GoalList>
 }

As per coding guidelines, 비즈니스 로직이 명확히 표현되어 있는가?

feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorIntent.kt (1)

17-19: Intent 명칭이 RepeatCycle과 불일치합니다.

Intent 이름이 실제 payload 용어와 달라 검색/이해가 어려워질 수 있습니다. SetRepeatCycle로 정합성을 맞추는 게 어떨까요?

🔧 제안 변경 예시
-    data class SetRepeatType(
+    data class SetRepeatCycle(
         val repeatCycle: RepeatCycle,
     ) : GoalEditorIntent

As per coding guidelines, Intent가 사용자 액션 단위로 명확히 정의되어 있는가?

feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorScreen.kt (1)

296-336: 내부 변수명이 RepeatType으로 남아 가독성이 떨어집니다.

왜: 타입은 RepeatCycle인데 변수명은 RepeatType이라 의미가 엇갈립니다.
어떻게: 변수명만 Cycle로 맞추면 읽기 쉬워집니다. 변경해 보시는 건 어떨까요?

✏️ 제안 리네이밍
-    var internalSelectedRepeatType by remember { mutableStateOf(selectedRepeatCycle) }
-    val maxCount = if (internalSelectedRepeatType == RepeatCycle.WEEKLY) 6 else 25
+    var internalSelectedRepeatCycle by remember { mutableStateOf(selectedRepeatCycle) }
+    val maxCount = if (internalSelectedRepeatCycle == RepeatCycle.WEEKLY) 6 else 25
@@
-                color = if (internalSelectedRepeatType == RepeatCycle.WEEKLY) CommonColor.White else GrayColor.C500,
+                color = if (internalSelectedRepeatCycle == RepeatCycle.WEEKLY) CommonColor.White else GrayColor.C500,
@@
-                        .background(if (internalSelectedRepeatType == RepeatCycle.WEEKLY) GrayColor.C500 else CommonColor.White)
+                        .background(if (internalSelectedRepeatCycle == RepeatCycle.WEEKLY) GrayColor.C500 else CommonColor.White)
@@
-                            internalSelectedRepeatType = RepeatCycle.WEEKLY
+                            internalSelectedRepeatCycle = RepeatCycle.WEEKLY
@@
-                color = if (internalSelectedRepeatType == RepeatCycle.MONTHLY) CommonColor.White else GrayColor.C500,
+                color = if (internalSelectedRepeatCycle == RepeatCycle.MONTHLY) CommonColor.White else GrayColor.C500,
@@
-                        .background(if (internalSelectedRepeatType == RepeatCycle.MONTHLY) GrayColor.C500 else CommonColor.White)
+                        .background(if (internalSelectedRepeatCycle == RepeatCycle.MONTHLY) GrayColor.C500 else CommonColor.White)
@@
-                            internalSelectedRepeatType = RepeatCycle.MONTHLY
+                            internalSelectedRepeatCycle = RepeatCycle.MONTHLY
@@
-            onClick = { onCommit(internalSelectedRepeatType, internalRepeatCount) },
+            onClick = { onCommit(internalSelectedRepeatCycle, internalRepeatCount) },
feature/goal-editor/src/main/java/com/twix/goal_editor/component/GoalInfoCard.kt (1)

59-105: 함수명이 RepeatType으로 남아 혼란을 줄 수 있습니다.

왜: 실제로는 RepeatCycle을 다루는데 함수명이 RepeatType이라 의미가 불일치합니다.
어떻게: 함수명만 RepeatCycle로 맞추면 가독성이 좋아집니다. 변경을 고려해 보실까요?

✏️ 제안 리네이밍
-        RepeatTypeSettings(
+        RepeatCycleSettings(
             selectedRepeatCycle = selectedRepeatCycle,
             repeatCount = repeatCount,
             onSelectedRepeatType = onSelectedRepeatType,
             onShowRepeatCountBottomSheet = onShowRepeatCountBottomSheet,
         )
@@
-private fun RepeatTypeSettings(
+private fun RepeatCycleSettings(
     selectedRepeatCycle: RepeatCycle,
     repeatCount: Int,
     onSelectedRepeatType: (RepeatCycle) -> Unit,
     onShowRepeatCountBottomSheet: () -> Unit,
 ) {

@chanho0908 chanho0908 merged commit a521464 into develop Feb 6, 2026
2 checks passed
Copy link
Copy Markdown
Contributor

@chanho0908 chanho0908 left a comment

Choose a reason for hiding this comment

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

고생했어 현수야 !

@chanho0908 chanho0908 deleted the feat/#60-home-goal-api branch February 11, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature Extra attention is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

홈 화면 목표 조회 API 연동

2 participants