6.5 KiB
6.5 KiB
PRD: JSON DTO enum 난독화 안정화
1. Overview
Release minify 환경에서 Gson/Retrofit 기반 JSON DTO와 API query enum 값이 난독화 영향으로 흔들리지 않도록, 확인된 누락 annotation과 고위험 enum query 경계를 최소 범위로 안정화한다.
2. Problem
minifyEnabled true인 release 빌드에서 Gson reflection 기반 DTO 필드명과 enum 이름 의존이 깨질 수 있다.- 일부 Retrofit request/response DTO에
@Keep또는 필드@SerializedName이 없어 R8 최적화/난독화 시 직렬화 계약이 불안정하다. AudioRankingType등 일부 enum은 JSON 응답 필드와 Retrofit@Query값에 직접 사용되고 있으나 enum entry@SerializedName이 없다.- Retrofit
@Queryenum 변환은 Gson@SerializedName을 사용하지 않고 기본적으로toString()fallback에 의존하므로, query 값은 repository/API 경계에서 명시 문자열로 넘기는 방식이 더 안전하다.
3. Goals
- 확정 DTO 누락 5개를 프로젝트 Gson 관례에 맞게
@Keep및 필드@SerializedName으로 보강한다. - 메인 콘텐츠 랭킹/전체/개요 및 관련 홈 랭킹/요일 enum의 JSON 이름과 query 값을 명시적으로 고정한다.
- 이번 이슈와 직접 연결된 Retrofit
@Queryenum 전달 경계를String/String?기반으로 바꿔 release minify에서 API parameter 값이 안정적으로 전달되게 한다. - 변경 범위를 문서화하고, 테스트/grep/Gradle 검증으로 회귀 위험을 확인한다.
4. Non-Goals
- Gson에서 Moshi 또는 Kotlin Serialization으로 마이그레이션하지 않는다.
- 전역 Retrofit
Converter.Factory또는 app-wide enum 변환 정책을 새로 만들지 않는다. - 레거시 화면 전체 리팩터링이나 관련 없는 DTO/enum 일괄 수정을 하지 않는다.
- 서버 API 스키마, query parameter 이름, response field 이름을 변경하지 않는다.
ChatMessage.isGrouped,LiveRoomDonationChat.isSecret처럼 클라이언트 전용 가능성이 있는 후보는 이번 확정 수정 범위에서 제외한다.
5. Target Users
- release/minify 빌드에서 메인 콘텐츠 랭킹/전체/개요, 홈 랭킹/요일 기반 콘텐츠를 사용하는 앱 사용자.
- Gson/Retrofit DTO와 R8 규칙을 유지보수하는 Android 개발자.
6. User Stories
- 사용자는 release 앱에서도 랭킹 유형을 바꿀 때 선택한 타입의 API 결과가 안정적으로 표시되길 기대한다.
- 사용자는 콘텐츠 전체/개요/홈 랭킹 화면에서 정렬, 타입, 요일 query가 debug/release 빌드 간 다르게 전달되지 않길 기대한다.
- 개발자는 API DTO 필드명이 obfuscation 결과에 의존하지 않고 서버 계약 이름으로 고정되길 원한다.
7. Core Features
DTO annotation 보강
확정된 Retrofit/Gson request/response DTO의 누락 annotation을 보강한다.
Requirements
OriginalWorkListResponse와OriginalWorkListItemResponse의 모든 constructor property에@SerializedName을 추가한다.AuthResponse에@Keep과@SerializedName("gender")를 추가한다.UpdatePlaylistRequest에@Keep을 추가한다.PayverseVerifyRequest에@Keep을 추가한다.
Edge Cases
- 기존 property type, nullability, 기본값은 변경하지 않는다.
- 기존
@Keep이 있는 DTO는 유지하고 필드 annotation만 추가한다.
Enum JSON 이름과 query 값 안정화
고위험 enum에 JSON 이름과 query 값을 명시한다.
Requirements
AudioRankingType,MainContentAllType,ContentSort,ContentOverviewType,SeriesPublishedDaysOfWeek,ContentRankingSortType에 enum entry별@SerializedName을 추가한다.- 위 enum에는 API wire 값과 같은 안정 문자열
queryValue를 제공한다. - 기존 enum 순서와 UI label mapping은 유지한다.
Edge Cases
AudioRankingType의 기존queryValue와label계약은 유지하되@SerializedName만 보강한다.ContentSort는 creator channel API에서도 사용되므로 query 경계 변경 시 기존 repository public API는 enum 타입을 유지하고 Retrofit API parameter만 문자열로 바꾼다.
Retrofit query 경계 문자열화
Gson annotation에 의존하지 않도록 Retrofit API interface의 고위험 enum @Query parameter를 문자열로 바꾼다.
Requirements
AudioRankingsApi,MainContentAllTabApi,ContentOverviewApi에서 enum@Queryparameter를String/String?로 변경한다.- 해당 repository에서는 기존 public method의 enum parameter를 유지하고, API 호출 직전에
.queryValue또는?.queryValue로 변환한다. - 홈/시리즈/크리에이터 채널 등 같은 enum을 직접 query로 넘기는 확인된 경계도 같은 방식으로 최소 변환한다.
Edge Cases
- nullable
dayOfWeek는 null이면 query를 보내지 않도록dayOfWeek?.queryValue를 사용한다. toString()override는 전역 side effect가 있으므로 사용하지 않는다.
8. UX / UI Expectations
- UI 변경은 없다.
- debug/release 간 API query 값과 JSON mapping 동작 차이를 줄이는 내부 안정화 작업이다.
9. Technical Constraints
- Kotlin, Retrofit, Gson, AndroidX
@Keep기존 스택을 유지한다. - DTO 필드명 안정화는
com.google.gson.annotations.SerializedName을 사용한다. - R8 제거/최적화 방지는
androidx.annotation.Keep을 사용한다. - 구현 전
docs/20260709_JSON_DTO_enum_난독화_안정화/plan-task.md를 작성하고, 범위 변경 시 계획 문서를 먼저 갱신한다. - 레거시 파일은 필요한 API query 경계 보강 외 리팩터링하지 않는다.
10. Metrics
- 확정 DTO 5개가 필요한
@Keep/@SerializedName을 가진다. - 고위험 enum 6개가 entry별
@SerializedName과queryValue를 가진다. - 확인된 고위험 enum이 Retrofit
@Queryparameter로 직접 전달되지 않는다. - 관련 unit test, grep 검증, Gradle compile/test가 통과하거나 환경 blocker가 문서에 기록된다.
11. Open Questions
- 없음. Backend wire 값은 현재 enum constant name과 동일하다고 전제한다.
12. Verification Log
- 2026-07-09: Gson/R8 공식 문서와 Retrofit Gson converter 동작을 확인했다.
@SerializedName은 JSON body/response enum과 field 이름 안정화에는 필요하지만 Retrofit@Queryenum 변환에는 적용되지 않으므로, query 경계에서는 명시 문자열 전달이 필요하다고 판단했다.