# 콘텐츠 기획 & 전략 수립 기능 구현 계획

## Context

현재 INFINITH 파이프라인은 3-phase (discover → collect → generate-report)까지 완성되어 있고, DB 스키마에는 `content_plans`, `performance_metrics`, `strategy_adjustments`, `content_performance` 테이블이 이미 설계되어 있다. 하지만:
- **콘텐츠 플랜 생성 Edge Function이 없다** — `content_plans` 테이블은 비어 있음
- **`contentDirector.ts`는 완전 deterministic** — AI 호출 없이 하드코딩 템플릿으로 캘린더 생성
- **PerformancePage는 mock 데이터** — 실제 DB 연동 없음
- **전략 조정 루프가 없다** — 성과 → 전략 피드백 메커니즘 미구현

이 기능은 파이프라인 Phase 4로 자연스럽게 확장되며, 기존 데이터 흐름 위에 AI 전략 계층을 추가한다.

---

## Phase 1: `generate-content-plan` Edge Function + 타입 확장

### 1-1. Edge Function 생성
**새 파일:** `supabase/functions/generate-content-plan/index.ts`

- [x] `generate-report/index.ts` 패턴 그대로 따름 (CORS, service role, Deno.serve)
- [x] Input 인터페이스: `{ reportId, clinicId?, runId? }`
- [x] `analysis_runs` (또는 `marketing_reports`)에서 channelAnalysis, kpiTargets, recommendations, services 읽기
- [x] Perplexity sonar 호출 (temp=0.3, 짧은 프롬프트)
  - System: `"You are a Korean medical marketing content strategist. Respond ONLY with valid JSON."`
  - User: 채널 점수 요약 + 서비스 목록 + KPI 타겟 + 전략 생성 요청
- [x] JSON 파싱 (기존 regex 패턴 재사용)
- [x] `content_plans` 테이블에 INSERT (`is_active=true`, 이전 플랜 비활성화)
- [x] AI 실패 시 fallback: deterministic `contentDirector.ts` 결과 사용

**AI 출력 스키마:**
```json
{
  "channelStrategies": [{ "channelId", "targetGoal", "contentTypes", "postingFrequency", "priority" }],
  "contentPillars": [{ "title", "description", "relatedUSP", "exampleTopics" }],
  "calendar": { "weeks": [{ "weekNumber", "label", "entries": [...] }], "monthlySummary": [...] },
  "postingSchedule": { "bestTimes", "rationale" }
}
```

### 1-2. CalendarEntry 타입 확장
**수정:** `src/types/plan.ts` (line 107-113)

- [x] `id?: string` — UUID (드래그&드롭, 개별 재생성용)
- [x] `description?: string` — AI 생성 가이드
- [x] `pillar?: string` — 콘텐츠 필러 연결
- [x] `status?: 'draft' | 'approved' | 'published'`
- [x] `isManualEdit?: boolean` — AI 덮어쓰기 방지 플래그
- [x] `aiPromptSeed?: string` — 개별 재생성 컨텍스트

### 1-3. 데이터 레이어
**수정:** `src/lib/supabase.ts`

- [x] `generateContentPlan(reportId, clinicId?, runId?)` — Edge Function 호출
- [x] `fetchActiveContentPlan(clinicId)` — content_plans 쿼리
- [x] `updateCalendarEntry(planId, entryId, updates)` — JSONB 패치

**수정:** `src/hooks/useMarketingPlan.ts`

- [x] 데이터 소스 우선순위: content_plans → navigation state → marketing_reports

---

## Phase 2: Enhanced Content Calendar UI

### 2-1. ContentCalendar 인터랙티브 업그레이드
**수정:** `src/components/plan/ContentCalendar.tsx`

- [x] `useState`로 로컬 편집 상태 관리
- [x] 엔트리 클릭 → EditEntryModal 열기
- [x] Status 뱃지 (gray=draft, purple=approved, green=published)
- [x] 엔트리 hover 시 AI 재생성 버튼
- [x] Weekly/Monthly 뷰 토글
- [x] 채널/콘텐츠 타입 필터

### 2-2. EditEntryModal 생성
**새 파일:** `src/components/plan/EditEntryModal.tsx`

- [x] Title, Description, Channel, Content Type, Day, Status 필드
- [x] "AI 재생성" 버튼 (aiPromptSeed 기반)
- [x] Save / Cancel 버튼
- [x] 기존 디자인 시스템 적용 (rounded-2xl, shadow, purple accent)

---

## Phase 3: Strategy Adjustment Loop

### 3-1. adjust-strategy Edge Function
**새 파일:** `supabase/functions/adjust-strategy/index.ts`

- [x] Input: `{ clinicId }`
- [x] `channel_weekly_delta` 뷰로 최근 채널 변화량 조회
- [x] 활성 `content_plans` 조회
- [x] `analysis_runs.report`에서 kpiTargets 추출
- [x] KPI 달성률 계산
- [x] Perplexity sonar로 조정 추천 생성
- [x] `performance_metrics` INSERT (channel_deltas, kpi_progress, strategy_suggestions)
- [x] `strategy_adjustments` INSERT (adjustment_type, before/after values)

### 3-2. StrategyAdjustmentSection
**새 파일:** `src/components/plan/StrategyAdjustmentSection.tsx`

- [x] KPI 진행률 프로그레스 바
- [x] 전략 제안 카드 (수락/거절)
- [x] 조정 이력 타임라인

---

## Phase 4: 파이프라인 & 페이지 통합

### 4-1. AnalysisLoadingPage에 Phase 4 추가
**수정:** `src/pages/AnalysisLoadingPage.tsx`

- [x] `PHASE_STEPS`에 planning 단계 추가
- [x] `runPipeline`에서 generate-report 후 `generateContentPlan()` 호출

### 4-2. MarketingPlanPage에 조정 섹션 추가
**수정:** `src/pages/MarketingPlanPage.tsx`

- [x] AssetCollection 다음에 `<StrategyAdjustmentSection>` 추가

### 4-3. PerformancePage 실제 데이터 연동
**수정:** `src/pages/PerformancePage.tsx`

- [x] Mock 데이터 → 실제 DB 쿼리로 교체
- [x] "전략 조정 실행" 버튼 → `triggerStrategyAdjustment()` 호출

**새 파일:** `src/hooks/usePerformanceData.ts`

- [x] `channel_snapshots`, `performance_metrics`, `content_performance` 통합 조회

### 4-4. Route 업데이트
**수정:** `src/main.tsx`

- [x] `/performance/:clinicId?` 형태로 변경

---

## 파일 변경 요약

### 새로 생성 (6)
| 파일 | 목적 | Phase |
|------|------|-------|
| `supabase/functions/generate-content-plan/index.ts` | AI 콘텐츠 전략 생성 | 1 |
| `supabase/functions/adjust-strategy/index.ts` | 성과 기반 전략 조정 | 3 |
| `src/components/plan/EditEntryModal.tsx` | 캘린더 엔트리 편집 | 2 |
| `src/components/plan/StrategyAdjustmentSection.tsx` | 전략 조정 UI | 3 |
| `src/hooks/useContentPlan.ts` | content_plans 데이터 훅 | 1 |
| `src/hooks/usePerformanceData.ts` | 성과 데이터 통합 훅 | 4 |

### 수정 (7)
| 파일 | 변경 내용 | Phase |
|------|-----------|-------|
| `src/types/plan.ts` | CalendarEntry에 optional 필드 6개 추가 | 1 |
| `src/hooks/useMarketingPlan.ts` | content_plans 우선 소스 추가 | 1 |
| `src/lib/supabase.ts` | 새 API 함수 4개 추가 | 1 |
| `src/components/plan/ContentCalendar.tsx` | 인터랙티브 UI 업그레이드 | 2 |
| `src/pages/AnalysisLoadingPage.tsx` | Phase 4 파이프라인 추가 | 4 |
| `src/pages/MarketingPlanPage.tsx` | StrategyAdjustment 섹션 추가 | 4 |
| `src/pages/PerformancePage.tsx` | Mock → 실제 DB 데이터 | 4 |

### 변경 없음 (Fallback 유지)
- `src/lib/contentDirector.ts` — deterministic fallback 엔진
- `src/lib/transformPlan.ts` — fallback 변환
- `supabase/functions/_shared/config.ts` — 재사용

---

## 검증 체크리스트

- [x] Edge Function 테스트: `curl`로 `generate-content-plan` 호출 → `content_plans` 테이블 적재 확인
- [x] 프론트엔드 테스트: `npm run dev` → `/plan/:id` → content_plans 데이터 렌더링 확인
- [x] 캘린더 인터랙션: 엔트리 클릭 → 편집 → 저장 → 새로고침 후 유지 확인
- [x] 파이프라인 E2E: URL 입력 → 4단계 파이프라인 완료 → 플랜 페이지 자동 표시
- [x] 타입 체크: `npm run lint` (tsc --noEmit) 통과

## 핵심 패턴 참조 파일
- `supabase/functions/generate-report/index.ts` — Edge Function 패턴
- `src/lib/contentDirector.ts` — 현재 deterministic 엔진 (fallback)
- `src/hooks/useMarketingPlan.ts` — 데이터 소스 우선순위 체인
- `src/components/plan/ContentCalendar.tsx` — 현재 캘린더 UI
