Skip to content

[Feat] 탐색 화면 API 연결#161

Merged
nahy-512 merged 13 commits into
developfrom
feat/#154-explore-api
Jan 22, 2026
Merged

[Feat] 탐색 화면 API 연결#161
nahy-512 merged 13 commits into
developfrom
feat/#154-explore-api

Conversation

@giovannijunseokim

@giovannijunseokim giovannijunseokim commented Jan 21, 2026

Copy link
Copy Markdown
Contributor

📮 관련 이슈

📌 작업 내용

  • 탐색 화면 API 연결

📸 스크린샷

스크린샷
Screen_recording_20260122_001708.mp4

Summary by CodeRabbit

릴리스 노트

  • 새 기능
    • 탐색 화면에서 컬렉션 페이지네이션 지원이 추가되었습니다. 사용자가 화면 끝에 가까워지면 자동으로 다음 컬렉션이 로드됩니다.
    • 탐색 화면이 동적 컬렉션 데이터를 표시하도록 업데이트되었습니다. 각 컬렉션은 이미지, 제목, 설명과 함께 표시됩니다.

✏️ Tip: You can customize this high-level summary in your review settings.

- `CollectionsModel`: 도메인 레이어에서 사용할 컬렉션 데이터 모델 정의
- `CollectionsResponseDto`: API 응답 값 파싱을 위한 DTO 클래스 추가 (kotlinx.serialization 적용)
- `CollectionApi`에 `getCollections` 메서드 추가
- `cursor`와 `page`를 파라미터로 받는 GET 요청 정의
- `CollectionsResponseDto`를 `CollectionsModel`로 변환하는 Mapper 함수 추가
- `CollectionRepository`에 컬렉션 목록 조회(`getCollections`) 함수 추가
- `ExploreViewModel`을 생성하여 `CollectionRepository`로부터 컬렉션 목록을 가져오는 로직 추가
- `ExploreScreen`에서 `UiState`에 따라 로딩 인디케이터 표시 및 데이터 바인딩 처리
- `CollectionsModel`의 데이터 타입을 `ImmutableList`로 변경 및 관련 매퍼 수정
- `CollectionRepository.getCollections`의 반환 타입을 `Result<CollectionsModel>`로 명시 및 데이터 변환 로직 추가
- `getCollections` 함수 내에서 사용되지 않는 `uiState` 변수 제거
- `ExploreScreen`에서 `pagerState`를 기반으로 다음 페이지 로드 로직 추가 (`onLoadNextPage`)
- `ExploreViewModel`에서 페이징 처리를 위한 `currentCursor`, `isLastPage` 등 상태 관리 및 데이터 추가 로직 구현
- `CollectionRepository` 및 `CollectionApi`의 파라미터 명칭 수정 (`page` -> `size`)
- `ExploreUiState`의 `currentCursor`를 `nextCursor`로 변경하고 타입을 `Long?`으로 수정
- `CollectionsResponseDto` 및 `CollectionsModel`의 Meta 정보에서 불필요한 필드(`currentPage`, `totalElements` 등) 제거 및 `nextCursor` 타입을 `Long?`으로 변경
- `CollectionRepository` 및 `CollectionApi`의 `getCollections` 함수 파라미터 타입을 `Long?`으로 변경
- `isLastPage` 판정 로직을 `nextCursor`의 null 여부로 단순화
- `ExploreViewModel`에서 데이터 로드 시 다음 커서 값을 전달하도록 수정
- `ExploreUiState`에 `canLoadMore` 속성을 추가하여 페이징 가능 여부 판단 로직 캡슐화
- `isLastPage` 제거 및 `nextCursor` 유무로 마지막 페이지 판단 로직 통합
- `ExploreViewModel`의 컬렉션 로드 로직을 `fetchCollections` 공통 메서드로 분리 및 구조 개선
- `Collection` 데이터 클래스 내 필드(`imageUrl`, `title`, `description`, `createdAt`) 순서 조정
@giovannijunseokim giovannijunseokim self-assigned this Jan 21, 2026
@giovannijunseokim giovannijunseokim requested a review from a team as a code owner January 21, 2026 15:18
@giovannijunseokim giovannijunseokim added 🔖 API feat - API 연동 Feat ✨ 신규 기능을 추가하거나 기존 기능의 동작, 정책을 변경 labels Jan 21, 2026
@coderabbitai

coderabbitai Bot commented Jan 21, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

탐색 화면을 위한 페이지네이션 기반 컬렉션 API를 구현했습니다. API 계층에서 새로운 엔드포인트를 추가하고, 데이터 매핑을 거쳐 도메인 모델로 변환한 뒤, ViewModel을 통해 페이지네이션 상태를 관리하며, UI에서는 동적으로 컬렉션을 렌더링하는 end-to-end 통합입니다.

Changes

코호트 / 파일 변경 사항
API 및 DTO 계층
app/src/main/java/com/flint/data/api/CollectionApi.kt, app/src/main/java/com/flint/data/dto/collection/response/CollectionsResponseDto.kt
페이지네이션 쿼리 파라미터(cursor, size)를 지원하는 새로운 GET /api/v1/collections 엔드포인트 추가. CollectionsResponseDto DTO 정의로 응답 데이터 구조 명시.
도메인 계층 (매퍼 및 모델)
app/src/main/java/com/flint/domain/mapper/collection/CollectionMapper.kt, app/src/main/java/com/flint/domain/model/collection/CollectionsModel.kt, app/src/main/java/com/flint/domain/repository/CollectionRepository.kt
CollectionsResponseDto를 CollectionsModel로 변환하는 매퍼 함수와 중첩 매퍼 추가. 불변 리스트와 페이지네이션 메타데이터를 포함하는 새로운 도메인 모델 정의. 리포지토리에 컬렉션 조회 메서드 추가.
프레젠테이션 계층 (ViewModel 및 UI)
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
페이지네이션 로직을 관리하는 ExploreViewModel 신규 생성. 로딩 상태와 페이지네이션 정보를 포함하는 ExploreUiState 정의. ExploreScreen/Route를 ViewModel 기반으로 리팩토링하고, ContentModel에서 CollectionsModel.Collection으로 변경, loadNextPage 콜백 및 lazy 페이지네이션 트리거 추가.

Sequence Diagram

sequenceDiagram
    participant User as 사용자
    participant Screen as ExploreScreen
    participant ViewModel as ExploreViewModel
    participant Repo as CollectionRepository
    participant API as CollectionApi
    participant State as UiState

    User->>Screen: 화면 진입
    Screen->>ViewModel: getInitialCollections 호출
    ViewModel->>Repo: fetchCollections(cursor=null)
    Repo->>API: getCollections(cursor=null, size=10)
    API-->>Repo: BaseResponse<CollectionsResponseDto>
    Repo->>Repo: toModel() 매핑
    Repo-->>ViewModel: Result<CollectionsModel>
    ViewModel->>State: UiState 업데이트<br/>(collections, nextCursor)
    State-->>Screen: collectAsStateWithLifecycle
    Screen->>Screen: 컬렉션 렌더링

    User->>Screen: 마지막 페이지 근처 스크롤
    Screen->>ViewModel: loadNextPage() 호출
    ViewModel->>ViewModel: canLoadMore 확인
    ViewModel->>Repo: fetchCollections(cursor=nextCursor)
    Repo->>API: getCollections(cursor=nextCursor, size=10)
    API-->>Repo: BaseResponse<CollectionsResponseDto>
    Repo->>Repo: toModel() 매핑
    Repo-->>ViewModel: Result<CollectionsModel>
    ViewModel->>ViewModel: 기존 + 신규 데이터 병합<br/>isLoadingMore = false
    ViewModel->>State: UiState 업데이트<br/>(확장된 collections, 새 nextCursor)
    State-->>Screen: 상태 반영
    Screen->>Screen: 추가 컬렉션 렌더링
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • [Feat] Home UI #104: ExploreScreen/ExploreRoute의 공개 API 파라미터 변경 및 사용 패턴 수정으로 직접 연관.
  • [Refactor]: Home model #142: CollectionMapper에서 새로운 응답 DTO 매핑 함수 추가 및 컬렉션 매퍼 리팩토링으로 매퍼 계층 변경 연관.
  • [Feat] Home api #138: CollectionApi 엔드포인트 추가, DTO, 매퍼, 리포지토리 메서드 구현 등 전체 API 계층 확장 연관.

Suggested reviewers

  • nahy-512
  • kimjw2003

Poem

🐰 호핑홉, 페이지 넘으며 달려가고
📜 커서 따라 데이터 흐르고
🔄 ViewModel이 상태를 쥐고 있고
✨ 탐색 화면은 반짝반짝
🎉 무한 스크롤의 꿈을 이루네!

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.76% 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 연결이라는 주요 변경사항을 명확하고 간결하게 요약합니다.
Description check ✅ Passed PR 설명은 기본 템플릿을 따르고 관련 이슈(#154)와 주요 작업 내용을 포함하지만 세부사항이 부족합니다.
Linked Issues check ✅ Passed PR 변경사항이 #154 요구사항을 충족합니다: API 지원, 백엔드 통합, 데이터 모델 구현, 페이지네이션 지원, 상태 관리 및 UI 업데이트가 모두 포함되어 있습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 탐색 화면 API 연결 범위 내에 있으며, 불필요한 변경사항은 발견되지 않았습니다.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

@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

🤖 Fix all issues with AI agents
In `@app/src/main/java/com/flint/domain/mapper/collection/CollectionMapper.kt`:
- Around line 109-122: The mapping in CollectionsResponseDto.Meta.toModel()
converts nextCursor (String?) to Long? using toLongOrNull(), which will silently
drop non-numeric cursors and prematurely end pagination; either confirm the
backend always returns numeric cursors and keep the conversion, or change the
domain type to accept String? by updating CollectionsModel.Meta.nextCursor to
String? and stop calling toLongOrNull() in
CollectionsResponseDto.Meta.toModel(); locate the conversion in the toModel()
function and adjust the mapping accordingly (or add validation/parsing with
explicit error handling if numeric cursors are required).

In `@app/src/main/java/com/flint/presentation/explore/ExploreViewModel.kt`:
- Around line 75-77: The onFailure block in ExploreViewModel is empty so API
failures leave loading flags set and the UI stuck; update the onFailure handler
used with the API call (the onFailure lambda) to log the throwable, set any
loading flags (e.g., isLoading and isLoadingMore) back to false, and emit an
error or empty state to _uiState (or call the existing method that handles
errors) so the UI can hide spinners and allow retry/pagination again; ensure you
reference the same properties (isLoadingMore, _uiState) and the surrounding
fetch/load method in ExploreViewModel when making these changes.
🧹 Nitpick comments (1)
app/src/main/java/com/flint/presentation/explore/ExploreScreen.kt (1)

55-72: 에러 상태 처리 및 변수 섀도잉 개선이 필요합니다.

  1. Line 61: uiState 변수가 외부 uiState를 섀도잉하여 혼란을 줄 수 있습니다.
  2. Line 71: else 브랜치가 비어있어 UiState.Error 발생 시 빈 화면이 표시됩니다.
♻️ 개선 제안
     when (uiState) {
         UiState.Loading -> {
             FlintLoadingIndicator()
         }

         is UiState.Success -> {
-            val uiState = (uiState as UiState.Success<ExploreUiState>).data
+            val exploreData = (uiState as UiState.Success<ExploreUiState>).data
             ExploreScreen(
-                collections = uiState.collections,
+                collections = exploreData.collections,
                 onWatchCollectionButtonClick = navigateToCollectionDetail,
                 onMakeCollectionButtonClick = navigateToCollectionCreate,
                 onLoadNextPage = viewModel::loadNextPage,
                 modifier = Modifier.padding(paddingValues),
             )
         }

-        else -> {}
+        is UiState.Error -> {
+            // TODO: 에러 UI 표시 (재시도 버튼 등)
+        }
     }

@nahy-512 nahy-512 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.

고생하셨습니다!!


import kotlinx.collections.immutable.ImmutableList

data class CollectionsModel(

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.

p2
기존 CollectionListModel이랑 조금 헷갈릴 것 같은데, 저번에 얘기하기로는 explore 붙이기로 하지 않았었나요??

val pagerState: PagerState = rememberPagerState(pageCount = { pageCount + 1 })

LaunchedEffect(pagerState.currentPage) {
if (pagerState.currentPage >= pageCount - 3 && pageCount > 0) {

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.

p3
pageCount - 3이 미리 컬렉션 정보를 불러오기 위함인가요?

# Conflicts:
#	app/src/main/java/com/flint/presentation/explore/ExploreScreen.kt
@nahy-512 nahy-512 merged commit 40a621e into develop Jan 22, 2026
2 checks passed
@nahy-512 nahy-512 deleted the feat/#154-explore-api branch January 22, 2026 07:41
This was referenced Jan 22, 2026
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.

[Feat] 탐색 화면 API

2 participants