Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6f00438
[fix] 보호장소, 발견장소 데이터 수정
ikseong00 Jan 4, 2026
bcd27bc
[fix] 하단바(BNV) 노출 로직 수정
ikseong00 Jan 4, 2026
7a28f91
[feat] bg_radius_20 배경 색상 제거
ikseong00 Jan 4, 2026
f033342
[refactor] 보호 장소 UI 수정
ikseong00 Jan 4, 2026
bed4636
[fix] 디스코드 에러 로깅 범위 수정
ikseong00 Jan 4, 2026
e5ff60c
[feat] 게스트 로그인 버튼 UI 복원
ikseong00 Jan 4, 2026
0a23bc3
[fix] 지도 위치 정보 없을 시 지도 숨김 처리
ikseong00 Jan 4, 2026
dffa147
[refactor] 게스트 로그인 토스트 메시지 수정
ikseong00 Jan 4, 2026
80b9257
[feat] refreshToken 추가
ikseong00 Jan 4, 2026
40cd83a
[refactor] 메인 컬러 변경
ikseong00 Jan 4, 2026
3ce4483
[fix] 회원 탈퇴 완료 시 토큰을 제거하는 것으로 수정
ikseong00 Jan 4, 2026
e91d2c2
[feat] 조회 createdAt 필드 추가
ikseong00 Jan 4, 2026
76944d8
[refactor] 온보딩 프로필 설정 로직 제거
ikseong00 Jan 4, 2026
a8886ac
[refactor] 스플래시 화면 레거시 색상 적용
ikseong00 Jan 4, 2026
1bca665
[fix] 마이페이지 프로필 응답값 수정
ikseong00 Jan 9, 2026
a7b9f3a
[refactor] 회원가입 API 요청 형식 변경
ikseong00 Jan 9, 2026
af8f1a5
[feat] 토큰 재발급 API 구현
ikseong00 Jan 9, 2026
c511eb7
[feat] 토큰 재발급 로직 구현
ikseong00 Jan 9, 2026
de3647c
[feat] 게스트 로그인 시 이미 가입된 계정이면 에러 메시지 표시
ikseong00 Jan 9, 2026
450d33b
[feat] 게스트 유저 제보 기능 제한
ikseong00 Jan 9, 2026
b96e2d9
[feat] 홈 화면 스크롤 최상단 이동 버튼 제거
ikseong00 Jan 13, 2026
3bfa6be
[chore] 앱 버전 정보 업데이트
ikseong00 Jan 13, 2026
d202b7f
[feat] Proguard 규칙 추가
ikseong00 Jan 13, 2026
25dc686
[feat] 게스트 유저 '내 제보 내역' 조회 기능 제한
ikseong00 Jan 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ android {
applicationId = "com.kuit.findu"
minSdk = 28
targetSdk = 35
versionCode = 12
versionName = "1.0.11"
versionCode = 14
versionName = "1.0.13"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
buildConfigField("String", "GPT_KEY", properties["GPT_KEY"].toString())
Expand Down
166 changes: 152 additions & 14 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,155 @@
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# Keep line numbers for debugging
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile

# Keep annotations
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes Exceptions

# ========== Retrofit & OkHttp ==========
-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn javax.annotation.**
-keepclasseswithmembers class * {
@retrofit2.http.* <methods>;
}
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>

# ========== Kotlinx Serialization ==========
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.AnnotationsKt
-keepclassmembers class kotlinx.serialization.json.** {
*** Companion;
}
-keepclasseswithmembers class kotlinx.serialization.json.** {
kotlinx.serialization.KSerializer serializer(...);
}
-keep,includedescriptorclasses class com.kuit.findu.**$$serializer { *; }
-keepclassmembers class com.kuit.findu.** {
*** Companion;
}
-keepclasseswithmembers class com.kuit.findu.** {
kotlinx.serialization.KSerializer serializer(...);
}

# Keep all data classes and their properties
-keep class com.kuit.findu.data.** { *; }
-keep class com.kuit.findu.domain.** { *; }

Comment on lines +47 to +50
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's check the actual proguard-rules.pro file
cat -n app/proguard-rules.pro | head -150

Repository: FindYou-Kuit/FindYou-Android

Length of output: 5948


🏁 Script executed:

# Search for reflection and serialization usage patterns
rg -n --type=kt --type=java -C2 'Class\.forName|java\.lang\.reflect|kotlin\.reflect|canonicalName|qualifiedName' 2>/dev/null | head -100

Repository: FindYou-Kuit/FindYou-Android

Length of output: 54


🏁 Script executed:

# Check for `@Keep` and `@Serializable` annotations
rg -n '@Keep|@Serializable' --type=kt --type=java 2>/dev/null

Repository: FindYou-Kuit/FindYou-Android

Length of output: 54


🏁 Script executed:

# Also check what packages exist in the codebase
find . -type d -name "com" | head -5 && find . -path "*/com/kuit/findu/data" -type d && find . -path "*/com/kuit/findu/domain" -type d

Repository: FindYou-Kuit/FindYou-Android

Length of output: 232


🏁 Script executed:

# Check how many data classes exist and if they're all serializable
find app/src/main/java/com/kuit/findu/data -name "*.kt" -type f | wc -l
find app/src/main/java/com/kuit/findu/domain -name "*.kt" -type f | wc -l

# Check if classes use `@Serializable` annotation
rg '@Serializable' app/src/main/java/com/kuit/findu/data --type=kt
rg '@Serializable' app/src/main/java/com/kuit/findu/domain --type=kt

Repository: FindYou-Kuit/FindYou-Android

Length of output: 149


🏁 Script executed:

# Check a few sample data/domain files to see if they're data classes
find app/src/main/java/com/kuit/findu/data -name "*.kt" -type f | head -5 | xargs -I {} sh -c 'echo "=== {} ===" && head -20 {}'

Repository: FindYou-Kuit/FindYou-Android

Length of output: 2648


🏁 Script executed:

# Search for `@Serializable` without specifying file type
rg '@Serializable' app/src/main/java/com/kuit/findu/data
rg '@Serializable' app/src/main/java/com/kuit/findu/domain

Repository: FindYou-Kuit/FindYou-Android

Length of output: 8260


🏁 Script executed:

# Check actual structure of data package - look for typical serialization targets (models/DTOs)
find app/src/main/java/com/kuit/findu/data -type d | head -15

Repository: FindYou-Kuit/FindYou-Android

Length of output: 978


🏁 Script executed:

# Look at actual serialization usage in the codebase
rg 'Json\.encodeToString|Json\.decodeFromString' --type-list --no-heading -A 2 | head -30
rg 'kotlinx\.serialization' app/src/main/java --no-heading | head -20

Repository: FindYou-Kuit/FindYou-Android

Length of output: 3101


🏁 Script executed:

# Check domain package structure - what's actually in there?
find app/src/main/java/com/kuit/findu/domain -type d | head -10

Repository: FindYou-Kuit/FindYou-Android

Length of output: 573


🏁 Script executed:

# Count how many classes in data are actually serializable vs total
rg '@Serializable' app/src/main/java/com/kuit/findu/data --count-matches 2>/dev/null | tail -1

Repository: FindYou-Kuit/FindYou-Android

Length of output: 149


🏁 Script executed:

# Check what's actually in domain - are they mostly interfaces/use cases vs data classes?
find app/src/main/java/com/kuit/findu/domain/repository -name "*.kt" | head -2 | xargs -I {} sh -c 'echo "=== {} ===" && head -15 {}'
find app/src/main/java/com/kuit/findu/domain/usecase -name "*.kt" | head -1 | xargs -I {} sh -c 'echo "=== {} ===" && head -15 {}'

Repository: FindYou-Kuit/FindYou-Android

Length of output: 1484


🏁 Script executed:

# Check if the data package keeps are actually needed or if kotlinx rules cover them
# Look for actual data classes with `@Serializable`
rg '@Serializable\s+data class' app/src/main/java/com/kuit/findu/data --count

Repository: FindYou-Kuit/FindYou-Android

Length of output: 54


🏁 Script executed:

# Check what's actually in domain/model - are they data classes?
find app/src/main/java/com/kuit/findu/domain/model -name "*.kt" | head -3 | xargs -I {} sh -c 'echo "=== {} ===" && head -15 {}'

Repository: FindYou-Kuit/FindYou-Android

Length of output: 867


🏁 Script executed:

# Get count of how many classes in data need serialization vs total
echo "Total data package files:" && find app/src/main/java/com/kuit/findu/data -name "*.kt" | wc -l
echo "Serializable classes in data:" && rg '@Serializable' app/src/main/java/com/kuit/findu/data | wc -l

Repository: FindYou-Kuit/FindYou-Android

Length of output: 134


패키지 전체 -keep은 축소/난독화 효과를 크게 줄 수 있어요

data/domain 패키지 전체를 보존하면 불필요한 클래스도 남아 APK 용량 증가 및 난독화 약화 가능성이 커요. data 패키지에는 128개 중 약 76개만 @Serializable로 표시되어 있고, domain은 repository/usecase 인터페이스와 구현체들이 대부분이라 전체 보존이 필수는 아닙니다.

기존 kotlinx.serialization 규칙(39-45줄)에서 KSerializer serializer(...) 패턴으로 필요한 클래스만 검증하고 있으니, data의 serializable 모델들은 이미 보호되고 있습니다. 나머지 범위를 좁혀서 보존 대상을 명확히 하면, 난독화 효과를 더 높일 수 있어요.

♻️ 범위 축소 예시
-keep class com.kuit.findu.data.** { *; }
-keep class com.kuit.findu.domain.** { *; }
+-keep class com.kuit.findu.data.dataremote.model.** { *; }
+-keep class com.kuit.findu.domain.model.** { *; }
🤖 Prompt for AI Agents
In `@app/proguard-rules.pro` around lines 47 - 50, 현재 proguard 규칙에서
com.kuit.findu.data.** 및 com.kuit.findu.domain.** 전체를 보존하고 있어 난독화/축소 효과가 약해집니다;
com.kuit.findu.data 패키지는 `@Serializable로` 표시된 모델(예: data 모델 패키지나 *Dto/*Model 클래스)만
보존하도록 범위를 좁히고, com.kuit.findu.domain은 실제로 리플렉션/직렬화가 필요한 인터페이스나 구현체(예: Repository
인터페이스만 또는 필요한 구현 클래스 이름들)만 명시적으로 keep 하며 전패키지 보존을 제거하세요; 또한 기존
kotlinx.serialization 관련 규칙(현재 39-45줄의 KSerializer serializer(...) 패턴)을 유지해 직렬화
대상은 이미 보호되고 있음을 확인하고, 불필요한 전체 보존 규칙(com.kuit.findu.data.**,
com.kuit.findu.domain.**)을 삭제하거나 구체적인 클래스/하위패턴으로 대체하세요.

# ========== Hilt ==========
-dontwarn com.google.errorprone.annotations.**
-keep class dagger.** { *; }
-keep class javax.inject.** { *; }
-keep class * extends dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper { *; }
-keep class * implements dagger.hilt.internal.GeneratedComponent { *; }
-keep class * implements dagger.hilt.internal.GeneratesRootInput { *; }
-keep class dagger.hilt.** { *; }
-keep class javax.inject.** { *; }
-keep class * extends dagger.hilt.android.lifecycle.HiltViewModel { *; }

# ========== Glide ==========
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep class * extends com.bumptech.glide.module.AppGlideModule {
<init>(...);
}
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
*** rewind();
}

# ========== Naver Map SDK ==========
-keep class com.naver.maps.** { *; }
-keep interface com.naver.maps.** { *; }
-dontwarn com.naver.maps.**

# ========== CameraX ==========
-keep class androidx.camera.** { *; }
-dontwarn androidx.camera.**

# ========== Kakao SDK ==========
-keep class com.kakao.sdk.**.model.* { <fields>; }
-keep class * extends com.google.gson.TypeAdapter
-keep class com.kakao.sdk.auth.** { *; }
-keep class com.kakao.sdk.user.** { *; }
-keep class com.kakao.sdk.common.** { *; }

# ========== Firebase ==========
-keep class com.google.firebase.** { *; }
-keep class com.google.android.gms.** { *; }
-dontwarn com.google.firebase.**
-dontwarn com.google.android.gms.**

# ========== Jetpack Compose ==========
-keep class androidx.compose.** { *; }
-keep class androidx.compose.runtime.** { *; }
-keep class androidx.compose.ui.** { *; }
-dontwarn androidx.compose.**

# Keep ViewModels
-keep class * extends androidx.lifecycle.ViewModel {
<init>();
}
-keep class * extends androidx.lifecycle.AndroidViewModel {
<init>(android.app.Application);
}

# ========== AndroidX Navigation ==========
-keep class androidx.navigation.fragment.NavHostFragment { *; }
-keepnames class * extends android.os.Parcelable
-keepnames class * extends java.io.Serializable

# ========== Material Components ==========
-keep class com.google.android.material.** { *; }
-dontwarn com.google.android.material.**

# ========== ViewBinding & DataBinding ==========
-keep class * implements androidx.viewbinding.ViewBinding {
public static * inflate(android.view.LayoutInflater);
public static * inflate(android.view.LayoutInflater, android.view.ViewGroup, boolean);
public static * bind(android.view.View);
}

# ========== Lottie ==========
-keep class com.airbnb.lottie.** { *; }
-dontwarn com.airbnb.lottie.**

# ========== WebView ==========
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}

# ========== Kotlin ==========
-keep class kotlin.** { *; }
-keep class kotlin.Metadata { *; }
-dontwarn kotlin.**
-keepclassmembers class **$WhenMappings {
<fields>;
}
-keepclassmembers class kotlin.Metadata {
public <methods>;
}
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
}

# ========== Coroutines ==========
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
-keepclassmembernames class kotlinx.** {
volatile <fields>;
}

# ========== R8 Full Mode ==========
-allowaccessmodification
-repackageclasses
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.kuit.findu.data.datalocal.datasource
interface DeviceLocalDataSource {
var deviceId: String
var nickname: String
var isGuestLogin: Boolean

fun clear()
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class DeviceLocalDataSourceImpl @Inject constructor(
get() = sharedPreferences.getString(NICKNAME, INITIAL_VALUE).toString()
set(value) = sharedPreferences.edit { putString(NICKNAME, value) }

override var isGuestLogin: Boolean
get() = sharedPreferences.getBoolean(IS_GUEST_LOGIN, false)
set(value) = sharedPreferences.edit { putBoolean(IS_GUEST_LOGIN, value) }

override fun clear() {
val currentDeviceId = deviceId
sharedPreferences.edit {
Expand All @@ -34,6 +38,7 @@ class DeviceLocalDataSourceImpl @Inject constructor(
const val PREFERENCES_NAME = "device_preferences"
const val DEVICE_ID = "deviceId"
const val NICKNAME = "nickname"
const val IS_GUEST_LOGIN = "isGuestLogin"

const val INITIAL_VALUE = ""
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,23 @@ import com.kuit.findu.data.dataremote.model.base.NullableBaseResponse
import com.kuit.findu.data.dataremote.model.request.CheckNicknameRequestDto
import com.kuit.findu.data.dataremote.model.request.GuestLoginRequestDto
import com.kuit.findu.data.dataremote.model.request.LoginRequestDto
import com.kuit.findu.data.dataremote.model.request.PostUserRequestDto
import com.kuit.findu.data.dataremote.model.response.CheckNicknameResponseDto
import com.kuit.findu.data.dataremote.model.response.auth.GuestLoginResponseDto
import com.kuit.findu.data.dataremote.model.response.auth.LoginResponseDto
import com.kuit.findu.data.dataremote.model.response.auth.UserInfoDto
import com.kuit.findu.data.dataremote.service.AuthService
import com.kuit.findu.data.mapper.torequest.toImageMultipart
import com.kuit.findu.data.mapper.torequest.toPlainTextRequestBody
import java.io.File
import javax.inject.Inject

class AuthRemoteDataSourceImpl @Inject constructor(
private val authService: AuthService
private val authService: AuthService,
) : AuthRemoteDataSource {
override suspend fun postLogin(loginRequestDto: LoginRequestDto): NullableBaseResponse<LoginResponseDto> =
authService.postLogin(loginRequestDto=loginRequestDto)
authService.postLogin(loginRequestDto = loginRequestDto)

override suspend fun postGuestLogin(guestLoginRequestDto: GuestLoginRequestDto): NullableBaseResponse<GuestLoginResponseDto> =
authService.postGuestLogin(guestLoginRequestDto=guestLoginRequestDto)
authService.postGuestLogin(guestLoginRequestDto = guestLoginRequestDto)

override suspend fun postCheckNickname(nickname: String): BaseResponse<CheckNicknameResponseDto> =
authService.postCheckNickname(CheckNicknameRequestDto(nickname))
Expand All @@ -33,12 +32,8 @@ class AuthRemoteDataSourceImpl @Inject constructor(
defaultImageName: String?,
nickname: String,
kakaoId: Long,
deviceId: String
deviceId: String,
): NullableBaseResponse<UserInfoDto> = authService.postSignup(
profileImage = profileImageFile?.toImageMultipart("profileImage"),
defaultImageName = defaultImageName?.toPlainTextRequestBody(),
nickname = nickname.toPlainTextRequestBody(),
kakaoId = kakaoId.toString().toPlainTextRequestBody(),
deviceId = deviceId.toPlainTextRequestBody()
PostUserRequestDto(nickname, kakaoId, deviceId)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.kuit.findu.data.dataremote.exception

class ApiNotFoundException(
message: String,
) : Exception(message)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.kuit.findu.data.dataremote.model.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class PostUserRequestDto(
@SerialName("nickname")
val nickname: String,
@SerialName("kakaoId")
val kakaoId: Long,
@SerialName("deviceId")
val deviceId: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.kuit.findu.data.dataremote.model.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class TokenReissueRequestDto(
@SerialName("refreshToken")
val refreshToken: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ data class GuestLoginResponseDto(
@SerialName("userId")
val userId: Long,
@SerialName("accessToken")
val accessToken: String
val accessToken: String,
@SerialName("refreshToken")
val refreshToken: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ data class UserInfoDto(
@SerialName("nickname")
val nickname: String,
@SerialName("accessToken")
val accessToken: String
val accessToken: String,
@SerialName("refreshToken")
val refreshToken: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.kuit.findu.data.dataremote.model.response.auth

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class TokenReissueResponseDto(
@SerialName("accessToken")
val accessToken: String,
@SerialName("refreshToken")
val refreshToken: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ data class MyNickNameResponseDto(
@SerialName("nickname")
val nickname: String,
@SerialName("profileImage")
val profileImage : String,
val profileImage : String? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ data class DetailMissingResponseDto(
@SerialName("significant") val significant: String,
@SerialName("missingLocation") val missingLocation: String,
@SerialName("missingAddress") val missingAddress: String,
@SerialName("latitude") val latitude: Double,
@SerialName("longitude") val longitude: Double,
@SerialName("latitude") val latitude: Double?,
@SerialName("longitude") val longitude: Double?,
@SerialName("reporterName") val reporterName: String,
@SerialName("reporterTel") val reporterTel: String,
@SerialName("interest") val interest: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ data class DetailProtectResponseDto(
@SerialName("careAddr")
val careAddr: String,
@SerialName("latitude")
val latitude: Double,
val latitude: Double?,
@SerialName("longitude")
val longitude: Double,
val longitude: Double?,
@SerialName("careTel")
val careTel: String,
@SerialName("foundDate")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ data class DetailWitnessResponseDto(
@SerialName("significant") val significant: String,
@SerialName("witnessLocation") val witnessLocation: String,
@SerialName("witnessAddress") val witnessAddress: String,
@SerialName("latitude") val latitude: Double,
@SerialName("longitude") val longitude: Double,
@SerialName("latitude") val latitude: Double?,
@SerialName("longitude") val longitude: Double?,
@SerialName("reporterInfo") val reporterInfo: String,
@SerialName("witnessDate") val witnessDate: String,
@SerialName("interest") val interest: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ data class SearchResponseDto(
@SerialName("cards")
val cards: List<SearchAnimalCard>,
@SerialName("lastId")
val lastId : Long?,
val lastId: Long?,
@SerialName("isLast")
val isLast : Boolean
val isLast: Boolean,
)

@Serializable
Expand All @@ -28,5 +28,7 @@ data class SearchAnimalCard(
@SerialName("location")
val location: String,
@SerialName("interest")
val interest: Boolean = false
val interest: Boolean = false,
@SerialName("createdAt")
val createdAt: String,
)
Loading
Loading