# task-1594.1 완료 보고서
> 네이버 블로그 키워드 분석 — 복수 키워드 동시 입력 지원

## SCQA

**S**: 대시보드의 네이버 블로그 키워드 분석 기능(`/api/naver-blog/keyword-analysis`)은 단일 키워드("수원GA") 입력 시 정상 동작한다.

**C**: "수원GA 수원인카 인카금융 보험대리점 이직"처럼 복수 키워드를 공백으로 구분하여 입력하면, 네이버 검색광고 API가 공백 포함 문자열을 400 Bad Request로 거부하여 502 에러가 발생한다.

**Q**: 복수 키워드 입력을 분리하여 개별 API 호출 후 결과를 병합하면 502 에러 없이 정상 처리할 수 있는가?

**A**: 입력 문자열을 공백/쉼표로 분리하여 각 키워드를 개별 API 호출하고, `relKeyword` 기준 중복 제거 후 병합하는 로직을 구현했다. 단일 키워드는 기존과 동일하게 동작하며, 복수 키워드는 개별 처리 후 합산 결과를 반환한다. 수정 파일 2건, pyright 신규 에러 0건.

## 수정 파일

- `/home/jay/workspace/dashboard/server.py` (line 4697~4752) — 키워드 분리 + 개별 API 호출 + 결과 병합 로직
- `/home/jay/workspace/dashboard/components/NaverBlogView.js` (line 220) — placeholder 텍스트 변경

## 변경 상세

### 백엔드 (server.py)
1. `keyword` → `raw_keyword`로 변수명 변경 (원본 입력 보존)
2. `re.split(r'[,\s]+', raw_keyword)`로 공백/쉼표 기준 키워드 분리
3. 각 키워드별 `_naver_searchad_keyword_tool()` 개별 호출
4. `relKeyword` 기준 `seen_keywords` set으로 중복 제거 후 `all_results`에 병합
5. 개별 키워드 실패 시 스킵, 전체 실패 시에만 502 반환
6. `_naver_blog_recommended()` 및 히스토리 저장은 병합된 `all_results` 기반으로 처리
7. 응답의 `keyword` 필드 및 히스토리의 `input_keyword`에는 원본 `raw_keyword` 저장

### 프론트엔드 (NaverBlogView.js)
- placeholder: "분석할 키워드를 입력하세요 (예: 실손보험)" → "키워드를 입력하세요 (예: 실손보험, 또는 여러개: 수원GA 인카금융 보험대리점)"

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **전체 키워드 실패 시 빈 결과 반환 방지** — `all_results`가 빈 경우 502 에러 반환으로 처리
2. **히스토리 DB 원본 키워드 유실** — `raw_keyword`를 히스토리에 저장하여 원본 보존
3. **API 응답 `keyword` 필드 변경** — 원본 입력(`raw_keyword`)을 응답에 유지하여 프론트엔드 호환성 보장

### 범위 외 미해결 (1건)
1. **네이버 블로그 키워드 분석 테스트 파일 부재** — 기존에 `test_server.py` 등에 해당 API 테스트가 없음. 신규 테스트 작성은 별도 태스크 범위.

## 테스트 시나리오

| 시나리오 | 입력 | 예상 동작 |
|----------|------|-----------|
| 단일 키워드 | "수원GA" | 기존과 동일 (1회 API 호출) |
| 복수 키워드 (공백) | "수원GA 수원인카 인카금융" | 3회 개별 호출 + 결과 병합 |
| 복수 키워드 (쉼표) | "수원GA, 인카금융, 보험대리점" | 3회 개별 호출 + 결과 병합 |
| 빈 문자열 | "" | 400 에러 |
| 공백만 | "   " | 400 에러 |
| 전체 실패 | 존재하지 않는 키워드 | 502 에러 |

## 셀프 QC 체크리스트

- [x] 1. 영향 파일: server.py, NaverBlogView.js (2건만, 외부 함수 시그니처 변경 없음)
- [x] 2. 엣지 케이스: 빈 문자열→400, 공백만→400, 전체 실패→502, 단일 키워드→기존 동일
- [x] 3. 작업 지시 일치: 키워드 분리/개별 호출/병합/중복 제거/placeholder 모두 충족
- [x] 4. 에러 처리/보안: 개별 실패 스킵, 전체 실패 502, SQL injection 위험 없음 (파라미터 바인딩 사용)
- [x] 5. 테스트: 기존 테스트 파일 없음 (해당 API), 수동 테스트 시나리오 명시
- [x] 6. 이슈 모두 해결: 3건 자체 해결, 1건 범위 외 명시
- [x] 7. 아키텍처 원칙: 기존 핸들러 패턴 유지, 단순 로직 확장
- [x] 8. 인터페이스 변경: API 응답 스키마 동일 (하위 호환)
- [x] 9. 이미지/배너: 해당 없음

## 모델 사용 기록

- 팀원: 토르(백엔드) / 작업: server.py 핸들러 수정 / 모델: sonnet
- 팀원: 프레이야(프론트엔드) / 작업: placeholder 텍스트 변경 / 모델: haiku / 정당성: 1줄 텍스트 변경 (판단 불필요)

## 진단 참고

server.py의 pyright 경고(reportMissingImports 등)는 기존 코드의 pre-existing 이슈이며, 본 작업에서 신규 발생한 에러/경고는 0건입니다.
