# InsuWiki 보안 강화: guest 역할 DB/API 레벨 차단

## 배경
현재 InsuWiki의 guest 차단은 **UI 레벨에서만** 이루어지고 있음.
- Firestore Rules: `isAuthenticated()`만 체크 → guest도 DB 직접 접근 가능
- API 미들웨어: 토큰 유효성만 검사 → guest도 AI API 호출 가능
- UserRole 타입: AuthContext(`guest/member/admin`)와 firestore.ts(`admin/editor/viewer`) 불일치

## 수정 대상 파일

### 1. `firestore.rules` — guest DB 접근 차단
**경로**: `/home/jay/projects/insuwiki/firestore.rules`

**추가할 헬퍼 함수:**
```javascript
// Check if user is member or admin (not guest)
function isMemberOrAdmin() {
    return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role in ['member', 'admin'];
}
```

**적용 대상 (isAuthenticated() → isAuthenticated() && isMemberOrAdmin() 로 변경):**
- `documents/{docId}` — read, create, update, delete 전부
- `documents/{docId}/versions/{versionId}` — read, write
- `documents/{docId}/revisions/{revisionId}` — read, write
- `documents/{docId}/tags/{tagId}` — read, write
- `dailyNotes/{dailyNoteId}` — create, read, update, delete
- `links/{linkId}` — read, write
- `tags/{tagId}` — read, write
- `insurance_metadata/{recordId}` — read
- `insurance_summaries/{summaryId}` — read
- `conversation_sessions/{sessionId}` — read, write, create
- `drafts/{draftId}` — read, write, create

**변경하지 않을 것 (그대로 유지):**
- `users/{userId}` — 본인 프로필은 guest도 읽기/쓰기 가능해야 함 (role 확인 등에 필요)
- `whitelist/{entryId}` — read는 인증만으로 충분 (가입 신청 확인용)
- server-side only 컬렉션 (`allow read, write: if false`) — 이미 차단됨

**주의:** Firestore Rules에서 `get()` 호출은 read 카운트에 포함됨. `isMemberOrAdmin()`을 매 규칙마다 호출하면 비용 증가. 그러나 보안이 우선이므로 적용.

### 2. `nextapp/src/lib/auth-middleware.ts` — member 이상만 허용하는 미들웨어 추가
**경로**: `/home/jay/projects/insuwiki/nextapp/src/lib/auth-middleware.ts`

**추가할 함수:**
```typescript
/**
 * Firebase ID Token 검증 + member/admin 역할 확인 미들웨어
 * guest 역할은 403 Forbidden 반환
 */
export async function verifyMember(req: NextRequest): Promise<AuthResult | NextResponse> {
    const authResult = await verifyAuth(req);
    if (authResult instanceof NextResponse) return authResult;

    // Firestore에서 역할 확인
    const { getFirestore } = await import('firebase-admin/firestore');
    const db = getFirestore();
    const userDoc = await db.collection('users').doc(authResult.uid).get();
    const role = userDoc.data()?.role;

    if (!role || role === 'guest') {
        return NextResponse.json(
            { error: 'Forbidden: Member access required' },
            { status: 403 }
        );
    }

    return authResult;
}
```

### 3. API 라우트 — verifyAuth → verifyMember 교체
아래 파일에서 `verifyAuth` 호출을 `verifyMember`로 교체하고, import도 변경:

- `nextapp/src/app/api/ai/query/route.ts`
- `nextapp/src/app/api/ai/vector-search/route.ts`
- `nextapp/src/app/api/ai/autocomplete/route.ts`
- `nextapp/src/app/api/ai/summarize/route.ts`
- `nextapp/src/app/api/ai/feedback/route.ts`
- `nextapp/src/app/api/ai/versions/route.ts`
- `nextapp/src/app/api/ai/settings/route.ts`
- `nextapp/src/app/api/ai/status/route.ts`

**주의:** `share-target/route.ts`는 `verifyAuthFromParam`을 사용하므로 별도 처리 필요. guest가 share-target을 쓸 수 있어야 하는지 판단 → guest는 문서 접근 불가이므로 share-target도 차단해야 함. `verifyAuthFromParam`에도 동일한 role 체크 로직 추가.

### 4. `nextapp/src/types/firestore.ts` — UserRole 타입 통일
**경로**: `/home/jay/projects/insuwiki/nextapp/src/types/firestore.ts`

**변경:**
```typescript
// 기존 (라인 14)
export type UserRole = 'admin' | 'editor' | 'viewer';

// 변경 후
export type UserRole = 'admin' | 'member' | 'guest';
```

**영향 체크:** `WhitelistEntry.role`이 `UserRole`을 참조함 (라인 182). 통일 후 정합성 확인 필요.

### 5. 기존 테스트 수정
- `nextapp/src/app/api/ai/autocomplete/__tests__/route.test.ts` — verifyAuth mock을 verifyMember로 변경
- `nextapp/src/app/api/ai/feedback/__tests__/route.test.ts` — 동일
- 기타 테스트 파일에서 `verifyAuth` mock이 있으면 모두 `verifyMember`로 교체

### 6. 배포 후 Firestore Rules 적용
- `firebase deploy --only firestore:rules` 실행 필요
- 단, 이 작업은 코드 수정 후 제이회장님 확인 후 별도 진행

## 검증 기준
1. guest 역할 사용자가 Firestore에서 documents 컬렉션 직접 읽기 시도 → 차단됨
2. guest 역할 사용자가 `/api/ai/query` 호출 시 → 403 반환
3. member/admin 역할 사용자는 기존과 동일하게 정상 작동
4. 기존 테스트 전체 PASS
5. UserRole 타입이 `'admin' | 'member' | 'guest'`로 통일됨

## 프로젝트 경로
- InsuWiki 루트: `/home/jay/projects/insuwiki/`
- 주요 코드: `/home/jay/projects/insuwiki/nextapp/src/`
- Firestore Rules: `/home/jay/projects/insuwiki/firestore.rules`

## 레벨
Lv.2 (기능 구현) — 파일/위치 특정, 변경 범위 명확