Files
sodalive-android/docs/20260627_메인_홈_콘텐츠_페이지_로그인_가드/plan-task.md

12 KiB

메인 홈/콘텐츠 페이지 로그인 및 성인 콘텐츠 가드 Plan/Task

Assumptions

  • "메인 홈, 콘텐츠 페이지"는 v2 HomeMainFragment, ContentMainFragment를 의미한다.
  • "이동시 guard"는 두 Fragment에서 발생하는 실제 화면 이동(startActivity)을 의미한다.
  • 로그인 여부는 기존 코드와 동일하게 SharedPreferenceManager.token.isBlank() 기준으로 판단한다.
  • 로그인 화면 이동은 기존 MainV2Activity.showLoginActivity()를 재사용한다.
  • 성인 콘텐츠 이동 여부를 판단할 수 있는 경우에는 로그인 이후 본인인증/성인콘텐츠 설정 가드를 적용한다.
  • 접속 국가가 한국인지 여부는 SharedPreferenceManager.countryCode.ifBlank { "KR" } == "KR" 기준으로 판단한다.
  • 한국 접속자는 SharedPreferenceManager.isAuthtrue일 때 본인인증 완료로 판단한다.
  • 한국 외 접속자는 본인인증 여부와 무관하게 성인 콘텐츠 설정 확인 단계로 진행한다.
  • 성인 콘텐츠 표시 설정은 SharedPreferenceManager.isAdultContentVisible 기준으로 판단한다.

Success Criteria

  • v2 메인 전용 이동 guard helper가 추가된다.
  • HomeMainFragment의 모든 실제 화면 이동이 helper를 통과한다.
  • ContentMainFragment의 모든 실제 화면 이동이 helper를 통과한다.
  • 성인 콘텐츠로 판별 가능한 이동은 login -> country/auth -> adult setting 순서로 helper를 통과한다.
  • helper는 SharedPreferenceManager.countryCode, SharedPreferenceManager.isAuth, SharedPreferenceManager.isAdultContentVisible, ContentSettingsActivity 이동을 포함한다.
  • 레거시 HomeFragment, MainActivity, BaseFragment는 수정하지 않는다.
  • 지정된 source test, 컴파일, ktlint, diff whitespace 검증이 통과한다.

Phase 1: 현재 이동 지점과 기존 로그인 진입점 확인

  • Task 1.1: HomeMainFragment 이동 지점 확인

    • 파일: app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragment.kt
    • 확인 대상:
      • openHomeOnAirLive
      • openFollowingChat
      • onBannerClick
      • onRecentActivityClick
      • onAiCharacterClick
      • openCreatorProfile
      • openAudioContentDetail
      • openPopularCommunityPost
    • 검증 기준: 실제 startActivity 호출 지점을 목록화하고, Unit placeholder handler는 이동 대상에서 제외한다.
    • 검증 기록:
      • 2026-06-27: source 확인 결과 위 함수들이 실제 화면 이동 지점이다. onLiveClick, onFollowingSectionMoreClick, onFollowingLiveClick, onFollowingScheduleClick, onFollowingNewsClick은 현재 Unit 또는 이동 없음이므로 이번 가드 적용 대상이 아니다.
  • Task 1.2: ContentMainFragment 이동 지점 확인

    • 파일: app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainFragment.kt
    • 확인 대상:
      • onBannerClick
      • openAudioContentDetail
      • openSeriesDetail
      • openRankingAudioContentDetailopenAudioContentDetail로 위임됨
    • 검증 기준: 실제 startActivity 호출 지점과 위임 구조를 목록화한다.
    • 검증 기록:
      • 2026-06-27: source 확인 결과 onBannerClick, openAudioContentDetail, openSeriesDetail이 실제 화면 이동 지점이다. 랭킹/카드 클릭은 이 함수들로 위임되므로 최종 이동 함수에 가드를 적용하면 된다.
  • Task 1.3: 기존 로그인 진입점 확인

    • 파일: app/src/main/java/kr/co/vividnext/sodalive/v2/main/MainV2Activity.kt
    • 확인 대상: MainV2Activity.showLoginActivity()
    • 검증 기준: SharedPreferenceManager.token.isBlank() 조건에서 LoginActivity를 시작하는 기존 메서드를 재사용할 수 있다.
    • 검증 기록:
      • 2026-06-27: MainV2Activity.showLoginActivity()는 token blank 조건에서 LoginActivity를 시작한다. helper는 이 메서드를 호출하는 방식으로 계획한다.
  • Task 1.4: 기존 성인 콘텐츠/본인인증 정책 확인

    • 파일:
      • app/src/main/java/kr/co/vividnext/sodalive/common/AdultContentVisibilityPolicy.kt
      • app/src/main/java/kr/co/vividnext/sodalive/common/SharedPreferenceManager.kt
      • app/src/main/java/kr/co/vividnext/sodalive/settings/ContentSettingsActivity.kt
    • 확인 대상:
      • AdultContentVisibilityPolicy.shouldShowAdultRestrictionSetting(countryCode, isAdultContentVisible, isAuth)
      • SharedPreferenceManager.countryCode
      • SharedPreferenceManager.isAuth
      • SharedPreferenceManager.isAdultContentVisible
      • ContentSettingsActivity
      • Constants.EXTRA_SHOW_SENSITIVE_CONTENT_GUIDE
    • 검증 기준: v2 helper가 사용할 기존 정책/설정 값을 목록화한다.
    • 검증 기록:
      • 2026-06-27: countryCode 기본값은 KR이고, blank country도 KR로 취급하는 기존 패턴을 확인했다. ContentSettingsActivityConstants.EXTRA_SHOW_SENSITIVE_CONTENT_GUIDEtrue이면 민감 콘텐츠 안내 Toast를 표시한다.

Phase 2: v2 메인 전용 이동 guard helper 추가

  • Task 2.1: helper source test 추가

    • 파일: app/src/test/java/kr/co/vividnext/sodalive/v2/main/MainV2LoginGuardSourceTest.kt
    • 검증 기준:
      • helper가 SharedPreferenceManager.token.isBlank()를 사용한다.
      • helper가 (activity as? MainV2Activity)?.showLoginActivity()를 사용한다.
      • helper가 SharedPreferenceManager.countryCode.ifBlank { "KR" }를 사용한다.
      • helper가 한국 접속자에 대해 SharedPreferenceManager.isAuth를 확인한다.
      • helper가 한국 접속 미인증 사용자에게 SodaDialog 본인인증 안내를 표시한다.
      • helper가 본인인증 진입에 Auth.auth를 직접 재사용한다.
      • helper가 SharedPreferenceManager.isAdultContentVisible를 확인한다.
      • helper가 ContentSettingsActivity로 이동할 때 Constants.EXTRA_SHOW_SENSITIVE_CONTENT_GUIDEtrue로 전달한다.
      • helper에 레거시 MainActivity 의존이 포함되지 않는다.
    • 실행 명령:
      ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.MainV2LoginGuardSourceTest"
      
    • 기대 결과: 구현 전에는 helper 파일 부재로 실패한다.
  • Task 2.2: helper 구현

    • 파일: app/src/main/java/kr/co/vividnext/sodalive/v2/main/MainV2LoginGuard.kt
    • 구현 방향:
      fun Fragment.ensureMainV2NavigationAllowed(
          requiresAdultContentAccess: Boolean = false,
          onAllowed: () -> Unit
      ) {
          if (SharedPreferenceManager.token.isBlank()) {
              (activity as? MainV2Activity)?.showLoginActivity()
              return
          }
      
          if (requiresAdultContentAccess) {
              val isKoreanCountry = SharedPreferenceManager.countryCode.ifBlank { "KR" } == "KR"
              if (isKoreanCountry && !SharedPreferenceManager.isAuth) {
                  showMainV2AuthDialog()
                  return
              }
      
              if (!SharedPreferenceManager.isAdultContentVisible) {
                  startActivity(
                      Intent(requireContext(), ContentSettingsActivity::class.java).apply {
                          putExtra(Constants.EXTRA_SHOW_SENSITIVE_CONTENT_GUIDE, true)
                      }
                  )
                  return
              }
          }
      
          onAllowed()
      }
      
    • 검증 기준: Task 2.1 source test가 통과한다.
  • Task 2.3: 한국 접속 미인증 사용자 처리 방식 확정

    • 파일:
      • app/src/main/java/kr/co/vividnext/sodalive/v2/main/MainV2LoginGuard.kt
      • 필요 시 v2 main 하위 신규 auth guide helper
    • 확인 대상:
      • 기존 SodaDialog + Auth.auth 흐름을 v2 helper에서 직접 재사용한다.
      • Fragment별 callback 위임 방식은 사용하지 않는다.
    • 검증 기준: 레거시 파일 수정 없이 v2 main helper 범위에서 본인인증 안내/진입을 처리한다.
    • 검증 기록:
      • 2026-06-27: 사용자 결정에 따라 한국 접속 미인증 사용자 본인인증 안내 흐름은 v2 helper에서 직접 재사용하는 것으로 확정했다.

Phase 3: HomeMainFragment 이동 지점에 로그인 가드 적용

  • Task 3.1: HomeMainFragment source test 추가

    • 파일: app/src/test/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragmentLoginGuardSourceTest.kt
    • 검증 기준:
      • HomeMainFragmentensureMainV2NavigationAllowed를 import/use 한다.
      • Task 1.1의 실제 화면 이동 함수들이 helper를 통해 startActivity를 실행한다.
      • invalid route/id return 조건은 가드보다 먼저 유지된다.
      • 성인 콘텐츠 여부를 판단할 수 없는 홈 이동은 requiresAdultContentAccess = false 또는 기본값을 사용한다.
    • 실행 명령:
      ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLoginGuardSourceTest"
      
    • 기대 결과: 구현 전에는 helper 사용 부재로 실패한다.
  • Task 3.2: HomeMainFragment 적용

    • 파일: app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragment.kt
    • 구현 방향:
      • ensureMainV2NavigationAllowed { startActivity(...) } 형태로 감싼다.
      • route ?: return, invalid id return은 기존 위치를 유지한다.
      • 홈 모델에서 성인 콘텐츠 여부를 판단할 수 있는 필드가 확인되면 requiresAdultContentAccess = true를 전달한다.
      • 성인 콘텐츠 여부를 판단할 수 없는 이동에는 임의 adult 판정을 추가하지 않는다.
      • BaseFragment, legacy MainActivity, legacy HomeFragment는 수정하지 않는다.
    • 검증 기준: Task 3.1 source test가 통과한다.

Phase 4: ContentMainFragment 이동 지점에 로그인 가드 적용

  • Task 4.1: ContentMainFragment source test 추가

    • 파일: app/src/test/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainFragmentLoginGuardSourceTest.kt
    • 검증 기준:
      • ContentMainFragmentensureMainV2NavigationAllowed를 import/use 한다.
      • onBannerClick, openAudioContentDetail, openSeriesDetail이 helper를 통해 startActivity를 실행한다.
      • invalid id return 조건은 가드보다 먼저 유지된다.
      • showAdultBadge 또는 isAdult에서 유래한 성인 콘텐츠 여부가 helper의 requiresAdultContentAccess로 전달된다.
    • 실행 명령:
      ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.content.ContentMainFragmentLoginGuardSourceTest"
      
    • 기대 결과: 구현 전에는 helper 사용 부재로 실패한다.
  • Task 4.2: ContentMainFragment 적용

    • 파일: app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainFragment.kt
    • 구현 방향:
      • 최종 이동 함수인 onBannerClick, openAudioContentDetail, openSeriesDetail에서 ensureMainV2NavigationAllowed { startActivity(...) }를 사용한다.
      • ContentAudioCardUiModel.showAdultBadge, ContentCommentedAudioUiModel.showAdultBadge, 전체 탭 audio/series item의 showAdultBadge를 성인 콘텐츠 가드 입력으로 전달한다.
      • 랭킹 아이템이나 배너처럼 성인 콘텐츠 여부를 판단할 수 없는 이동은 로그인 가드만 적용한다.
      • 랭킹/카드 클릭 위임 구조는 유지한다.
    • 검증 기준: Task 4.1 source test가 통과한다.

Phase 5: 통합 검증

  • Task 5.1: v2 main source test 실행

    • 실행 명령:
      ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.*"
      
    • 기대 결과: v2 main 관련 source/unit test 통과.
  • Task 5.2: 컴파일 검증

    • 실행 명령:
      ./gradlew :app:compileDebugKotlin
      
    • 기대 결과: Kotlin debug compile 통과.
  • Task 5.3: ktlint 검증

    • 실행 명령:
      ./gradlew :app:ktlintCheck
      
    • 기대 결과: ktlint 통과.
  • Task 5.4: diff whitespace 검증

    • 실행 명령:
      git diff --check
      
    • 기대 결과: whitespace error 없음.

Verification Log

  • 2026-06-27: 사용자 요청에 따라 이번 작업은 문서 생성만 수행한다. source/test/helper 구현 및 Gradle 검증은 아직 실행하지 않는다.
  • 2026-06-27: 사용자 요청에 따라 본인인증/성인 콘텐츠 설정 가드를 문서 범위에 추가했다. 구현은 아직 수행하지 않는다.
  • 2026-06-27: 한국 접속 미인증 사용자 본인인증 안내 흐름은 v2 helper에서 기존 SodaDialog + Auth.auth 패턴을 직접 재사용하는 것으로 확정했다.