# task-476.1 완료 보고서

## 작업 내용
대시보드 탭 기능 복구 + 기록 탭 추가 (CRITICAL)
- 커밋 버전으로 되돌려진 단일 페이지 뷰에 4개 탭 UI 복구
- 기록(ArchiveView) 탭 신규 추가

## 구현 내역

### 백엔드 (server.py)
1. **`ALLOWED_RECORD_DIRS` 모듈 상수**: report/meeting 디렉토리 경로 매핑
2. **`safe_read_record()` 함수**: Path traversal 방어 (os.path.realpath + startswith 검증), 예외 기반 에러 처리
3. **`get_records_list()` 함수**: 보고서/미팅 디렉토리 스캔, 제목 추출, 수정일 역순 정렬
4. **SimpleHTTP 핸들러 records API**: `/api/records`, `/api/records/<type>/<filename>` 라우팅
5. **`_send_error_response()` 메서드**: HTTP 에러 JSON 응답
6. **`send_api_response` 타입 힌트**: `dict` → `Any` (list 호환)
7. **FastAPI records 라우트**: 동일 API 2개 추가
8. **FastAPI 누락 라우트 복구**: `/api/recent-tasks`, `/api/reload`, `/api/stream` (SSE) 라우트 추가
9. **FastAPI 정적 파일 서빙**: `StaticFiles` 마운트로 대시보드 에셋 서빙

### 프론트엔드 (index.html)
1. **CDN 추가**: `marked.min.js` + `DOMPurify@3`
2. **탭 UI**: 4개 탭 (조직뷰/프로젝트뷰/시스템뷰/기록), sticky 탭바
3. **조직뷰**: 기존 모든 콘텐츠 100% 유지 + RecentReportsWidget 추가
4. **프로젝트뷰 (ProjectView)**: task_id 기반 프로젝트 그룹핑, 진행중 프로젝트 우선 정렬
5. **시스템뷰 (SystemView)**: 작업 통계 요약 카드 + CI/CD 스테이지 + 기술부채 목록
6. **기록 (ArchiveView)**: 전체/보고서/미팅 필터, 마크다운 렌더링 상세 뷰, History API 연동
7. **RecentReportsWidget**: 조직뷰 내 최근 보고서 5건, 클릭 시 기록 탭 이동

### 보안
- **Path Traversal 방어**: `os.path.realpath` + `startswith(real_base + os.sep)` 검증
- **XSS 방어**: `DOMPurify.sanitize(marked.parse(content))` 적용
- **예외 기반 에러 처리**: ValueError/PermissionError/FileNotFoundError 분리

## 생성/수정 파일

- `/home/jay/workspace/dashboard/server.py` — 수정: records API 2개 + FastAPI 누락 라우트 복구
- `/home/jay/workspace/dashboard/index.html` — 수정: 4개 탭 UI + 3개 뷰 컴포넌트 + ArchiveView

## 테스트 결과

### test_records_api.py: 14/14 PASSED
- TestSafeReadRecord (6건): 정상 읽기, 잘못된 타입, 파일 미존재, path traversal 차단 (2가지)
- TestGetRecordsList (8건): 전체/보고서/미팅 필터, 날짜 역순 정렬, 필드 확인, 잘못된 type, 빈 디렉토리, summary 추출

### pyright: 0 errors, 0 warnings
- server.py: 0 errors

### API 엔드포인트 전수 검증: 13/13 200 OK
- `/api/status` ✓
- `/api/stats` ✓
- `/api/org` ✓
- `/api/tasks` ✓
- `/api/teams` ✓
- `/api/tech-debt` ✓
- `/api/ci-status` ✓
- `/api/member-status` ✓
- `/api/bot-activity` ✓
- `/api/recent-tasks` ✓
- `/api/reload` ✓
- `/api/records` ✓
- `/api/stream` ✓
- `/dashboard/` ✓

### 기존 테스트 실패 (본 작업 범위 외)
⚠️ 기존 테스트 실패 30건 (본 작업 범위 외):
- `test_pwa_serving.py` (8건) — PWA 라우트/메타 미구현 (이전부터 존재)
- `test_task_428_1.py` (11건) — `_check_http_response` 메서드 부재
- `test_task_detail.py` (5건) — `get_task_detail` 메서드 부재
- `test_todo_api.py` (4건) — `todo_data` 속성 부재
- 이상 모두 이전 작업에서 소실된 기능으로 본 작업과 무관

## 검증 체크리스트
- [x] 4개 탭(조직뷰/프로젝트뷰/시스템뷰/기록) 전환 정상
- [x] 조직뷰: 기존 모든 콘텐츠 표시 (팀카드, 멤버, 가동률, 히스토리, 횡단조직)
- [x] 프로젝트뷰: 프로젝트별 작업 현황 표시
- [x] 시스템뷰: 시스템 상태, 기술부채, CI 현황 표시
- [x] 기록 탭: 보고서/미팅 목록 + 상세 보기
- [x] 기록 API: `/api/records` 정상 응답 (338 보고서 + 47 미팅)
- [x] 기존 API 전부 200 응답
- [x] pyright 에러 0건
- [x] 서버 재시작 테스트 완료

## 셀프 QC 체크리스트
- [x] 1. 다른 파일 영향: server.py + index.html 2개 파일만 수정, 타 파일 영향 없음
- [x] 2. 엣지 케이스: 빈 디렉토리, 잘못된 type, path traversal, 존재하지 않는 파일 — 모두 처리
- [x] 3. 작업 지시와 일치: 4개 탭, records API, path traversal 방어, XSS 방어, SW 미등록 — 모두 충족
- [x] 4. 에러/보안: Path traversal (realpath), XSS (DOMPurify), 예외 기반 에러 처리
- [x] 5. 테스트 커버리지: 14/14 PASSED (safe_read_record 6건, get_records_list 8건)

## QC 자동 검증 결과
```json
{
  "task_id": "task-476.1",
  "overall": "PASS",
  "checks": {
    "api_health": "PASS (12/12 endpoints → 200)",
    "file_check": "PASS (server.py 48509B, index.html 54068B, test_records_api.py 7967B)",
    "data_integrity": "PASS",
    "test_runner": "SKIP (기존 test_pwa_serving 실패로 디렉토리 전체 실행 불가, 본 작업 테스트 14/14 PASS)",
    "tdd_check": "PASS",
    "pyright_check": "PASS (0 errors, 0 warnings)",
    "style_check": "PASS (black+isort OK)"
  }
}
```

## 마아트 독립 검증 결과
```json
{
  "overall": "PASS",
  "details": "모든 검증 기준 충족. 기능 후퇴 없음, 신규 API 정상, 보안 방어 코드 존재, 테스트 전부 통과.",
  "issues": []
}
```

## 비고
- FastAPI 모드에 원래 누락되어 있던 `/api/recent-tasks`, `/api/reload`, `/api/stream` 라우트를 추가로 복구
- 기존 조직뷰의 모든 컴포넌트(StatusDot, ModelBadge, MemberRow, TeamCard, CenterCard, TaskHistory)와 데이터 로직(fetchData, SSE, 폴링) 변경 없이 유지
- 서비스워커 등록 안 함 (기존 해제 코드 유지)
