-
Notifications
You must be signed in to change notification settings - Fork 0
[Qa/#119] 빛나길 2.0.0 버전 자체 QA 사항을 반영합니다. #122
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
- 감정 등록 시 추천 루틴 목록을 다시 받아오도록 구현
Walkthrough내비게이션 스택 처리 변경(약관동의→온보딩에서 전체 백스택 제거), 가이드 타입에 HOME_LIST 추가, 추천 루틴 화면에서 감정 변경 이벤트 구독으로 목록 자동 갱신 도입, 버튼 타이포그래피에 LineHeightStyle 적용이 포함됩니다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant TermsAgreement
participant NavController
participant OnBoarding
User->>TermsAgreement: 동의 버튼 클릭
TermsAgreement->>NavController: navigate(Route.OnBoarding(), popUpTo(0){inclusive=true})
Note over NavController: 전체 백스택 제거
NavController-->>OnBoarding: OnBoarding 화면 표시
sequenceDiagram
autonumber
participant ViewModel as RecommendRoutineViewModel
participant EmotionFlow as GetEmotionChangeEventFlowUseCase
participant Repo as RecommendRepository
participant UI
ViewModel->>EmotionFlow: collect()
EmotionFlow-->>ViewModel: EmotionChangedEvent
ViewModel->>Repo: fetchRecommendRoutines()
Repo-->>ViewModel: routines
ViewModel-->>UI: state update (갱신된 목록)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type 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.
고생하셨습니다! 🚀
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: 0
🧹 Nitpick comments (5)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/atom/BitnagilSelectButton.kt (1)
97-103
: LineHeightStyle 적용은 👍 — lineHeight 미설정 시 효과 제한 + Trim 옵션 재검토 권장.
- subtitle1SemiBold에 lineHeight가 명시되지 않았다면 lineHeightStyle의 효과가 제한적일 수 있습니다. 디자인 토큰에서 subtitle1SemiBold의 lineHeight 지정 여부를 확인해 주세요.
- 현재 Trim.None이라 상·하단 여백이 넉넉하게 잡힐 수 있습니다. 타이포 그리드 기준을 맞추려면 Trim.Both를 검토해 볼 가치가 있습니다. (멀티라인 타이틀에서 특히 체감)
디자인 가이드가 Trim.None을 요구하지 않는다면 아래처럼 변경을 제안드립니다.
- style = titleTextStyle.copy( - lineHeightStyle = LineHeightStyle( - alignment = LineHeightStyle.Alignment.Center, - trim = LineHeightStyle.Trim.None, - ), - ), + style = titleTextStyle.copy( + lineHeightStyle = LineHeightStyle( + alignment = LineHeightStyle.Alignment.Center, + trim = LineHeightStyle.Trim.Both, + ), + ),또한 subtitle1SemiBold에 lineHeight가 정의되어 있는지 확인 부탁드립니다. 없다면 해당 TextStyle 쪽에 lineHeight를 명시하는 편이 전역 일관성 측면에서 더 안전합니다.
presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideType.kt (1)
16-20
: GuideType enum 순서 변경 검토 결과
- 코드베이스 내에서 GuideType.ordinal, GuideType.values()/entries 기반 인덱싱, SharedPreferences/DataStore/Room/@SerializedName/encode/decode/putString/getString 등을 통한 직렬화 사용처가 발견되지 않았습니다.
when(guideType)
형태로 exhaustive 처리된 분기도 없습니다.따라서 현재로서는 enum 순서 변경 시 내부 호환성 문제는 발생하지 않을 것으로 보입니다.
다만, 백엔드 API나 외부 시스템과 연관된 직렬화 로직이 있을 경우 영향을 받을 수 있으니 최종 확인을 부탁드립니다.또한, enum에 하드코딩된 한글 문자열(title, description)은 유지·보수를 위해 장기적으로 string 리소스로 이전할 것을 권장드립니다.
app/src/main/java/com/threegap/bitnagil/MainNavHost.kt (1)
83-85
: TermsAgreement → OnBoarding 전환 시 전체 스택 제거는 의도에 부합 — 중복 내비게이션 방지와 의도 명시성 강화 제안.
- 빠른 연속 탭으로 인한 중복 push를 막기 위해 launchSingleTop 추가를 권장합니다.
- OnBoarding의 isNew 기본값에 의존하기보다 의도를 명시하는 편이 가독성·안전성 측면에서 좋습니다(기본값이 바뀌어도 안전).
아래처럼 수정을 제안드립니다(기본값이 true라면 동작 동일):
- navigator.navController.navigate(Route.OnBoarding()) { - popUpTo(0) { inclusive = true } - } + navigator.navController.navigate(Route.OnBoarding(isNew = true)) { + launchSingleTop = true + popUpTo(0) { inclusive = true } + }QA 체크 포인트:
- TermsAgreement에서 동의 후 OnBoarding 진입 → 시스템 뒤로가기 시 앱 종료 또는 기대 동작 여부.
- 동의 버튼을 빠르게 2회 이상 탭해도 OnBoarding가 한 번만 올라오는지.
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineViewModel.kt (2)
31-34
: 초기 로드 + 이벤트 구독 동시 시작 → 이중 로드 가능성 점검 필요.getEmotionChangeEventFlowUseCase()가 replay(최근 이벤트 재방출) 특성을 갖고 있다면, init에서의 loadRecommendRoutines()와 즉시 방출된 이벤트가 중복 호출을 유발할 수 있습니다. 실제로 중복 API 호출이 발생하는지 확인해 주세요. 발생한다면 아래 두 가지 중 하나로 정리하는 것을 권장합니다:
- init에서의 직접 로드를 제거하고, 이벤트 스트림의 onStart에서 초기 로드를 트리거
- 또는 이벤트 스트림에서 첫 방출을 drop(1) 처리
원하시면 이벤트 소스 특성(Hot/Cold, replay 여부)에 맞춘 형태로 리팩터 제안 드리겠습니다.
96-102
: 이벤트당 네트워크 로드가 중첩되어 동시 실행될 수 있음 — 취소 가능성/중복 방지 고려.현재 observeEmotionChangeEvent()는 매 이벤트마다 loadRecommendRoutines()를 호출하고, 내부에서 viewModelScope.launch로 새 잡을 생성합니다. 짧은 시간 내 연속 이벤트 시 호출이 중첩될 수 있습니다. 다음 중 하나를 권장합니다.
- loadRecommendRoutines를 suspend로 바꾸고 collectLatest 사용(가장 간결, 최신 이벤트만 반영):
- private fun observeEmotionChangeEvent() { - viewModelScope.launch { - getEmotionChangeEventFlowUseCase().collect { - loadRecommendRoutines() - } - } - } + private fun observeEmotionChangeEvent() { + viewModelScope.launch { + getEmotionChangeEventFlowUseCase() + .collectLatest { + loadRecommendRoutines() // suspend 함수로 변경 필요 + } + } + }그리고 아래처럼 loadRecommendRoutines를 변경(외부에서 launch하지 않고 내부를 suspend로 전환):
// 변경 제안(파일의 다른 위치) private suspend fun loadRecommendRoutines() { sendIntent(RecommendRoutineIntent.UpdateLoading(true)) val result = fetchRecommendRoutinesUseCase() result.fold( onSuccess = { recommendRoutines = it.toUiModel() sendIntent(RecommendRoutineIntent.LoadRecommendRoutines) }, onFailure = { sendIntent(RecommendRoutineIntent.UpdateLoading(false)) }, ) }init 블록에서는:
init { viewModelScope.launch { loadRecommendRoutines() } observeEmotionChangeEvent() }
- 기존 시그니처 유지 시, 최근 호출만 유지(취소)하는 Job 관리:
// 클래스 필드 private var loadJob: Job? = null private fun loadRecommendRoutines() { loadJob?.cancel() loadJob = viewModelScope.launch { sendIntent(RecommendRoutineIntent.UpdateLoading(true)) fetchRecommendRoutinesUseCase().fold( onSuccess = { recommendRoutines = it.toUiModel() sendIntent(RecommendRoutineIntent.LoadRecommendRoutines) }, onFailure = { sendIntent(RecommendRoutineIntent.UpdateLoading(false)) }, ) } }추가로 이벤트 스트림에 .catch { … }를 붙여 예외 발생 시 스트림이 종료되지 않도록 방어하는 것도 고려해 주세요.
중복 호출이 있었는지 로그로 확인하려면 다음을 일시 삽입해 트래픽을 모니터링해 보세요.
- loadRecommendRoutines 진입/완료 시점에 로그 추가
- 이벤트 수신 시점에 로그 추가
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (5)
core/designsystem/src/main/res/drawable-hdpi/img_list_guide.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-mdpi/img_list_guide.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xhdpi/img_list_guide.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxhdpi/img_list_guide.png
is excluded by!**/*.png
core/designsystem/src/main/res/drawable-xxxhdpi/img_list_guide.png
is excluded by!**/*.png
📒 Files selected for processing (4)
app/src/main/java/com/threegap/bitnagil/MainNavHost.kt
(1 hunks)core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/atom/BitnagilSelectButton.kt
(2 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideType.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineViewModel.kt
(3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-21T10:38:49.104Z
Learnt from: l5x5l
PR: YAPP-Github/Bitnagil-Android#38
File: presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/component/atom/textbutton/TextButton.kt:30-35
Timestamp: 2025-07-21T10:38:49.104Z
Learning: presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/component/atom/textbutton/TextButton.kt의 TextButton 컴포넌트는 임시로 구현된 컴포넌트로, 디자인 시스템 구현시 대체 예정입니다.
Applied to files:
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/atom/BitnagilSelectButton.kt
⏰ 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: build
🔇 Additional comments (2)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/atom/BitnagilSelectButton.kt (1)
32-32
: Compose 버전 호환성 확인 완료:TextStyle.copy(lineHeightStyle=…)
지원
gradle/libs.versions.toml
파일의 37번째 줄에서 Compose BOM 버전이2025.06.00
임을 확인했습니다.- 해당 BOM에 포함된 Compose UI 모듈에서는
TextStyle.copy(lineHeightStyle = …)
API가 이미 제공되므로,LineHeightStyle
import 추가는 안전합니다.presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineViewModel.kt (1)
5-5
: GetEmotionChangeEventFlowUseCase DI 바인딩 정상 확인
GetEmotionChangeEventFlowUseCase 클래스에 이미@Inject constructor
가 정의되어 있어 Hilt가 자동으로 바인딩을 생성합니다.
별도의@Module
/@Provides
또는@Binds
설정이 필요하지 않습니다.
또한, 해당 UseCase가 의존하는EmotionRepository
도RepositoryModule
에서@Binds
로 제공되고 있으므로 의존성 주입에 문제가 없습니다.
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: 0
🧹 Nitpick comments (2)
presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/model/mvi/WriteRoutineSideEffect.kt (1)
7-7
: ShowToast SideEffect 메시지 리소스화 제안ViewModel에서 하드코딩된 문자열을 직접 넘기기보다, 리소스 ID(@stringres)와 포맷 인자를 전달하고 화면(WriteRoutineScreen.kt)에서
stringResource
로 해석하는 구조로 리팩터링할 것을 권장합니다.WriteRoutineSideEffect 변경 예시
- data class ShowToast(val message: String) : WriteRoutineSideEffect() + data class ShowToast( + @androidx.annotation.StringRes val messageResId: Int, + val args: List<Any> = emptyList() + ) : WriteRoutineSideEffect()WriteRoutineScreen.kt (라인 62) 처리부 예시
is WriteRoutineSideEffect.ShowToast -> { val text = if (sideEffect.args.isEmpty()) { stringResource(sideEffect.messageResId) } else { stringResource(sideEffect.messageResId, *sideEffect.args.toTypedArray()) } GlobalBitnagilToast.showCheck(message = text) }현재
WriteRoutineScreen.kt
에 이미ShowToast
분기가 추가되어 있어 누락된 처리 지점은 없습니다.presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt (1)
62-64
: 토스트 처리 분기는 적절합니다. 다만 VM에서 내비와 토스트가 연속 발행될 때 토스트 누락 가능성 주의.현재 VM이 MoveToPreviousScreen 직후 ShowToast를 보냅니다. 화면 pop으로 수집 코루틴이 취소되면 이 분기가 호출되지 않을 수 있습니다. VM 쪽에서 제안한 “토스트 → 내비” 순서 변경(또는 상위 화면에서 토스트 처리)과 함께 보면 안정적입니다. 메시지는 stringResource 기반으로 전환하면 i18n/테마 일관성도 좋아집니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt
(2 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineViewModel.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/model/mvi/WriteRoutineSideEffect.kt
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-21T10:38:49.104Z
Learnt from: l5x5l
PR: YAPP-Github/Bitnagil-Android#38
File: presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/component/atom/textbutton/TextButton.kt:30-35
Timestamp: 2025-07-21T10:38:49.104Z
Learning: presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/component/atom/textbutton/TextButton.kt의 TextButton 컴포넌트는 임시로 구현된 컴포넌트로, 디자인 시스템 구현시 대체 예정입니다.
Applied to files:
presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt
🧬 Code graph analysis (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineViewModel.kt (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/common/mviviewmodel/MviViewModel.kt (1)
sendSideEffect
(23-23)
⏰ 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: build
🔇 Additional comments (2)
presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineViewModel.kt (1)
205-207
: EditRoutineSuccess: 내비게이션 직후 토스트 누락 가능성 검토 필요현재
EditRoutineSuccess
핸들러에서 내비게이션(뒤로가기) → 토스트 순으로sendSideEffect
를 연속 발행하고 있어, Compose 화면이 pop 되면서 토스트 이벤트가 수신되지 않을 위험이 있습니다. UX 관점에서 “수정 완료” 토스트 노출이 필수라면 아래 중 하나의 패턴을 적용해 주세요.• 위치
- 파일:
presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineViewModel.kt
- 핸들러:
WriteRoutineIntent.EditRoutineSuccess
블록 (약 205–207라인)• 옵션 A) 토스트 → 내비게이션 (이벤트 드랍 리스크 최소화)
- sendSideEffect(WriteRoutineSideEffect.MoveToPreviousScreen) - sendSideEffect(WriteRoutineSideEffect.ShowToast("루틴 수정이 완료되었습니다.")) + sendSideEffect(WriteRoutineSideEffect.ShowToast("루틴 수정이 완료되었습니다.")) + sendSideEffect(WriteRoutineSideEffect.MoveToPreviousScreen)• 옵션 B) 수정 성공 시 현재 화면 유지 후 토스트만 노출 (자동 내비 제거 요구사항일 경우)
- sendSideEffect(WriteRoutineSideEffect.MoveToPreviousScreen) - sendSideEffect(WriteRoutineSideEffect.ShowToast("루틴 수정이 완료되었습니다.")) + sendSideEffect(WriteRoutineSideEffect.ShowToast("루틴 수정이 완료되었습니다."))• 추가 권장 패턴
- 상위 화면으로 NavResult/SavedStateHandle로 성공 신호만 전달하고, 실제 토스트는 상위 Composable에서 처리
RegisterRoutineSuccess
에도 동일한 UX 일관화를 위해 성공 케이스 호출부 순서 일괄 정리 고려위 두 옵션 및 보완 패턴 중 서비스 요구사항에 맞는 방식을 선택해 적용해 주세요.
presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt (1)
32-32
: GlobalBitnagilToast 의존 추가 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.
고생 많으셨습니다!
[ PR Content ]
빛나길 2.0.0 버전 자체 QA 사항을 반영합니다.
Related issue
Screenshot 📸
Work Description
To Reviewers 📢
Summary by CodeRabbit
신규 기능
개선