# 재고 현황 E2E 체크리스트

## 개요
- `/inventory/summary` 플로우가 백엔드 계약(`stock_approval_system_api_v4.md` §4.8~4.9)과 UI 명세(`doc/inventory_management_feature_plan.md`)을 모두 만족하는지 QA 단계에서 검증한다.
- Chrome CanvasKit 렌더러 기준으로 테스트하며, 로그인 응답의 `permissions` 또는 `permission_codes`에 `scope:inventory.view`가 포함된 계정을 사용한다.

## 사전 조건
1. `.env.development` 또는 `.env.production`에서 `Environment.initialize()`가 성공적으로 수행되어야 한다.
2. `inventory_balance_snapshots` 마테뷰 리프레시 스크립트가 직전 5분 내 실행되어 `last_refreshed_at`이 현재 시각과 5분 이상 차이나지 않아야 한다.
3. QA 계정은 `scope:inventory.view` 및 `menu_code=inventory` `can_read=true` 권한을 모두 보유해야 한다.

## 시나리오
1. **기본 목록 로딩**
   - 조건: 초기 페이지 진입
   - 기대 결과: View Only 배지, 총 제품 수, 최근 이벤트 기준 카드 노출, 테이블 기본 정렬은 `last_event_at DESC`.
2. **자동 새로고침 토글**
   - 조건: 자동 새로고침 스위치를 활성화한 상태에서 30초 이상 대기
   - 기대 결과: 추가 조작 없이 목록이 다시 로딩되고 `마지막 리프레시` 라벨이 최신 값으로 갱신된다.
3. **자동 새로고침 비활성화**
   - 조건: 스위치를 끄고 45초 이상 대기
   - 기대 결과: 추가 로딩이 발생하지 않으며, 다시 스위치를 켜면 즉시 주기 타이머가 재시작된다.
4. **필터 적용/리셋**
   - 조건: 검색어 + 벤더 + 창고 선택 후 적용 → 리셋
   - 기대 결과: 적용 시 해당 파라미터가 API 호출에 포함되고, 리셋 시 모든 입력/토글이 초기 상태로 돌아간다.
5. **상세 시트 그래프 & 접근성**
   - 조건: 행 클릭 → 상세 시트 오픈
   - 기대 결과: 창고 잔량 미니 차트가 창고명/수량과 함께 노출되고, 스크린리더에서 `창고명 잔량 N개`로 읽힌다.
6. **최근 이벤트 타임라인**
   - 조건: 상세 시트에서 최근 이벤트가 존재하는 제품 선택
   - 기대 결과: 이벤트 라벨, 수량 증감 색상, 거래처 정보 표기가 존재하며, 스크린리더는 `최근 이벤트 <라벨>`과 변화량/발생 시각을 낭독한다.
7. **빈 상태 / 오류 배너**
   - 조건: 존재하지 않는 제품명으로 필터 → 빈 상태 확인, 이후 프록시로 500 오류를 강제
   - 기대 결과: 빈 상태 문구와 오류 배너가 각각 노출되고 닫기 버튼 작동.
8. **권한 미보유 접근**
   - 조건: `scope:inventory.view`가 없는 계정으로 직접 URL 접근
   - 기대 결과: 라우터가 가드를 통해 접근을 차단하고, 감사 로그에는 권한 부족 사유가 남는다.

## 추가 메모
- E2E 수행 후 `doc/qa/inventory_data_replay.md`에 사용한 시드 데이터와 `last_refreshed_at` 값을 기록한다.
- 자동 새로고침으로 발생하는 API 호출 횟수는 30초 간격 기준 초당 0.033회이므로, 부하 테스트 시 50 동시 사용자까지 문제 없는지 모니터링한다.
