Skip to content

[Fix] 1차 QA 수정사항 반영 (로그인/회원가입 · 홈 · 설정) - #218

Merged
kimjw2003 merged 6 commits into
developfrom
FLT-26-1차-qa-수정
Aug 9, 2026

Hidden character warning

The head ref may contain hidden characters: "FLT-26-1\ucc28-qa-\uc218\uc815"
Merged

[Fix] 1차 QA 수정사항 반영 (로그인/회원가입 · 홈 · 설정)#218
kimjw2003 merged 6 commits into
developfrom
FLT-26-1차-qa-수정

Conversation

@kimjw2003

@kimjw2003 kimjw2003 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📮 관련 이슈

  • closed #이슈번호

📌 작업 내용

1차 QA 시트의 로그인/회원가입 · 홈 · 설정 탭 Android fail 항목 대응입니다.

1. 닉네임 유효성 검사에 숫자 허용 (TC 1-34)

NICKNAME_REGEX0-9가 빠져 있어 숫자가 포함된 닉네임이 거부됐습니다. 서버는 원래 숫자를 허용하고 있었고 클라이언트만 막고 있었습니다.

온보딩(OnboardingUiState)과 프로필 수정(EditProfileUiState)에 동일한 정규식이 복사돼 있어 양쪽 모두 수정했습니다. 한쪽만 고치면 "가입은 flint2로 되는데 설정에서 수정은 거부"되는 불일치가 생깁니다.

2. 홈 최근 저장한 콘텐츠 10개 제한 (TC 3-23, 3-24)

저장 콘텐츠가 10개를 넘어도 전부 노출되고 있었습니다.

getUserBookmarkedContents()는 프로필·저장한 콘텐츠 화면에서도 쓰이고 SavedContentsSectionProfileScreen과 공유하는 컴포넌트라, Repository나 컴포넌트가 아닌 HomeViewModel에서 잘랐습니다. totalCount는 프로필 쪽에서 사용하므로 전체 개수를 유지합니다.

3. 홈 OTT 바텀시트 노출 (TC 3-33, 3-34)

홈에서 저장 콘텐츠를 눌러도 바텀시트가 뜨지 않았습니다.

원인은 서버가 GET /api/v1/contents/ott/{contentId}에 대해 {"otts":[]} 빈 배열만 반환하는 것이었습니다. 빈 목록이면 isNotEmpty() 가드에 걸려 무반응이 됩니다.

반면 북마크 목록 응답은 같은 콘텐츠에 getOttSimpleList를 정상적으로 내려주고 있고, 프로필·저장한 콘텐츠 화면은 이미 이 값을 사용합니다. 홈만 별도 API를 호출해서 홈에서만 실패한 구조였습니다. 홈도 동일한 방식으로 맞췄습니다.

바텀시트는 OttType의 로컬 iconRes/ottName으로 렌더링하므로 서버의 logoUrl·contentUrl은 애초에 필요하지 않습니다.

4. 설정 계정 이메일 노출 (TC 12-6, 12-7)

스웨거 MyProfileResemail이 문서화돼 있으나 UserProfileResponseDto에 필드가 없어 값이 와도 받을 수 없는 상태였습니다. DTO → 모델 → 매퍼 → UiState → UI까지 연결했습니다.

⚠️ 다만 실기기 확인 결과 서버가 실제로는 email을 내려주지 않습니다. 아래 "To. 리뷰어" 참고.

5. OTT 응답 DTO 방어 + 유닛 테스트

OttItemResponseDto.contentUrl이 기본값 없는 필수 필드인데 서버 스키마 GetOttResponse에는 존재하지 않습니다. 지금은 서버가 빈 배열을 주고 있어 드러나지 않지만, 실제 OTT 데이터가 채워지는 순간 MissingFieldException으로 깨집니다. 기본값을 지정해 막았습니다.

함께 유닛 테스트 16개를 추가했습니다.

  • OttListResponseDtoTestcontentUrl 유무 양쪽 역직렬화 (4개)
  • NicknameValidationTest — 닉네임 숫자 허용/거부 규칙, 온보딩·프로필 수정 판정 일치 검증 (12개)

📸 스크린샷

OTT 바텀시트 (수정 후) 설정 계정 행
저장 콘텐츠 탭 시 왓챠피디아/넷플릭스 정상 노출 이메일 있으면 노출, 없으면 로고만

✅ 검증

Pixel_9a 에뮬레이터에서 신규 가입 후 실제 서버로 확인했습니다.

TC 결과
1-34 닉네임 숫자 ✅ 클라 통과 + 서버 {"available":true}
3-23 / 3-24 홈 10개 제한 ✅ 북마크 12개 → 홈 10개 노출, 가장 오래된 2개 제거 확인
3-33 / 3-34 OTT 바텀시트 ✅ 정상 노출, /contents/ott/ 호출 0건
12-6 / 12-7 계정 이메일 🔶 클라 완료 · 서버 미제공

정렬 방향 확인: 북마크를 순서대로 추가해 API가 최신순으로 반환하는 것을 확인했습니다. take(10)이 맞고 takeLast가 아닙니다.

유닛 테스트 16개 전부 통과 (./gradlew testDebugUnitTest).

😅 미구현

  • TC 12-6, 12-7 — 서버가 email을 내려주지 않아 클라이언트만으로 닫을 수 없음
  • OTT 데이터가 없는 콘텐츠 탭 시 무반응 (403·네트워크 실패도 동일). 전체오류 모달(TC 1-45, 3-51, 12-68)과 묶어서 별도 처리 필요

🫛 To. 리뷰어

백엔드 확인이 필요한 사항 2건입니다.

1. GET /api/v1/users/meemail을 반환하지 않습니다

스웨거 MyProfileRes에는 "email": "이메일 (미보유 시 null)"로 문서화돼 있으나 실제 응답에는 키 자체가 없습니다.

{"status":200,"data":{"id":"873202440779292987","nickname":"김종우",
 "isFliner":false,"keywordRecalculatable":false,"termsAgreementStatus":{...}}}

카카오 로그인 시 이메일 동의항목을 수집하는지 확인이 필요합니다. 클라이언트는 값이 오면 노출, 없으면 로고만 표시하는 구조로 잡아뒀습니다.

2. GET /api/v1/contents/ott/{contentId}가 빈 배열을 반환합니다

같은 콘텐츠에 대해 북마크 API는 OTT를 정상적으로 내려주는데, 전용 OTT API는 비어 있습니다.

GET /api/v1/contents/ott/4  →  {"otts":[]}
북마크 응답의 id=4          →  getOttSimpleList:[{"ottName":"Netflix","logoUrl":"adsf"}]

이번 PR은 북마크 응답 쪽 데이터를 쓰도록 우회했지만 서버 데이터 불일치는 그대로 남아 있습니다. 덧붙여 logoUrl 값이 전부 "adsf", "asgfd", "adfds" 같은 더미값입니다.


참고로 봐주실 부분

  • HomeViewModel에서 ContentRepository 의존성을 제거했습니다 (OTT API를 더 이상 호출하지 않음)
  • ProfileViewModel.getOttListPerContent(142행)는 호출처가 없는 데드코드입니다. 이번 PR 범위에서 벗어나 두었는데 정리하는 게 좋을 것 같습니다
  • SettingMenuItemtrailingContentRowScope로 바꿨습니다. 라벨이 weight(1f)라 trailing이 먼저 측정되는데, 긴 이메일이 "계정" 라벨을 밀어내는 걸 막기 위함입니다

🤖 Generated with Claude Code

Summary by CodeRabbit

  • 새로운 기능

    • 설정 화면의 계정 메뉴에서 이메일 주소를 확인할 수 있습니다.
    • 저장된 콘텐츠의 OTT 목록을 더 빠르게 확인할 수 있습니다.
  • 개선

    • 닉네임에 숫자를 포함할 수 있도록 허용 범위를 확장했습니다.
    • OTT 정보가 일부 누락된 응답도 안정적으로 처리합니다.
  • 버그 수정

    • 저장된 콘텐츠에서 OTT 목록을 불러오는 동작을 개선했습니다.

kimjw2003 and others added 5 commits August 6, 2026 22:34
QA TC 1-34 - 한글/영문/숫자 혼합 입력 시 에러가 발생하던 문제 수정

NICKNAME_REGEX에 0-9가 빠져 있어 숫자가 포함된 닉네임이 거부됐습니다.
온보딩과 프로필 수정 화면에 동일한 정규식이 복사돼 있어 함께 수정했습니다.
(온보딩만 고치면 가입은 되는데 수정은 거부되는 불일치가 생깁니다)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
QA TC 3-23, 3-24 - 저장한 콘텐츠가 10개를 넘어도 계속 노출되던 문제 수정

getUserBookmarkedContents()는 프로필/저장한 콘텐츠 화면에서도 사용하므로
Repository가 아닌 HomeViewModel에서 잘랐습니다.
totalCount는 프로필 쪽에서 쓰이므로 전체 개수를 유지합니다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
QA TC 12-6, 12-7 - 계정 정보 영역에 이메일이 표시되지 않던 문제 대응

스웨거 MyProfileRes(GET /api/v1/users/me)에 email이 문서화돼 있으나
UserProfileResponseDto에 필드가 없어 값이 와도 받을 수 없는 상태였습니다.
DTO/모델/매퍼/UiState까지 email을 연결하고 UI에 노출합니다.

단, 실기기 확인 결과 서버가 실제로는 email을 내려주지 않습니다
(null인 필드를 응답에서 생략하는 구조라 키 자체가 없음).
따라서 이 커밋만으로 TC 12-6/12-7이 닫히지는 않으며,
카카오 이메일 동의항목 수집 여부에 대한 백엔드 확인이 필요합니다.

이메일이 있으면 노출하고 없으면 로고만 표시하는 구조로 정리했습니다.

타 유저 응답(UserProfileRes)에는 email이 없고 DTO를 공유하므로
keywordRecalculatable과 동일하게 nullable + 기본값으로 처리했습니다.

긴 이메일이 "계정" 라벨을 밀어내지 않도록 trailingContent를
RowScope로 변경하고 weight(1f, fill = false)를 적용했습니다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
서버 스키마 GetOttResponse는 { ottId, name, logoUrl } 세 필드뿐이라
기본값 없는 contentUrl이 있으면 MissingFieldException으로 역직렬화가 실패합니다.
현재는 서버가 빈 배열을 주고 있어 드러나지 않지만,
실제 OTT 데이터가 채워지는 순간 홈 바텀시트가 깨집니다.

ignoreUnknownKeys/coerceInputValues로는 막을 수 없어(누락 필드는 대상 아님)
기본값을 지정했습니다.

함께 추가한 유닛 테스트:
- OttListResponseDtoTest: contentUrl 유무 양쪽 역직렬화 (4개)
- NicknameValidationTest: 닉네임 숫자 허용 및 거부 규칙 (12개)
  온보딩과 프로필 수정의 판정이 일치하는지도 함께 검증

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
QA TC 3-33, 3-34 - 홈에서 저장 콘텐츠를 눌러도 바텀시트가 뜨지 않던 문제

원인은 서버가 GET /api/v1/contents/ott/{contentId} 에 대해
{"otts":[]} 빈 배열만 반환하는 것이었습니다.
빈 목록이면 HomeScreen 의 isNotEmpty() 가드에 걸려 아무 반응이 없었습니다.

반면 북마크 목록 응답은 같은 콘텐츠에 대해 getOttSimpleList 를 정상적으로
내려주고 있고, 프로필(ProfileScreen)과 저장한 콘텐츠(SavedContentScreen)는
이미 이 값을 사용합니다. 홈만 별도 API 를 호출하고 있어 홈에서만 실패했습니다.

홈도 동일하게 이미 로드된 북마크 목록의 getOttSimpleList 를 사용하도록 변경했습니다.
바텀시트는 OttType 의 로컬 iconRes/ottName 으로 렌더링하므로
서버의 logoUrl(현재 "adsf" 등 더미값)과 contentUrl 은 필요하지 않습니다.

부수 효과:
- 콘텐츠 탭마다 발생하던 네트워크 호출이 사라짐
- OttShortCutListItem 의 OttType.valueOf() 는 runCatching 없이 호출되는데,
  로컬 값은 이미 OttType 으로 검증된 값이라 IllegalArgumentException 위험이 없어짐
- 미사용이 된 ContentRepository 의존성 제거

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 74e73e76-84b4-4a97-9243-2bf573d337a1

📥 Commits

Reviewing files that changed from the base of the PR and between 71c29be and e0bf207.

📒 Files selected for processing (3)
  • app/src/main/java/com/flint/presentation/home/HomeViewModel.kt
  • app/src/main/java/com/flint/presentation/setting/SettingScreen.kt
  • app/src/test/java/com/flint/presentation/onboarding/NicknameValidationTest.kt
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/src/test/java/com/flint/presentation/onboarding/NicknameValidationTest.kt
  • app/src/main/java/com/flint/presentation/home/HomeViewModel.kt
  • app/src/main/java/com/flint/presentation/setting/SettingScreen.kt

📝 Walkthrough

Walkthrough

OTT 응답 기본값과 저장 콘텐츠의 OTT 목록 표시 흐름을 변경했습니다. 사용자 프로필 이메일을 설정 화면에 연결했습니다. 온보딩과 프로필 수정 화면에서 숫자를 포함한 닉네임을 허용하고 관련 테스트를 추가했습니다.

Changes

OTT 목록 처리

Layer / File(s) Summary
OTT 응답 기본값 처리
app/src/main/java/com/flint/data/dto/ott/response/OttListResponseDto.kt, app/src/test/java/com/flint/data/dto/ott/OttListResponseDtoTest.kt
contentUrl이 없는 응답에 빈 문자열을 적용합니다. 제공된 값과 빈 목록의 역직렬화를 테스트합니다.
저장 콘텐츠 OTT 목록 표시
app/src/main/java/com/flint/presentation/home/HomeViewModel.kt, app/src/main/java/com/flint/presentation/home/HomeScreen.kt
홈 화면이 저장된 콘텐츠의 ottSimpleList를 사용해 ShowOttListBottomSheet side effect를 발생시킵니다. 북마크 상태는 최대 10개로 제한합니다.

프로필 이메일 연동

Layer / File(s) Summary
프로필 이메일 데이터 계약
app/src/main/java/com/flint/data/dto/user/response/UserProfileResponseDto.kt, app/src/main/java/com/flint/domain/model/user/UserProfileResponseModel.kt, app/src/main/java/com/flint/domain/mapper/user/ProfileMapper.kt
프로필 DTO와 모델에 nullable email을 추가하고 매퍼에서 전달합니다.
설정 화면 이메일 표시
app/src/main/java/com/flint/presentation/setting/SettingUiState.kt, app/src/main/java/com/flint/presentation/setting/SettingViewModel.kt, app/src/main/java/com/flint/presentation/setting/SettingScreen.kt
프로필 조회 결과의 이메일을 설정 상태에 저장합니다. 계정 메뉴에 한 줄 말줄임으로 표시합니다.

닉네임 검증

Layer / File(s) Summary
숫자 포함 닉네임 검증
app/src/main/java/com/flint/presentation/onboarding/OnboardingUiState.kt, app/src/main/java/com/flint/presentation/setting/editprofile/EditProfileUiState.kt, app/src/test/java/com/flint/presentation/onboarding/NicknameValidationTest.kt
한글·영문·숫자 닉네임을 허용하도록 정규식을 변경합니다. 허용·거부 입력과 자음·모음 검출 규칙을 검증합니다.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant HomeScreen
  participant HomeViewModel
  participant ContentModel
  participant ShowOttListBottomSheet
  HomeScreen->>HomeViewModel: showOttList(contentId)
  HomeViewModel->>ContentModel: 저장된 콘텐츠에서 contentId 검색
  ContentModel-->>HomeViewModel: ottSimpleList 반환
  HomeViewModel->>ShowOttListBottomSheet: OTT 목록 표시 이벤트 전달
Loading

Possibly related PRs

Suggested labels: 🧩 Component

Suggested reviewers: chanmi1125, giovannijunseokim

Poem

토끼가 OTT 목록을 열고
이메일을 설정에 담아요.
숫자 닉네임은 통과하고
빈 URL은 빈 문자열이 돼요.
테스트가 깡충, 변경을 확인해요.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% 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 제목은 1차 QA 수정사항과 대상 영역인 로그인·회원가입, 홈, 설정을 명확하게 요약합니다.
Description check ✅ Passed 작업 내용, 검증 결과, 미구현 사항, 리뷰어 참고 사항을 포함해 대부분의 템플릿 요구사항을 충족합니다.
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-26-1차-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.

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

🤖 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/home/HomeViewModel.kt`:
- Around line 80-82: Update getUserBookmarkedContents() and the
bookmarked-content flow so contents are ordered by save date descending before
take(MAX_SAVED_CONTENT_COUNT), or add the save-date field to the response DTO to
enable that ordering. Ensure the resulting home list always contains the latest
saved 10 items, and keep the immutable-list conversion after limiting.

In `@app/src/main/java/com/flint/presentation/setting/SettingScreen.kt`:
- Around line 117-130: 중첩된 Row가 SettingMenuItem의 가용 폭을 사용하도록 수정하고, 그 안의 email
Text가 남은 공간만 차지하게 하여 TextOverflow.Ellipsis가 동작하도록 하세요. SettingMenuItem의 제한된 폭과
아이콘 영역을 침범하지 않도록 Row의 weight 또는 동등한 폭 제약을 적용하고, Text의 기존 말줄임 설정은 유지하세요.

In
`@app/src/test/java/com/flint/presentation/onboarding/NicknameValidationTest.kt`:
- Around line 49-51: Update the test input in `한글 영문 숫자를 모두 섞은 닉네임을 허용한다` to a
2–8-character nickname that mixes Korean, English, and digits, so it satisfies
both UI states’ `MAX_LENGTH` constraint while preserving the intended validation
coverage.
🪄 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: 6d2a7556-7db1-4401-afa4-33e160bb4db8

📥 Commits

Reviewing files that changed from the base of the PR and between 11c1e1a and 71c29be.

📒 Files selected for processing (13)
  • app/src/main/java/com/flint/data/dto/ott/response/OttListResponseDto.kt
  • app/src/main/java/com/flint/data/dto/user/response/UserProfileResponseDto.kt
  • app/src/main/java/com/flint/domain/mapper/user/ProfileMapper.kt
  • app/src/main/java/com/flint/domain/model/user/UserProfileResponseModel.kt
  • app/src/main/java/com/flint/presentation/home/HomeScreen.kt
  • app/src/main/java/com/flint/presentation/home/HomeViewModel.kt
  • app/src/main/java/com/flint/presentation/onboarding/OnboardingUiState.kt
  • app/src/main/java/com/flint/presentation/setting/SettingScreen.kt
  • app/src/main/java/com/flint/presentation/setting/SettingUiState.kt
  • app/src/main/java/com/flint/presentation/setting/SettingViewModel.kt
  • app/src/main/java/com/flint/presentation/setting/editprofile/EditProfileUiState.kt
  • app/src/test/java/com/flint/data/dto/ott/OttListResponseDtoTest.kt
  • app/src/test/java/com/flint/presentation/onboarding/NicknameValidationTest.kt

Comment thread app/src/main/java/com/flint/presentation/home/HomeViewModel.kt
Comment thread app/src/main/java/com/flint/presentation/setting/SettingScreen.kt

@ckals413 ckals413 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.

굿굿 pr이랑 이미 리뷰가 달려서 달게 없네요. 리뷰 확인만 부탁드려요!
리뷰어 섹션에 남겨주신 이메일/OTT 서버 불일치 2건은 이슈로 분리해두시면 좋을 것 같습니다!

CodeRabbit 리뷰 3건 대응

1) SettingMenuItem - 긴 trailingContent가 라벨을 밀어내던 문제 (실제 결함)
   trailingContent를 RowScope로 바꾸고 이메일에 weight를 준 것만으로는
   효과가 없었습니다. 중첩 Row 자체는 가중치가 없어 상위 Row에서 전체 폭으로
   먼저 측정되고, weight(1f)인 라벨이 남은 0에 가까운 폭을 받습니다.

   라벨에서 weight를 빼 자연 폭으로 먼저 측정되게 하고,
   남는 폭은 Spacer(weight)가 흡수하도록 바꿨습니다.
   trailingContent는 계속 우측에 붙고, 긴 이메일은 말줄임됩니다.
   라벨과 붙지 않도록 최소 간격 16dp도 확보했습니다.

   긴 이메일을 임시 주입해 에뮬레이터에서 확인했습니다.

2) NicknameValidationTest - 테스트 입력값이 MAX_LENGTH 초과
   "플린트flint7"은 9자로 MAX_LENGTH(8)를 넘어 실제 입력 흐름에서
   도달할 수 없는 값이었습니다. "플린트fl7"(6자)로 교체했습니다.

3) 홈 저장 콘텐츠 정렬 - 코드 변경 없이 계약만 명시
   북마크를 순서대로 추가해 API가 최근 저장순으로 반환하는 것을
   실기기에서 확인했으므로 take(10)은 올바릅니다.
   다만 응답에 저장 시각 필드가 없어 클라이언트 재정렬이 불가능한 점과
   서버 정렬에 의존한다는 점을 주석으로 남겼습니다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kimjw2003
kimjw2003 merged commit 47fc9bf into develop Aug 9, 2026
2 checks passed
@kimjw2003
kimjw2003 deleted the FLT-26-1차-qa-수정 branch August 9, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants