Phase 99: 검증
빌드 검증
# 프론트엔드 빌드 확인
nx build dha-sleep-app-web
# 린트 검증
nx lint dha-sleep-app-web
모든 빌드가 성공해야 구현 완료로 간주한다.
기능 테스트
테스트 1: Pull-to-Refresh 기본 동작
경로: localhost:6010 (홈 화면)
기대 동작:
- 홈 화면 상단에서 아래로 스와이프를 시작한다
- 당기는 거리에 비례하여 화살표 인디케이터가 나타난다
- 80px 이상 당기면 인디케이터가 완전 표시(opacity: 1, scale: 1)된다
- 손을 떼면 스피너로 전환되고 데이터 갱신이 시작된다
- 갱신 완료 후 인디케이터가 사라지고 콘텐츠가 원위치로 복귀한다
- HomeCard 인사말이 최신 데이터로 업데이트된다
기대 로그:
[HomeScreen] Pull-to-refresh triggered
[Prefetch] Starting parallel prefetch (Zygote + Profile)...
[HomeScreen] Pull-to-refresh completed
테스트 2: Threshold 미만 스냅백
경로: localhost:6010 (홈 화면)
기대 동작:
- 홈 화면에서 아래로 약간만 당긴다 (80px 미만)
- 인디케이터가 반투명하게 표시된다
- 손을 떼면 콘텐츠가 원위치로 스냅백된다
- 데이터 갱신이 발생하지 않는다
테스트 3: 중복 Refresh 방지
경로: localhost:6010 (홈 화면)
기대 동작:
- Pull-to-refresh를 트리거하여 스피너가 표시된다
- 스피너가 회전하는 동안 다시 아래로 당기려 시도한다
- 추가 당김이 무시된다 (isRefreshing 체크)
- 첫 번째 갱신이 완료된 후에야 다시 pull-to-refresh 가능
테스트 4: 하단 고정 영역과의 독립성
경로: localhost:6010 (홈 화면)
기대 동작:
- Pull-to-refresh 시 하단 제안 칩과 입력창(
fixed요소)은 이동하지 않는다 - 하단 영역의 가로 스크롤이 정상 동작한다
- 입력창 탭 시 키보드가 정상적으로 올라온다
테스트 5: 브라우저 기본 Pull-to-Refresh 차단
경로: Chrome DevTools → Mobile View로 테스트
기대 동작:
overscroll-behavior-y: none으로 인해 Chrome 기본 pull-to-refresh가 비활성화- 커스텀 pull-to-refresh 인디케이터만 표시
테스트 6: Reduced Motion 접근성
경로: Chrome DevTools → Rendering → Emulate CSS media feature prefers-reduced-motion: reduce
기대 동작:
- Pull-to-refresh 스피너 애니메이션이 최소화된다
- 콘텐츠 이동 애니메이션이 즉시(0.01ms) 전환된다
체크리스트
Frontend 체크리스트
| 체크 | 항목 |
|---|---|
| [ ] | 접근성: 인디케이터에 aria-label, role="status" 적용 |
| [ ] | 터치 타겟: 인디케이터 영역 44x44px 이상 (40x40 아이콘 + 패딩) |
| [ ] | prefers-reduced-motion 적용 (globals.css 기존 규칙으로 자동) |
| [ ] | overscroll-behavior-y: none 적용 확인 |
| [ ] | 빈 상태 처리: HomeCard가 null이어도 pull-to-refresh 동작 |
| [ ] | 에러 처리: API 실패 시에도 인디케이터 해제 (finally 블록) |
| [ ] | 로딩 상태: isRefreshing 중 추가 pull 방지 |
변경 파일 총 목록
| # | 파일 | 유형 | Phase |
|---|---|---|---|
| 1 | apps/dha-sleep-app-web/components/ui/pull-to-refresh.tsx | NEW | 1 |
| 2 | apps/dha-sleep-app-web/components/screens/home/home-screen.tsx | EDIT | 1 |
| 3 | apps/dha-sleep-app-web/app/globals.css | EDIT | 1 |
| 총계 | 1 NEW + 2 EDIT |
변경하지 않는 것:
stores/home-card-store.ts,stores/prefetch-store.ts,hero-section.tsx,home-top-bar.tsx, 백엔드 API,capacitor.config.ts— 기존 로직 그대로 활용하므로 변경 불필요