# task-621.2 완료 보고서: 인슈로 플랜 관리 고도화 Phase 2 — 토큰제 + 플랜별 AI 모델

## SCQA

**S**: 인슈로 플랜 관리가 Phase 1(task-621.1)에서 5개 플랜 체계(무료/베이직/프로/맥스/히든)로 개편되고, 기능 매트릭스 UI가 AdminSubscriptions.tsx에 구현되었다.

**C**: AI 기능 사용량 제어를 위한 토큰 시스템과 플랜별 AI 모델 등급(haiku/sonnet/opus) 매핑이 부재하여, 모든 플랜에서 동일한 AI 모델이 사용되고 사용량 추적이 불가능하다.

**Q**: 토큰 기반 AI 사용량 관리 + 플랜별 AI 모델 차등 적용을 DB~프론트엔드까지 구현할 수 있는가?

**A**: 5개 DB 테이블(plan_token_config, feature_token_costs, user_tokens, token_usage_log, plan_ai_models) + RLS 10개 정책 + 관리자 UI 토큰 탭 + 사용자 토큰 잔액/이력 컴포넌트를 구현 완료. vitest 26건 전체 통과, tsc 에러 0건.

## 생성/수정 파일 목록

### 신규 생성 (5개)
- `supabase/migrations/20260316130000_token_system_and_ai_models.sql` — DB 마이그레이션 (385줄)
- `src/hooks/use-user-tokens.ts` — 사용자 토큰 정보 훅
- `src/components/TokenBalance.tsx` — 토큰 잔액 표시 컴포넌트
- `src/components/TokenUsageHistory.tsx` — 토큰 사용 이력 컴포넌트
- `src/hooks/use-user-tokens.test.ts` — 토큰 훅 유닛 테스트 (11건)

### 수정 (2개)
- `src/pages/AdminSubscriptions.tsx` — 712줄 → 1179줄 (토큰/AI 모델 탭 추가)
- `src/pages/AdminSubscriptions.test.ts` — 35줄 → 200줄 (토큰 관련 15건 추가)

## 구현 상세

### DB (2-1, 2-2)
- 5개 테이블 IF NOT EXISTS로 멱등성 보장
- RLS: 공개 설정(plan_token_config, feature_token_costs, plan_ai_models) = authenticated SELECT + system_admin ALL / 개인 데이터(user_tokens, token_usage_log) = auth.uid() SELECT + system_admin ALL
- 시드: UPSERT(ON CONFLICT DO UPDATE)로 멱등성 보장
- 인덱스 3개: token_usage_log(user_id, created_at DESC), user_tokens(quota_reset_at)
- updated_at 트리거 2개
- reset_monthly_tokens() SECURITY DEFINER 함수

### 관리자 UI (2-3)
- "토큰 / AI 모델" 탭 추가 (TabsContent value="tokens")
- 섹션 1: 플랜별 월간 토큰 할당량 편집 (개별 저장)
- 섹션 2: 기능×모델별 토큰 소비량 매트릭스 (기능 추가/삭제, 일괄 저장)
- 섹션 3: 플랜별 AI 모델 선택 드롭다운 (haiku/sonnet/opus)

### 사용자 UI (2-4)
- useUserTokens 훅: 세션→user_tokens→plan_token_config 순차 조회, isUnlimited 계산
- TokenBalance: 프로그레스 바, 20% 이하 경고, 무제한 표시, 리셋 날짜, 업그레이드 링크
- TokenUsageHistory: 최근 20건, 날짜/기능/모델/소비량 테이블

## 테스트 결과
- vitest: 26건 전체 PASS (use-user-tokens.test.ts 11건 + AdminSubscriptions.test.ts 15건)
- tsc --noEmit: 에러 0건

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **Supabase 타입 미등록 테이블 접근** — `(supabase as any)` 캐스팅으로 우회. Phase 3에서 Supabase 타입 재생성 필요.
2. **AdminSubscriptions 토큰 탭 데이터 로드 타이밍** — 탭 전환 시 fetchTokenData 호출하여 lazy loading 적용
3. **feature_token_costs 삭제 시 plan_ai_models와의 불일치** — removeFeatureKey가 로컬 state만 제거하고 DB 삭제는 saveAllTokenCosts에서 처리하는 구조로 해결

### 범위 외 미해결 (1건)
1. **Supabase 타입 재생성** — 새 테이블 5개가 Supabase 자동 생성 타입에 반영되지 않음. `supabase gen types` 실행 필요. 범위 외 사유: Supabase CLI 접근 + 배포 환경 의존.

## 다음 Phase 지시서
- `/home/jay/workspace/memory/tasks/task-621.3.md`
- Phase 3: 아누 시스템 연동 + Pricing.tsx 동적 개편 + PlanUpgradeDialog 업데이트

## QC 자동 검증
- overall: **PASS**
- file_check: PASS (7/7 파일 확인, 보고서 3913 bytes)
- data_integrity: PASS
- tdd_check: PASS (테스트 2개 + 구현 4개 확인)
- critical_gap: PASS
- vitest 26건 전체 PASS, tsc --noEmit 에러 0건

## 다음 Phase 지시서
`/home/jay/workspace/memory/tasks/task-621.3.md`
