[FIX] 안드자체 QA 수정사항 반영 (온보딩/탐색) - #221
Hidden character warning
Conversation
📝 WalkthroughWalkthrough탐색 기능을 컬렉션 페이지 조회에서 세션 기반 조회로 전환했습니다. API, DTO, 도메인 모델, 저장소, ViewModel, Compose 화면을 갱신했습니다. 온보딩 화면 복귀와 닉네임 확인 상태 초기화도 추가했습니다. Changes탐색 세션 전환
온보딩 상태 처리
Estimated code review effort: 4 (Complex) | ~45 minutes Mergeability Score: 🟡 Moderate · up to The exploration flow may fail to transition to its end screen when no more content is available, leaving users on the last work instead of showing the intended end state and preventing the expected return to earlier content. This should be fixed before merging. Sequence Diagram(s)sequenceDiagram
participant ExploreScreen
participant ExploreViewModel
participant ExplorationRepository
participant ExplorationApi
ExploreScreen->>ExploreViewModel: 초기 세션 조회
ExploreViewModel->>ExplorationRepository: getExplorationSession()
ExplorationRepository->>ExplorationApi: GET /api/v1/exploration
ExplorationApi-->>ExplorationRepository: BaseResponse<ExplorationResponseDto>
ExplorationRepository-->>ExploreViewModel: Result<ExplorationSessionModel>
ExploreViewModel-->>ExploreScreen: 항목 및 UI 상태 표시
ExploreScreen->>ExploreViewModel: 다음 세션 요청
ExploreViewModel->>ExplorationRepository: advanceToNextExplorationSession()
ExplorationRepository->>ExplorationApi: POST /api/v1/exploration/next
ExplorationApi-->>ExploreViewModel: 다음 세션 응답
ExploreViewModel-->>ExploreScreen: 항목 및 종료 상태 갱신
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/src/main/java/com/flint/presentation/explore/ExploreScreen.kt`:
- Around line 93-103: Update the pager configuration in the ExploreScreen flow
around pagerState so the additional end page is counted only when isEnd is true;
preserve the content item count otherwise, ensuring ExploreEndPage is not shown
while loading the next session or after a failed request.
In `@app/src/main/java/com/flint/presentation/explore/uistate/ExploreUiState.kt`:
- Around line 20-21: Update the canAdvance getter in ExploreUiState so it also
requires hasNext to be true, while preserving the existing isLoadingNext and
exploration-state checks.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 61b940b1-7121-4a65-82c0-c3c93d682710
📒 Files selected for processing (12)
app/src/main/java/com/flint/data/api/ExplorationApi.ktapp/src/main/java/com/flint/data/di/ServiceModule.ktapp/src/main/java/com/flint/data/dto/exploration/response/ExplorationResponseDto.ktapp/src/main/java/com/flint/domain/mapper/exploration/ExplorationMapper.ktapp/src/main/java/com/flint/domain/model/exploration/ExplorationModel.ktapp/src/main/java/com/flint/domain/repository/ExplorationRepository.ktapp/src/main/java/com/flint/presentation/explore/ExploreScreen.ktapp/src/main/java/com/flint/presentation/explore/ExploreViewModel.ktapp/src/main/java/com/flint/presentation/explore/uistate/ExploreUiState.ktapp/src/main/java/com/flint/presentation/onboarding/OnboardingDoneScreen.ktapp/src/main/java/com/flint/presentation/onboarding/OnboardingProfileScreen.ktapp/src/main/java/com/flint/presentation/onboarding/OnboardingViewModel.kt
jongwoo2003-sidewalk
left a comment
There was a problem hiding this comment.
코드 스타일이 아니라 버그 가능성과 사용자 경험 관점으로만 봤습니다. 실제로 파일을 열어 확인한 것만 적었고, 서버 동작에 달린 항목은 질문으로 남겼습니다.
🔴 탐색 API가 실패하면 아무것도 없는 빈 화면이 됩니다
ExploreScreen.kt ExploreRoute
when (uiState) {
UiState.Loading -> { FlintLoadingIndicator() }
is UiState.Success -> { ... }
else -> {} // ← UiState.Failure 가 여기로 들어옵니다
}loadSession() 실패 시 UiState.Failure 로 가는데 이 분기가 비어 있어서, 사용자에게는 탐색 탭이 그냥 까맣게 비어 보입니다. 오류 문구도 재시도 버튼도 없습니다.
게다가 loadSession() 은 init 에서만 호출돼서 화면 안에서 회복할 방법이 없습니다. 지금은 탭 이동 시 백스택이 초기화되어(popUpTo(0)) 다시 들어오면 재조회되지만, 사용자가 그걸 알기 어렵습니다. 비행기모드나 순간적인 네트워크 오류에서 바로 재현될 것 같습니다.
에러 화면 + 재시도를 넣어주시면 좋겠습니다.
🔴 항목 하나에 필드가 비면 탐색 전체가 실패합니다
ExplorationResponseDto.kt
data class Item(
@SerialName("contentId") val contentId: String,
@SerialName("title") val title: String,
@SerialName("description") val description: String,
@SerialName("imageUrl") val imageUrl: String,
@SerialName("year") val year: Int,
@SerialName("collectionId") val collectionId: String,
)전부 non-null 이고 기본값이 없어서, 30개 중 한 항목이라도 필드가 누락되거나 null 이면 MissingFieldException 으로 세션 전체 파싱이 실패합니다. 그러면 위의 빈 화면으로 이어집니다.
특히 description, imageUrl, year 가 위험해 보입니다. 개봉 연도가 없는 작품이나 설명이 아직 안 채워진 작품이 하나만 섞여도 탐색 탭 전체가 죽습니다. 예전에 contentUrl 기본값 추가(0d22600)로 같은 문제를 겪은 적이 있어서 더 걸립니다.
선택적인 필드에는 기본값(= "", = 0)이나 nullable 을 주는 게 안전할 것 같습니다.
🔴 가입 요청 중에 앱을 나갔다 오면 닉네임 화면으로 튕깁니다
OnboardingDoneScreen.kt
Lifecycle.Event.ON_RESUME -> {
if (hasStopped) {
hasStopped = false
if (!currentSignupUiState.isSuccess) {
currentNavigateUp()
}
}
}isSuccess 만 확인하고 isLoading 은 보지 않습니다. 다음 순서가 가능해 보입니다.
- 사용자가
시작하기를 누름 →signupState = Loading - 요청이 도는 동안 화면이 꺼지거나 다른 앱으로 이동 (
ON_STOP) - 돌아옴 →
isSuccess는 아직 false →navigateUp()으로 닉네임 화면으로 이동 - 그 직후 가입이 성공하지만, Done 화면이 사라져서
LaunchedEffect(isSuccess)의navigateToHome()이 실행되지 않음
여기서 그치지 않고, 4번 이후 사용자는 이미 자기 계정이 그 닉네임을 쓰고 있는 상태가 됩니다. 이 PR에서 추가된 resetNicknameCheck() 때문에 중복확인을 다시 해야 하는데, 자기가 방금 만든 계정 때문에 "이미 사용 중인 닉네임" 이 뜨면서 온보딩을 끝낼 수 없게 될 수 있습니다.
signup() 에도 중복 호출 가드가 없어서, 이 상태에서 시작하기 를 다시 누르면 가입 요청이 한 번 더 나갑니다.
최소한 if (!currentSignupUiState.isSuccess && !currentSignupUiState.isLoading) 로 막아주시고, signup() 초입에 if (_signupUiState.value.isLoading) return 을 넣는 걸 제안드립니다.
🟡 화면 잠금만으로도 Done 화면에서 되돌아갑니다
같은 DisposableEffect 입니다. ON_STOP 은 다른 앱으로 이동할 때뿐 아니라 화면이 꺼질 때도 발생합니다.
Done 화면을 보다가 잠깐 화면이 꺼지거나, 알림을 확인하고 돌아오는 것만으로도 닉네임 입력 화면으로 돌아가게 됩니다. 그리고 중복확인까지 다시 해야 합니다. QA 항목을 만족시키려는 의도는 이해했는데, 실제 사용에서는 꽤 자주 걸릴 것 같습니다.
"가입 미완료 상태 이탈"의 판정 기준을 백그라운드 체류 시간 같은 걸로 좁히거나, 되돌리는 대신 Done 화면에 그대로 두는 선택지도 검토해볼 만합니다.
🟡 서버가 모르는 state를 주면 "다 살펴봤어요" 화면이 뜹니다
ExplorationMapper 는 알 수 없는 값을 ExplorationState.UNKNOWN 으로 떨어뜨리는데, UNKNOWN 은 isEmpty 도 isEnd 도 false 입니다. 이때 items 가 비어 있으면:
itemCount = 0→pageCount = 1→ 0번 페이지에서items.getOrNull(0)이 null- 결과적으로
ExploreEndPage("지금 뜨는 추천을 모두 살펴봤어요")가 노출됩니다 LaunchedEffect의 재조회 조건에itemCount > 0이 있어서 추가 요청도 나가지 않습니다
즉 서버 스펙이 바뀌거나 오타가 있으면 사용자에게는 "콘텐츠를 다 봤다"로 보입니다. 오류 상태로 처리하는 게 맞지 않을까요?
🟡 POST /exploration/next 가 선제적으로, 그리고 반복해서 호출됩니다
LaunchedEffect(pagerState.currentPage) {
if (!isEnd && pagerState.currentPage >= itemCount - 3 && itemCount > 0) {
onLoadNextSession()
}
}두 가지가 걸립니다.
- 마지막 3장을 보기 전에 미리 호출됩니다. GET 이면 프리페치로 자연스러운데
POST /exploration/next는 이름상 서버의 세션 포인터를 넘기는 요청으로 보입니다. 사용자가 아직 27~30번째 작품을 보지 않았는데 서버 세션이 다음으로 넘어가도 괜찮은 동작인가요? - 실패하면 페이지를 넘길 때마다 다시 호출됩니다.
fetchNextSession실패 시isLoadingNext = false로만 되돌리고 state 는IN_PROGRESS로 남아서, 끝부분에서 좌우로 스와이프할 때마다 POST 가 계속 나갑니다.
canAdvance 가 UNKNOWN 도 허용하고 있어서, 서버가 예상 밖 값을 주는 동안에도 계속 호출됩니다.
서버에서 next 가 멱등한지, 아니면 호출할 때마다 세션이 소모되는지에 따라 위험도가 달라질 것 같습니다. 후자라면 사용자가 보지 못한 작품이 건너뛰어질 수 있습니다.
🟢 PR 설명에 있는데 실제로는 동작하지 않는 것 두 가지
1. 다음 세션 로딩 표시가 화면에 없습니다
ExploreUiState.isLoadingNext 는 ViewModel 에서 true/false 로 갱신되지만, ExploreScreen 으로 전달되지 않습니다. (ExploreScreen.kt 전체에서 isLoadingNext 참조 0건) 다음 세션을 불러오는 동안 사용자에게는 아무 피드백이 없습니다.
2. 연도가 화면에 표시되지 않습니다
ExplorePageItem(year: Int) 로 값은 전달되는데 함수 본문에서 year 를 쓰는 곳이 없습니다. Preview 에만 year = 2014 가 들어가 있습니다.
🟢 작은 것
Done 화면의 navigateUp() 은 "닉네임 입력 화면으로 되돌린다"는 주석과 달리 직전 화면으로 한 칸 돌아가는 동작입니다. 지금은 OnboardingProfile 만 Done 으로 이동해서 결과가 같지만, navigateToOnboardingOtt 가 정의만 되어 있고 아직 흐름에 연결되지 않은 상태입니다. 나중에 OTT 단계가 들어가면 조용히 깨지니, 목적지를 명시적으로 지정하는 편이 안전해 보입니다.
수정 의도 자체는 QA 항목을 잘 짚었다고 생각합니다. 위에서 🔴 세 개만 정리되면 좋을 것 같고, POST 관련 부분은 서버 동작 확인 후에 판단하면 될 것 같습니다.
📮 관련 이슈
Flt 29 안드 자체 qa 임차민
📌 작업 내용
state/hasNext)으로 교체, End 화면 유지 및 위로 스크롤 시 재조회 없이 이전 작품 확인 가능하도록 수정Summary by CodeRabbit
새로운 기능
버그 수정