docs(banner): Phase 5 검증을 기록한다

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-05-28 10:50:30 +09:00
parent bc15a0997e
commit dcc76abf94

View File

@@ -229,7 +229,7 @@
### Phase 5: 자동 전환, 수동 스와이프, lifecycle ### Phase 5: 자동 전환, 수동 스와이프, lifecycle
- [ ] **Task 5.1: 자동 전환 timer 구현** - [x] **Task 5.1: 자동 전환 timer 구현**
- 수정 파일: `BannerView.kt` - 수정 파일: `BannerView.kt`
- 요구사항: - 요구사항:
- 배너 2개 이상일 때만 5초 timer를 시작한다. - 배너 2개 이상일 때만 5초 timer를 시작한다.
@@ -237,7 +237,7 @@
- 전환 애니메이션 시간은 350ms를 기준으로 한다. - 전환 애니메이션 시간은 350ms를 기준으로 한다.
- 검증: 테스트 가능한 timer wrapper를 두거나 Robolectric scheduler로 자동 전환 호출을 검증한다. - 검증: 테스트 가능한 timer wrapper를 두거나 Robolectric scheduler로 자동 전환 호출을 검증한다.
- [ ] **Task 5.2: 무한 순환 이동 구현** - [x] **Task 5.2: 무한 순환 이동 구현**
- 수정 파일: `BannerView.kt`, `BannerAdapter.kt`, `BannerState.kt` - 수정 파일: `BannerView.kt`, `BannerAdapter.kt`, `BannerState.kt`
- 요구사항: - 요구사항:
- 마지막 배너 다음 방향은 첫 번째 배너로 이어진다. - 마지막 배너 다음 방향은 첫 번째 배너로 이어진다.
@@ -245,14 +245,14 @@
- virtual position을 사용하는 경우 실제 index와 counter index가 항상 일치한다. - virtual position을 사용하는 경우 실제 index와 counter index가 항상 일치한다.
- 검증: `BannerStateTest``BannerViewTest`에서 next/previous remap을 확인한다. - 검증: `BannerStateTest``BannerViewTest`에서 next/previous remap을 확인한다.
- [ ] **Task 5.3: 수동 스와이프 timer reset 구현** - [x] **Task 5.3: 수동 스와이프 timer reset 구현**
- 수정 파일: `BannerView.kt` - 수정 파일: `BannerView.kt`
- 요구사항: - 요구사항:
- RecyclerView scroll state가 사용자 drag로 시작되면 자동 전환 예약을 취소한다. - RecyclerView scroll state가 사용자 drag로 시작되면 자동 전환 예약을 취소한다.
- scroll settle 후 현재 시점부터 5초 timer를 다시 예약한다. - scroll settle 후 현재 시점부터 5초 timer를 다시 예약한다.
- 검증: 수동 scroll 이벤트 시 timer reset 메서드가 호출되는지 view test에서 확인한다. - 검증: 수동 scroll 이벤트 시 timer reset 메서드가 호출되는지 view test에서 확인한다.
- [ ] **Task 5.4: attach/detach lifecycle 정리** - [x] **Task 5.4: attach/detach lifecycle 정리**
- 수정 파일: `BannerView.kt` - 수정 파일: `BannerView.kt`
- 요구사항: - 요구사항:
- `onAttachedToWindow()`에서 조건에 맞으면 timer를 시작한다. - `onAttachedToWindow()`에서 조건에 맞으면 timer를 시작한다.
@@ -343,3 +343,6 @@
- 2026-05-27 Phase 4 검증: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.widget.banner.*"``./gradlew :app:assembleDebug`를 순차 실행해 모두 `BUILD SUCCESSFUL`을 확인했다. Kotlin LSP는 `kotlin-lsp`가 설치되어 있지 않아 diagnostics를 실행할 수 없었다. - 2026-05-27 Phase 4 검증: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.widget.banner.*"``./gradlew :app:assembleDebug`를 순차 실행해 모두 `BUILD SUCCESSFUL`을 확인했다. Kotlin LSP는 `kotlin-lsp`가 설치되어 있지 않아 diagnostics를 실행할 수 없었다.
- 2026-05-27 Phase 4 리뷰 수정: 리뷰에서 `BannerView(context)` 실제 사용 경로가 내부 layout을 inflate하지 않는 문제가 지적되어, `view_banner.xml``<merge>`로 변경하고 `BannerView` 생성 시 내부 layout을 inflate하도록 수정했다. `배너 view는 코드로 생성해도 내부 layout을 포함한다` 테스트로 RED를 확인한 뒤 GREEN을 확인했다. - 2026-05-27 Phase 4 리뷰 수정: 리뷰에서 `BannerView(context)` 실제 사용 경로가 내부 layout을 inflate하지 않는 문제가 지적되어, `view_banner.xml``<merge>`로 변경하고 `BannerView` 생성 시 내부 layout을 inflate하도록 수정했다. `배너 view는 코드로 생성해도 내부 layout을 포함한다` 테스트로 RED를 확인한 뒤 GREEN을 확인했다.
- 2026-05-27 Phase 4 리뷰 수정 후 검증: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.widget.banner.*"``./gradlew :app:assembleDebug`를 다시 실행해 모두 `BUILD SUCCESSFUL`을 확인했다. - 2026-05-27 Phase 4 리뷰 수정 후 검증: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.widget.banner.*"``./gradlew :app:assembleDebug`를 다시 실행해 모두 `BUILD SUCCESSFUL`을 확인했다.
- 2026-05-28 Phase 5 RED: `BannerViewTest`에 자동 전환, 수동 drag timer reset, detach cleanup 테스트를 추가한 뒤 production 변경 전 실행해 자동 전환/drag reset 시나리오 실패를 확인했다.
- 2026-05-28 Phase 5 구현: `BannerView`에 main looper `Handler/Runnable` 기반 5초 자동 전환, `SCROLL_STATE_DRAGGING` 중 timer 취소, `SCROLL_STATE_IDLE` 후 재예약, `onAttachedToWindow` 시작, `onDetachedFromWindow` callback 제거를 추가했다. `BannerAdapter.startPosition()`으로 carousel 시작 위치를 virtual range 중앙에 맞췄다.
- 2026-05-28 Phase 5 검증: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.widget.banner.BannerViewTest"`, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.widget.banner.*"`, `./gradlew :app:assembleDebug` 실행 결과 모두 `BUILD SUCCESSFUL`을 확인했다.