---
task_id: task-2132
type: context
scope: task
created: 2026-04-23
updated: 2026-04-23
status: completed
---

# 맥락 노트: task-2132

**task**: task-2132

---

## 결정 근거

### 3 Step Why 자문

**1st Why: "왜 이 설계가 필요한가?"**
→ Hidden/Max 플랜 사용자가 모든 채널/모델을 쓸 수 없는 심각한 비즈니스 버그.
- 프론트엔드가 한글 label("네이버 블로그")을 보내고 백엔드는 영문 value를 기대하는 불일치
- DB subscription_plans.features에 allowed_channels 필드 자체가 없어 항상 ["blog"] 기본값 사용
- 프론트 모델명(google/gemini-2.5-flash)과 EF 모델명(gemini-2.0-flash-lite) 불일치

**2nd Why: "왜 FE value 전송 + EF 계층 상속이 최선인가?"**
→ A방안(FE가 value 전송)은 근본 원인(값 형식 불일치)을 소스에서 해결.
  B방안(EF 매핑 테이블)은 채널 추가 시마다 매핑 유지 필요 → 유지보수 비용 높음.
  계층 상속을 EF 코드에서 구현하면 DB 스키마 변경 없이 해결 가능.

**3rd Why: "왜 코드 기반 계층 정의가 DB 스키마 변경보다 나은가?"**
→ DB에 allowed_channels를 모든 플랜마다 정의하면 플랜/채널 추가 시 DB 업데이트 필요.
  코드에서 계층+채널맵 관리 → 단일 배포로 해결, 테스트 용이, 리뷰 가능.

### Codex 사전 검증 (FAIL → 설계 수정)

Codex가 4개 리스크 지적:
1. (critical) 채널 label vs value 불일치 — MT-1에서 해결
2. (critical) 모델명 FE↔EF 불일치 — MT-2에서 TIER_MODEL_MAP 교체로 해결
3. (high) 플랜 계층 상속 미구현 — MT-2에서 구현
4. (medium) server/main.py와 EF 간 권한 로직 불일치 — 범위 외 (EF만 수정)

### FE 모델명 → EF 모델명 매핑 결정

프론트: `google/gemini-2.5-flash`, `google/gemini-2.5-pro`, `anthropic/claude-sonnet`
기존 EF: `gemini-2.0-flash-lite`, `gemini-2.0-flash`, `gemini-2.5-pro`, `claude-sonnet-4-6`
결정: EF의 TIER_MODEL_MAP을 프론트와 동일하게 수정 (`gemini-2.5-flash`, `gemini-2.5-pro`, `claude-sonnet`)
추가: prefix strip에 `anthropic/`도 포함

## 참조 자료

- 채널 정의: `/home/jay/projects/InsuRo/src/data/generateOptions.ts` L4~155
- 모델 정의: `/home/jay/projects/InsuRo/src/data/generateOptions.ts` L453~479
- Edge Function: `/home/jay/projects/InsuRo/supabase/functions/generate-content/index.ts`
- DB subscription_plans.features: allowed_channels 필드 없음 (조회 확인)
- DB plan_ai_models: 빈 테이블 (조회 확인)

## 주의사항

- suggest-topics Edge Function의 channel 값은 label 그대로 유지 (프롬프트용이므로)
- Free 플랜 기존 제한(월 3건, 네이버 블로그만, Gemini Flash만) 유지 필수
- Edge Function 배포 시 SUPABASE_ACCESS_TOKEN 필요 (.env.keys에서 로드)
- generateOptions.ts의 모델 value에 `google/`, `anthropic/` prefix가 붙어있음 → EF에서 양쪽 모두 strip
