# task-1175.1 완료 보고서

**작업**: 대시보드 계정 드롭다운에 사용량 표시 (statusline rate_limits 방식)
**팀**: dev1-team (헤르메스)
**담당**: 불칸(백엔드), 이리스(프론트엔드), 아르고스(테스트)

---

## SCQA

**S**: 대시보드 상단에 계정 전환 드롭다운이 구현되어 있으며, 계정명/이메일/구독타입을 표시하고 있다. task-1168.1 리서치에서 OAuth Usage API를 통해 계정별 사용량을 프로그래매틱하게 조회 가능함이 확인되었다.

**C**: 현재 사용량 정보가 없어 어느 계정이 rate limit에 가까운지 대시보드에서 확인할 수 없다. 계정을 전환하려면 CLI에서 직접 `claude status`를 실행해야 한다.

**Q**: 계정 드롭다운에서 각 계정의 5시간/7일 사용량을 실시간으로 확인할 수 있는가?

**A**: `GET /api/usage-status` API를 추가하고 OAuth Usage API(`api.anthropic.com/api/oauth/usage`)로 계정별 사용량을 조회하여 드롭다운에 프로그레스 바로 표시. 5분 캐시 적용으로 API rate limit 방어. 테스트 6건 통과, pyright 에러 0건.

---

## 구현 내역

### 1. server.py — `GET /api/usage-status` API (불칸)
- `_get_usage_status()` 메서드 추가 (line 3469-3527)
- `~/.claude/.credentials-*.json` 순회하여 각 계정의 `accessToken` 추출
- `https://api.anthropic.com/api/oauth/usage` API 호출 (헤더: `anthropic-beta: oauth-2025-04-20`)
- `utilization` 0~1 소수 → 0~100% 변환
- 모듈 레벨 5분(300초) TTL 캐시 적용 (line 40-43)
- `import urllib.request` 추가 (line 31)
- `do_GET()` 라우팅 추가 (line 3366-3368)

### 2. App.js — 드롭다운 사용량 UI (이리스)
- `usageStatus` state 추가 (line 42)
- 드롭다운 열릴 때 `/api/usage-status` fetch (line 67-70)
- 헤더 계정 버튼에 사용량 % 간략 표시 (line 274-279)
- 각 계정 항목에 프로그레스 바 + 리셋 시간 표시 (line 333-354)
- 색상: 0-49% emerald, 50-79% amber, 80%+ red + ⚠️ 아이콘

### 3. test_usage_status.py — 단위 테스트 (아르고스)
- 6개 테스트 케이스: 정상 fetch, 빈 credential, accessToken 누락, API 실패 graceful, 캐시 히트, 캐시 만료

---

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **Path.stem mock 불가** — 테스트에서 `Path.stem`을 클래스 레벨 patch할 수 없어, 임시 디렉토리에 실제 파일을 생성하는 방식으로 변경
2. **HTTP handler 인스턴스 캐시 문제** — HTTP handler는 요청마다 새 인스턴스이므로, 캐시를 모듈 레벨 전역 변수(`_usage_cache`)로 구현하여 해결
3. **utilization 단위 불일치** — OAuth API는 0~1 소수, UI는 0~100% 필요 → `* 100` 변환 적용

### 범위 외 미해결 (2건)
1. **비활성 계정 사용량 정확도** — OAuth API는 현재 로그인된 계정이 아닌 credential의 accessToken으로 호출하므로, 토큰이 만료된 계정은 조회 실패 가능. 범위 외 사유: 토큰 갱신 로직은 claude CLI 내부 관리
2. **OAuth Usage API 비공식** — 비문서화 API이므로 향후 변경/폐기 가능 (task-1168.1 리서치에서 #31637 이슈로 기록됨). 범위 외 사유: Anthropic 서버 정책

---

## 산출물

- `/home/jay/workspace/dashboard/server.py` (수정: API 엔드포인트 + 메서드 + 캐시)
- `/home/jay/workspace/dashboard/components/App.js` (수정: state + fetch + 프로그레스 바 UI)
- `/home/jay/workspace/dashboard/tests/test_usage_status.py` (신규: 6개 테스트)
- `/home/jay/workspace/memory/reports/task-1175.1.md` (본 보고서)

---

## 테스트 결과

- pytest: 6/6 통과 (0.07s)
- 기존 test_server.py: 7/7 통과 (0.23s) — 회귀 없음
- pyright server.py: 0 errors, 0 warnings
- python3 py_compile: server.py syntax OK

---

## QC 자동 검증 결과

- **전체**: WARN (7 PASS, 4 SKIP, 1 WARN)
- file_check: PASS (server.py 199,017B, App.js 60,642B, test_usage_status.py 6,013B)
- data_integrity: PASS
- test_runner: PASS (pytest 7 passed in 0.23s)
- pyright_check: PASS (0 errors, 0 warnings)
- style_check: WARN (black/isort 포맷팅 필요 — 기능 무관)
- critical_gap: PASS
- spec_compliance: PASS
- duplicate_check: PASS (최대 유사도 10.5%)
- api_health/tdd_check/schema_contract/scope_check: SKIP
