# task-1690.1 완료 보고서
> 네이버블로그 — Failed to fetch 에러 수정 + 히스토리 재생성 기능

## SCQA

**S**: 네이버 블로그 워크플로우 대시보드에서 AI 글 생성 기능과 키워드 분석 히스토리가 운영 중이다.

**C**: 글 생성 버튼 클릭 시 "Failed to fetch" 에러가 발생하여 글 작성이 불가능하다. 원인은 서버의 subprocess.run `timeout=None` 설정으로 CLI 호출이 무한 대기하면서 브라우저 fetch가 타임아웃되는 것이다. 또한 키워드 분석 히스토리에서 이전 분석 결과로 글을 재생성하는 기능이 없어 매번 키워드를 수동 입력해야 한다.

**Q**: Failed to fetch 에러를 해소하고, 히스토리에서 글 재생성이 가능하도록 할 수 있는가?

**A**: 서버에 모델별 타임아웃(sonnet 300초, haiku 180초, gemini 300초, gpt 120초)을 설정하고 `subprocess.TimeoutExpired` 예외 처리를 추가하여 504 응답과 구체적 에러 메시지를 반환하도록 수정했다. 프론트엔드에는 AbortController(330초 타임아웃) 추가 + 에러 메시지 3단계 분기(AbortError/Failed to fetch/기타)를 구현했다. 히스토리에서는 키워드분석/글작성 탭 모두에 "이 키워드로 글 재생성" 버튼을 추가하여, 클릭 시 키워드가 글 생성 단계(step=1)로 전달되고 어투/모델 선택 후 재생성 가능하다.

## 수정 파일 목록

- `/home/jay/workspace/dashboard/server.py` (라인 5292-5334)
- `/home/jay/workspace/dashboard/components/NaverBlogView.js` (라인 558-597, 1561, 1686-1698, 1701-1726, 1797-1801)

## 변경 상세

### 1. Failed to fetch 에러 수정

**서버 (server.py)**
- `timeout = None` → 모델별 딕셔너리: `{"sonnet": 300, "haiku": 180, "gemini": 300, "gpt": 120}`
- `subprocess.TimeoutExpired` 전용 except 블록 추가 → HTTP 504 + 구체적 타임아웃 메시지 반환

**프론트엔드 (NaverBlogView.js)**
- `AbortController` + 330초 클라이언트 타임아웃 추가
- 에러 메시지 3단계 분기:
  - `AbortError` → "AI 글 생성 시간이 초과되었습니다..."
  - `Failed to fetch` → "서버 연결에 실패했습니다..."
  - 서버 에러 → 서버 반환 에러 메시지 표시 (기존 "서버 오류 (status)" → JSON error 필드 파싱)

### 2. 히스토리 재생성 기능

- `HistorySection` 컴포넌트에 `onRegenerate` prop 추가
- 키워드분석 탭 상세: "이 키워드로 글 재생성" 버튼
  - `recommended_json`에서 `relKeyword` 추출 → keywords 배열 구성
  - 폴백: `input_keyword` 쉼표 분리 파싱
- 글작성 탭 상세: "이 키워드로 글 재생성" 버튼
  - `keywords_json` 파싱 → keywords 배열 구성
- `NaverBlogView`에서 `onRegenerate` 콜백: `setConfirmedRankings` + `setStep(1)`로 글 생성 단계 이동

## 발견 이슈 및 해결

### 자체 해결 (2건)
1. **recommended_json 키 불일치** — `keyword` → `relKeyword`로 수정 (NaverBlogView.js:1712)
   - 실제 DB 데이터 확인: `relKeyword`가 올바른 필드명
2. **input_keyword 쉼표 구분 문자열 처리** — split(',') 파싱 추가 (NaverBlogView.js:1714-1715)
   - DB 확인: "인카금융,티오피사업단,수원" 형태로 저장됨

### 범위 외 미해결 (0건)

## 다크모드 호환

기존 컴포넌트가 Tailwind 유틸리티 클래스 기반(bg-white, text-slate-*)이며 다크모드는 `isDarkMode()` inline style 패턴 사용. 추가한 재생성 버튼(bg-blue-600/text-white)은 양쪽 모드에서 가시성 문제 없음.

## 테스트 결과

- API 엔드포인트 정상 응답 확인: `GET /api/naver-blog/history/keywords` → 200 OK
- 키워드 상세 API 정상: `GET /api/naver-blog/history/keywords/21` → recommended_json 포함
- 서버 재시작 후 정상 운영: PID 1964760
- pyright 신규 에러 0건 (기존 미해결 경고만 존재)

## 셀프 QC 체크리스트

- [x] 1. 영향 파일: server.py, NaverBlogView.js (2개)
- [x] 2. 엣지 케이스: recommended_json이 비었을 때 input_keyword 폴백, keywords가 0개면 재생성 안 함
- [x] 3. 작업 지시 일치: Failed to fetch 수정 + 에러 메시지 개선 + 히스토리 재생성 기능
- [x] 4. 에러 처리: TimeoutExpired 504 처리, AbortError 처리, JSON 파싱 try/catch
- [x] 5. 테스트: API 응답 확인, 에러 분기 로직 검증
- [x] 6. 발견 이슈 모두 해결: relKeyword 키 불일치 + 쉼표 파싱 (2건)
- [x] 7. 코드 아키텍처: 기존 패턴 준수, 불필요 추상화 없음
- [x] 8. 인터페이스 변경: HistorySection에 onRegenerate prop 추가 (컴포넌트 내부, 외부 API 변경 없음)

## 모델 사용 기록

- 엔키(백엔드) / 서버 타임아웃 수정 / sonnet
- 이쉬타르(프론트엔드) / 에러 메시지 개선 + 히스토리 재생성 UI / sonnet

## 세션 통계
- 총 도구 호출: 11회

### 수정 파일 목록
- /home/jay/workspace/dashboard/components/NaverBlogView.js: 7회 (Edit)
- /home/jay/workspace/dashboard/server.py: 2회 (Edit)
- /home/jay/workspace/memory/reports/task-1690.1.md: 1회 (Write)
- /home/jay/workspace/memory/tasks/task-1690.1.md: 1회 (dispatch)

### 도구 사용 현황
- Edit: 9회
- Write: 1회
- dispatch: 1회

