Skip to content

Conversation

@easyhooon
Copy link
Contributor

@easyhooon easyhooon commented Dec 24, 2025

🔗 관련 이슈

📙 작업 설명

  • 도서 검색 결과 EmptyResult 케이스시 UI 변경 사항 반영
  • 문의하기 버튼 클릭시 Reed 카카오톡 문의 채널 채팅방으로 바로 이동 되도록 구현
  • 각 build.gradle.kts에서 사용하던 local.properties value 조회 함수 공통화

🧪 테스트 내역 (선택)

  • 주요 기능 정상 동작 확인
  • 브라우저/기기에서 동작 확인
  • 엣지 케이스 테스트 완료
  • 기존 기능 영향 없음

📸 스크린샷 또는 시연 영상 (선택)

Reed.mp4

💬 추가 설명 or 리뷰 포인트 (선택)

Summary by CodeRabbit

릴리스 노트

  • 새 기능

    • 검색 결과 없음 화면 개선 — 제목, 설명과 문의 버튼 추가
    • 문의 버튼으로 KakaoTalk 채널 바로 이동 가능
  • 기타

    • 검색 상태 관리 및 흐름 개선으로 안정성 향상
    • 앱 구성(환경값) 로컬 설정 방식 갱신 — 빌드 시 환경값 주입 개선
    • 온보딩 텍스트 처리의 일부 매개변수 유연성 강화

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

@coderabbitai
Copy link

coderabbitai bot commented Dec 24, 2025

Walkthrough

Gradle 로컬 속성 접근을 getLocalProperty로 통합하고, 도서 검색 실패 시 카카오톡 채널로 문의할 수 있는 버튼/사이드이펙트를 추가하며 검색 상태를 SearchUiState로 리네이밍하고 상태 확장을 도입합니다. (50단어 이내)

Changes

Cohort / File(s) 변경 사항
Gradle 유틸리티 추가
build-logic/src/main/kotlin/com/ninecraft/booket/convention/Extensions.kt
Project.getLocalProperty(propertyKey: String): String 확장 함수 추가 (gradleLocalProperties 래핑)
Gradle 설정 통합
app/build.gradle.kts, core/network/build.gradle.kts, core/ocr/build.gradle.kts, feature/login/build.gradle.kts, feature/search/build.gradle.kts
기존의 gradleLocalProperties 직접 사용/개별 헬퍼(getApiKey, getServerBaseUrl) 제거, getLocalProperty 임포트 및 buildConfigField에 적용(예: GOOGLE_WEB_CLIENT_ID, REED_KAKAOTALK_CHANNEL_URL 등). buildFeatures에 buildConfig = true 추가된 파일 존재
검색 Presenter 및 이벤트
feature/search/src/main/kotlin/.../BookSearchPresenter.kt
uiStatesearchUiState로 속성/참조 변경. SearchUiState 타입 사용으로 상태 분기 변경. BookSearchUiEvent.OnInquireClick 이벤트 추가 및 해당 이벤트 발생 시 카카오톡 네비게이션 사이드이펙트 발행
검색 UI 상태 정의 확장
feature/search/src/main/kotlin/.../BookSearchUiState.kt
UiStateSearchUiState로 재정의(Idle/Loading/Success/Error). BookSearchUiStatesearchResult, books, selectedBookIsbn, isBookRegisterBottomSheetVisible, selectedBookStatus, upsertedBookStatus, isBookRegisterSuccessBottomSheetVisible, isGuestMode 등 필드 추가. NavigateToKakaoTalkChannel 사이드이펙트 추가
검색 UI 컴포저블 변경
feature/search/src/main/kotlin/.../BookSearchUi.kt
UI 상태 분기 SearchUiState로 변경. 빈 결과 UI를 제목/설명/문의하기 버튼을 포함하는 Column으로 개편. 문의하기 버튼에 OnInquireClick 연결. 프리뷰 함수 재구성
사이드이펙트 핸들러
feature/search/src/main/kotlin/.../HandleBookSearchSideEffect.kt
LocalUriHandler 사용 추가. NavigateToKakaoTalkChannel 처리 로직으로 BuildConfig.REED_KAKAOTALK_CHANNEL_URL을 열도록 구현
리소스·메타·기타
feature/search/src/main/res/values/strings.xml, feature/onboarding/stability/onboarding.stability, feature/search/stability/search.stability
empty_results 문자열을 empty_results_title, empty_results_description, inquire로 분리. OnboardingPage의 highlightTextRes 파라미터를 nullable로 변경. 검색 프리뷰 메타데이터(프리뷰 함수 추가/재배치) 수정

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as BookSearchUi
    participant Presenter as BookSearchPresenter
    participant SideEffectHandler as HandleBookSearchSideEffect
    participant UriHandler as LocalUriHandler

    User->>UI: 빈 검색 화면에서 "문의하기" 클릭
    UI->>Presenter: eventSink(OnInquireClick)
    Presenter->>Presenter: searchUiState 유지/업데이트 없음
    Presenter->>SideEffectHandler: Emit NavigateToKakaoTalkChannel

    rect rgb(235,245,255)
      Note right of SideEffectHandler: 사이드이펙트 처리 (카카오톡 URL 열기)
      SideEffectHandler->>SideEffectHandler: val url = BuildConfig.REED_KAKAOTALK_CHANNEL_URL
      SideEffectHandler->>UriHandler: openUri(url)
      UriHandler-->>User: 카카오톡 채널로 포워딩 (앱/브라우저)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • seoyoon513

Poem

🐰
빈 결과에 버튼 하나 띄워두니,
톡으로 길 열리고 문의가 오네.
SearchUiState로 깔끔히 정리하고,
속성은 모여 더 많은 이야길 담아,
당근처럼 부드럽게 연결됐네 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 주요 변경 사항(도서 검색 실패시 카카오톡 채널 문의 버튼 추가)을 명확히 요약하고 있습니다.
Linked Issues check ✅ Passed 링크된 이슈 #240의 요구사항(도서 검색 실패시 문의하기 버튼을 통해 카톡 채널로 진입)이 완전히 충족되었습니다.
Out of Scope Changes check ✅ Passed 빌드 설정 리팩토링(getLocalProperty 통합)은 로컬 속성 관리를 개선하는 부가적 개선사항으로 원래 목표 달성에 도움이 됩니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch BOOK-479-feature/#240

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

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

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 25c1f6b and 6116acf.

📒 Files selected for processing (13)
  • app/build.gradle.kts
  • build-logic/src/main/kotlin/com/ninecraft/booket/convention/Extensions.kt
  • core/network/build.gradle.kts
  • core/ocr/build.gradle.kts
  • feature/login/build.gradle.kts
  • feature/onboarding/stability/onboarding.stability
  • feature/search/build.gradle.kts
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUiState.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/HandleBookSearchSideEffect.kt
  • feature/search/src/main/res/values/strings.xml
  • feature/search/stability/search.stability
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-07-20T12:34:23.786Z
Learnt from: easyhooon
Repo: YAPP-Github/Reed-Android PR: 61
File: feature/webview/build.gradle.kts:17-21
Timestamp: 2025-07-20T12:34:23.786Z
Learning: Reed-Android 프로젝트에서는 `booket.android.feature` convention plugin을 사용하여 feature 모듈들의 공통 의존성을 관리한다. 이 plugin은 Circuit, Compose, 그리고 core 모듈들의 의존성을 자동으로 포함하므로, 각 feature 모듈의 build.gradle.kts에서는 특별한 의존성(예: libs.logger, libs.kakao.auth)만 별도로 선언하면 된다.

Applied to files:

  • build-logic/src/main/kotlin/com/ninecraft/booket/convention/Extensions.kt
  • core/network/build.gradle.kts
  • feature/search/build.gradle.kts
  • feature/login/build.gradle.kts
  • core/ocr/build.gradle.kts
📚 Learning: 2025-08-28T12:25:54.058Z
Learnt from: easyhooon
Repo: YAPP-Github/Reed-Android PR: 174
File: feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt:128-133
Timestamp: 2025-08-28T12:25:54.058Z
Learning: In BookSearchPresenter.kt, when a guest user tries to register a book and is redirected to login, the bottom sheet (isBookRegisterBottomSheetVisible) and selection state (selectedBookIsbn, selectedBookStatus) are intentionally kept open/preserved so that when the user returns from login, they can continue from where they left off without losing context.

Applied to files:

  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUiState.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt
  • feature/search/stability/search.stability
🧬 Code graph analysis (5)
core/network/build.gradle.kts (1)
build-logic/src/main/kotlin/com/ninecraft/booket/convention/Extensions.kt (1)
  • getLocalProperty (15-17)
app/build.gradle.kts (1)
build-logic/src/main/kotlin/com/ninecraft/booket/convention/Extensions.kt (1)
  • getLocalProperty (15-17)
feature/search/build.gradle.kts (1)
build-logic/src/main/kotlin/com/ninecraft/booket/convention/Extensions.kt (1)
  • getLocalProperty (15-17)
feature/login/build.gradle.kts (1)
build-logic/src/main/kotlin/com/ninecraft/booket/convention/Extensions.kt (1)
  • getLocalProperty (15-17)
core/ocr/build.gradle.kts (1)
build-logic/src/main/kotlin/com/ninecraft/booket/convention/Extensions.kt (1)
  • getLocalProperty (15-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: ci-build
  • GitHub Check: Compose Stability Check
🔇 Additional comments (20)
feature/onboarding/stability/onboarding.stability (1)

28-34: highlightTextRes nullable 변경이 올바르게 구현되었습니다.

자동 생성된 stability 파일의 변경 사항이 실제 구현부와 일치하는지 확인했습니다:

  1. 구현부: OnboardingPage.kt 라인 29에서 highlightTextRes: Int? = null으로 올바르게 정의되었고, 라인 34-42에서 null 값을 적절히 처리합니다 (null일 때 AnnotatedString, null이 아닐 때 HighlightedText 사용).

  2. 호출 지점: OnboardingUi.kt의 모든 호출 지점이 올바르게 처리됩니다 (페이지 0, 1은 highlight 텍스트를 전달하고, 페이지 2는 전달하지 않아 기본값 null 사용).

  3. Stability 주석: kotlin.Int?는 primitive type이 아니므로 "class with no mutable properties" 표기가 정확합니다.

변경 사항이 완벽하게 처리되었으므로 추가 조정은 필요하지 않습니다.

feature/search/src/main/res/values/strings.xml (1)

8-10: LGTM!

빈 검색 결과에 대한 문자열 리소스가 명확하고 사용자 친화적입니다. 제목, 설명, 액션 버튼으로 구성된 구조가 적절합니다.

feature/login/build.gradle.kts (1)

3-3: LGTM!

로컬 속성 접근 방식을 중앙화된 getLocalProperty 함수로 통일한 리팩토링이 올바르게 적용되었습니다. 디버그 및 릴리스 빌드 타입에서 적절하게 사용되고 있습니다.

Also applies to: 14-26

core/network/build.gradle.kts (1)

3-3: LGTM!

서버 베이스 URL 접근 방식이 새로운 getLocalProperty 유틸리티로 올바르게 마이그레이션되었습니다. 디버그 및 릴리스 빌드에서 일관되게 적용되어 있습니다.

Also applies to: 21-21, 25-25

feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/HandleBookSearchSideEffect.kt (1)

6-7: LGTM!

카카오톡 채널로 이동하는 사이드 이펙트 처리가 올바르게 구현되었습니다. LocalUriHandler를 사용하여 외부 URI를 여는 표준 Compose 패턴을 따르고 있습니다.

Also applies to: 16-16, 24-26

build-logic/src/main/kotlin/com/ninecraft/booket/convention/Extensions.kt (1)

3-3: LGTM!

로컬 속성 접근을 중앙화하는 getLocalProperty 함수가 깔끔하게 구현되었습니다. 여러 모듈에서 일관된 방식으로 로컬 속성에 접근할 수 있게 되었습니다.

Also applies to: 15-17

app/build.gradle.kts (1)

4-4: LGTM!

앱 모듈에서 로컬 속성 접근 방식이 getLocalProperty로 일관되게 마이그레이션되었습니다. KAKAO_NATIVE_APP_KEY의 매니페스트 플레이스홀더 처리에서 따옴표 제거 로직도 적절합니다.

Also applies to: 35-35, 46-46, 58-59

feature/search/stability/search.stability (1)

7-11: 자동 생성된 파일입니다.

Compose Stability Analyzer가 생성한 파일로, 새로운 프리뷰 함수들(BookRecentSearchPreview, BookSearchEmptyResultPreview)과 코드 변경사항이 올바르게 반영되어 있습니다. 모든 Composable 함수가 적절하게 안정성 분석되었습니다.

Also applies to: 22-31

feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt (4)

27-29: LGTM!

새로운 문의하기 버튼 기능에 필요한 ReedButton, ReedButtonColorStyle, smallButtonStyle import가 적절하게 추가되었습니다.


120-132: LGTM!

UiState에서 SearchUiState로의 마이그레이션이 올바르게 적용되었습니다. when 분기문에서 스마트 캐스트를 통해 exception 속성에 안전하게 접근하고 있습니다.


185-205: LGTM!

검색 결과가 없을 때의 UI가 깔끔하게 구성되었습니다. 제목, 설명, 문의하기 버튼이 적절한 spacing과 함께 배치되어 있으며, OnInquireClick 이벤트가 올바르게 연결되어 있습니다.


326-337: LGTM!

빈 검색 결과 상태에 대한 새로운 프리뷰 함수가 추가되어 개발 시 UI 확인이 용이해졌습니다. BookSearchContent를 직접 사용하여 불필요한 Scaffold 래핑 없이 핵심 콘텐츠를 프리뷰합니다.

feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt (3)

70-70: LGTM!

SearchUiState로의 상태 타입 마이그레이션이 올바르게 적용되었습니다. 초기값으로 SearchUiState.Idle을 사용하는 것이 적절합니다.


86-127: LGTM!

검색 흐름에서의 상태 전환이 적절하게 구현되었습니다:

  • 첫 페이지 검색 시 SearchUiState.LoadingSearchUiState.Success 또는 SearchUiState.Error
  • 페이지네이션 시 FooterState를 별도로 관리

264-266: LGTM!

OnInquireClick 이벤트 핸들러가 NavigateToKakaoTalkChannel 사이드 이펙트를 올바르게 트리거합니다.

feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUiState.kt (4)

17-22: LGTM!

SearchUiState sealed interface가 잘 설계되었습니다. Error variant가 Throwable을 포함하여 UI에서 에러 타입에 따른 처리가 가능하고, @Immutable 어노테이션으로 Compose 최적화가 적용되어 있습니다.


24-41: LGTM!

BookSearchUiState의 구조가 명확합니다. isEmptySearchResult 계산 속성이 SearchUiState.Success이면서 결과가 0인 경우를 정확하게 판별합니다.


49-51: LGTM!

NavigateToKakaoTalkChannel 사이드 이펙트가 data object로 정의되어 파라미터가 필요 없는 네비게이션 액션에 적합합니다.


69-69: LGTM!

OnInquireClick 이벤트가 적절하게 추가되었습니다.

core/ocr/build.gradle.kts (1)

3-3: 프로퍼티 누락 시 타입 안전성 문제 해결 필요

getLocalProperty 함수가 String (null 불가) 타입으로 선언되어 있으나, 실제 구현에서는 gradleLocalProperties().getProperty()가 null을 반환할 수 있습니다. CLOUD_VISION_API_KEYlocal.properties에 없을 경우 null이 반환되어 타입 안전성 위반이 발생합니다.

함수 반환 타입을 String?으로 변경하거나, null 시 기본값을 제공하거나, 필수 프로퍼티 누락 시 명시적 오류를 발생시키는 방식으로 개선해야 합니다. 현재 이 함수는 여러 모듈(app, feature/login, feature/search, core/ocr, core/network)에서 사용되고 있으므로 일관된 에러 처리가 필요합니다.

Copy link

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

🧹 Nitpick comments (1)
feature/search/build.gradle.kts (1)

15-21: 구조가 올바르게 수정되었습니다.

이전 리뷰에서 지적된 defaultConfig의 중첩 문제가 해결되었습니다. buildFeaturesdefaultConfig가 모두 android 블록의 직접 자식으로 올바르게 배치되어 있으며, BuildConfig 기능이 적절히 활성화되었습니다.

다만, 프로젝트를 빌드하기 위해서는 REED_KAKAOTALK_CHANNEL_URL 속성을 local.properties에 추가해야 합니다. 팀의 다른 개발자들이 프로젝트를 정상적으로 빌드할 수 있도록 README 또는 개발 가이드에 이 속성의 설정 방법을 문서화하는 것이 좋습니다.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6116acf and b065c0c.

📒 Files selected for processing (1)
  • feature/search/build.gradle.kts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-20T12:34:23.786Z
Learnt from: easyhooon
Repo: YAPP-Github/Reed-Android PR: 61
File: feature/webview/build.gradle.kts:17-21
Timestamp: 2025-07-20T12:34:23.786Z
Learning: Reed-Android 프로젝트에서는 `booket.android.feature` convention plugin을 사용하여 feature 모듈들의 공통 의존성을 관리한다. 이 plugin은 Circuit, Compose, 그리고 core 모듈들의 의존성을 자동으로 포함하므로, 각 feature 모듈의 build.gradle.kts에서는 특별한 의존성(예: libs.logger, libs.kakao.auth)만 별도로 선언하면 된다.

Applied to files:

  • feature/search/build.gradle.kts
🧬 Code graph analysis (1)
feature/search/build.gradle.kts (1)
build-logic/src/main/kotlin/com/ninecraft/booket/convention/Extensions.kt (1)
  • getLocalProperty (15-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Compose Stability Check
  • GitHub Check: ci-build
🔇 Additional comments (1)
feature/search/build.gradle.kts (1)

3-3: 올바른 import 추가입니다.

프로젝트의 공통 유틸리티 함수인 getLocalProperty를 import하여 사용하는 것은 다른 모듈(app, core/ocr, core/network, feature/login)과 일관된 패턴을 따릅니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BOOK-479/feat] 도서 검색 실패시 대응

2 participants