# InsuWiki 출처/신뢰도 체계 설계 + Sync 아키텍처 재설계

> **작성일**: 2026-04-10
> **작성자**: 헤르메스 (개발1팀장) — 5 Cycle Agent Meeting 결과
> **상태**: 설계 확정 (구현 대기)
> **관련 태스크**: task-1589.1

---

## 1. 권위 계층 (Source Authority Hierarchy) — 확장판

### 1.1 확장된 6단계 계층

```
[1순위]   약관 원문 (policy_pdf)           ← 법적 효력, 최고 권위
[1.5순위] 금감원/보험업법 (regulation)     ← [Phase 2] 행정지도, 법령 조문
[2순위]   소식지 (newsletter)              ← 공식 안내 + [Phase 2] 판례 (court_ruling)
[3순위]   위키 본문 (wiki_editorial)       ← expert_verified 문서
[3.5순위] 전문가 단톡 (kakao_expert)       ← 이해철 등 전문가 채널 + auto_passed 사용자 문서
[4순위]   참고 자료                         ← youtube + kakao_community + unverified 사용자 문서
[5순위]   비공개                            ← 검증 실패, 내부 참조용
```

### 1.2 상충 시 처리 규칙 (기존 RAG spec v2.1 확장)

- 카카오 전문가 답변이 약관과 다를 경우 → 약관 원문 기준 답변 + 전문가 의견 병기
- 카카오 커뮤니티 정보 단독 인용 금지 (유튜브와 동일 규칙 적용)
- unverified 사용자 문서: 답변 생성 시 "(미검증)" 경고 레이블 병기

### 1.3 카카오 채널 분류 (MVP)

| 채널명 | sourceType | authorityTier | 비고 |
|--------|-----------|---------------|------|
| 앞서가는 설계사, 스레드 보상스터디 | kakao_expert | 3.5 | 이해철 프라임 전문가 |
| 박준현의 1일1보 | kakao_community | 4 | 일일 보험 지식 |
| 강동훈과 운전자-자보 | kakao_community | 4 | 자동차보험 전문 |
| 보험가득 정보방 | kakao_community | 4 | 일반 보험 정보 |

---

## 2. Document 스키마 확장

### 2.1 신규 타입 정의

```typescript
// ─── 출처 유형 (MVP 7개 + Phase 2 2개) ───────────────────────

export type SourceType =
  | 'policy_pdf'       // 약관 원문 PDF — tier 1
  | 'regulation'       // 금감원/보험업법 — tier 1.5 [Phase 2]
  | 'newsletter'       // 소식지·보도자료 — tier 2
  | 'court_ruling'     // 판례 — tier 2 [Phase 2]
  | 'kakao_expert'     // 전문가 카카오 단톡 — tier 3.5
  | 'kakao_community'  // 일반 카카오 단톡 — tier 4
  | 'youtube'          // 유튜브 채널 — tier 4
  | 'wiki_editorial'   // 위키 자체 편집 — tier 3
  | 'user_submitted';  // 사용자 제출 (검증 전) — tier 4~5

// ─── 검증 상태 ───────────────────────────────────────────────

export type VerificationStatus =
  | 'unverified'       // 미검토 (기본값)
  | 'auto_passed'      // 시스템 자동 검토 통과 [Phase 2]
  | 'expert_verified'; // 전문가/관리자 수동 검토 완료

// ─── 소스 메타데이터 ─────────────────────────────────────────

export interface SourceMeta {
  channelName?: string;       // 단톡방/채널 표시명
  expertName?: string;        // 전문가 이름 (Python sync의 'expert' 매핑)
  collectedAt: Timestamp;     // 원본 수집 일시
  sourceHash: string;         // 수집 시점 콘텐츠 SHA-256 해시
  verifiedBy?: string;        // 검토자 ID
  verifiedAt?: Timestamp;     // 검토 완료 일시
  expiresAt?: Timestamp;      // 정보 만료일 [Phase 2]
  publishedBy?: string;       // 발행 기관명 [Phase 2]
}

// ─── 원본 위치 포인터 ────────────────────────────────────────

export interface SourceRef {
  channelId: string;          // 내부 고유 채널 식별자
  channelName: string;        // 표시용 채널명
  collectedAt: Timestamp;     // 수집 일시
  messageRef?: string;        // 메시지 단위 식별자 [Phase 2]
}
```

### 2.2 Document 인터페이스 확장 (추가 필드)

```typescript
export interface Document {
  // ... 기존 필드 모두 유지 ...

  // ── 신규: Q&A 형식 콘텐츠 ──────────────────────
  question?: string;              // Q&A 질문 원문
  answer?: string;                // Q&A 답변 원문
  subcategory?: string;           // 세부 카테고리

  // ── 신규: 출처/신뢰도 (최상위 인덱싱 필드) ─────
  sourceType?: SourceType;        // 출처 유형
  verificationStatus?: VerificationStatus;  // 검증 상태
  authorityTier?: number;         // 권위 등급 (1~5, 0.5 단위)
  sourceMeta?: SourceMeta;        // 소스 메타데이터
  sourceRef?: SourceRef;          // 원본 위치 포인터
}
```

모든 신규 필드는 `optional` — 기존 documents에 영향 없음.

### 2.3 sourceType → authorityTier 매핑 함수

```typescript
export function getDefaultAuthorityTier(sourceType: SourceType): number {
  const TIER_MAP: Record<SourceType, number> = {
    policy_pdf:      1,
    regulation:      1.5,
    newsletter:      2,
    court_ruling:    2,
    wiki_editorial:  3,
    kakao_expert:    3.5,
    kakao_community: 4,
    youtube:         4,
    user_submitted:  4,
  };
  return TIER_MAP[sourceType];
}
```

---

## 3. Sync 아키텍처 재설계

### 3.1 듀얼 라이트 전략

- `wiki` 컬렉션: 관리용 원본으로 **보존** (삭제 금지)
- `documents` 컬렉션: 앱 표시용으로 **신규 추가 라이트**
- 두 컬렉션에 동시 기록 (WriteBatch 원자성)

### 3.2 문서 ID 체계

```
wiki__{sourceType}__{originalId}

예시:
wiki__kakao_expert__Q001
wiki__kakao_community__Q002
```

- `wiki__` 프리픽스로 외부 소스 문서 명시
- Firestore 자동 생성 ID와 절대 충돌 없음

### 3.3 필드 매핑 (wiki_entries → Document)

| wiki_entries 키 | Document 필드 | 변환 |
|----------------|--------------|------|
| `title` | `title` | 직접 매핑 |
| `question` | `question` | 직접 매핑 |
| `answer` | `answer` | 직접 매핑 |
| (question+answer 조합) | `content` | `"**Q.** {q}\n\n**A.** {a}"` 마크다운 |
| `expert` | `sourceMeta.expertName` | 구조 변경 |
| `keywords` | `searchKeywords` | 키 이름 변경 |
| `source_chat` | `sourceRef.channelId` | 구조화 |
| `source_date` | `sourceRef.collectedAt` | Timestamp 변환 |
| `category` | `category` | 직접 매핑 |
| `subcategory` | `subcategory` | 직접 매핑 |
| (고정값) | `authorId` | `"system_kakao_qa"` |
| `expert` fallback "카카오 보험 Q&A" | `authorName` | 전문가명 우선 |
| (고정값) | `visibility` | `"public"` (approved만 sync) |
| (고정값) | `version` | 신규=1, 기존=increment |
| (고정값) | `docType` | `"wiki"` |

### 3.4 역방향 동기화

- approved → rejected 상태 변경 시: `visibility: "private"` 처리
- 배치 처리: WriteBatch 400건 단위 (500 한도 내 안전 마진)

### 3.5 전체 Sync 플로우

```
┌──────────────────────────────┐
│   대시보드 (Admin)            │
│   wiki_entries.json           │
│   → 상태 관리 → [승인/반려]   │
└──────────┬───────────────────┘
           │ POST /api/wiki/sync-firestore
           ▼
┌──────────────────────────────────────┐
│   server.py (sync 로직)              │
│                                      │
│   WriteBatch (원자적):               │
│   ├─ wiki 컬렉션 (원본 보존)         │
│   └─ documents 컬렉션 (앱 표시용)    │
│       ID: wiki__{type}__{id}         │
│                                      │
│   rejected → visibility: "private"   │
└──────────┬───────────────────────────┘
           │
    ┌──────┴──────┐
    ▼             ▼
┌────────┐  ┌────────────────────┐
│ wiki   │  │ documents          │
│ (관리) │  │ (앱 표시)          │
│        │  │ + wiki__ 문서들    │
│        │  │ + 기존 문서들      │
└────────┘  └────────┬───────────┘
                     │ fetchDocuments
                     ▼
            ┌─────────────────┐
            │ 인슈위키 앱      │
            │ page.tsx         │
            │ visibility=public│
            │ → 통합 표시      │
            └─────────────────┘
```

---

## 4. 앱 UI 설계

### 4.1 배지 시스템

**3단계 UI 그룹** (authorityTier → 시각적 배지):

| Tier | UI 그룹 | 배지 텍스트 | 색상 | 아이콘 |
|------|---------|------------|------|--------|
| 1, 1.5 | 공식 | `약관` / `금감원` | 파랑 (#1A56DB) | 방패 |
| 2, 3, 3.5 | 검증됨 | `전문가` / `위키` | 초록 (#057A55) | 체크 |
| 4, 5 | 참고용 | `커뮤니티` / `유튜브` | 회색 (#9CA3AF) | 말풍선 |

- **리스트 카드**: 신뢰등급 배지 1개 (제목 아래)
- **상세 페이지**: 신뢰등급 + 출처종류 배지 2개
- expert_verified → `✓ 전문가 검증` 추가 배지

### 4.2 필터 구조

```
[전체] [의료] [손해] [자산] [실무]          ← 토픽 탭 (category)
─────────────────────────────────────
[전체] [약관] [전문가] [커뮤니티]          ← 출처 칩 (sourceType)
```

출처 칩 → sourceType 매핑:
- `전체`: 필터 없음
- `약관`: ['policy_pdf']
- `전문가`: ['newsletter', 'wiki_editorial', 'kakao_expert']
- `커뮤니티`: ['youtube', 'kakao_community', 'user_submitted']

### 4.3 정렬

- 기본: 최신 순 (updatedAt DESC)
- 옵션: 신뢰도 높은 순 (authorityTier ASC)
- MVP: 클라이언트 사이드 정렬 → 데이터 증가 시 서버 사이드 전환

### 4.4 단톡방별 필터

- **Phase 1 미포함** — Phase 2로 이연
- SourceRef에 channelId/channelName optional 필드 선제 추가
- Phase 2 전제조건: 채널 공개/비공개 분류 완료

---

## 5. 사용자 작성 문서 검증 체계

### 5.1 3단계 검증 워크플로우

| 상태 | 정의 | authorityTier | 인용 규칙 |
|------|------|--------------|----------|
| `unverified` | 작성 직후 기본값 | 4 | 단독 인용 금지 |
| `auto_passed` | 약관 충돌 없음 확인 [Phase 2] | 3.5 | 인용 가능, 경고 레이블 |
| `expert_verified` | 전문가/관리자 승인 | 3 | 위키 본문과 동급 |

### 5.2 MVP 운영

- `unverified` → `expert_verified` 2단계만 운영 (auto_passed 생략)
- 관리자 1인 승인으로 전환
- SLA 목표: 72시간 이내 1차 검토
- 검증 이력: `sourceMeta.verifiedBy`, `sourceMeta.verifiedAt`에 기록

---

## 6. 구현 로드맵

### Phase 1: Foundation (3일)

**목표**: Document 타입 확장 + server.py 듀얼 라이트 + Firestore 인덱스/Rules

| 수정 파일 | 변경 내용 |
|----------|----------|
| `nextapp/src/types/firestore.ts` | Document 인터페이스 확장 (7개 optional 필드) |
| `dashboard/server.py` (4462-4533) | sync 엔드포인트 듀얼 라이트 전환 |
| `firestore.indexes.json` | sourceType+visibility+updatedAt, authorityTier+visibility+updatedAt 복합 인덱스 |
| `firestore.rules` | system_wiki_sync 문서 읽기 허용 + 클라이언트 생성 차단 |

**완료 기준**:
- 기존 documents 쿼리 결과 무변화
- sync 후 wiki + documents 양쪽 라이트 확인
- TypeScript 컴파일 오류 0건

### Phase 2: UI (4일)

**목표**: 출처 배지 + 필터 칩 + Q&A 렌더링

| 수정 파일 | 변경 내용 |
|----------|----------|
| `nextapp/src/app/page.tsx` | sourceType 필터 state + 쿼리 확장 |
| `nextapp/src/components/HubDocuments.tsx` | 출처 칩 UI, 클라이언트 필터 |
| `nextapp/src/components/SourceBadge.tsx` (신규) | 재사용 배지 컴포넌트 |
| `nextapp/src/components/QnaRenderer.tsx` (신규) | Q&A 전용 렌더러 |
| `nextapp/src/lib/constants.ts` | SOURCE_CHIP_MAP 매핑 테이블 |

**완료 기준**:
- 출처 필터 동작, 배지 9종 정상 렌더링
- Q&A 문서 질문/답변 구분 표시
- 모바일 레이아웃 정상

### Phase 3: 안정화 (3일)

**목표**: 마이그레이션 + 롤백 + 모니터링

| 수정 파일 | 변경 내용 |
|----------|----------|
| `scripts/migrate-wiki-to-documents.ts` (신규) | 기존 wiki → documents 배치 마이그레이션 |
| `scripts/rollback-wiki-documents.ts` (신규) | wiki__ 문서 일괄 롤백 |
| `dashboard/server.py` | sync-health 엔드포인트 추가 |

**완료 기준**:
- wiki 컬렉션 데이터 100% 보존
- documents wiki__ 문서 수 = wiki approved 수
- DRY RUN → 샘플 100건 → 전체 순차 마이그레이션

### 전체 일정

```
Phase 1 (Day 1-3):  타입 + Sync + 인덱스 + Rules
Phase 2 (Day 3-7):  UI 배지 + 필터 + Q&A (Phase 1 인덱스 배포 후 병렬 가능)
Phase 3 (Day 7-10): 마이그레이션 + 롤백 + 모니터링
──────────────────────────────────────
총 10일 (병렬화 시 8일)
```

---

## 7. 향후 확장 예약 (Phase 2+)

| 항목 | 시기 | 비고 |
|------|------|------|
| auto_passed 검증 단계 | Phase 2+ | RAG 충돌 감지 자동화 |
| regulation sourceType 수집 | Phase 2+ | 금감원/보험업법 데이터 |
| court_ruling sourceType 수집 | Phase 2+ | 판례 데이터 |
| 단톡방별 필터 UI | Phase 2+ | 채널 공개/비공개 분류 선행 |
| peer review 체계 | Phase 3+ | 커뮤니티 규모 확대 시 |
| 학술 논문 편입 | 미정 | 법무/도메인 전문가 별도 검토 |

---

## 부록 A: Firestore 인덱스 추가 사항

```json
[
  {
    "collectionGroup": "documents",
    "fields": [
      {"fieldPath": "sourceType", "order": "ASCENDING"},
      {"fieldPath": "visibility", "order": "ASCENDING"},
      {"fieldPath": "updatedAt", "order": "DESCENDING"}
    ]
  },
  {
    "collectionGroup": "documents",
    "fields": [
      {"fieldPath": "authorityTier", "order": "ASCENDING"},
      {"fieldPath": "visibility", "order": "ASCENDING"},
      {"fieldPath": "updatedAt", "order": "DESCENDING"}
    ]
  }
]
```

## 부록 B: Agent Meeting 참석자 합의 기록

5 Cycle × 5 페르소나 (데이터 아키텍트, 도메인 전문가, PM, 보안/무결성, 레드팀)

- **Cycle 1**: 권위 계층 확장 → 6단계 확정, kakao_expert/community 분리
- **Cycle 2**: Document 스키마 → 7개 optional 필드, sourceType 9개 값
- **Cycle 3**: Sync 아키텍처 → 듀얼 라이트, wiki__ ID 프리픽스
- **Cycle 4**: 앱 UI → 3단계 배지, 탭+칩 필터, 단톡방 필터 Phase 2 이연
- **Cycle 5**: 구현 로드맵 → 3 Phase / 10일 (8일 최적화)
