# task-1039.1 완료 보고서

## SCQA

**S**: 대시보드의 "작업별 토큰 사용량"이 `token-ledger.json` 기반으로 표시되며, 이 파일은 `python3 scripts/token-tracker.py scan` 수동 실행으로만 갱신된다.

**C**: 대시보드 새로고침 시에도 `last_scan`이 수 시간 전에 머물러 있어 최신 작업의 토큰 데이터가 표시되지 않는다.

**Q**: 대시보드 API 호출 시 `token-ledger.json`이 30분 이상 오래되었으면 자동으로 스캔을 트리거하여 최신 데이터를 제공할 수 있는가?

**A**: `_maybe_trigger_token_scan()` 공통 메서드를 도입하여 `get_token_usage()`와 `_enrich_tasks_with_tokens()` 양쪽에서 호출하도록 구현 완료. 인스턴스 변수 `_last_token_scan_trigger`로 30분 내 중복 스캔 방지. pytest 19건 전체 통과, pyright 에러 0건.

## 수정 파일

- `/home/jay/workspace/dashboard/server.py`

## 변경 내용

### 1. `__init__` — 인스턴스 변수 추가 (line 66)
```python
self._last_token_scan_trigger: Optional[datetime] = None
```

### 2. `_maybe_trigger_token_scan()` 헬퍼 메서드 신규 (line 733~758)
- `token-ledger.json`의 `last_scan` 타임스탬프 확인
- 30분(1800초) 이상 경과 시 `scripts/token-tracker.py scan` 실행
- `subprocess.run(..., capture_output=True, timeout=60)` — 타임아웃 60초
- `_last_token_scan_trigger` 인스턴스 변수로 30분 내 재트리거 방지 (2중 보호)
- 모든 예외를 catch하여 스캔 실패 시에도 기존 데이터로 진행

### 3. `_enrich_tasks_with_tokens()` — 호출 추가 (line 762)
```python
self._maybe_trigger_token_scan()
```

### 4. `get_token_usage()` — 호출 추가 (line 1035)
```python
self._maybe_trigger_token_scan()
```

## 완료 조건 검증

1. **30분 이상 경과 시 자동 스캔** — `last_scan` 타임스탬프 비교 로직 구현 ✅
2. **스캔 완료 후 최신 데이터로 응답** — 동기 실행 후 ledger 재읽기 ✅
3. **스캔 실패 시 기존 데이터로 정상 응답** — `except Exception: pass` ✅
4. **30분 내 중복 스캔 방지** — `_last_token_scan_trigger` 인스턴스 변수 ✅
5. **기존 토큰 관련 로직 파괴 없음** — pytest 19건 전체 통과 ✅

## 테스트 결과

- pytest `tests/test_automation_api.py`: **19 passed** (0.21s)
- pyright: **0 errors, 0 warnings, 0 informations**
- AST parse: **OK** (문법 에러 없음)

## 발견 이슈 및 해결

### 자체 해결 (1건)
1. **공통 메서드 추출로 중복 방지** — 지시서에서는 양쪽 메서드에 각각 스캔 로직을 넣으라 했으나, 코드 중복을 방지하기 위해 `_maybe_trigger_token_scan()` 공통 메서드로 추출하여 양쪽에서 호출하도록 설계. 중복 스캔 방지도 인스턴스 레벨 1곳에서만 관리.

### 범위 외 미해결 (1건)
1. **token-tracker.py 스캔 성능** — 현재 동기 실행(최대 60초 블로킹). 향후 요청 빈도가 높아지면 비동기 실행 검토 필요. 범위 외 사유: 지시서에서 동기 실행 명시 ("보통 5-10초").

### 범위 외 참고 (1건)
1. **ledger 파일 미존재 시 스캔 미실행** — ledger 파일 자체가 없으면 `_maybe_trigger_token_scan()`이 조기 return하므로 최초 스캔은 여전히 수동 필요. 지시서 범위 외이지만 참고 기록.
