docs(home): title bar 메뉴 액션 계획을 기록한다
This commit is contained in:
196
docs/20260630_메인_홈_title_bar_우측_메뉴_액션/plan-task.md
Normal file
196
docs/20260630_메인_홈_title_bar_우측_메뉴_액션/plan-task.md
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
# 메인 홈 title bar 우측 메뉴 액션 구현 계획/TASK
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED SUB-SKILL: 구현 시 `superpowers:subagent-driven-development` 또는 `superpowers:executing-plans`를 사용해 task 단위로 진행한다. 각 단계는 체크박스(`- [ ]`)로 추적하고, 완료 즉시 `- [x]`로 갱신한다. 구현 범위 변경이 생기면 이 문서를 먼저 수정한 뒤 코드에 반영한다.
|
||||||
|
|
||||||
|
**Goal:** v2 메인 홈 title bar 우측 `cash`, `search`, `bell` 아이콘 터치 시 기존 충전, 검색, 알림 리스트 페이지로 이동한다.
|
||||||
|
|
||||||
|
**Architecture:** `view_title_bar_home.xml`과 `fragment_v2_main_home.xml`의 기존 UI는 유지하고, `HomeMainFragment`에서 title bar action click listener만 연결한다. 목적지 화면은 기존 레거시 Activity를 명시적 `Intent`로 호출하며, 비로그인 처리는 기존 `ensureMainV2NavigationAllowed`를 재사용한다.
|
||||||
|
|
||||||
|
**Tech Stack:** Kotlin, Android XML Views, ViewBinding, Fragment, Android explicit Intent, JUnit4 source-level test.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 전제와 성공 기준
|
||||||
|
- PRD: `docs/20260630_메인_홈_title_bar_우측_메뉴_액션/prd.md`
|
||||||
|
- 구현 대상:
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragment.kt`
|
||||||
|
- 확인 대상:
|
||||||
|
- `app/src/main/res/layout/view_title_bar_home.xml`
|
||||||
|
- `app/src/main/res/layout/fragment_v2_main_home.xml`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/MainV2LoginGuard.kt`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/home/HomeFragment.kt`
|
||||||
|
- 목적지:
|
||||||
|
- cash: `CanChargeActivity`
|
||||||
|
- search: `SearchActivity`
|
||||||
|
- bell: `PushNotificationListActivity`
|
||||||
|
- 성공 기준:
|
||||||
|
- `HomeMainFragment`가 `setupTitleBarActions()` 또는 동등한 최소 메서드에서 세 아이콘 click listener를 연결한다.
|
||||||
|
- 세 click listener는 모두 `ensureMainV2NavigationAllowed`를 거친다.
|
||||||
|
- 목적지 기존 Activity 파일은 수정하지 않는다.
|
||||||
|
- 레이아웃 XML과 아이콘 리소스는 변경하지 않는다.
|
||||||
|
- 구현 완료 후 최소 다음 명령을 실행한다.
|
||||||
|
- `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainTitleBarActionSourceTest"`
|
||||||
|
- `./gradlew :app:compileDebugKotlin`
|
||||||
|
- `./gradlew :app:ktlintCheck`
|
||||||
|
- `git diff --check`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 파일 구조
|
||||||
|
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragment.kt`
|
||||||
|
- title bar action click listener를 추가한다.
|
||||||
|
- `CanChargeActivity`, `SearchActivity`, `PushNotificationListActivity` import를 추가한다.
|
||||||
|
- Create: `app/src/test/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainTitleBarActionSourceTest.kt`
|
||||||
|
- source-level로 세 아이콘 routing 계약을 검증한다.
|
||||||
|
- No Modify:
|
||||||
|
- `app/src/main/res/layout/view_title_bar_home.xml`
|
||||||
|
- `app/src/main/res/layout/fragment_v2_main_home.xml`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/mypage/can/charge/CanChargeActivity.kt`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/search/SearchActivity.kt`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/home/pushnotification/PushNotificationListActivity.kt`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 1: 수정 지점과 기존 목적지 확인
|
||||||
|
|
||||||
|
- [x] **Task 1.1: title bar 아이콘 선언 위치 확인**
|
||||||
|
- 확인:
|
||||||
|
- `app/src/main/res/layout/view_title_bar_home.xml`
|
||||||
|
- `app/src/main/res/layout/fragment_v2_main_home.xml`
|
||||||
|
- 결과:
|
||||||
|
- `view_title_bar_home.xml`에 `iv_title_bar_cash`, `iv_title_bar_search`, `iv_title_bar_bell`이 선언되어 있다.
|
||||||
|
- `fragment_v2_main_home.xml`이 해당 title bar를 `view_home_title_bar`로 include한다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-30: `rg -n "view_home_title_bar|iv_title_bar_cash|iv_title_bar_search|iv_title_bar_bell" app/src/main/java app/src/main/res/layout -S`로 세 아이콘 선언 위치와 코드 미연결 상태를 확인했다.
|
||||||
|
|
||||||
|
- [x] **Task 1.2: 기존 목적지 Activity 확인**
|
||||||
|
- 확인:
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/mypage/can/charge/CanChargeActivity.kt`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/search/SearchActivity.kt`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/home/pushnotification/PushNotificationListActivity.kt`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/home/HomeFragment.kt`
|
||||||
|
- 결과:
|
||||||
|
- 레거시 `HomeFragment`에서 search, charge, push notification 이동 사례를 확인했다.
|
||||||
|
- 목적지 Activity는 별도 factory 없이 `Intent(context, Activity::class.java)` 형태로 호출 가능하다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-30: `HomeFragment.setupView()`의 short icon click listener와 각 Activity의 존재를 정적으로 확인했다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 2: source-level 회귀 테스트 추가
|
||||||
|
|
||||||
|
- [x] **Task 2.1: title bar action source test 작성**
|
||||||
|
- 생성:
|
||||||
|
- `app/src/test/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainTitleBarActionSourceTest.kt`
|
||||||
|
- 작업:
|
||||||
|
- `HomeMainFragment.kt` source text를 읽어 다음 계약을 검증한다.
|
||||||
|
- `viewHomeTitleBar.ivTitleBarCash.setOnClickListener`
|
||||||
|
- `viewHomeTitleBar.ivTitleBarSearch.setOnClickListener`
|
||||||
|
- `viewHomeTitleBar.ivTitleBarBell.setOnClickListener`
|
||||||
|
- 세 listener 내부 또는 공통 helper에서 `ensureMainV2NavigationAllowed` 사용
|
||||||
|
- `CanChargeActivity::class.java`
|
||||||
|
- `SearchActivity::class.java`
|
||||||
|
- `PushNotificationListActivity::class.java`
|
||||||
|
- 테스트 예시:
|
||||||
|
```kotlin
|
||||||
|
package kr.co.vividnext.sodalive.v2.main.home
|
||||||
|
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class HomeMainTitleBarActionSourceTest {
|
||||||
|
private val source = File(
|
||||||
|
"src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragment.kt"
|
||||||
|
).readText()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `홈 title bar 우측 아이콘은 기존 목적지로 이동한다`() {
|
||||||
|
assertTrue(source.contains("viewHomeTitleBar.ivTitleBarCash.setOnClickListener"))
|
||||||
|
assertTrue(source.contains("viewHomeTitleBar.ivTitleBarSearch.setOnClickListener"))
|
||||||
|
assertTrue(source.contains("viewHomeTitleBar.ivTitleBarBell.setOnClickListener"))
|
||||||
|
assertTrue(source.contains("ensureMainV2NavigationAllowed"))
|
||||||
|
assertTrue(source.contains("CanChargeActivity::class.java"))
|
||||||
|
assertTrue(source.contains("SearchActivity::class.java"))
|
||||||
|
assertTrue(source.contains("PushNotificationListActivity::class.java"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- 검증:
|
||||||
|
- Run: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainTitleBarActionSourceTest"`
|
||||||
|
- Expected: 구현 전에는 `AssertionError`로 실패한다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-30: `HomeMainTitleBarActionSourceTest`를 추가한 뒤 구현 전 테스트를 실행해 `HomeMainTitleBarActionSourceTest.kt:15`의 listener 문자열 누락 `AssertionError`로 RED를 확인했다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 3: title bar action 최소 구현
|
||||||
|
|
||||||
|
- [x] **Task 3.1: `HomeMainFragment`에 title bar action setup 추가**
|
||||||
|
- 수정:
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragment.kt`
|
||||||
|
- 작업:
|
||||||
|
- `onViewCreated()`에서 기존 tab setup 흐름을 깨지 않는 위치에 `setupTitleBarActions()`를 호출한다.
|
||||||
|
- `setupTitleBarActions()`에서 세 icon click listener를 연결한다.
|
||||||
|
- 구현 예시:
|
||||||
|
```kotlin
|
||||||
|
private fun setupTitleBarActions() {
|
||||||
|
binding.viewHomeTitleBar.ivTitleBarCash.setOnClickListener {
|
||||||
|
openWithLoginGuard(CanChargeActivity::class.java)
|
||||||
|
}
|
||||||
|
binding.viewHomeTitleBar.ivTitleBarSearch.setOnClickListener {
|
||||||
|
openWithLoginGuard(SearchActivity::class.java)
|
||||||
|
}
|
||||||
|
binding.viewHomeTitleBar.ivTitleBarBell.setOnClickListener {
|
||||||
|
openWithLoginGuard(PushNotificationListActivity::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openWithLoginGuard(activityClass: Class<*>) {
|
||||||
|
ensureMainV2NavigationAllowed {
|
||||||
|
startActivity(Intent(requireContext(), activityClass))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- 필요한 import:
|
||||||
|
```kotlin
|
||||||
|
import kr.co.vividnext.sodalive.home.pushnotification.PushNotificationListActivity
|
||||||
|
import kr.co.vividnext.sodalive.mypage.can.charge.CanChargeActivity
|
||||||
|
import kr.co.vividnext.sodalive.search.SearchActivity
|
||||||
|
```
|
||||||
|
- 검증:
|
||||||
|
- Run: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainTitleBarActionSourceTest"`
|
||||||
|
- Expected: PASS
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-30: `HomeMainFragment`에 `setupTitleBarActions()`와 `openWithLoginGuard()`를 추가해 cash/search/bell listener가 각각 `CanChargeActivity`, `SearchActivity`, `PushNotificationListActivity`로 이동하도록 구현했다. 구현 후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainTitleBarActionSourceTest"` PASS, `./gradlew :app:compileDebugKotlin` PASS를 확인했다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 4: 빌드/린트와 수동 확인
|
||||||
|
|
||||||
|
- [x] **Task 4.1: Kotlin compile 및 ktlint 확인**
|
||||||
|
- 실행:
|
||||||
|
- `./gradlew :app:compileDebugKotlin`
|
||||||
|
- `./gradlew :app:ktlintCheck`
|
||||||
|
- `git diff --check`
|
||||||
|
- 기대 결과:
|
||||||
|
- 모두 PASS한다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-30: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainTitleBarActionSourceTest"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`, `git diff --check` PASS를 확인했다. Gradle deprecation warning과 Agora namespace warning은 기존 빌드 경고로 출력됐으나 실패는 없었다.
|
||||||
|
|
||||||
|
- [ ] **Task 4.2: 수동 화면 확인**
|
||||||
|
- 확인:
|
||||||
|
- v2 메인 홈 진입 후 title bar 우측 cash/search/bell 아이콘이 기존과 동일하게 보인다.
|
||||||
|
- 로그인 상태에서 cash 터치 시 충전 페이지로 이동한다.
|
||||||
|
- 로그인 상태에서 search 터치 시 검색 페이지로 이동한다.
|
||||||
|
- 로그인 상태에서 bell 터치 시 알림 리스트 페이지로 이동한다.
|
||||||
|
- 비로그인 상태에서 각 아이콘 터치 시 기존 v2 login guard 흐름으로 이동한다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 구현 후 실행 결과를 이 항목 아래에 누적한다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verification Log
|
||||||
|
- 2026-06-30: 문서 작성 단계에서 코드 구현은 수행하지 않았다. `view_title_bar_home.xml`, `fragment_v2_main_home.xml`, `HomeMainFragment.kt`, 레거시 `HomeFragment.kt`, 목적지 Activity 세 개를 정적으로 확인해 구현 위치와 범위를 확정했다.
|
||||||
|
- 2026-06-30: Phase 2, 3 구현 후 `./gradlew :app:ktlintCheck` PASS를 확인했다. 실행 중 `.editorconfig`의 기존 `disabled_rules` deprecation warning이 출력됐으나 lint 실패는 없었다.
|
||||||
|
- 2026-06-30: Phase 2, 3 구현 후 `git diff --check` PASS를 확인했다.
|
||||||
103
docs/20260630_메인_홈_title_bar_우측_메뉴_액션/prd.md
Normal file
103
docs/20260630_메인_홈_title_bar_우측_메뉴_액션/prd.md
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
# PRD: 메인 홈 title bar 우측 메뉴 액션
|
||||||
|
|
||||||
|
## 1. Overview
|
||||||
|
v2 메인 홈 title bar 우측의 `cash`, `search`, `bell` 아이콘 터치 시 기존 충전, 검색, 알림 리스트 페이지로 이동하도록 액션을 연결한다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Problem
|
||||||
|
- `fragment_v2_main_home.xml`은 `view_title_bar_home.xml`을 include하고, 해당 title bar에는 `ic_bar_cash`, `ic_bar_search`, `ic_bar_bell` 아이콘이 이미 표시된다.
|
||||||
|
- `HomeMainFragment`에는 현재 이 세 아이콘의 클릭 리스너가 연결되어 있지 않다.
|
||||||
|
- 레거시 `HomeFragment`에는 동일 목적의 short icon 액션이 이미 있으며, v2 홈 title bar도 같은 목적지로 이동해야 한다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Goals
|
||||||
|
- v2 메인 홈 title bar 우측 아이콘 터치 액션을 추가한다.
|
||||||
|
- `ic_bar_cash` 터치 시 기존 `CanChargeActivity`로 이동한다.
|
||||||
|
- `ic_bar_search` 터치 시 기존 `SearchActivity`로 이동한다.
|
||||||
|
- `ic_bar_bell` 터치 시 기존 `PushNotificationListActivity`로 이동한다.
|
||||||
|
- 목적지 기존 Activity는 수정하지 않고 호출만 한다.
|
||||||
|
- 로그인 필요 여부는 기존 v2 navigation guard 패턴을 따른다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Non-Goals
|
||||||
|
- 이번 PRD 작성 단계에서는 코드, 리소스, 레이아웃 파일을 구현하지 않는다.
|
||||||
|
- title bar 디자인, 아이콘 리소스, 간격, 크기, 노출 조건을 변경하지 않는다.
|
||||||
|
- `CanChargeActivity`, `SearchActivity`, `PushNotificationListActivity` 내부 동작을 수정하지 않는다.
|
||||||
|
- 신규 충전, 검색, 알림 화면을 만들지 않는다.
|
||||||
|
- 레거시 `HomeFragment`의 short icon 액션은 변경하지 않는다.
|
||||||
|
- 콘텐츠 탭의 `ic_bar_storage` 등 이번 요구에 없는 아이콘 액션은 범위에 포함하지 않는다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Target Users
|
||||||
|
- v2 메인 홈에서 상단 아이콘으로 충전, 검색, 알림 리스트에 빠르게 진입하려는 사용자.
|
||||||
|
- 기존 화면을 재사용하면서 v2 홈 title bar 동작을 연결해야 하는 Android 개발자.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. User Stories
|
||||||
|
- 사용자는 홈 상단 cash 아이콘을 누르면 충전 페이지로 이동하고 싶다.
|
||||||
|
- 사용자는 홈 상단 search 아이콘을 누르면 검색 페이지로 이동하고 싶다.
|
||||||
|
- 사용자는 홈 상단 bell 아이콘을 누르면 알림 리스트 페이지로 이동하고 싶다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Core Features
|
||||||
|
|
||||||
|
### title bar 우측 메뉴 routing
|
||||||
|
|
||||||
|
#### Requirements
|
||||||
|
- 구현 대상 title bar:
|
||||||
|
- `app/src/main/res/layout/view_title_bar_home.xml`
|
||||||
|
- include 위치: `app/src/main/res/layout/fragment_v2_main_home.xml`
|
||||||
|
- 연결 Fragment: `app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragment.kt`
|
||||||
|
- 목적지 Activity:
|
||||||
|
- `ic_bar_cash` / `iv_title_bar_cash` -> `kr.co.vividnext.sodalive.mypage.can.charge.CanChargeActivity`
|
||||||
|
- `ic_bar_search` / `iv_title_bar_search` -> `kr.co.vividnext.sodalive.search.SearchActivity`
|
||||||
|
- `ic_bar_bell` / `iv_title_bar_bell` -> `kr.co.vividnext.sodalive.home.pushnotification.PushNotificationListActivity`
|
||||||
|
- `HomeMainFragment.onViewCreated()` 흐름에서 별도 `setupTitleBarActions()`를 호출해 클릭 리스너를 연결한다.
|
||||||
|
- 각 클릭은 `ensureMainV2NavigationAllowed { ... }` 안에서 `startActivity(Intent(requireContext(), TargetActivity::class.java))`를 호출한다.
|
||||||
|
- 새 wrapper, adapter, ViewModel은 만들지 않는다.
|
||||||
|
|
||||||
|
#### Edge Cases
|
||||||
|
- 비로그인 상태에서 아이콘을 터치하면 기존 `ensureMainV2NavigationAllowed` 정책에 따라 로그인 화면으로 유도한다.
|
||||||
|
- Fragment가 view lifecycle 밖에 있을 때 클릭 리스너가 실행되지 않도록 기존 ViewBinding 생명주기 안에서만 연결한다.
|
||||||
|
- Activity launch 실패에 대한 별도 처리나 Toast는 추가하지 않는다. 기존 명시적 Activity intent 경로만 사용한다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. UX / UI Expectations
|
||||||
|
- 화면에 이미 표시되는 title bar 아이콘의 디자인은 유지한다.
|
||||||
|
- 터치 후 목적지 화면 전환은 기존 Android Activity 전환 방식과 동일하게 동작한다.
|
||||||
|
- 아이콘 순서와 의미는 기존 title bar XML과 동일하게 cash, search, bell 순서를 유지한다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Technical Constraints
|
||||||
|
- Android XML View, ViewBinding, Fragment 기반 기존 구조를 유지한다.
|
||||||
|
- 신규 구현은 `kr.co.vividnext.sodalive.v2.main.home.HomeMainFragment`에 한정한다.
|
||||||
|
- 기존 레거시 화면은 직접 수정하지 않는다.
|
||||||
|
- 로그인 guard는 `kr.co.vividnext.sodalive.v2.main.ensureMainV2NavigationAllowed`를 재사용한다.
|
||||||
|
- 관련 근거 파일:
|
||||||
|
- `app/src/main/res/layout/view_title_bar_home.xml`
|
||||||
|
- `app/src/main/res/layout/fragment_v2_main_home.xml`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragment.kt`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/home/HomeFragment.kt`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/MainV2LoginGuard.kt`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/mypage/can/charge/CanChargeActivity.kt`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/search/SearchActivity.kt`
|
||||||
|
- `app/src/main/java/kr/co/vividnext/sodalive/home/pushnotification/PushNotificationListActivity.kt`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Metrics
|
||||||
|
- 정량 지표는 이번 범위에 추가하지 않는다.
|
||||||
|
- 검증 기준은 세 아이콘 클릭 리스너가 코드에 존재하고 각 목적지 Activity로 routing되는지 여부다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Open Questions
|
||||||
|
- 없음. 이번 문서는 세 아이콘이 모두 존재하는 v2 메인 홈 title bar를 구현 대상으로 확정한다.
|
||||||
Reference in New Issue
Block a user