# InsuRo 소식지/보험료 AI 채팅을 서버 사이드로 전환

## 작업 레벨: Lv.2

## 프로젝트 시스템 3문서
- DevSystem: `/home/jay/workspace/memory/plans/anu-guide-system/plan.md`

## 프로젝트
- InsuRo: `/home/jay/projects/InsuRo`
- 서버: `/home/jay/projects/InsuRo/server` (FastAPI, port 8001)

## 배경
현재 소식지분석/보험료분석 AI 채팅이 Supabase Edge Function(`newsletter-chat`, `premium-chat`)에서 외부 AI API(Gemini)를 호출하는 구조. `GOOGLE_AI_API_KEY` 미설정 + 외부 API 의존 문제. 제이회장님 지시: **아누 서버(InsuRo 서버)에서 직접 Claude API 호출** (Max200 플랜 활용).

## ★ 제이회장님 결정사항
1. **소식지**: 조직 구분 없이 전체 사용자 접근 가능 → organization_id 필터 제거
2. **보험료**: 조직별 접근 제한 유지
3. **AI**: 외부 API 대신 InsuRo 서버에서 anthropic SDK로 직접 처리

## 현재 구조 (Edge Function)
```
프론트(MarketNewsletter.tsx) → newsletter-chat Edge Function → Gemini API
프론트(PremiumComparison.tsx) → premium-chat Edge Function → Gemini API
```

## 변경 후 구조 (서버 사이드)
```
프론트(MarketNewsletter.tsx) → InsuRo 서버 /api/insuro/newsletter-chat
프론트(PremiumComparison.tsx) → InsuRo 서버 /api/insuro/premium-chat
서버 → Supabase DB에서 extracted_text 조회 → anthropic SDK로 Claude 호출 → SSE 스트리밍 응답
```

## 구현 상세

### 1. 서버 엔드포인트 추가 (main.py)

#### POST /api/insuro/newsletter-chat
```python
@app.post("/api/insuro/newsletter-chat")
async def newsletter_chat(request: Request):
    # 1. JWT 인증 (사용자 확인)
    # 2. DB에서 newsletters의 extracted_text 조회 (★ organization_id 필터 없음 — 전체 공개)
    # 3. month_key 필터 (선택사항)
    # 4. anthropic SDK로 Claude Haiku 호출 (SSE 스트리밍)
    # 5. 시스템 프롬프트는 기존 Edge Function의 것을 그대로 사용
```

#### POST /api/insuro/premium-chat
```python
@app.post("/api/insuro/premium-chat")
async def premium_chat(request: Request):
    # 1. JWT 인증 + 사용자 organization_id 확인
    # 2. DB에서 premium_data의 extracted_text 조회 (★ organization_id 필터 적용)
    # 3. month_key 필터 (선택사항)
    # 4. anthropic SDK로 Claude Haiku 호출 (SSE 스트리밍)
```

### 2. Claude API 호출 방식
```python
import anthropic

client = anthropic.Anthropic()  # ANTHROPIC_API_KEY 환경변수 자동 사용

# 스트리밍 응답
with client.messages.stream(
    model="claude-haiku-4-5-20251001",
    max_tokens=4096,
    system=system_prompt,
    messages=messages,
) as stream:
    for text in stream.text_stream:
        yield f"data: {json.dumps({'choices': [{'delta': {'content': text}}]})}\n\n"
```

### 3. 시스템 프롬프트
기존 Edge Function의 시스템 프롬프트를 그대로 서버로 이전:
- 소식지: "보험업계 전문 AI 어시스턴트" + 마크다운 표 규칙
- 보험료: "보험료/환급률 분석 전문 어시스턴트" + 비교 분석 규칙

### 4. 프론트엔드 수정
```tsx
// MarketNewsletter.tsx
// Before
const CHAT_URL = `${SUPABASE_FUNCTION_BASE}/newsletter-chat`;
// After  
const CHAT_URL = `${INSURO_API_BASE}/api/insuro/newsletter-chat`;

// PremiumComparison.tsx
// Before
const CHAT_URL = `${SUPABASE_FUNCTION_BASE}/premium-chat`;
// After
const CHAT_URL = `${INSURO_API_BASE}/api/insuro/premium-chat`;
```

### 5. 환경변수
- `ANTHROPIC_API_KEY` — .env에 설정 필요 (또는 Max200 세션에서 자동 사용)
- ★ Max200 플랜이므로 API 키가 별도로 필요한지, 아니면 서버에서 직접 사용 가능한지 확인 필요
- 확인 방법: `python3 -c "import anthropic; c = anthropic.Anthropic(); print(c.api_key[:10])"`

### 6. SSE 응답 형식
기존 Edge Function과 동일한 SSE 형식 유지 (프론트 변경 최소화):
```
data: {"choices":[{"delta":{"content":"답변 텍스트..."}}]}
```

## affected_files
- `server/main.py` (수정 — 2개 엔드포인트 추가)
- `src/pages/MarketNewsletter.tsx` (수정 — CHAT_URL 변경)
- `src/pages/PremiumComparison.tsx` (수정 — CHAT_URL 변경)

## 검증 시나리오
1. 소식지분석 페이지에서 "이번 달 소식지 요약해줘" 질문 → AI 응답 (스트리밍)
2. 보험료분석 페이지에서 "3대 질병 보험료 비교해줘" 질문 → AI 응답
3. 보험료분석: 다른 조직 사용자 → 해당 조직 데이터만 표시
4. 소식지분석: 조직 무관 전체 접근 확인
5. npm run build 성공
6. 서버 재시작 후 엔드포인트 정상 응답

## goal_assertions (auto-generated)
- `python3 -c "import anthropic; c = anthropic.Anthropic(); print(c.api_key[:10])"`
