Skip to content

Conversation

@m6z1
Copy link
Member

@m6z1 m6z1 commented Aug 15, 2025

📌𝘐𝘴𝘴𝘶𝘦𝘴

N/A

📎𝘞𝘰𝘳𝘬 𝘋𝘦𝘴𝘤𝘳𝘪𝘱𝘵𝘪𝘰𝘯

  • 1.3.0 업데이트!
  • 알림 상세 화면 edgeToEdge 적용 안 되어있어서 반영했습니다!

📷𝘚𝘤𝘳𝘦𝘦𝘯𝘴𝘩𝘰𝘵

스크린샷 2025-08-15 오후 11 58 49

💬𝘛𝘰 𝘙𝘦𝘷𝘪𝘦𝘸𝘦𝘳𝘴

Summary by CodeRabbit

  • 신기능
    • 알림 상세 화면에 엣지-투-엣지 UI 적용으로 콘텐츠 확장감 개선
  • 버그 수정
    • 시스템 상태/내비게이션 바와 겹치던 레이아웃 패딩 문제 개선으로 가시성 향상
    • 카카오 로그인 흐름의 오류 처리 보강으로 로그인 안정성 향상
    • 회원가입/로그인 화면의 불필요한 토스트 노출 제거
  • 유지보수
    • 앱 버전 업데이트: 1.3.0
    • 카카오 SDK 및 네트워크 라이브러리 관련 난독화/압축 규칙 정비 및 빌드 타입 설정 추가

@coderabbitai
Copy link

coderabbitai bot commented Aug 15, 2025

Walkthrough

알림 상세 화면에 엣지-투-엣지 및 시스템 바 인셋 처리가 추가되었고, 카카오 로그인 흐름의 분기 로직이 재구성되었습니다. 앱/모듈별 ProGuard 및 consumer-rules가 정비되었으며, 일부 모듈에 release 빌드타입이 추가되었습니다. 앱 버전이 1.3.0(10019)으로 갱신되었습니다.

Changes

Cohort / File(s) Summary
알림 상세 엣지-투-엣지 적용
app/src/main/java/com/into/websoso/ui/notificationDetail/NotificationDetailActivity.kt, app/src/main/java/com/into/websoso/ui/notificationDetail/NotificationDetailScreen.kt
Activity에서 enableEdgeToEdge() 호출 추가. Compose 화면에 WindowInsets.systemBars 기반 windowInsetsPadding 추가.
앱 버전 갱신
gradle/libs.versions.toml
versionCode 10015 → 10019, versionName 1.2.0 → 1.3.0.
Sign-in 모듈 동작/빌드 설정
feature/signin/src/main/java/.../SignInScreen.kt, feature/signin/build.gradle.kts, feature/signin/consumer-rules.pro, feature/signin/proguard-rules.pro
ShowToast 효과 핸들러를 빈 블록으로 변경. release 빌드타입 추가(isMinifyEnabled=false, consumerProguardFiles("consumer-rules.pro")). Kakao/Retrofit/OkHttp 보존 및 dontwarn 규칙 추가. 기존 proguard 내용 삭제(파일 비움).
앱 레벨 ProGuard 정비
app/proguard-rules.pro
기존 특정 keep 규칙 제거 후 Kakao SDK, Retrofit, OkHttp, Gson, Activity 관련 보존 및 dontwarn 규칙을 광범위하게 추가/정리.
Kakao Auth 모듈 빌드/규칙
core/auth-kakao/build.gradle.kts, core/auth-kakao/consumer-rules.pro, core/auth-kakao/proguard-rules.pro
release 빌드타입 추가(isMinifyEnabled=false, consumer rules 지정). consumer-rules에 Kakao/Retrofit/OkHttp 보존 및 dontwarn 규칙 추가. 기존 proguard 파일 내용 제거(파일 비움).
KakaoAuthClient 로그인 분기 재구성
core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt
when 기반 분기로 재작성. KakaoTalk 실패(오류 비null) 시 즉시 KakaoAccount로 폴백. KakaoAccount에서 토큰·오류 모두 null인 경우 IllegalStateException으로 처리.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as User
  participant App as App
  participant Auth as KakaoAuthClient
  participant KT as KakaoTalk SDK
  participant KA as KakaoAccount SDK

  User->>App: 로그인 요청
  App->>Auth: login()
  rect rgba(200,230,255,0.3)
    note right of Auth: 1차 시도: KakaoTalk
    Auth->>KT: loginWithKakaotalk()
    alt 토큰 수신
      KT-->>Auth: token
      Auth-->>App: token
    else 오류 수신(비null)
      KT-->>Auth: error
      note right of Auth: 즉시 KakaoAccount로 폴백
      Auth->>KA: loginWithKakaoAccount()
      alt 토큰 수신
        KA-->>Auth: token
        Auth-->>App: token
      else 오류 수신
        KA-->>Auth: error
        Auth-->>App: error
      end
    else 토큰/오류 모두 없음
      note right of Auth: KakaoAccount로 폴백
      Auth->>KA: loginWithKakaoAccount()
      alt 토큰 수신
        KA-->>Auth: token
        Auth-->>App: token
      else 오류 수신
        KA-->>Auth: error
        Auth-->>App: error
      else 둘 다 null
        KA-->>Auth: null 결과
        Auth-->>App: IllegalStateException
      end
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

🍯 [FEAT], 🏹 궁사 명지

Suggested reviewers

  • s9hn
  • junseo511
  • yeonjeen

Poem

토끼가 깡충, 코드 밭을 지나
가장자리까지 빛을 불러와서
인셋으로 살포시 자리 내주네 🥕
카카오 문 열면 폴짝 폴백,
버전은 한 칸 뛰어 1.3.0 🎉

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch release/1.3.0

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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 (3)
gradle/libs.versions.toml (1)

3-4: 릴리스 부수 작업 점검 제안

다음 사소한 확인을 권장합니다.

  • 스토어 배포 파이프라인에서 versionCode 10016이 정상 반영되는지
  • CHANGELOG/릴리스 노트, 태그(v1.3.0) 업데이트
  • 버전 표시가 UI/About 화면 등에 노출된다면 해당 경로에서도 1.3.0 반영
app/src/main/java/com/into/websoso/ui/notificationDetail/NotificationDetailScreen.kt (1)

29-34: systemBars 전체 패딩은 AppBar와 중복될 수 있습니다

NotificationAppBar 내부가 TopAppBar(Material3) 등으로 이미 statusBars 인셋을 처리한다면, Column에 WindowInsets.systemBars를 그대로 적용할 경우 상단 패딩이 이중 적용될 가능성이 있습니다. 하단(nav bar)만 패딩하거나, 인셋을 소비하도록 처리하는 것을 고려해 주세요.

옵션 A: 하단만 패딩

-            .windowInsetsPadding(WindowInsets.systemBars),
+            .windowInsetsPadding(
+                WindowInsets.systemBars.only(WindowInsetsSides.Bottom)
+            ),

추가 임포트:

import androidx.compose.foundation.layout.WindowInsetsSides

옵션 B: 전체 패딩 유지하되 중복 방지용 consume 처리

             .background(White)
-            .windowInsetsPadding(WindowInsets.systemBars),
+            .windowInsetsPadding(WindowInsets.systemBars)
+            .consumeWindowInsets(WindowInsets.systemBars),

추가 임포트:

import androidx.compose.foundation.layout.consumeWindowInsets

참고: 현재 구성은 상단/하단 모두 안전하게 비침을 방지하지만, AppBar가 자체적으로 statusBarsPadding을 적용하는 경우에는 A 또는 B로 조정 시 레이아웃 일관성이 좋아집니다. 실제 UI에서 상단 마진이 과도하게 벌어지지 않는지 확인 부탁드립니다.

app/src/main/java/com/into/websoso/ui/notificationDetail/NotificationDetailActivity.kt (1)

21-22: enableEdgeToEdge와 setupWhiteStatusBar를 하나로 정리하는 방안 제안

현재 순서는 기능상 문제는 없지만, enableEdgeToEdge의 매개변수(SystemBarStyle)를 사용하면 상태바/내비게이션바 스타일을 한 곳에서 일관되게 지정할 수 있어 중복 설정이나 깜빡임을 줄일 수 있습니다.

예시:

-        enableEdgeToEdge()
-        this.setupWhiteStatusBar()
+        enableEdgeToEdge(
+            statusBarStyle = SystemBarStyle.light(
+                scrim = android.graphics.Color.WHITE,
+                darkScrim = android.graphics.Color.BLACK,
+            ),
+            navigationBarStyle = SystemBarStyle.light(
+                scrim = android.graphics.Color.TRANSPARENT,
+                darkScrim = android.graphics.Color.BLACK,
+            ),
+        )

추가/수정 필요한 import:

import androidx.activity.SystemBarStyle
// (선택) setupWhiteStatusBar를 더 이상 쓰지 않는다면 해당 import 정리

주의:

  • 프로젝트의 activity 라이브러리 버전에 따라 SystemBarStyle API 시그니처가 다를 수 있습니다. 위 방식이 사용 가능한지 빌드 확인을 부탁드립니다.
  • 의도적으로 상태바를 White로 유지하려는 디자인이라면 상단 콘텐츠가 status bar 뒤로 그려지지 않도록(=현재처럼 인셋 패딩으로 회피) Compose 쪽과 일관되게 유지해 주세요.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 03e15e7 and 085fa08.

📒 Files selected for processing (3)
  • app/src/main/java/com/into/websoso/ui/notificationDetail/NotificationDetailActivity.kt (2 hunks)
  • app/src/main/java/com/into/websoso/ui/notificationDetail/NotificationDetailScreen.kt (2 hunks)
  • gradle/libs.versions.toml (1 hunks)
⏰ 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: build
  • GitHub Check: build
🔇 Additional comments (3)
gradle/libs.versions.toml (1)

3-4: 1.3.0 버전 상향 LGTM

버전 코드/이름 증분이 명확하며 릴리스 목적과 일치합니다.

app/src/main/java/com/into/websoso/ui/notificationDetail/NotificationDetailScreen.kt (1)

5-9: WindowInsets 관련 임포트 추가 적절

edge-to-edge 대응을 위한 insets API 임포트 구성이 타당합니다.

app/src/main/java/com/into/websoso/ui/notificationDetail/NotificationDetailActivity.kt (1)

9-9: edge-to-edge 활성화 임포트 LGTM

필요한 KTX 임포트가 정확합니다.

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: 6

🧹 Nitpick comments (2)
feature/signin/src/main/java/com/into/websoso/feature/signin/SignInScreen.kt (2)

119-119: 불필요한 주석 제거.

“SignInScreen의 if문 안에 넣을 코드” 주석은 잔여물로 보입니다.

-// SignInScreen의 if문 안에 넣을 코드

128-135: 디자인 시스템 색상 및 텍스트 제한 적용 권장.

하드코딩 색상/무제한 줄수는 유지보수와 접근성에 불리합니다. MaterialTheme 컬러를 사용하고, 텍스트를 적절히 줄바꿈/말줄임 처리하세요.

-                colors = CardDefaults.cardColors(
-                    containerColor = if (error.isNotEmpty()) {
-                        Color.Red.copy(alpha = 0.9f)
-                    } else {
-                        Color.Green.copy(alpha = 0.9f)
-                    },
-                ),
+                colors = CardDefaults.cardColors(
+                    containerColor = if (error.isNotEmpty())
+                        MaterialTheme.colorScheme.errorContainer
+                    else
+                        MaterialTheme.colorScheme.primaryContainer,
+                    contentColor = if (error.isNotEmpty())
+                        MaterialTheme.colorScheme.onErrorContainer
+                    else
+                        MaterialTheme.colorScheme.onPrimaryContainer,
+                ),
-                    color = Color.White,
-                    maxLines = Int.MAX_VALUE, // 모든 줄 표시
-                    overflow = TextOverflow.Visible,
+                    maxLines = 3,
+                    overflow = TextOverflow.Ellipsis,

추가 import:

+import androidx.compose.material3.MaterialTheme

Also applies to: 139-139, 146-147

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 085fa08 and a4578e1.

📒 Files selected for processing (3)
  • feature/signin/src/main/java/com/into/websoso/feature/signin/SignInScreen.kt (6 hunks)
  • feature/signin/src/main/java/com/into/websoso/feature/signin/SignInViewModel.kt (4 hunks)
  • gradle/libs.versions.toml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • gradle/libs.versions.toml
⏰ 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: build
  • GitHub Check: build
🔇 Additional comments (1)
feature/signin/src/main/java/com/into/websoso/feature/signin/SignInScreen.kt (1)

87-89: 프롭스 전달은 적절합니다.

상태 분리는 적절하나, ViewModel 변경(에러 상태 캡슐화/성공 토스트 정책) 반영 시 시그니처도 함께 조정 필요합니다.

Comment on lines 60 to 62
val isShowToast = remember { mutableStateOf(false) }
val error = signInViewModel.error.collectAsStateWithLifecycle()

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

토스트 표시 후 사라지지 않습니다(자동 해제 로직 누락).

isShowToast를 true로만 설정하고 false로 되돌리는 코드가 없어 토스트가 영구 고정됩니다. 일정 시간 뒤 자동으로 숨기세요.

     val pagerState = rememberPagerState { Onboarding_Images.size }
     val isShowToast = remember { mutableStateOf(false) }
     val error = signInViewModel.error.collectAsStateWithLifecycle()
+    LaunchedEffect(isShowToast.value) {
+        if (isShowToast.value) {
+            delay(2000)
+            isShowToast.value = false
+        }
+    }

추가 import:

+import androidx.compose.runtime.LaunchedEffect
+import kotlinx.coroutines.delay
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
val isShowToast = remember { mutableStateOf(false) }
val error = signInViewModel.error.collectAsStateWithLifecycle()
// At the top of the file, add the necessary imports
import androidx.compose.runtime.LaunchedEffect
import kotlinx.coroutines.delay
// … other imports …
@Composable
fun SignInScreen(
/* params */
) {
// … earlier code …
val pagerState = rememberPagerState { Onboarding_Images.size }
val isShowToast = remember { mutableStateOf(false) }
val error = signInViewModel.error.collectAsStateWithLifecycle()
// Automatically hide the toast 2 seconds after it's shown
LaunchedEffect(isShowToast.value) {
if (isShowToast.value) {
delay(2000)
isShowToast.value = false
}
}
// … rest of the UI, including where you show the toast when isShowToast.value is true …
}
🤖 Prompt for AI Agents
In feature/signin/src/main/java/com/into/websoso/feature/signin/SignInScreen.kt
around lines 60 to 62, isShowToast is set true but never reset so the toast
never disappears; add an automatic hide by launching a coroutine effect that
observes isShowToast.value and when it becomes true calls delay( e.g. 2000L )
then sets isShowToast.value = false. Use LaunchedEffect(key1 =
isShowToast.value) to scope the timer and add the required imports
(kotlinx.coroutines.delay and androidx.compose.runtime.LaunchedEffect).

)

val uiEffect: Flow<UiEffect> = merge(autoScrollEventFlow, _uiEffect.receiveAsFlow())
val error = MutableStateFlow("")
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

MutableStateFlow를 외부에 그대로 노출하지 말고 불변 StateFlow로 캡슐화하세요.

외부에서 ViewModel의 상태를 수정할 수 있어 안전하지 않습니다. 비공개 MutableStateFlow + 공개 StateFlow로 교체 권장.

-        val error = MutableStateFlow("")
+        private val _error = MutableStateFlow("")
+        val error: StateFlow<String> = _error.asStateFlow()

추가 import:

+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
val error = MutableStateFlow("")
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
private val _error = MutableStateFlow("")
val error: StateFlow<String> = _error.asStateFlow()
🤖 Prompt for AI Agents
In
feature/signin/src/main/java/com/into/websoso/feature/signin/SignInViewModel.kt
around line 38, the MutableStateFlow named error is being exposed directly;
change it to a private MutableStateFlow (e.g., private val _error =
MutableStateFlow("")) and expose a public immutable StateFlow (e.g., val error:
StateFlow<String> = _error); update any internal writes to use _error.value =
... and external reads to use error; also add the import
kotlinx.coroutines.flow.StateFlow.

Comment on lines 53 to 56
error.update {
it.toString()
}
signInWithFailure()
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

예외를 그대로 사용자에게 보여주지 말고 유저 친화적 메시지로 매핑하세요.

Throwable.toString()은 내부 구현/스택 정보를 노출할 수 있어 보안/UX에 모두 부적절합니다.

-                    error.update {
-                        it.toString()
-                    }
+                    _error.update {
+                        it.localizedMessage ?: "로그인에 실패했습니다. 잠시 후 다시 시도해주세요."
+                    }

동일 패턴을 하단 실패 경로에도 적용:

-                        error.update {
-                            it.toString()
-                        }
+                        _error.update {
+                            it.localizedMessage ?: "회원 생성에 실패했습니다. 잠시 후 다시 시도해주세요."
+                        }

Also applies to: 79-83

🤖 Prompt for AI Agents
In
feature/signin/src/main/java/com/into/websoso/feature/signin/SignInViewModel.kt
around lines 53-56 (and similarly lines 79-83), the code sets error.update {
it.toString() } which exposes raw Throwable details to the user; instead map
throwable to a user-friendly, non-sensitive message. Replace the direct
toString() usage by mapping the Throwable (or error state) to a
localized/templated message (e.g., network error, invalid credentials,
unexpected error) via a helper function or when-expression, update the error
state with that message, and then call signInWithFailure(); apply the same
mapping for the failure path at lines 79-83.

Comment on lines 71 to 73
error.update {
it.toString()
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

성공 경로에서 임의 객체를 에러 스트링에 기록하지 마세요.

성공 시 it.toString()을 기록하면 UI가 “에러 있음”으로 오인(빨간색 토스트)합니다.

-                        error.update {
-                            it.toString()
-                        }
+                        _error.update { "" } // 성공이면 에러 메시지 비움
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
error.update {
it.toString()
}
_error.update { "" } // 성공이면 에러 메시지 비움
🤖 Prompt for AI Agents
In
feature/signin/src/main/java/com/into/websoso/feature/signin/SignInViewModel.kt
around lines 71 to 73, the success path is incorrectly writing a non-error
object via error.update { it.toString() } which causes the UI to show an error;
remove or change this so the success path clears the error state (e.g., set to
null or empty) instead of writing a toString(), and only call error.update with
actual error messages in failure branches.

Comment on lines 71 to 77
error.update {
it.toString()
}
when (accountRepository.isRegisterUser) {
true -> _uiEffect.send(UiEffect.NavigateToHome)
false -> _uiEffect.send(UiEffect.NavigateToOnboarding)
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

성공 토스트 노출 의도 확인 필요(현재 로직으론 성공 시 토스트가 뜨지 않습니다).

UI는 ShowToast 효과를 받아야 토스트가 보입니다. 성공 경로에서 해당 효과를 보내지 않으므로, “성공(초록)” 토스트는 절대 나타나지 않습니다. 성공에도 토스트가 필요하면 아래처럼 ShowToast를 전송하고, 필요 없다면 UI에서 성공 분기를 제거하세요.

                     when (accountRepository.isRegisterUser) {
                         true -> _uiEffect.send(UiEffect.NavigateToHome)
                         false -> _uiEffect.send(UiEffect.NavigateToOnboarding)
                     }
+                    // 성공 토스트가 필요하다면:
+                    // _uiEffect.send(UiEffect.ShowToast)

ShowToast 효과 적용 여부를 확인하기 위해 아래 스크립트를 실행합니다.


🏁 Script executed:

#!/bin/bash
# SignInViewModel.kt에서 ShowToast 호출 여부 검색
grep -R "ShowToast" -n feature/signin/src/main/java/com/into/websoso/feature/signin/SignInViewModel.kt || true

# 전체 코드베이스에서 UiEffect.ShowToast 사용 검색
grep -R "UiEffect\\.ShowToast" -n . || true

# SignInViewModel.kt 상단 200줄 출력
sed -n '1,200p' feature/signin/src/main/java/com/into/websoso/feature/signin/SignInViewModel.kt || true

Length of output: 4361


성공 시 ShowToast 효과 전송 로직 추가 필요
현재 성공 분기(홈 또는 온보딩 네비게이션) 이후에 _uiEffect.send(UiEffect.ShowToast) 호출이 없어 성공 토스트가 표시되지 않습니다. 성공 토스트가 필요하면 아래처럼 추가하고, 필요 없다면 UI의 성공 분기를 제거하세요.

                     when (accountRepository.isRegisterUser) {
                         true -> _uiEffect.send(UiEffect.NavigateToHome)
                         false -> _uiEffect.send(UiEffect.NavigateToOnboarding)
                     }
+                    // 성공 토스트가 필요하다면:
+                    // _uiEffect.send(UiEffect.ShowToast)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
error.update {
it.toString()
}
when (accountRepository.isRegisterUser) {
true -> _uiEffect.send(UiEffect.NavigateToHome)
false -> _uiEffect.send(UiEffect.NavigateToOnboarding)
}
error.update {
it.toString()
}
when (accountRepository.isRegisterUser) {
true -> _uiEffect.send(UiEffect.NavigateToHome)
false -> _uiEffect.send(UiEffect.NavigateToOnboarding)
}
// 성공 토스트가 필요하다면:
// _uiEffect.send(UiEffect.ShowToast)
🤖 Prompt for AI Agents
In
feature/signin/src/main/java/com/into/websoso/feature/signin/SignInViewModel.kt
around lines 71 to 77, the success branch sends navigation UiEffects but does
not emit a success ShowToast, so users won't see a success toast; either emit a
success toast after navigation by calling
_uiEffect.send(UiEffect.ShowToast("Sign in successful")) (or the
localized/specified message) in both true and false branches, or if a toast is
not desired remove the success toast handling from the UI and keep only
navigation; ensure the _uiEffect.send call is performed from the same coroutine
context and handle exceptions from send if necessary.

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: 8

🧹 Nitpick comments (4)
feature/signin/consumer-rules.pro (1)

24-31: 중복 규칙 정리 필요

이미 -keep class/interface com.kakao.sdk.**로 SDK 전반을 보존하므로, 하위 패키지(auth/user/common) 개별 keep는 중복입니다. 유지보수성을 위해 제거 권고합니다.

 -keep class com.kakao.sdk.** { *; }
 -keep interface com.kakao.sdk.** { *; }
 -dontwarn com.kakao.sdk.**
 
-# 카카오 로그인 관련 클래스 보호
--keep class com.kakao.sdk.auth.** { *; }
--keep class com.kakao.sdk.user.** { *; }
--keep class com.kakao.sdk.common.** { *; }
app/proguard-rules.pro (1)

54-59: Gson 보존 규칙도 과도함 — 라이브러리 전체 keep 삭제

Gson 라이브러리 전체를 keep할 필요는 없습니다. 현재 TypeAdapterFactory/Serializer/Deserializer 구현 보존 규칙이면 충분합니다.

-# JSON 직렬화 관련
--keep class com.google.gson.** { *; }
 -keep class * implements com.google.gson.TypeAdapterFactory
 -keep class * implements com.google.gson.JsonSerializer
 -keep class * implements com.google.gson.JsonDeserializer
core/auth-kakao/consumer-rules.pro (1)

24-31: 중복 규칙 정리

com.kakao.sdk.** 전체 보존이 이미 있으므로, 하위 패키지(auth/user/common) 개별 keep는 중복입니다.

 -keep class com.kakao.sdk.** { *; }
 -keep interface com.kakao.sdk.** { *; }
 -dontwarn com.kakao.sdk.**
 
-# 카카오 로그인 관련 클래스 보호
--keep class com.kakao.sdk.auth.** { *; }
--keep class com.kakao.sdk.user.** { *; }
--keep class com.kakao.sdk.common.** { *; }
core/auth-kakao/build.gradle.kts (1)

14-14: consumer-rules 범위 과대 여부 점검

Retrofit/OkHttp/Kakao SDK에 대한 keep/dontwarn가 광범위하면 소비 앱의 축소 효과를 해칠 수 있습니다. 반드시 필요한 엔트리 포인트만 명시적으로 keep하고, dontwarn는 구체 패키지/클래스 한정으로 축소해 주세요.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a4578e1 and f20fd66.

📒 Files selected for processing (9)
  • app/proguard-rules.pro (1 hunks)
  • core/auth-kakao/build.gradle.kts (1 hunks)
  • core/auth-kakao/consumer-rules.pro (1 hunks)
  • core/auth-kakao/proguard-rules.pro (0 hunks)
  • core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt (1 hunks)
  • feature/signin/build.gradle.kts (1 hunks)
  • feature/signin/consumer-rules.pro (1 hunks)
  • feature/signin/proguard-rules.pro (0 hunks)
  • feature/signin/src/main/java/com/into/websoso/feature/signin/SignInScreen.kt (1 hunks)
💤 Files with no reviewable changes (2)
  • feature/signin/proguard-rules.pro
  • core/auth-kakao/proguard-rules.pro
🚧 Files skipped from review as they are similar to previous changes (1)
  • feature/signin/src/main/java/com/into/websoso/feature/signin/SignInScreen.kt
⏰ 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: build
  • GitHub Check: build
🔇 Additional comments (3)
feature/signin/build.gradle.kts (1)

10-16: Scripts 실행 준비 완료. 결과를 기다립니다.

core/auth-kakao/build.gradle.kts (2)

10-16: 확인 완료: consumer-rules.pro 파일 존재 및 참조 검증
core/auth-kakao/consumer-rules.pro 파일이 정상적으로 존재하며, 빌드에 영향 줄 과도한 -keep/-dontwarn 규칙도 없습니다. 추가 조치 불필요합니다.


10-16: websoso.android.library 플러그인에 buildTypes 정의가 없어 충돌 우려가 없습니다.

Likely an incorrect or invalid review comment.

Comment on lines +28 to +42
# 카카오 SDK 관련 난독화 방지
-keep class com.kakao.** { *; }
-keep interface com.kakao.** { *; }
-dontwarn com.kakao.**

# 카카오 로그인 SDK
-keep class com.kakao.sdk.** { *; }
-keep interface com.kakao.sdk.** { *; }
-dontwarn com.kakao.sdk.**

# 카카오 인증 관련
-keep class com.kakao.sdk.auth.** { *; }
-keep class com.kakao.sdk.user.** { *; }
-keep class com.kakao.sdk.common.** { *; }

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Kakao 보존 규칙 범위 축소 및 중복 제거 권장

com.kakao.**com.kakao.sdk.**를 동시에 보존하는 것은 과도·중복입니다. SDK 하위만 보존하거나, 실제 사용 패키지로 한정하세요. 전역 -dontwarn com.kakao.**도 신중히 사용(디버깅 정보 손실).

-# 카카오 SDK 관련 난독화 방지
--keep class com.kakao.** { *; }
--keep interface com.kakao.** { *; }
--dontwarn com.kakao.**
-
-# 카카오 로그인 SDK
 -keep class com.kakao.sdk.** { *; }
 -keep interface com.kakao.sdk.** { *; }
 -dontwarn com.kakao.sdk.**
 
 # 카카오 인증 관련
 -keep class com.kakao.sdk.auth.** { *; }
 -keep class com.kakao.sdk.user.** { *; }
 -keep class com.kakao.sdk.common.** { *; }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +48 to +53
# Retrofit/OkHttp
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-dontwarn retrofit2.**
-dontwarn okhttp3.**

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Retrofit/OkHttp 전체 보존·dontwarn 제거

라이브러리 전체 keep은 불필요하며 바이너리 팽창을 유발합니다. 어노테이션·시그니처 보존으로 대체하고, 필요한 경우에만 서비스 인터페이스 패키지 단위 keep를 추가하세요.

-# Retrofit/OkHttp
--keep class retrofit2.** { *; }
--keep class okhttp3.** { *; }
--dontwarn retrofit2.**
--dontwarn okhttp3.**

파일 상단에 다음 추가(이미 없다면):

-keepattributes Signature
-keepattributes RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations
-keepattributes AnnotationDefault
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Retrofit/OkHttp
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-dontwarn retrofit2.**
-dontwarn okhttp3.**
🤖 Prompt for AI Agents
app/proguard-rules.pro around lines 48-53: 현재 retrofit2./okhttp3. 전체를 keep하고
dontwarn를 사용하는 것은 불필요하니, 전체 클래스 보존은 제거하고 대신 어노테이션·시그니처를 보존하도록 프로가드 규칙을 변경하세요; 파일
상단에 keepattributes Signature 및 RuntimeVisible/InvisibleAnnotations,
RuntimeVisible/InvisibleParameterAnnotations, AnnotationDefault 항목이 없는 경우 추가하고,
retrofit/okhttp 관련 dontwarn 규칙은 제거하며 필요한 경우에 한해 서비스 인터페이스(예: your.api.package.*)
수준에서 인터페이스만 keep하도록 제한하세요.

Comment on lines +10 to +16
buildTypes {
release {
isMinifyEnabled = false

consumerProguardFiles("consumer-rules.pro")
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

release에서 minify 비활성화 — 라이브러리 AAR 축소/난독화 미적용 위험

라이브러리 모듈이라도 release 시 R8 축소/난독화를 켜는 편이 크기·심볼 노출 측면에서 유리합니다. consumer-rules.pro로 보존 규칙을 전달하면서 모듈 자체는 축소하도록 전환을 권장합니다.

 release {
-    isMinifyEnabled = false
-
-    consumerProguardFiles("consumer-rules.pro")
+    isMinifyEnabled = true
+    proguardFiles(
+        getDefaultProguardFile("proguard-android-optimize.txt"),
+        "proguard-rules.pro"
+    )
+    consumerProguardFiles("consumer-rules.pro")
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
buildTypes {
release {
isMinifyEnabled = false
consumerProguardFiles("consumer-rules.pro")
}
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
consumerProguardFiles("consumer-rules.pro")
}
}
🤖 Prompt for AI Agents
In core/auth-kakao/build.gradle.kts around lines 10–16, the release build
currently has minify disabled which leaves the library AAR unshrunk/obfuscated;
enable R8 by setting isMinifyEnabled to true for the release build, keep the
consumerProguardFiles("consumer-rules.pro") entry, and add the module
proguard/proguard-android-optimize default proguard file (via proguardFiles with
the default optimize file and a module proguard-rules file) so the module is
shrunk/optimized while preserving consumer rules; then rebuild and verify
mappings and resulting AAR.

Comment on lines +24 to +37
-keep class com.kakao.sdk.** { *; }
-keep interface com.kakao.sdk.** { *; }
-dontwarn com.kakao.sdk.**

# 카카오 로그인 관련 클래스 보호
-keep class com.kakao.sdk.auth.** { *; }
-keep class com.kakao.sdk.user.** { *; }
-keep class com.kakao.sdk.common.** { *; }

# 네트워크 관련 (카카오 SDK 의존성)
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-dontwarn retrofit2.**
-dontwarn okhttp3.**
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Retrofit/OkHttp 전체 보존 제거 및 keepattributes로 대체

라이브러리 전체 keep/dontwarn은 릴리스 최적화 품질을 떨어뜨립니다.

-# 네트워크 관련 (카카오 SDK 의존성)
--keep class retrofit2.** { *; }
--keep class okhttp3.** { *; }
--dontwarn retrofit2.**
--dontwarn okhttp3.**

추가(파일 상단):

-keepattributes Signature
-keepattributes RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations
-keepattributes AnnotationDefault

Comment on lines 36 to 53
client.loginWithKakaoTalk(context) { token, error ->
if (error != null) {
if (error is ClientError && error.reason == ClientErrorCause.Cancelled) {
loginContinuation.resumeWithException(error)
when {
error != null -> {
when {
error is ClientError && error.reason == ClientErrorCause.Cancelled -> {
loginWithKakaoAccount(loginContinuation)
}

else -> loginWithKakaoAccount(loginContinuation)
}
}

loginWithKakaoAccount(loginContinuation)
} else if (token != null) {
loginContinuation.resume(token.accessToken.toAuthToken())
token != null -> {
loginContinuation.resume(token.accessToken.toAuthToken())
}

else -> loginWithKakaoAccount(loginContinuation)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

카카오톡 로그인 취소(Cancelled) 시 계정 로그인으로 강제 폴백은 UX상 부적절 — 취소는 그대로 전달해야 합니다

사용자 취소를 계정 로그인으로 전환하면 의도치 않은 추가 UI가 뜹니다. Cancelled는 예외로 전파하고, 그 외 오류에만 폴백하세요. 또한 콜백 재진입/취소 후 재개 방지를 위해 isActive 가드가 필요합니다.

 client.loginWithKakaoTalk(context) { token, error ->
-    when {
-        error != null -> {
-            when {
-                error is ClientError && error.reason == ClientErrorCause.Cancelled -> {
-                    loginWithKakaoAccount(loginContinuation)
-                }
-                else -> loginWithKakaoAccount(loginContinuation)
-            }
-        }
-        token != null -> {
-            loginContinuation.resume(token.accessToken.toAuthToken())
-        }
-        else -> loginWithKakaoAccount(loginContinuation)
-    }
+    if (!loginContinuation.isActive) return@loginWithKakaoTalk
+    when {
+        token != null -> loginContinuation.resume(token.accessToken.toAuthToken())
+        error is ClientError && error.reason == ClientErrorCause.Cancelled ->
+            loginContinuation.resumeWithException(error) // 사용자 취소 그대로 전달
+        error != null -> loginWithKakaoAccount(loginContinuation) // 기타 오류만 폴백
+        else -> loginWithKakaoAccount(loginContinuation)
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
client.loginWithKakaoTalk(context) { token, error ->
if (error != null) {
if (error is ClientError && error.reason == ClientErrorCause.Cancelled) {
loginContinuation.resumeWithException(error)
when {
error != null -> {
when {
error is ClientError && error.reason == ClientErrorCause.Cancelled -> {
loginWithKakaoAccount(loginContinuation)
}
else -> loginWithKakaoAccount(loginContinuation)
}
}
loginWithKakaoAccount(loginContinuation)
} else if (token != null) {
loginContinuation.resume(token.accessToken.toAuthToken())
token != null -> {
loginContinuation.resume(token.accessToken.toAuthToken())
}
else -> loginWithKakaoAccount(loginContinuation)
}
client.loginWithKakaoTalk(context) { token, error ->
// prevent re-entry or resuming after cancellation
if (!loginContinuation.isActive) return@loginWithKakaoTalk
when {
// successful token → resume normally
token != null ->
loginContinuation.resume(token.accessToken.toAuthToken())
// user-cancelled → propagate as exception
error is ClientError && error.reason == ClientErrorCause.Cancelled ->
loginContinuation.resumeWithException(error)
// other errors → fallback to account login
error != null ->
loginWithKakaoAccount(loginContinuation)
// no token and no error → also fallback
else ->
loginWithKakaoAccount(loginContinuation)
}
}
🤖 Prompt for AI Agents
In
core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt
around lines 36 to 53, the current logic force-falls back to account login when
the KakaoTalk login error is ClientErrorCause.Cancelled; change it to propagate
the Cancelled error to the loginContinuation instead of switching to account
login, and only fall back to account login for non-cancel errors. Also add an
isActive check on the continuation before resuming or resumingWithException to
prevent callback re-entry or resumption after cancellation. Ensure all
resume/resumeWithException calls are guarded by continuation.isActive and that
the Cancelled branch calls loginContinuation.resumeWithException(error) (or
equivalent) rather than calling loginWithKakaoAccount.

Comment on lines 58 to 73
client.loginWithKakaoAccount(context) { token, error ->
if (error != null) {
loginContinuation.resumeWithException(error)
} else if (token != null) {
loginContinuation.resume(token.accessToken.toAuthToken())
when {
error != null -> {
loginContinuation.resumeWithException(error)
}

token != null -> {
loginContinuation.resume(token.accessToken.toAuthToken())
}

else -> {
loginContinuation.resumeWithException(
IllegalStateException("Both token and error are null"),
)
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

콜백 재개 시점 경합 대비: 취소 후 재개를 방지하세요

loginWithKakaoAccount 콜백에서도 isActive 체크 없이 resume/resumeWithException을 호출하고 있습니다. 취소 뒤 재개로 인한 IllegalStateException을 방지하세요.

 client.loginWithKakaoAccount(context) { token, error ->
-    when {
-        error != null -> {
-            loginContinuation.resumeWithException(error)
-        }
-        token != null -> {
-            loginContinuation.resume(token.accessToken.toAuthToken())
-        }
-        else -> {
-            loginContinuation.resumeWithException(
-                IllegalStateException("Both token and error are null"),
-            )
-        }
-    }
+    if (!loginContinuation.isActive) return@loginWithKakaoAccount
+    when {
+        token != null -> loginContinuation.resume(token.accessToken.toAuthToken())
+        error != null -> loginContinuation.resumeWithException(error)
+        else -> loginContinuation.resumeWithException(
+            IllegalStateException("Both token and error are null"),
+        )
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
client.loginWithKakaoAccount(context) { token, error ->
if (error != null) {
loginContinuation.resumeWithException(error)
} else if (token != null) {
loginContinuation.resume(token.accessToken.toAuthToken())
when {
error != null -> {
loginContinuation.resumeWithException(error)
}
token != null -> {
loginContinuation.resume(token.accessToken.toAuthToken())
}
else -> {
loginContinuation.resumeWithException(
IllegalStateException("Both token and error are null"),
)
}
}
client.loginWithKakaoAccount(context) { token, error ->
if (!loginContinuation.isActive) return@loginWithKakaoAccount
when {
token != null -> loginContinuation.resume(token.accessToken.toAuthToken())
error != null -> loginContinuation.resumeWithException(error)
else -> loginContinuation.resumeWithException(
IllegalStateException("Both token and error are null"),
)
}
}
🤖 Prompt for AI Agents
In
core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt
around lines 58 to 73, the callback passed to client.loginWithKakaoAccount
resumes the continuation without checking whether it is still active, which can
cause IllegalStateException if the operation was cancelled; update the callback
to guard all resume/resumeWithException calls with a check that the continuation
is still active (e.g., if (loginContinuation.isActive) { ... }) and only call
resume or resumeWithException when active, otherwise ignore/clean up to avoid
resuming a cancelled continuation.

Comment on lines +23 to +37
# consumer-rules.pro (feature.signin 모듈)
-keep class com.kakao.sdk.** { *; }
-keep interface com.kakao.sdk.** { *; }
-dontwarn com.kakao.sdk.**

# 카카오 로그인 관련 클래스 보호
-keep class com.kakao.sdk.auth.** { *; }
-keep class com.kakao.sdk.user.** { *; }
-keep class com.kakao.sdk.common.** { *; }

# 네트워크 관련 (카카오 SDK 의존성)
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-dontwarn retrofit2.**
-dontwarn okhttp3.**
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

룰의 소유 모듈을 단일화하세요(중복·드리프트 방지)

이 모듈(feature/signin)이 Kakao SDK를 직접 참조하지 않는다면, Kakao 관련 consumer-rules는 core/auth-kakao 모듈 한 곳에서만 관리하는 것이 적합합니다(해당 모듈이 이 SDK를 노출/소비하므로).

다음 스크립트로 실제 참조 여부와 중복 위치를 확인해 주세요:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Kakao SDK 직접 참조 파일 확인
rg -n --type=kt -S 'com\.kakao\.sdk\.' -g '!**/build/**'

# 2) consumerProguardFiles 참조 위치 확인
rg -n 'consumerProguardFiles\("consumer-rules\.pro"\)' -C2

# 3) feature/signin 모듈에서 Kakao 의존이 없는 경우, 본 파일의 Kakao 규칙 제거 검토

Length of output: 105


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) feature/signin 모듈 내 Kotlin/Java 파일에서 Kakao SDK import 검색
rg -n 'com\.kakao\.sdk\.' -g 'feature/signin/**/*.{kt,java}' || echo "feature/signin에서 SDK 참조 없음"

# 2) feature/signin 모듈의 Gradle 스크립트에서 Kakao SDK 의존성 검색
rg -n 'implementation.*com\.kakao\.sdk' -g 'feature/signin/**/*.gradle' || echo "feature/signin build 스크립트에 의존성 없음"

# 3) 전체 모듈에서 consumerProguardFiles("consumer-rules.pro") 사용 위치 확인
rg -n 'consumerProguardFiles.*consumer-rules\.pro' -C2

Length of output: 1078


feature/signin 모듈에서 Kakao SDK ProGuard 룰 제거
feature/signin 모듈은 com.kakao.sdk 의존이 없으므로 build.gradle.kts 14행의 consumerProguardFiles("consumer-rules.pro") 호출과 feature/signin/consumer-rules.pro 파일을 삭제하고, Kakao 룰은 core/auth-kakao 모듈에서만 관리하세요.

Comment on lines +33 to +37
# 네트워크 관련 (카카오 SDK 의존성)
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-dontwarn retrofit2.**
-dontwarn okhttp3.**
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Retrofit/OkHttp 전체 보존과 전역 dontwarn은 과도합니다. 용량 증가·최적화 저해 우려

라이브러리 전체를 keep/dontwarn 하는 대신, 실제 리플렉션 기반 호출 보존은 keepattributes(+ 서비스 인터페이스 한정 keep)로 해결하는 편이 안전합니다.

적용 예(해당 블록 제거):

-# 네트워크 관련 (카카오 SDK 의존성)
--keep class retrofit2.** { *; }
--keep class okhttp3.** { *; }
--dontwarn retrofit2.**
--dontwarn okhttp3.**

그리고 파일 상단(주석 블록 아래)에 다음 속성 보존을 추가해 주세요:

-keepattributes Signature
-keepattributes RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations
-keepattributes AnnotationDefault
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# 네트워크 관련 (카카오 SDK 의존성)
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-dontwarn retrofit2.**
-dontwarn okhttp3.**
// (Lines 3337—the entire “# 네트워크 관련 (카카오 SDK 의존성)” block—have been removed as per review)
🤖 Prompt for AI Agents
In feature/signin/consumer-rules.pro around lines 33 to 37, the proguard rules
currently keep entire retrofit2/okhttp3 packages and suppress all warnings which
is excessive; remove that block (delete the four lines keeping and dontwarn-ing
retrofit2/okhttp3) and instead add attribute-preservation rules at the top of
the file (below the existing comment block) to preserve reflection/annotation
metadata: include keepattributes for Signature, RuntimeVisibleAnnotations,
RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations,
RuntimeInvisibleParameterAnnotations, and AnnotationDefault, and restrict any
keep rules to only the specific service interfaces that require runtime
reflection rather than entire packages.

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

♻️ Duplicate comments (5)
core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt (3)

40-45: [중요] 사용자가 ‘취소’한 경우 계정 로그인으로 폴백하지 말고 예외를 그대로 전파하세요

ClientErrorCause.Cancelled는 명시적 사용자 의사입니다. 현재는 취소 시에도 loginWithKakaoAccount로 강제 폴백하고 있어 UX/정합성 문제입니다. 취소는 resumeWithException(error)로 전달하고, 그 외 오류만 계정 로그인으로 폴백하세요.

적용 diff:

-                            error is ClientError && error.reason == ClientErrorCause.Cancelled -> {
-                                loginWithKakaoAccount(loginContinuation)
-                            }
+                            error is ClientError && error.reason == ClientErrorCause.Cancelled ->
+                                loginContinuation.resumeWithException(error)

56-67: 계정 로그인 콜백도 isActive 가드 필요

loginWithKakaoAccount 콜백 역시 취소 이후 재개 위험이 있습니다. 모든 resume* 호출 전 isActive를 확인하세요.

적용 diff:

 client.loginWithKakaoAccount(context) { token, error ->
-                when {
-                    error != null -> loginContinuation.resumeWithException(error)
-
-                    token != null -> loginContinuation.resume(token.accessToken.toAuthToken())
-
-                    else -> {
-                        loginContinuation.resumeWithException(
-                            IllegalStateException("Both token and error are null"),
-                        )
-                    }
-                }
+                if (!loginContinuation.isActive) return@loginWithKakaoAccount
+                when {
+                    token != null ->
+                        if (loginContinuation.isActive)
+                            loginContinuation.resume(token.accessToken.toAuthToken())
+                    error != null ->
+                        if (loginContinuation.isActive)
+                            loginContinuation.resumeWithException(error)
+                    else ->
+                        if (loginContinuation.isActive)
+                            loginContinuation.resumeWithException(
+                                IllegalStateException("Both token and error are null"),
+                            )
+                }
             }

37-51: 콜백 재진입/취소 이후 재개 방지: isActive 가드 누락

resume/resumeWithException 호출 전 loginContinuation.isActive 검사가 없습니다. 취소 후 재개 시 IllegalStateException이 발생할 수 있습니다. 콜백 초입에서 빠른 반환 가드와 분기 내 호출 전 가드를 추가하세요.

권장 diff(취소 전파와 함께 정리):

 client.loginWithKakaoTalk(context) { token, error ->
-                when {
-                    error != null -> {
-                        when {
-                            error is ClientError && error.reason == ClientErrorCause.Cancelled -> {
-                                loginWithKakaoAccount(loginContinuation)
-                            }
-
-                            else -> loginWithKakaoAccount(loginContinuation)
-                        }
-                    }
-
-                    token != null -> loginContinuation.resume(token.accessToken.toAuthToken())
-
-                    else -> loginWithKakaoAccount(loginContinuation)
-                }
+                if (!loginContinuation.isActive) return@loginWithKakaoTalk
+                when {
+                    token != null ->
+                        if (loginContinuation.isActive)
+                            loginContinuation.resume(token.accessToken.toAuthToken())
+                    error is ClientError && error.reason == ClientErrorCause.Cancelled ->
+                        if (loginContinuation.isActive)
+                            loginContinuation.resumeWithException(error)
+                    error != null -> loginWithKakaoAccount(loginContinuation)
+                    else -> loginWithKakaoAccount(loginContinuation)
+                }
             }
app/proguard-rules.pro (2)

28-36: Kakao 보존 범위 과도/중복: com.kakao.** 전역 keep/dontwarn 제거 권장

SDK 외 영역까지 전역 보존/경고 억제는 난독화 효과를 크게 저하시킵니다. com.kakao.**는 제거하고, 필요 시 com.kakao.sdk.**만 최소화하여 유지하세요. 또한 dontwarn은 실제 이슈가 있을 때 국소적으로만 사용하세요.

적용 diff:

-# 카카오 SDK 관련 난독화 방지
--keep class com.kakao.** { *; }
--keep interface com.kakao.** { *; }
--dontwarn com.kakao.**
+# Kakao SDK (최소 범위 유지; 라이브러리 consumer-rules에 위임 권장)

48-53: Retrofit/OkHttp 전체 keep/dontwarn 제거 및 -keepattributes로 대체

라이브러리 전체 보존은 바이너리 팽창과 최적화 저해로 이어집니다. 보존 속성을 추가하고, 서비스 인터페이스 등 필요한 지점만 국소적으로 keep하세요.

적용 diff:

-# Retrofit/OkHttp
--keep class retrofit2.** { *; }
--keep class okhttp3.** { *; }
--dontwarn retrofit2.**
--dontwarn okhttp3.**

상단(파일 초반부)에 다음 속성 보존 추가를 권장합니다:

+# Retrofit/Gson 반영을 위한 보존 속성
+-keepattributes Signature
+-keepattributes RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations
+-keepattributes RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations
+-keepattributes AnnotationDefault
🧹 Nitpick comments (3)
core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt (2)

26-33: 취소 시 정리 동작(optional): invokeOnCancellation으로 콜백 무시/정리 명시

Kakao SDK 호출을 직접 취소할 수 없더라도, invokeOnCancellation에서 로깅/상태 정리를 추가하면 의도 명확성과 디버깅 편의가 올라갑니다.

예시:

override suspend fun signIn(): AuthToken =
    suspendCancellableCoroutine { cont ->
        cont.invokeOnCancellation {
            // TODO: 로그/상태 정리. Kakao SDK API는 취소 미지원이므로 콜백에서 isActive 가드로 무시.
        }
        if (isKakaoTalkLoginAvailable) {
            loginWithKakaoTalk(cont)
        } else {
            loginWithKakaoAccount(cont)
        }
    }

29-36: 타이포/일관성: loginWithKakaotalkloginWithKakaoTalk로 정정

메서드/호출부의 표기 일관성을 맞춰 가독성을 높이세요.

적용 diff:

-                    loginWithKakaotalk(loginContinuation)
+                    loginWithKakaoTalk(loginContinuation)
...
-        private fun loginWithKakaotalk(loginContinuation: CancellableContinuation<AuthToken>) {
+        private fun loginWithKakaoTalk(loginContinuation: CancellableContinuation<AuthToken>) {
app/proguard-rules.pro (1)

66-66: BuildConfig 전역 keep 불필요

BuildConfig는 난독화되어도 일반적으로 문제 없습니다. 필요 근거 없으면 제거하세요.

적용 diff:

--keep class *.BuildConfig { *; }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f20fd66 and 9f0da1f.

📒 Files selected for processing (2)
  • app/proguard-rules.pro (1 hunks)
  • core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt (1 hunks)
⏰ 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: build
  • GitHub Check: build
🔇 Additional comments (2)
core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt (1)

17-23: 스코프 확인 완료: KakaoAuthClientModule에서 @ActivityScoped으로 바인딩되어 있습니다
이로써 @ActivityContext 주입 시 메모리 누수 위험이 없습니다.

app/proguard-rules.pro (1)

23-27: 중복 미발견: 앱 레벨 규칙 유지 필요
consumer-rules.pro 파일들에서 org.bouncycastle.jsse, org.conscrypt, org.openjsse 관련 dontwarn 규칙이 없으므로, 해당 규칙은 app/proguard-rules.pro에 유지해야 합니다.

Likely an incorrect or invalid review comment.

Comment on lines +33 to +42
# 카카오 로그인 SDK
-keep class com.kakao.sdk.** { *; }
-keep interface com.kakao.sdk.** { *; }
-dontwarn com.kakao.sdk.**

# 카카오 인증 관련
-keep class com.kakao.sdk.auth.** { *; }
-keep class com.kakao.sdk.user.** { *; }
-keep class com.kakao.sdk.common.** { *; }

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

중복 규칙 정리: com.kakao.sdk.** 와 하위(auth/user/common) 중복

상위 com.kakao.sdk.**와 하위 패키지 keep가 중복입니다. 하나로 통일하거나, 실제 필요한 서브패키지만 명시하세요. dontwarn도 불필요하면 제거하세요.

적용 diff(상위만 유지):

-# 카카오 로그인 SDK
--keep class com.kakao.sdk.** { *; }
--keep interface com.kakao.sdk.** { *; }
--dontwarn com.kakao.sdk.**
-
-# 카카오 인증 관련
--keep class com.kakao.sdk.auth.** { *; }
--keep class com.kakao.sdk.user.** { *; }
--keep class com.kakao.sdk.common.** { *; }
+# Kakao SDK
+-keep class com.kakao.sdk.** { *; }
+-keep interface com.kakao.sdk.** { *; }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# 카카오 로그인 SDK
-keep class com.kakao.sdk.** { *; }
-keep interface com.kakao.sdk.** { *; }
-dontwarn com.kakao.sdk.**
# 카카오 인증 관련
-keep class com.kakao.sdk.auth.** { *; }
-keep class com.kakao.sdk.user.** { *; }
-keep class com.kakao.sdk.common.** { *; }
# Kakao SDK
-keep class com.kakao.sdk.** { *; }
-keep interface com.kakao.sdk.** { *; }
🤖 Prompt for AI Agents
In app/proguard-rules.pro around lines 33 to 42, the proguard rules are
duplicated: you keep both the top-level rule "-keep class com.kakao.sdk.** { *;
}" (and interface) and the same subpackage rules for auth/user/common and an
unnecessary "dontwarn"; remove the redundant subpackage keep rules and the
dontwarn if not required by build (retain only the single top-level keep for
com.kakao.sdk.** or, if you prefer stricter scope, keep only the specific
subpackage rules you actually rely on), so update the file to contain a single
keep line for com.kakao.sdk.** (and interface if needed) and delete the three
subpackage keep lines and the dontwarn line.

Comment on lines +54 to +59
# JSON 직렬화 관련
-keep class com.google.gson.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Gson 전역 keep 축소

com.google.gson.** 전체 보존은 과합니다. 커스텀 어댑터 구현체만 유지하고, 나머지는 속성 보존으로 충분합니다.

적용 diff:

-# JSON 직렬화 관련
--keep class com.google.gson.** { *; }
--keep class * implements com.google.gson.TypeAdapterFactory
--keep class * implements com.google.gson.JsonSerializer
--keep class * implements com.google.gson.JsonDeserializer
+# JSON 직렬화 관련: 커스텀 어댑터만 유지
+-keep class * implements com.google.gson.TypeAdapterFactory
+-keep class * implements com.google.gson.JsonSerializer
+-keep class * implements com.google.gson.JsonDeserializer
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# JSON 직렬화 관련
-keep class com.google.gson.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# JSON 직렬화 관련: 커스텀 어댑터만 유지
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
🤖 Prompt for AI Agents
In app/proguard-rules.pro around lines 54 to 59, replace the overly-broad -keep
class com.google.gson.** { *; } rule with targeted rules: remove the global
keep, keep full definitions for custom adapter implementations (classes
implementing com.google.gson.TypeAdapterFactory, com.google.gson.JsonSerializer,
com.google.gson.JsonDeserializer) and add lighter preservation for Gson library
classes (e.g., keep their public members only) so that only custom adapters are
retained fully while the rest of com.google.gson.* only preserve necessary
public API.

Comment on lines +60 to +65
# Intent 관련 유지
-keep class * extends android.app.Activity
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Activity 전역 keep 제거: onClick 멤버만 유지하면 충분

-keep class * extends android.app.Activity는 앱 전체 Activity 난독화를 해제합니다. 레이아웃 android:onClick 대응만 필요하다면 멤버 보존 규칙만 남기세요.

적용 diff:

-# Intent 관련 유지
--keep class * extends android.app.Activity
--keepclassmembers class * extends android.app.Activity {
-   public void *(android.view.View);
-}
+# 레이아웃 android:onClick 메서드 보존
+-keepclassmembers class * extends android.app.Activity {
+   public void *(android.view.View);
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Intent 관련 유지
-keep class * extends android.app.Activity
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# 레이아웃 android:onClick 메서드 보존
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
🤖 Prompt for AI Agents
In app/proguard-rules.pro around lines 60 to 65, remove the broad keep rule that
preserves all Activity classes and replace it with a member-only rule that
preserves only onClick handlers; specifically delete the line "-keep class *
extends android.app.Activity" and retain or ensure a rule that keeps public void
*(android.view.View) methods on classes extending android.app.Activity so only
the layout onClick methods are kept from obfuscation.

@m6z1 m6z1 closed this Aug 29, 2025
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.

3 participants