# task-1145.1 완료 보고서: 대시보드 파일 뷰어 이미지 지원

## SCQA

**S**: 대시보드 파일 뷰어가 .md, .txt, .json, .yaml, .py 5종만 지원하여, 광고 소재 등 이미지 파일은 대시보드에서 직접 확인할 수 없었다.

**C**: 이미지 산출물이 output/ 디렉토리에 생성되지만, ALLOWED_PREFIXES에도 포함되지 않아 접근 자체가 차단되고, 이미지 확장자도 허용되지 않아 열람이 불가능했다.

**Q**: 대시보드 파일 뷰어에서 이미지 파일(.png, .jpg, .jpeg, .gif, .svg, .webp)을 안전하게 열람할 수 있는가?

**A**: server.py에 이미지 확장자 6종 + output/ 경로 허용 + base64 인코딩 응답을 추가하고, utils.js FileViewerModal에 이미지 렌더링 분기를 구현했다. 기존 보안 검증(path traversal, workspace 범위, 민감 파일 차단)은 그대로 유지. pytest 7건 통과, pyright 에러 0건.

## 변경 파일

- `/home/jay/workspace/dashboard/server.py`
  - ALLOWED_PREFIXES: `"output/"` 추가 (line 2906)
  - ALLOWED_EXTENSIONS: `.png`, `.jpg`, `.jpeg`, `.gif`, `.svg`, `.webp` 추가 (line 2911)
  - 파일 응답 로직: 이미지/텍스트 분기 처리 — 이미지는 `read_bytes()` + base64 인코딩, 텍스트는 기존 `read_text()` (line 2934~2967)
  - 응답에 `type` 필드 추가 (`"image"` 또는 `"text"`)

- `/home/jay/workspace/dashboard/components/utils.js`
  - FileViewerModal: API 응답 전체 객체 저장 (`setContent(data)`) (line 693)
  - 렌더링 로직: `content.type === 'image'` 시 `<img>` 태그로 base64 데이터 표시 (line 730~737)
  - 텍스트/마크다운 렌더링: `content.content || content` fallback으로 하위호환 유지 (line 740, 743)

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **base64 중복 import으로 Pyright unbound 에러** — 상단(line 17)에 이미 `import base64` 존재하는데 이미지 처리 블록 내부에 중복 import 추가됨. 중복 제거로 해결.
2. **output/ 경로 ALLOWED_PREFIXES 누락** — 태스크 지시대로 추가 완료. 이미지 산출물이 저장되는 경로 접근 허용.
3. **프론트엔드 하위호환성** — API 응답 구조 변경(content → data 객체)으로 기존 텍스트 뷰어 깨질 수 있음. `content.content || content` fallback 패턴 적용으로 해결.

### 범위 외 미해결 (0건)
없음.

## 테스트 결과

- pytest: 7건 통과 (0.22s)
- pyright: 에러 0건, 경고 0건
- style_check: WARN (black 포맷 — 기존 코드 스타일 이슈, 본 작업 범위 외)

## QC 자동 검증 결과

```json
{
  "task_id": "task-1145.1",
  "overall": "4 PASS, 1 FAIL(report/done 미생성 시점), 6 SKIP, 1 WARN",
  "pyright_check": "PASS (0 errors)",
  "test_runner": "PASS (7 passed in 0.22s)",
  "style_check": "WARN (black formatting)"
}
```
