# Task 95.1 완료 보고서: 대시보드 실시간 상태 시스템

- 작업 ID: task-95.1
- 팀: dev2-team (오딘 팀장)
- 담당: 토르(백엔드), 프레이야(프론트엔드), 헤임달(테스터)
- 일시: 2026-03-02

## 작업 요약

훅 기반 봇/팀원 활동 자동 감지 시스템과 SSE 실시간 대시보드 업데이트를 구현했다.

## 구현 항목

### A) 훅 기반 봇 세션 상태 감지
- **user-prompt-submit.sh**: 봇 식별 후 `bot-activity.json`에 `processing` 상태 기록
- **stop-qc-reminder.sh**: Stop 훅에서 해당 봇을 `idle`로 업데이트
- 포맷: `{"bots": {"anu": {"status": "processing", "since": "ISO8601"}, ...}}`
- jq로 해당 봇 키만 원자적 업데이트 (다른 봇 상태 보존)

### B) PreToolUse/PostToolUse 훅으로 팀원 상태 감지
- **settings.json**: PreToolUse(Task) 추가, PostToolUse matcher에 Task 추가
- **pre-tool-use.sh** (신규): Task tool 시작 시 팀원명 파싱 → `member-status.json`에 `working` 기록
- **post-tool-use.sh**: Task tool 완료 시 해당 팀원을 `idle`로 업데이트
- 20개 팀원 한국어/영어 이름 매핑 (긴 패턴 우선 순서)
- 기존 Edit/Write/NotebookEdit audit trail 로직 완전 유지

### C) 대시보드 실시간 업데이트: SSE 구현

**검토한 대안과 기각 사유:**

| 방안 | 장점 | 단점 | 판정 |
|------|------|------|------|
| SSE (Server-Sent Events) | 단방향 푸시, EventSource API 네이티브 지원, 자동 재연결, stdlib 구현 가능 | ThreadingTCPServer 필요, 클라이언트당 1스레드 | **채택** |
| WebSocket | 양방향, 저지연 | 외부 라이브러리 필요, 양방향 불필요, 프로토콜 업그레이드 복잡 | **기각** - 단방향 데이터 흐름에 오버킬 |
| 폴링 최적화 | 가장 단순 | 변경 없어도 요청 발생, 서버 부하, 지연 = 폴링 주기 | **폴백** - SSE 실패 시 2초 폴링으로 폴백 |

**SSE 구현 상세:**
- `ThreadingTCPServer`로 전환 (SSE 장기 연결 + 일반 API 동시 처리)
- `/api/stream` 엔드포인트: 0.5초마다 파일 mtime 변경 감지 → `refresh` 이벤트 푸시
- 감시 대상: bot-activity.json, member-status.json, task-timers.json, tech-debt.json, ci-latest.json
- 15초마다 keepalive 전송 (프록시 타임아웃 방지)
- 클라이언트 연결 끊김 시 BrokenPipeError graceful 처리

### D) 대시보드 프론트엔드 통합
- `/api/bot-activity` API 추가 (bot-activity.json 데이터 반환)
- `EventSource('/api/stream')` 연결: SSE 이벤트 수신 시 즉시 데이터 리프레시
- SSE 실패 시 2초 폴링으로 자동 폴백, SSE 복구 시 폴링 중지
- 헤더에 봇 활동 배지: 아누/1팀/2팀/3팀 processing/idle 실시간 표시
- 연결 상태 인디케이터: SSE(초록)/폴링(노란)/끊김(빨간) 점 표시

## 생성/수정 파일 목록

### 수정된 파일
- `/home/jay/.claude/hooks/user-prompt-submit.sh` - 봇 활동 processing 기록 추가
- `/home/jay/.claude/hooks/stop-qc-reminder.sh` - 봇 활동 idle 기록 추가
- `/home/jay/.claude/settings.json` - PreToolUse 추가, PostToolUse matcher 확장
- `/home/jay/.claude/hooks/post-tool-use.sh` - Task tool 팀원 idle 기록 추가
- `/home/jay/workspace/dashboard/server.py` - /api/bot-activity, /api/stream SSE, ThreadingTCPServer
- `/home/jay/workspace/dashboard/index.html` - SSE EventSource, 봇 상태 UI, 연결 상태 표시

### 신규 생성 파일
- `/home/jay/.claude/hooks/pre-tool-use.sh` - Task PreToolUse 훅 (팀원 working 감지)

### 런타임 생성 파일 (훅에 의해 자동 생성)
- `/home/jay/workspace/memory/events/bot-activity.json` - 봇 활동 상태
- `/home/jay/workspace/memory/events/member-status.json` - 팀원 상태 (기존 파일, 훅이 업데이트)

## 테스트 결과

총 11개 테스트 모두 PASS:

1. bash -n user-prompt-submit.sh → PASS (문법)
2. bash -n stop-qc-reminder.sh → PASS (문법)
3. bash -n pre-tool-use.sh → PASS (문법)
4. bash -n post-tool-use.sh → PASS (문법)
5. settings.json JSON 유효성 → PASS
6. server.py 컴파일 → PASS
7. 봇 활동 기록 (processing) → PASS
8. 봇 idle 업데이트 → PASS
9. 팀원 working 기록 (토르) → PASS
10. 팀원 idle 업데이트 → PASS
11. 다중 팀원 이름 파싱 (프레이야/헤임달/미미르/불칸/아누비스) → PASS
12. 기존 audit trail 동작 유지 → PASS
13. 비-Task tool에서 pre-tool-use.sh graceful exit → PASS
14. 다중 봇 상태 추적 (anu+dev2) → PASS
15. ThreadingTCPServer 사용 가능 → PASS
16. DataLoader.load_bot_activity() 동작 → PASS

## 변경 사유 (감사추적)

- user-prompt-submit.sh: 봇 세션 시작 시 처리 중 상태를 대시보드에 실시간 반영하기 위해 (task-95.1 A항)
- stop-qc-reminder.sh: 봇 세션 종료 시 유휴 상태를 반영하기 위해 (task-95.1 A항)
- settings.json: Task tool 호출 시 팀원 상태를 추적하기 위해 PreToolUse/PostToolUse 훅 매칭 (task-95.1 B항)
- pre-tool-use.sh (신규): Task tool 시작 시점에 팀원 working 상태를 기록하기 위해 (task-95.1 B항)
- post-tool-use.sh: Task tool 완료 시 팀원 idle로 전환 + 기존 audit trail 유지 (task-95.1 B항)
- server.py: SSE 실시간 스트림 + bot-activity API 지원 + ThreadingTCPServer 동시 연결 (task-95.1 C+D항)
- index.html: SSE 기반 실시간 업데이트 + 봇 활동 UI + 연결 상태 표시 (task-95.1 D항)

## 수정 기록 로그
- 2026-03-02 토르: hooks 4개 파일 수정/생성, server.py 수정 (백엔드 전체)
- 2026-03-02 프레이야: index.html 수정 (프론트엔드 SSE + 봇 상태 UI)
- 2026-03-02 헤임달: 16개 테스트 수행, 전원 PASS

## 버그
- 없음

## 비고
- SSE 연결은 인증 면제 처리 (EventSource는 커스텀 Authorization 헤더 불가)
- 대시보드 서버 재시작 필요 (ThreadingTCPServer 전환 반영)
- 기존 5초 폴링 → SSE 이벤트 기반 즉시 업데이트 (파일 변경 후 ~0.5초 내 반영)
