# InsuWiki Sync 듀얼 라이트 구현 (task-1590.1 이어서)

## 배경
- task-1590.1에서 Phase 1의 절반 완료:
  - ✅ firestore.ts 타입 확장 (sourceType, verificationStatus 등 7개 필드)
  - ✅ firestore.indexes.json 인덱스 추가
  - ✅ firestore.rules 업데이트
  - ❌ server.py Sync 듀얼 라이트 — 미완 (세션 끊김)
- 코드 위치: `/home/jay/projects/insuwiki/.worktrees/task-1590.1-dev1/` (커밋 5c23c40)

## 작업 내용

### 1. task-1590.1 워크트리 머지
```bash
cd /home/jay/projects/insuwiki
git merge task/task-1590.1-dev1
```

### 2. Sync 듀얼 라이트 구현
- 파일: `/home/jay/workspace/dashboard/server.py` — `POST /api/wiki/sync-firestore` (라인 4462~4533)
- 설계서: `/home/jay/workspace/memory/specs/insuwiki/source-authority-design.md`

현재 코드:
```python
db.collection("wiki").document(eid).set(doc_data, merge=True)
```

변경 후:
```python
# 듀얼 라이트: wiki(원본) + documents(앱 표시) 동시 기록
batch = db.batch()

# 1. wiki 컬렉션 (원본 보존)
batch.set(db.collection("wiki").document(eid), wiki_data, merge=True)

# 2. documents 컬렉션 (앱 표시)
doc_id = f"wiki__kakao_qa__{eid}"
doc_data = {
    "title": entry.get("title", ""),
    "content": f"## 질문\n{entry.get('question', '')}\n\n## 답변\n{entry.get('answer', '')}",
    "visibility": "public",
    "authorId": "system_kakao_qa",
    "authorName": "카카오 Q&A",
    "docType": "wiki",
    "category": _map_wiki_category(entry.get("category", "")),
    "sourceType": "kakao_expert",
    "verificationStatus": "expert_verified",
    "authorityTier": 3.5,
    "sourceRef": entry.get("source_chat", ""),
    "question": entry.get("question", ""),
    "answer": entry.get("answer", ""),
    "searchKeywords": _generate_search_keywords(entry),
    "version": 1,
    "createdAt": SERVER_TIMESTAMP,
    "updatedAt": SERVER_TIMESTAMP,
}
batch.set(db.collection("documents").document(doc_id), doc_data, merge=True)

batch.commit()
```

### 3. 카테고리 매핑 함수
```python
def _map_wiki_category(wiki_cat: str) -> str:
    mapping = {
        "보상": "casualty", "보상/장기": "casualty", "보상/일반": "casualty",
        "보상/자동차": "casualty", "고지의무": "practice",
        "약관": "practice", "약관해석": "practice",
        "상품": "general", "상품비교": "general",
        "의학지식": "medical", "언더라이팅": "practice",
    }
    return mapping.get(wiki_cat, "general")
```

### 4. 검색 키워드 생성
```python
def _generate_search_keywords(entry: dict) -> list:
    text = f"{entry.get('title','')} {entry.get('question','')} {entry.get('answer','')}"
    # 간단한 형태소 분리 (공백 기준 + 키워드 필드)
    words = set(text.split())
    words.update(entry.get("keywords", []))
    return [w.lower() for w in words if len(w) >= 2][:50]
```

### 5. 서버 재시작 + 테스트
1. `systemctl --user restart dashboard.service`
2. 대시보드에서 insight-001 승인 → InsuWiki Sync 클릭
3. 인슈위키 앱 Wiki 탭에서 표시되는지 확인
4. 출처 배지(✅ 검증)가 표시되는지 확인

## 보고서
`/home/jay/workspace/memory/reports/task-1595.md`에 작성