Skip to content

[Feat] 회원가입 api 수정#206

Merged
ckals413 merged 6 commits into
developfrom
FLT-16-회원가입-api-수정
May 14, 2026

Hidden character warning

The head ref may contain hidden characters: "FLT-16-\ud68c\uc6d0\uac00\uc785-api-\uc218\uc815"
Merged

[Feat] 회원가입 api 수정#206
ckals413 merged 6 commits into
developfrom
FLT-16-회원가입-api-수정

Conversation

@ckals413
Copy link
Copy Markdown
Contributor

@ckals413 ckals413 commented May 13, 2026

📮 관련 이슈

Flt 16 회원가입 api 수정

📌 작업 내용

  • 약관동의 api연결
  • 회원가입 api 수정(약관동의 id)
  • 온보딩 api 수정(장르 칩)

📸 스크린샷

온보딩 콘텐츠 선택 약관동의
image image

😅 미구현

  • 서버명세엔 장르칩이 단일로 바껴서, 맞게 수정했는데, 다시 다중으로 명세 변경 될 예정이라 그에 맞출 예정

🫛 To. 리뷰어

온보딩에서 장르 칩을 클릭해 정보를 가져오기 전에 다른 장르칩을 클릭하면 이전 요청이 취소되면서 OkHttp가 던지는 IOException을 NetworkErrorInterceptor가 실제 네트워크 오류로 잘못인식해
"문제가 발생했어요" 모달이 노출되는 문제가 있어서
chain.call().isCanceled() 체크를 추가해 의도적 취소는 에러 emit 없이 넘기도록 수정했습니당

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 검색 기능에 장르 필터 옵션 추가
    • 회원가입 시 약관 동의 프로세스 추가
    • 온보딩 약관 동의 화면 개선 및 동적 약관 로드 기능 구현
  • Improvements

    • 장르 선택을 다중 선택에서 단일 선택으로 변경
    • 검색 결과 페이지네이션 기본값 업데이트

Review Change Stack

@ckals413 ckals413 self-assigned this May 13, 2026
@ckals413 ckals413 added 🔖 API feat - API 연동 Feat ✨ 신규 기능을 추가하거나 기존 기능의 동작, 정책을 변경 labels May 13, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

📝 Walkthrough

개요

PR은 온보딩 흐름을 백엔드 약관 동적 로드, 검색 API 장르 필터링 추가, 가입 요청에 동의한 약관 ID 포함으로 확장합니다. 약관 API, 응답 DTO, 도메인 계층을 새로 추가하고 검색 API 응답 구조를 변경한 후 온보딩 화면을 리팩토링합니다.

변경 사항

온보딩 약관 동의 및 검색 흐름 통합

계층 / 파일 요약
약관 API 및 도메인 계층
app/src/main/java/com/flint/data/api/TermsApi.kt, app/src/main/java/com/flint/data/dto/terms/response/*, app/src/main/java/com/flint/domain/model/terms/TermModel.kt, app/src/main/java/com/flint/domain/mapper/terms/TermsMapper.kt, app/src/main/java/com/flint/domain/repository/TermsRepository.kt, app/src/main/java/com/flint/data/di/ServiceModule.kt
TermsApi Retrofit 인터페이스와 TermResponseDto, TermsListResponseDto 응답 DTO를 정의하고, TermModel 도메인 모델과 매퍼 확장 함수를 추가한 후, 약관을 로드하는 TermsRepository를 구현하며 Hilt에서 TermsApi를 제공하도록 설정합니다.
검색 API 장르 필터 및 응답 구조 업데이트
app/src/main/java/com/flint/data/api/SearchApi.kt, app/src/main/java/com/flint/data/dto/search/SearchContentsResponseDto.kt, app/src/main/java/com/flint/domain/mapper/search/SearchContentMapper.kt, app/src/main/java/com/flint/domain/repository/SearchRepository.kt
SearchApi.getSearchContentList에 선택적 genre 파라미터와 기본값이 지정된 cursor, size 페이지네이션 파라미터를 추가하고, 엔드포인트를 /api/v1/contents/search로 변경하며, SearchContentsResponseDto의 응답 구조를 중첩된 data 필드와 선택적 meta 메타데이터로 변경합니다.
가입 요청에 약관 동의 통합
app/src/main/java/com/flint/domain/model/auth/SignupModel.kt, app/src/main/java/com/flint/data/dto/auth/request/SignupRequestDto.kt, app/src/main/java/com/flint/domain/mapper/auth/SignupMapper.kt
SignupRequestModelSignupRequestDtosubscribedOttIds 필드를 agreedTermsIds로 교체하고, 매퍼를 업데이트하여 가입 요청에 동의한 약관 ID를 포함합니다.
온보딩 UI 상태 확장
app/src/main/java/com/flint/presentation/onboarding/OnboardingUiState.kt
약관 로드 상태와 동의한 약관 ID를 관리하기 위해 새로운 OnboardingTermsUiState를 추가하고, OnboardingContentUiState를 업데이트하여 다중 선택 selectedGenres 대신 단일 selectedGenre: String?을 사용하며, 한글 표시명을 API 열거형 값으로 매핑하는 GENRES 맵으로 변경합니다.
온보딩 ViewModel 약관 및 장르 로직
app/src/main/java/com/flint/presentation/onboarding/OnboardingViewModel.kt
TermsRepository를 주입하고 termsUiState StateFlow를 추가하며, loadTerms() 메서드로 약관을 비동기로 로드하고 agreeToTerms(termIds)로 동의 ID를 저장합니다. 또한 selectGenre(genre)를 업데이트하여 단일 선택을 토글하고 즉시 검색을 재실행하며, 내부 getSearchContentList() 헬퍼가 UI 장르를 API 장르 값으로 변환하여 저장소를 호출합니다. 가입 요청은 termsUiStateagreedTermsIds를 포함하도록 확장됩니다.
온보딩 콘텐츠 화면 장르 칩 업데이트
app/src/main/java/com/flint/presentation/onboarding/OnboardingContentScreen.kt
장르 칩 렌더링을 GENRES.keys.toList()에서 반복하도록 변경하고, selectedGenres 멤버십 확인 대신 단일 contentUiState.selectedGenre와 비교하여 선택 상태를 결정하며, 인터랙티브 미리보기의 칩 클릭 핸들러를 단일 값을 토글하는 로직으로 업데이트합니다.
온보딩 약관 화면 리팩토링
app/src/main/java/com/flint/presentation/onboarding/OnboardingTermsScreen.kt, app/src/main/java/com/flint/presentation/onboarding/navigation/OnboardingNavigation.kt
OnboardingTermsRouteOnboardingTermsScreen을 동적 약관 로드로 리팩토링하여 공유된 OnboardingViewModel을 주입하고, LaunchedEffect에서 viewModel.loadTerms()를 실행하며, termsUiState 기반 조건부 렌더링(로딩, 오류, 성공)을 구현합니다. TermRowTermItem에서 TermModel로 변경하고 필수/선택 접두사를 추가하며, "동의하기" 버튼이 모든 필수 약관 체크 시에만 활성화되도록 하고 체크된 약관의 ID 목록을 onAgreeClick 콜백에 전달합니다. 네비게이션 그래프에서 OnboardingTermsRoute에 공유 ViewModel을 전달하도록 업데이트합니다.

예상 코드 검토 수고도

🎯 4 (Complex) | ⏱️ ~60 분

관련 PR

  • imflint/Flint-Android#205: 온보딩 "약관" 흐름 연결 시 공유 OnboardingViewModelOnboardingTermsRoute에 전달합니다.
  • imflint/Flint-Android#201: 온보딩 장르 선택 흐름을 다중 선택에서 단일 selectedGenre로 리팩토링하고 백엔드 genre 검색 파라미터와 연결합니다.
  • imflint/Flint-Android#155: SearchApi.getSearchContentList 엔드포인트/계약 및 관련 온보딩 콘텐츠 UI/ViewModel 연결을 수정합니다.

제안 검토자

  • kimjw2003
  • chanmi1125

🐰 약관 동의로 온보딩을 단단히,
장르 선택으로 콘텐츠 검색을 매끄럽게,
백엔드 데이터는 이제 동적이에요!
필수 체크박스 모두 확인해야만,
마침내 회원가입 버튼이 빛나요~ ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% 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 제목이 PR의 주요 변경 사항을 반영하고 있으나, 약관 동의 API 연결, 온보딩 API 수정 등 여러 주요 변경 사항을 포괄적으로 설명하고 있어 다소 광범위합니다.
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.
Description check ✅ Passed PR 설명이 필수 섹션을 대부분 포함하고 있으나 관련 이슈 번호 형식이 불완전하고 일부 섹션이 간략함.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch FLT-16-회원가입-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
Contributor

@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: 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/domain/mapper/terms/TermsMapper.kt`:
- Around line 6-15: TermResponseDto.toModel에서 id.toLong()으로 강제 변환하면 숫자가 아닌 id(예:
UUID, 공백 등)에서 NumberFormatException이 발생하므로 TermResponseDto.toModel의 id 매핑을 안전하게
바꾸세요: TermResponseDto.toModel 함수의 id.toLong() 호출을 제거하고, 해결책으로는 TermModel의 id 타입을
String으로 일치시키거나 id.toLongOrNull()을 사용해 null/비정상 값에 대한 디폴트(예: null 허용, 0L 대체, 또는
명확한 에러 처리 및 로깅)로 방어 로직을 추가하여 런타임 예외를 막으세요.

In
`@app/src/main/java/com/flint/presentation/onboarding/OnboardingTermsScreen.kt`:
- Around line 180-182: The "자세히 보기" click handler is a no-op (onDetailClick = {
/* TODO */ }) so the CTA appears clickable but does nothing; update the
OnboardingTermsScreen call/site to either pass null for onDetailClick or an
explicit enabled=false flag and adjust the Terms item composable (the component
that renders the CTA) to hide or render the CTA as disabled when onDetailClick
is null/disabled. Concretely: change the caller to onDetailClick = null (or
onDetailEnabled = false), and modify the Terms CTA rendering logic to check for
a nullable lambda or enabled boolean and avoid showing a clickable link when not
provided.

In `@app/src/main/java/com/flint/presentation/onboarding/OnboardingViewModel.kt`:
- Around line 148-151: The search can suffer from race conditions because each
genre/keyword change calls getSearchContentList without cancelling prior
requests; fix by making searches cancellable (e.g., track a Job or use a Flow
with flatMapLatest) and cancel the previous search before starting a new one:
update the ViewModel to hold a nullable Job (or a MutableSharedFlow of
query+genre) and in the handler for _contentUiState changes cancel(searchJob) or
use flatMapLatest to ensure only the latest invocation of getSearchContentList
produces results; keep references to getSearchContentList, _contentUiState and
any coroutine scope (e.g., viewModelScope) to implement the
cancellation/flatMapLatest approach and apply the same change to the other
occurrence covering the same logic.
🪄 Autofix (Beta)

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

Run ID: 25e73185-f6f6-480a-bbcd-ada8ba75182f

📥 Commits

Reviewing files that changed from the base of the PR and between 9620fb3 and 9c0952f.

📒 Files selected for processing (19)
  • app/src/main/java/com/flint/data/api/SearchApi.kt
  • app/src/main/java/com/flint/data/api/TermsApi.kt
  • app/src/main/java/com/flint/data/di/ServiceModule.kt
  • app/src/main/java/com/flint/data/dto/auth/request/SignupRequestDto.kt
  • app/src/main/java/com/flint/data/dto/search/SearchContentsResponseDto.kt
  • app/src/main/java/com/flint/data/dto/terms/response/TermResponseDto.kt
  • app/src/main/java/com/flint/data/dto/terms/response/TermsListResponseDto.kt
  • app/src/main/java/com/flint/domain/mapper/auth/SignupMapper.kt
  • app/src/main/java/com/flint/domain/mapper/search/SearchContentMapper.kt
  • app/src/main/java/com/flint/domain/mapper/terms/TermsMapper.kt
  • app/src/main/java/com/flint/domain/model/auth/SignupModel.kt
  • app/src/main/java/com/flint/domain/model/terms/TermModel.kt
  • app/src/main/java/com/flint/domain/repository/SearchRepository.kt
  • app/src/main/java/com/flint/domain/repository/TermsRepository.kt
  • app/src/main/java/com/flint/presentation/onboarding/OnboardingContentScreen.kt
  • app/src/main/java/com/flint/presentation/onboarding/OnboardingTermsScreen.kt
  • app/src/main/java/com/flint/presentation/onboarding/OnboardingUiState.kt
  • app/src/main/java/com/flint/presentation/onboarding/OnboardingViewModel.kt
  • app/src/main/java/com/flint/presentation/onboarding/navigation/OnboardingNavigation.kt

Comment thread app/src/main/java/com/flint/domain/mapper/terms/TermsMapper.kt
Comment on lines +180 to +182
onDetailClick = {
// TODO: 노션 약관 링크 확정 후 내부 웹뷰로 열기
},
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot May 13, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

자세히 보기 액션이 현재 무동작으로 노출됩니다.

Line 181 TODO로 인해 클릭 가능한 텍스트가 실제로는 아무 동작을 하지 않습니다. 약관 화면에서는 오해를 줄이기 위해 링크 준비 전까지 비노출/비활성 처리하는 게 안전합니다.

원하시면 링크 미연결 시 CTA를 숨기거나 비활성화하도록 최소 수정안 만들어드릴게요.

🤖 Prompt for 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.

In `@app/src/main/java/com/flint/presentation/onboarding/OnboardingTermsScreen.kt`
around lines 180 - 182, The "자세히 보기" click handler is a no-op (onDetailClick = {
/* TODO */ }) so the CTA appears clickable but does nothing; update the
OnboardingTermsScreen call/site to either pass null for onDetailClick or an
explicit enabled=false flag and adjust the Terms item composable (the component
that renders the CTA) to hide or render the CTA as disabled when onDetailClick
is null/disabled. Concretely: change the caller to onDetailClick = null (or
onDetailEnabled = false), and modify the Terms CTA rendering logic to check for
a nullable lambda or enabled boolean and avoid showing a clickable link when not
provided.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

곧 생길 예정이라 그대로 둘게요

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.

@ckals413 알겠습니다! 링크 연결 시 자연스럽게 추가될 수 있도록 TODO 주석이 잘 남아있으니 참고해 주세요. 🙂


🧠 Learnings used
Learnt from: nahy-512
Repo: imflint/Flint-Android PR: 135
File: app/src/main/java/com/flint/domain/repository/AuthRepository.kt:1-22
Timestamp: 2026-01-19T00:48:44.889Z
Learning: Architect the Android app following Google's recommended Android App Architecture for this repo: place the data layer innermost, the domain layer can depend on the data layer, and avoid circular dependencies with other layers. For Kotlin files under app/src/main/java, ensure accompanying architecture aligns with this guidance (e.g., domain interfaces depending on data layer implementations or abstractions, not the other way around).

Learnt from: giovannijunseokim
Repo: imflint/Flint-Android PR: 153
File: app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailViewModel.kt:98-105
Timestamp: 2026-01-21T08:37:42.767Z
Learning: Guideline: For APIs like toggleContentBookmark that do not return a bookmarkCount, perform optimistic updates by updating the isBookmarked state on the client and compute bookmarkCount locally if needed. Do not rely on the server for the count; ensure the server response only conveys the boolean bookmarked state and synchronize this state accordingly. This applies to Kotlin Android ViewModels and related UI state management across files that handle similar bookmark toggle endpoints.

Copy link
Copy Markdown
Contributor

@kimjw2003 kimjw2003 left a comment

Choose a reason for hiding this comment

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

머지 ㄱㄱ

@ckals413 ckals413 merged commit b597a3a into develop May 14, 2026
2 checks passed
@ckals413 ckals413 deleted the FLT-16-회원가입-api-수정 branch May 14, 2026 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔖 API feat - API 연동 Feat ✨ 신규 기능을 추가하거나 기존 기능의 동작, 정책을 변경

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants