Skip to content

[FIX] 안드자체 QA 수정사항 반영 (온보딩/탐색) - #221

Merged
kimjw2003 merged 6 commits into
developfrom
FLT-29-안드-자체-qa-임차민
Aug 13, 2026

Hidden character warning

The head ref may contain hidden characters: "FLT-29-\uc548\ub4dc-\uc790\uccb4-qa-\uc784\ucc28\ubbfc"
Merged

[FIX] 안드자체 QA 수정사항 반영 (온보딩/탐색)#221
kimjw2003 merged 6 commits into
developfrom
FLT-29-안드-자체-qa-임차민

Conversation

@ckals413

@ckals413 ckals413 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

📮 관련 이슈

Flt 29 안드 자체 qa 임차민

📌 작업 내용

  • 온보딩 닉네임 화면 재진입 시 중복확인 상태 초기화
  • 온보딩 End 화면에서 가입 미완료 상태로 백그라운드 이탈 후 복귀 시 닉네임 화면으로 이동 처리
  • 탐색(Explore) API를 서버 관리형(state/hasNext)으로 교체, End 화면 유지 및 위로 스크롤 시 재조회 없이 이전 작품 확인 가능하도록 수정

Summary by CodeRabbit

  • 새로운 기능

    • 탐색 콘텐츠를 세션 단위로 불러오고 다음 세션으로 이동할 수 있습니다.
    • 콘텐츠의 제목, 설명, 이미지, 연도 등의 정보가 표시됩니다.
    • 콘텐츠가 없거나 탐색이 종료된 상태를 안내합니다.
  • 버그 수정

    • 세션 로딩 중 진행 상태가 표시됩니다.
    • 탐색 요청 실패 시 재시도할 수 있습니다.
    • 온보딩 재진입 시 닉네임 확인 상태가 초기화됩니다.
    • 회원가입 없이 온보딩을 이탈하면 이전 화면으로 돌아갑니다.

@ckals413 ckals413 self-assigned this Aug 12, 2026
@ckals413 ckals413 added Fix 🐛 버그, UI 오류, 오타, 명세와의 불일치 등을 수정 Feat ✨ 신규 기능을 추가하거나 기존 기능의 동작, 정책을 변경 labels Aug 12, 2026
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

탐색 기능을 컬렉션 페이지 조회에서 세션 기반 조회로 전환했습니다. API, DTO, 도메인 모델, 저장소, ViewModel, Compose 화면을 갱신했습니다. 온보딩 화면 복귀와 닉네임 확인 상태 초기화도 추가했습니다.

Changes

탐색 세션 전환

Layer / File(s) Summary
탐색 계약과 도메인 변환
app/src/main/java/com/flint/data/api/ExplorationApi.kt, app/src/main/java/com/flint/data/di/ServiceModule.kt, app/src/main/java/com/flint/data/dto/exploration/..., app/src/main/java/com/flint/domain/model/exploration/..., app/src/main/java/com/flint/domain/mapper/exploration/...
탐색 세션 조회 및 다음 세션 API를 추가했습니다. 응답 DTO를 도메인 세션 모델로 변환합니다. 알 수 없는 상태는 UNKNOWN으로 매핑합니다.
탐색 세션 상태 흐름
app/src/main/java/com/flint/domain/repository/ExplorationRepository.kt, app/src/main/java/com/flint/presentation/explore/ExploreViewModel.kt, app/src/main/java/com/flint/presentation/explore/uistate/ExploreUiState.kt
컬렉션 커서 조회를 탐색 세션 조회로 교체했습니다. 세션 항목과 초기 및 다음 세션 상태를 관리합니다.
탐색 화면 세션 렌더링
app/src/main/java/com/flint/presentation/explore/ExploreScreen.kt
탐색 항목을 표시합니다. 빈 상태와 오류 상태를 분기하고 다음 세션을 요청합니다.

온보딩 상태 처리

Layer / File(s) Summary
온보딩 화면 복귀 처리
app/src/main/java/com/flint/presentation/onboarding/OnboardingDoneScreen.kt
ON_STOP 이후 ON_RESUME 시 회원가입 상태를 확인합니다. 회원가입이 완료되지 않았고 로딩 중이 아니면 이전 화면으로 이동합니다.
닉네임 확인 상태 초기화
app/src/main/java/com/flint/presentation/onboarding/OnboardingProfileScreen.kt, app/src/main/java/com/flint/presentation/onboarding/OnboardingViewModel.kt
프로필 화면 진입 시 닉네임 확인 작업과 결과를 초기화합니다. 회원가입 중복 호출을 차단합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Mergeability Score: 🟡 Moderate · up to a4569

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: 항목 및 종료 상태 갱신
Loading

Possibly related PRs

Suggested reviewers: chanmi1125, kimjw2003

Poem

당근을 문 토끼가 세션을 넘겨요
탐색 항목이 차곡차곡 쌓여요
빈 상태에는 안내를 띄우고
끝 상태에는 조용히 멈춰요
닉네임 확인도 새로 맑아져요
깡충, 변경 완료! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 온보딩과 탐색 QA 수정이라는 PR의 주요 변경 내용을 명확하게 요약합니다.
Description check ✅ Passed 핵심 작업 내용은 PR 목적과 일치하지만 스크린샷·미구현·리뷰어 안내 섹션과 이슈 형식은 템플릿과 다릅니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch FLT-29-안드-자체-qa-임차민

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.

@ckals413 ckals413 changed the title Flt 29 안드 자체 qa 임차민 [FIX] 안드자체 QA 수정사항 반영 (온보딩/탐색) Aug 12, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0a88ca6 and 2e0bad4.

📒 Files selected for processing (12)
  • app/src/main/java/com/flint/data/api/ExplorationApi.kt
  • app/src/main/java/com/flint/data/di/ServiceModule.kt
  • app/src/main/java/com/flint/data/dto/exploration/response/ExplorationResponseDto.kt
  • app/src/main/java/com/flint/domain/mapper/exploration/ExplorationMapper.kt
  • app/src/main/java/com/flint/domain/model/exploration/ExplorationModel.kt
  • app/src/main/java/com/flint/domain/repository/ExplorationRepository.kt
  • app/src/main/java/com/flint/presentation/explore/ExploreScreen.kt
  • app/src/main/java/com/flint/presentation/explore/ExploreViewModel.kt
  • app/src/main/java/com/flint/presentation/explore/uistate/ExploreUiState.kt
  • app/src/main/java/com/flint/presentation/onboarding/OnboardingDoneScreen.kt
  • app/src/main/java/com/flint/presentation/onboarding/OnboardingProfileScreen.kt
  • app/src/main/java/com/flint/presentation/onboarding/OnboardingViewModel.kt

Comment thread app/src/main/java/com/flint/presentation/explore/ExploreScreen.kt
Comment thread app/src/main/java/com/flint/presentation/explore/uistate/ExploreUiState.kt Outdated

@jongwoo2003-sidewalk jongwoo2003-sidewalk left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

코드 스타일이 아니라 버그 가능성과 사용자 경험 관점으로만 봤습니다. 실제로 파일을 열어 확인한 것만 적었고, 서버 동작에 달린 항목은 질문으로 남겼습니다.


🔴 탐색 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 은 보지 않습니다. 다음 순서가 가능해 보입니다.

  1. 사용자가 시작하기 를 누름 → signupState = Loading
  2. 요청이 도는 동안 화면이 꺼지거나 다른 앱으로 이동 (ON_STOP)
  3. 돌아옴 → isSuccess 는 아직 false → navigateUp() 으로 닉네임 화면으로 이동
  4. 그 직후 가입이 성공하지만, 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 으로 떨어뜨리는데, UNKNOWNisEmptyisEnd 도 false 입니다. 이때 items 가 비어 있으면:

  • itemCount = 0pageCount = 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()
    }
}

두 가지가 걸립니다.

  1. 마지막 3장을 보기 전에 미리 호출됩니다. GET 이면 프리페치로 자연스러운데 POST /exploration/next 는 이름상 서버의 세션 포인터를 넘기는 요청으로 보입니다. 사용자가 아직 27~30번째 작품을 보지 않았는데 서버 세션이 다음으로 넘어가도 괜찮은 동작인가요?
  2. 실패하면 페이지를 넘길 때마다 다시 호출됩니다. fetchNextSession 실패 시 isLoadingNext = false 로만 되돌리고 state 는 IN_PROGRESS 로 남아서, 끝부분에서 좌우로 스와이프할 때마다 POST 가 계속 나갑니다.

canAdvanceUNKNOWN 도 허용하고 있어서, 서버가 예상 밖 값을 주는 동안에도 계속 호출됩니다.

서버에서 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 관련 부분은 서버 동작 확인 후에 판단하면 될 것 같습니다.

coderabbitai[bot]

This comment was marked as off-topic.

@imflint imflint deleted a comment from coderabbitai Bot Aug 13, 2026
@kimjw2003
kimjw2003 merged commit 28df6e1 into develop Aug 13, 2026
2 checks passed
@kimjw2003
kimjw2003 deleted the FLT-29-안드-자체-qa-임차민 branch August 13, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feat ✨ 신규 기능을 추가하거나 기존 기능의 동작, 정책을 변경 Fix 🐛 버그, UI 오류, 오타, 명세와의 불일치 등을 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants