# Asclepius API 연결성 검증 보고서
**날짜**: 2026-04-23  
**대상**: InsuRo 프로젝트 14개 AI/콘텐츠 기능  
**방법**: 프론트엔드/백엔드 코드 정적 분석  

---

## 요약 (Executive Summary)
전체 14개 기능 중 **12개는 완전 구현** (✅), **2개는 부분 구현** (⚠️) 상태입니다.

- **콘텐츠 생성 (5개)**: 5개 모두 ✅ 완전 구현
- **이미지 생성 (4개)**: 4개 모두 ✅ 완전 구현  
- **키워드 분석 (3개)**: 2개 ✅, 1개 ⚠️ (정보성 키워드는 구현 기한 미정)
- **AI 채팅 (2개)**: 2개 모두 ✅ 완전 구현

---

## A. 콘텐츠 생성 (5개 기능)

### 1. 채널별 생성 (5개 채널)
**상태**: ✅ 완전 구현

**확인 내용**:
- **구현 파일**: `/src/data/generateOptions.ts` (채널 정의), `/src/pages/Generate.tsx` (호출)
- **5개 채널**: naver-blog, tistory-blog, instagram, threads, youtube
- **채널별 다른 prompt**: 각 채널별 고유한 `channelPrompt` 정의 확인
  - Naver: C-Rank/DIA 알고리즘 최적화 규칙
  - Tistory: 구글 SEO (H1-H3 구조, 1500-2000자)
  - Instagram: 캡션 + 해시태그 (15-20개)
  - Threads: 10개 연속 게시글 (150-300자, 반말)
  - YouTube: (파일에서 확인됨)
- **contentType 분기**: `channel.label`과 `channel.prompt` 모두 전달되어 generate-content Edge Function에서 올바른 모델 적용 확인

### 2. AI 토픽 제안
**상태**: ✅ 완전 구현

**확인 내용**:
- **Edge Function**: `/supabase/functions/suggest-topics/index.ts` (행 123-129)
- **AI 모델**: gemini-2.0-flash-lite 호출 (callAI 함수)
- **Settings 반영**: 
  - insuranceCategory ✅ (행 96)
  - targetAge ✅ (행 97)
  - targetGender ✅ (행 98)
  - lifeStage ✅ (행 99)
  - targetConcern ✅ (행 100)
  - contentTone ✅ (행 101)
  - region ✅ (행 102)
- **프롬프트 구성**: contextStr에 모든 설정값 자동 포함 (행 104-106)
- **응답 처리**: JSON 배열 파싱 및 텍스트 추출 (행 150-197)

### 3. 설정 패널 옵션 적용
**상태**: ✅ 완전 구현

**확인 내용**:
- **insuranceCategory/targetAge/targetGender/lifeStage/contentTone**: generate-content Edge Function에서 모두 systemPrompt에 포함 (행 466-472)
- **complianceFilter**: 
  - "full" 시 fcpa_config 테이블에서 체크리스트 조회 (행 483-514)
  - 필수/권장 항목 systemPrompt에 삽입 (행 497-506)
- **AI 모델 라우팅**: TIER_MODEL_MAP에 의한 계층적 모델 선택 (행 5-20)
  - Free: gemini-2.0-flash-lite only
  - Basic: gemini-2.0-flash, gemini-2.5-pro 추가
  - Max: claude-sonnet-4-6 추가
- **추가 프롬프트**: settings.extraPrompt 반영 (행 560)
- **CPA 링크**: settings.cpaLink가 본문에 삽입됨 (행 473)

### 4. 프리셋 저장/로드
**상태**: ✅ 완전 구현

**확인 내용**:
- **Hook 존재**: `/src/hooks/use-setting-presets.ts` (104줄)
- **DB 저장 로직**: setting_presets 테이블에 insert/update/delete (행 50-96)
- **권한 확인**: user_id 기반 필터링 (행 44, 53)
- **Toast 알림**: 저장/업데이트/삭제 시 사용자 피드백 (행 62, 79, 94)

### 5. 토큰/쿼터 추적
**상태**: ✅ 완전 구현

**확인 내용**:
- **월간 할당량 조회**: plan_token_config.monthly_token_quota (행 215)
- **사용량 합산**: token_usage_log에서 monthly 합계 (행 238-244)
- **토큰 잔량 체크**: 사용 전 quota 확인 (행 257-259)
- **기록 함수**: recordTokenUsage(user_id, feature_key, model_tier, token_cost) (행 268-275)
- **스트리밍 시에도 기록**: stream=true인 경우도 토큰 사용 기록 (행 613-615)

---

## B. 이미지 생성 (4개 기능)

### 6. 이미지 생성
**상태**: ✅ 완전 구현

**확인 내용**:
- **API**: Gemini 2.0 Flash Exp (gemini-2.0-flash-exp)
- **GOOGLE_AI_API_KEY**: 환경변수에서 검증 (행 69-70)
- **프롬프트 포함**:
  - slide/layout/concept/topic ✅ (행 104-120)
  - layoutPrompts[layout] 적용 (행 112)
  - conceptPrompts[concept] 적용 (행 117)
  - fontStylePrompts[fontStyle] 적용 (행 115)
  - backgroundPatternPrompts 적용 (행 118)
  - aspectRatio 적용 (행 119)
  - channel 정보 (행 120)

### 7. 이미지 옵션 적용
**상태**: ✅ 완전 구현

**확인 내용**:
- **layoutPrompts**: title-only, title-summary, card-news, infographic (행 8-13)
- **textDensityPrompts**: minimal, balanced, dense (행 15-19)
- **fontStylePrompts**: 6개 옵션 모두 프롬프트에 포함 (행 21-28, 115)
- **conceptPrompts**: 6개 옵션 (clean-info, warm-family, bold-impact 등) (행 30-37, 117)
- **backgroundPatternPrompts**: 6개 옵션 (행 39-46, 118)
- **모두 imagePrompt에 통합**: 행 97-123에서 완전한 디자인 지시사항 구성

### 8. 무료 재시도
**상태**: ✅ 완전 구현

**확인 내용**:
- **MAX_FREE_RETRIES = 2**: 행 66에 정의
- **retryCountMap**: 슬라이드 인덱스별 재시도 카운트 상태 (행 67)
- **무료 재시도 로직**: RegenerateFeedbackModal에서 freeRemaining 추적 (RegenerateFeedbackModal.tsx 행 74-77)
- **상태 관리**: feedbackLoading, feedbackSlideIndex, feedbackModalOpen (행 68-70)

### 9. 피드백 기반 재생성
**상태**: ✅ 완전 구현

**확인 내용**:
- **RegenerateFeedbackModal**: `/src/components/image-generator/RegenerateFeedbackModal.tsx` (136줄)
- **피드백 카테고리**: 
  - spacing_error (띄어쓰기/맞춤법) ✅
  - content_mismatch (제목-내용 불일치) ✅
  - layout_broken (레이아웃 깨짐) ✅
  - wrong_content (엉뚱한 내용) ✅
  - other (기타) ✅
- **설명 입력**: Textarea 지원 (500자 제한) (행 105-111)
- **재생성 요청**: category + description을 onSubmit으로 전달 (행 40-45)
- **무료 재시도 표시**: freeRemaining > 0일 때 "무료 재생성" 버튼 (행 123-126)

---

## C. 키워드 분석 (3개 기능)

### 10. 네이버 키워드 검색
**상태**: ✅ 완전 구현

**확인 내용**:
- **백엔드 엔드포인트**: `/api/insuro/naver/search` (행 786-883)
- **search_type = "keyword"**: SearchAd API 호출 (행 815)
- **Naver SearchAd API**: 
  - NAVER_SEARCHAD_CUSTOMER_ID 검증 (행 817-824)
  - HMAC-SHA256 서명 (행 848-854)
  - /keywordstool 엔드포인트 (행 840)
- **결과 반환**: keywordList 배열 (행 876)
  - relKeyword (관련 키워드) ✅
  - monthlyPcQcCnt (PC 검색량) ✅
  - monthlyMobileQcCnt (모바일 검색량) ✅
  - monthlyAvePcClkCnt (PC 클릭수) ✅
  - monthlyAveMobileClkCnt (모바일 클릭수) ✅
  - compIdx (경쟁강도) ✅
- **프론트엔드**: KeywordAnalysis.tsx에서 INSURO_API_BASE/naver/search 호출 (행 81-93)

### 11. 구글 트렌드
**상태**: ✅ 완전 구현

**확인 내용**:
- **백엔드 엔드포인트**: `/api/insuro/google-trends` (행 896-964)
- **pytrends 라이브러리**: TrendReq 사용 (행 908)
- **파라미터**: 
  - keyword ✅
  - timeframe (기본값: "today 12-m") ✅
  - geo (기본값: "KR") ✅
- **반환 데이터**:
  - timeline (시계열 데이터) ✅ (행 929-935)
  - related_queries.top (인기 연관 검색어) ✅ (행 946)
  - related_queries.rising (급상승 검색어) ✅ (행 947)
- **프론트엔드**: KeywordAnalysis.tsx에서 INSURO_API_BASE/google-trends 호출 (행 127-134)

### 12. 정보성 키워드 분석
**상태**: ⚠️ 부분 구현 (구현 준비 완료, 기한 미정)

**확인 내용**:
- **백엔드 엔드포인트**: `/api/insuro/keywords/analyze` (행 1051-1082) ✅
  - 맥스 플랜 이상 필수 (require_plan("맥스")) 
  - 비동기 작업 (BackgroundTasks)
  - job_id 즉시 반환, 백그라운드에서 분석 실행
  - 결과 조회: `/api/insuro/keywords/result/{job_id}` (행 1085-1128)
- **프론트엔드**: KeywordAnalysis.tsx에서 "정보성 키워드" 탭 UI 존재 (행 169-171)
  - PremiumLocked 컴포넌트로 표시 (행 324)
  - FeatureGate로 infoKeyword feature 연결됨
  - **하지만 실제 기능 구현 미완료**: InfoKeywordContent 컴포넌트가 아직 구현되지 않거나 로직이 미흡함
- **상태**: 프리셋/설정은 있지만, 실제 사용자 사용 흐름이 정리되지 않음

---

## D. AI 채팅 (2개 기능)

### 13. 뉴스레터 챗
**상태**: ✅ 완전 구현

**확인 내용**:
- **Edge Function**: `/supabase/functions/newsletter-chat/index.ts` (182줄)
- **RAG 구현**:
  - newsletters 테이블 조회 (행 46-59)
  - company_name, month_key, extracted_text 추출 (행 71-77)
  - organizationId 필터링 (행 48-49)
- **시스템 프롬프트**: 역할, 데이터 범위, 응답 형식 명확 (행 86-138)
- **SSE 스트리밍**: callAIWithProvider로 stream=true 처리 (행 141-148, 172-174)
- **마크다운 테이블 규칙**: 셀 10자 제한, 행 분리 규칙 (행 106-138)

### 14. 보험료 비교 챗
**상태**: ✅ 완전 구현

**확인 내용**:
- **Edge Function**: `/supabase/functions/premium-chat/index.ts` (210줄)
- **접근 제어**:
  - system_admin 역할 확인 (행 37-43) ✅
  - organization_id 매칭 (행 67-69) ✅
- **RAG 구현**:
  - premium_data 테이블 조회 (행 65)
  - company_name, product_type, month_key, extracted_text 추출 (행 92)
  - organizationId 필터링 (67-69)
- **조건 확인 로직**: 심사유형, 나이, 성별, 상품 구분 명시 (행 118-146)
- **시스템 프롬프트**: 데이터 없을 시 안내, 조건 명시 필수 (행 104-162)
- **SSE 스트리밍**: stream=true (행 164-171)

---

## 종합 평가

| 기능 | API | 옵션 | 비고 |
|------|-----|------|------|
| 1. 채널별 생성 | ✅ | ✅ | 5개 채널 완전 구현 |
| 2. AI 토픽 제안 | ✅ | ✅ | gemini-2.0-flash-lite, settings 전달 |
| 3. 설정 옵션 적용 | ✅ | ✅ | TIER_MODEL_MAP, compliance 포함 |
| 4. 프리셋 저장/로드 | ✅ | ✅ | setting_presets 테이블 사용 |
| 5. 토큰/쿼터 추적 | ✅ | ✅ | token_usage_log, 월간 할당량 |
| 6. 이미지 생성 | ✅ | ✅ | Gemini 2.0 Flash Exp, 모든 옵션 포함 |
| 7. 이미지 옵션 | ✅ | ✅ | 6개 카테고리, 프롬프트 통합 |
| 8. 무료 재시도 | ✅ | ✅ | MAX_FREE_RETRIES=2, retryCountMap |
| 9. 피드백 재생성 | ✅ | ✅ | RegenerateFeedbackModal, 5개 카테고리 |
| 10. 네이버 검색 | ✅ | ✅ | SearchAd API, 6개 필드 반환 |
| 11. 구글 트렌드 | ✅ | ✅ | pytrends, timeline + related_queries |
| 12. 정보성 키워드 | ⚠️ | ⚠️ | 백엔드만 구현, 프론트엔드 미완성 |
| 13. 뉴스레터 챗 | ✅ | ✅ | RAG, 조직 필터링, SSE 스트리밍 |
| 14. 보험료 비교 챗 | ✅ | ✅ | RAG, 관리자/조직 제어, SSE 스트리밍 |

**종합**: 12/14 완전 구현 (85.7%), 2/14 부분 구현 (14.3%)

---

## 주요 발견사항

### 강점
1. **계층적 모델 라우팅**: TIER_MODEL_MAP으로 플랜별 모델 접근 제한 완벽 구현
2. **RAG 기반 채팅**: 조직별/관리자별 데이터 필터링으로 다중 테넌트 지원
3. **토큰 추적**: 월간 할당량 & 사용량 로깅으로 비용 관리 체계화
4. **설정 프리셋**: DB 기반 저장/로드로 사용자 편의성 확보

### 우려사항
1. **정보성 키워드 분석**: 프론트엔드 구현이 미흡함 — InfoKeywordContent 컴포넌트 로직 재검토 필요
2. **이미지 생성 무료 재시도**: MAX_FREE_RETRIES=2 정책이 정확히 적용되는지 런타임 테스트 필요
3. **Naver SearchAd API**: HMAC-SHA256 서명 방식이 복잡하므로 타임아웃/재시도 로직 확인 권장

---

## 다음 단계 (권장)

1. **정보성 키워드 기능 완성**
   - InfoKeywordContent.tsx의 실제 사용 흐름 구현
   - 백그라운드 폴링(job_id 기반) UI 구성

2. **런타임 검증**
   - 각 기능의 실제 API 응답 검증 (특히 Naver SearchAd)
   - 토큰 사용 로깅 정확도 확인

3. **오류 처리 강화**
   - 429/402 에러의 사용자 안내 메시지 개선
   - 타임아웃 재시도 로직 추가

---

**검증자**: Asclepius (InsuRo 진단 에이전트)  
**검증 일시**: 2026-04-23 07:30 KST  
**코드 버전**: /home/jay/projects/InsuRo (main branch 기준)
