# InsuRo 이미지 생성을 아누 서버로 전환 + 플랜별 차등

## 작업 레벨: Lv.3

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

## 프로젝트
- InsuRo: `/home/jay/projects/InsuRo`
- 서버: `/home/jay/projects/InsuRo/server`

## 배경
이미지 생성이 Edge Function(`generate-image`) → Gemini API 의존. `GOOGLE_AI_API_KEY` 미설정으로 동작 안 함. 아누 서버 내부의 스킬(Satori/Gemini/Hybrid)로 전환하여 Max200 플랜 내 처리.

## ★ 플랜별 이미지 생성 차등

### 무료/베이직: Satori 기반 (비용 0)
- HTML/CSS → PNG 변환 (satori + @resvg/resvg-js)
- 카드뉴스/배너 스타일 (텍스트 중심, 템플릿)
- 한글 100% 정확
- pip: `satori`는 Node.js — 서버에서 `npx satori` 또는 `@resvg/resvg-wasm` 활용

### 프로: + Gemini AI 포토리얼 이미지
- Vertex AI Imagen 모델 (`imagegeneration@006`)
- 서비스 계정: `/home/jay/.config/gcloud/service-accounts/insuwiki-j2h-fa603f4f75f5.json`
- 포토리얼리스틱 배경 이미지 생성
- 보험 광고/SNS 메인 이미지에 적합

### 맥스/히든: + Hybrid (최고 품질)
- Gemini로 포토리얼 배경 생성 + Satori로 한글 텍스트 정밀 오버레이
- 광고 수준 품질, 한글 깨짐 없음
- 블로그 썸네일 + 카드뉴스 동시 생성

## 구현 상세

### 1. 서버 엔드포인트 (main.py)
```python
@app.post("/api/insuro/generate-image")
async def generate_image(request: Request):
    # 1. JWT 인증 + 플랜 확인
    # 2. 플랜별 이미지 생성 방식 결정
    # 3. 큐 시스템 활용 (generate-content와 공유 또는 별도)
    # 4. 이미지 생성 + base64 반환
```

### 2. Satori 기반 (무료/베이직)
- 서버에서 Node.js subprocess 호출: `node server/scripts/satori-render.js`
- 또는 Python의 `imgkit`/`playwright` 활용
- HTML 템플릿 → PNG 변환
- 템플릿: 카드뉴스용, 블로그 썸네일용 등 4~5종

### 3. Gemini Vertex AI (프로)
```python
from google.cloud import aiplatform
from vertexai.preview.vision_models import ImageGenerationModel

model = ImageGenerationModel.from_pretrained("imagegeneration@006")
response = model.generate_images(prompt=prompt, number_of_images=1)
image_bytes = response.images[0]._image_bytes
```
- 서비스 계정 인증: `GOOGLE_APPLICATION_CREDENTIALS` 환경변수
- 한국어 프롬프트 지원

### 4. Hybrid (맥스/히든)
1. Gemini로 배경 이미지 생성 (텍스트 없이)
2. Satori로 텍스트 레이어 생성 (투명 배경)
3. Pillow로 두 레이어 합성
4. 최종 PNG 반환

### 5. 프론트엔드 수정
```tsx
// ImageGeneratorPanel.tsx
// Before: supabase.functions.invoke("generate-image", ...)
// After: fetch(`${INSURO_API_BASE}/api/insuro/generate-image`, ...)
```

### 6. 플랜별 라우팅
```python
PLAN_IMAGE_TIER = {
    "Free": "satori",
    "Basic": "satori",
    "Pro": "gemini",
    "Max": "hybrid",
    "Hidden": "hybrid",
}
```

## affected_files
- `server/main.py` (수정 — generate-image 엔드포인트 추가)
- `server/image_generator.py` (신규 — Satori/Gemini/Hybrid 이미지 생성 모듈)
- `server/templates/` (신규 — Satori HTML 템플릿)
- `src/components/ImageGeneratorPanel.tsx` (수정 — Edge Function → 서버 API)
- `src/config/planSkillMap.ts` (수정 — 이미지 생성 티어 매핑 추가)

## 검증 시나리오
1. 무료 플랜: 이미지 생성 → Satori 기반 카드뉴스 스타일 PNG 반환
2. 프로 플랜: 이미지 생성 → Gemini 포토리얼 이미지 반환
3. 히든 플랜: 이미지 생성 → Hybrid (AI배경 + 한글 텍스트) 반환
4. 기존 이미지 설정 (레이아웃/폰트/색상) 반영
5. npm run build 성공
6. 서버 재시작 후 엔드포인트 정상 응답

## goal_assertions (auto-generated)
- `npx satori`
