# task-2156 완료 보고서: 금소법 면책동의 UX 개선

## SCQA

**S**: InsuRo AI 콘텐츠 작성 페이지에서 금소법 면책동의 체크박스가 "고급 옵션" 내부에 위치하여 사용자가 발견하지 못하고, 동의 기록이 클라이언트 state에만 존재하여 법적 증거력이 부족하다.

**C**: 사용자가 "블로그용" 빠른 선택을 클릭해도 동의 체크박스가 보이지 않아 콘텐츠 생성 시 에러가 발생하며, DB 기반 동의 이력이 없어 법적 분쟁 시 "고지 의무 충족" 방어선이 부재하다.

**Q**: 면책동의를 인라인 배너로 노출하고, DB 저장 + 서버 이중 검증으로 법적 방어력을 확보할 수 있는가?

**A**: Phase 1-3 모두 구현 완료. (1) DB 스키마: compliance_consents/compliance_versions 테이블 + RLS 정책 + v1.0 seed 데이터, (2) 백엔드: consent-status/consent API 2개 + Edge Function 동의 검증, (3) 프론트엔드: 인라인 배너 + useComplianceConsent 훅 + 생성 버튼 비활성화. TypeScript 빌드 0 에러, Vite 빌드 8초 성공, API 인증 검증(401) 확인.

---

## 산출물 파일

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| supabase/migrations/20260424180000_compliance_consents.sql | DB 마이그레이션 신규 | grep "compliance_consents" OK | verified |
| server/main.py:2529-2632 | consent-status/consent API 추가 | grep "consent-status" OK | verified |
| supabase/functions/generate-content/index.ts:362-380 | Edge Function 동의 검증 | grep "compliance_consent_required" OK | verified |
| src/config/complianceConfig.ts | 면책 상수 + SHA-256 해시 신규 | grep "COMPLIANCE_DISCLAIMER" OK | verified |
| src/hooks/use-compliance-consent.ts | useComplianceConsent 훅 신규 | grep "useComplianceConsent" OK | verified |
| src/components/ComplianceConsentBanner.tsx | 인라인 배너 컴포넌트 신규 | grep "ComplianceConsentBanner" OK | verified |
| src/pages/Generate.tsx:19,20,38,137,324-333,503-504 | 배너 연동 + 버튼 비활성화 | grep "hasValidConsent" OK | verified |
| src/components/GenerateSettingsPanel.tsx:690-712 | 기존 면책 섹션 호환 유지 | grep "면책 안내" OK | verified |

## 발견 이슈 및 해결

### 이슈 1: Codex 게이트 FAIL — 생성 경로 불일치
- **발견**: 실제 콘텐츠 생성이 `server/main.py`가 아닌 `supabase/functions/generate-content/index.ts` Edge Function을 경유
- **해결**: Edge Function에도 동의 검증 로직 추가 (complianceFilter !== "off" && userId 존재 시 DB 조회)
- **결과**: 서버 + Edge Function 이중 방어선 구축

### 이슈 2: Pyright 타입 에러 — Supabase 응답 타입
- **발견**: `ver_resp.data`가 `list[dict]` 대신 `list[JSON]` 타입으로 추론되어 `["key"]` 접근 시 에러
- **해결**: `list[dict[str, Any]]` 명시적 타입 어노테이션 + `# type: ignore[assignment]` 적용
- **결과**: Pyright 에러 0건 (기존 RateLimitExceeded 핸들러 제외)

### 이슈 3: Generate.tsx 미사용 import 경고
- **발견**: `refreshStatus` 변수가 destructure 되었지만 미사용
- **해결**: destructure에서 `refreshStatus` 제거
- **결과**: TypeScript 경고 0건

## L1 스모크테스트 결과

- 서버 재시작: 성공 (포트 8002, worktree 코드)
- API 응답 확인:
  - GET /api/status → 200 OK
  - GET /api/insuro/compliance/consent-status (미인증) → 401 "Missing or invalid authorization"
  - POST /api/insuro/compliance/consent (미인증) → 401 "Missing or invalid authorization"
- TypeScript 빌드: `npx tsc --noEmit` → exit 0
- Vite 프로덕션 빌드: 8초, 142 precache entries
- 스크린샷: AuthGuard에 의해 인증 없이 Generate 페이지 접근 차단 (정상 동작)

## 모델 사용 기록

- 토르(백엔드): Sonnet — DB 마이그레이션 + API + Edge Function 구현
- 프레이야(프론트엔드): Sonnet — 컴포넌트 + 훅 + 페이지 연동
- 오딘(팀장): Opus — 설계/검토/타입 에러 수정/통합

## 머지 판단

- **머지 필요**: Yes
- **브랜치**: task/task-2156-dev2
- **워크트리 경로**: /home/jay/projects/InsuRo/.worktrees/task-2156-dev2
- **머지 의견**: TypeScript/Vite 빌드 모두 통과, API 인증 검증 정상, 기존 complianceAgreed 호환 유지. Supabase 마이그레이션은 프로덕션 배포 시 실행 필요.

## 3문서 업데이트

- plan.md: status → completed
- context-notes.md: 3 Step Why 기록 완료
- checklist.md: 14/15 항목 완료 (93%), 미완료 1건은 프로덕션 마이그레이션

## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회

