# 대시보드 인프라 개선 Lv.4 — 코드 변경 즉시 반영 시스템

## ★★★ 목표 ★★★
대시보드 코드(server.py, *.js)를 수정하면 **수동 재시작/캐시 클리어 없이 즉시 반영**되어야 한다.
현재 반복되는 3가지 문제를 근본적으로 해결한다.

## 문제 1: server.py 수정 후 수동 서버 재시작 필수

### 해결: 파일 변경 감지 → 자동 graceful restart

**방식**: watchdog(파이썬 패키지) 기반 파일 감시 + systemd 연동

**구현**:
1. `/home/jay/workspace/dashboard/auto_reload.py` 신규 생성
   - watchdog FileSystemEventHandler로 dashboard/ 디렉토리 감시
   - `.py` 파일 변경 감지 시 → `systemctl --user restart dashboard.service` 실행
   - 디바운스: 2초 이내 연속 변경은 마지막 1회만 재시작
   - 제외 패턴: `data/`, `__pycache__/`, `.pyc`, `.db`, `.json`, `.log`
   - 로깅: 재시작 시각 + 변경된 파일명 기록

2. `/home/jay/.config/systemd/user/dashboard-watcher.service` 신규 생성
   - auto_reload.py를 systemd 서비스로 등록
   - Restart=always, After=dashboard.service
   - 대시보드 서비스와 독립 실행

3. `systemctl --user enable dashboard-watcher.service` 등록

**주의**:
- server.py 자체가 재시작되는 것이므로, 진행 중인 요청은 끊길 수 있음 → graceful shutdown 시그널(SIGTERM) 처리
- data/ 디렉토리 변경(json, db)은 재시작 트리거에서 제외 (데이터 변경마다 재시작하면 안 됨)
- worktree 내 파일 변경은 감시 대상 아님 (머지 후 main에 반영될 때만)

## 문제 2: 프론트엔드 JS 수정 후 브라우저 캐시로 구버전 표시

### 해결: SW 캐시 버전을 파일 해시 기반으로 자동 갱신

**현재**: `sw.js`에 `CACHE_NAME = "dashboard-v14"` 하드코딩 → 수동 bump 필요

**구현**:
1. server.py의 정적 파일 서빙에 **ETag 헤더** 추가
   - 파일의 mtime 또는 MD5 해시 기반
   - `Cache-Control: no-cache` + ETag 조합 → 브라우저가 매번 서버에 확인, 변경 시만 다운로드

2. sw.js에서 **네트워크 우선(Network First) 전략** 적용
   - `.js`, `.css` 파일은 항상 네트워크에서 먼저 로드
   - 실패 시에만 캐시 폴백
   - 이미지/폰트 등 무거운 리소스만 캐시 우선

3. CACHE_NAME에 **빌드 타임스탬프** 자동 삽입
   - server.py 시작 시 sw.js의 CACHE_NAME을 현재 시각 기반으로 동적 생성
   - 또는 `/api/version` 엔드포인트 → sw.js가 주기적으로 확인 → 버전 변경 시 캐시 전체 갱신

**권장 방식**: 2번(Network First) + 1번(ETag) 조합이 가장 안전.
- sw.js의 PRE_CACHE_URLS에서 컴포넌트 JS 파일 제거 (프리캐시하지 않음)
- 또는 sw.js 자체를 제거하고 ETag만 활용 (가장 단순)

**★ 결정 필요**: sw.js를 유지할지 제거할지. 오프라인 지원이 필요 없으면 제거가 가장 깔끔.
→ 대시보드는 항상 온라인에서 사용하므로 **sw.js 제거 권장**. 대신 ETag + no-cache로 즉시 반영.

## 문제 3: 여러 봇이 같은 파일 수정 시 덮어쓰기

### 해결: worktree 머지 규칙은 이미 추가됨 (DIRECT-WORKFLOW.md)

추가 안전장치:
1. server.py 수정 전 `git stash` 또는 현재 diff 확인 로직을 워크플로우에 추가
2. 머지 후 자동 재시작 (문제 1 해결로 자동 적용)

## 구현 순서 (의존성 고려)

1. **Step 1**: sw.js 제거 + ETag 헤더 추가 (프론트엔드 캐시 문제 해결)
   - sw.js 삭제 (또는 unregister 코드만 남김)
   - server.py end_headers에서 정적 파일에 ETag + Cache-Control: no-cache 추가
   - index.html에서 SW 등록 코드 제거 (또는 기존 SW unregister 코드로 교체)

2. **Step 2**: auto_reload.py + systemd watcher 서비스 (서버 자동 재시작)
   - watchdog 패키지 설치 확인 (`pip install watchdog`)
   - auto_reload.py 작성
   - systemd 서비스 등록 + 활성화

3. **Step 3**: 통합 테스트
   - server.py 수정 → 2초 내 자동 재시작 확인
   - JS 파일 수정 → 브라우저 새로고침만으로 즉시 반영 확인
   - 수동 서버 재시작 불필요 확인

## 검증 시나리오

### Step 1 검증
1. JS 파일 수정 → 브라우저 새로고침(F5)만으로 변경 반영 → 성공
2. Ctrl+Shift+R (강제 새로고침) 불필요 → 성공
3. 다른 브라우저/시크릿 모드에서도 즉시 반영 → 성공
4. F12 → Application → Service Workers → 등록된 SW 없음 → 성공
5. 기존 유저가 접속 시 자동으로 구 SW unregister → 성공

### Step 2 검증
1. `echo "# test" >> server.py && sleep 3 && curl -s http://localhost:8000/api/org` → 응답 정상 (자동 재시작됨) → 성공
2. data/wiki-statuses.json 수정 → 서버 재시작 안 됨 (data/ 제외) → 성공
3. `systemctl --user status dashboard-watcher.service` → active(running) → 성공
4. 서버 재시작 로그에 변경 파일명 기록 → 성공

### Step 3 통합 검증
1. server.py에 새 API 추가 → 저장 → 2초 후 curl로 호출 → 정상 응답 → 성공
2. NaverBlogView.js 수정 → 브라우저 F5 → 변경 반영 → 성공
3. 동시에 server.py + JS 수정 → 둘 다 반영 → 성공

## ★★★ 절대 규칙 ★★★
- 기존 대시보드 기능에 영향 없어야 함 (회귀 테스트)
- data/ 디렉토리 파일(json, db, log)은 자동 재시작 트리거에서 제외
- index.html의 SW unregister 코드는 기존 유저의 구 SW 정리를 위해 일정 기간 유지