# 프론트엔드 Mock 데이터 개발 가이드

**작성일**: 2025-10-27
**대상**: 프론트엔드 개발자 (유진)
**작성자**: AI팀 (서연), 백엔드팀 (준호)

---

## 📋 개요

**현재 상황**: STT 서비스 개발 완료 전까지는 **실제 AI 제안사항이 생성되지 않습니다.**

**해결 방안**: Mock 데이터를 사용하여 프론트엔드 UI를 독립적으로 개발할 수 있습니다.

---

## 🎯 왜 Mock 데이터가 필요한가?

### 실제 데이터 생성 흐름

```
회의 (음성)
    ↓
STT 서비스 (음성 → 텍스트) ← 아직 개발 중
    ↓
Redis (텍스트 축적)
    ↓
AI 서비스 (Claude API 분석)
    ↓
SSE 스트리밍
    ↓
프론트엔드
```

**문제점**: STT가 없으면 텍스트가 생성되지 않아 → Redis가 비어있음 → AI 분석이 실행되지 않음

**해결**: Mock 데이터로 **STT 없이도** UI 개발 가능

---

## 💻 Mock 데이터 구현 방법

### 방법 1: 로컬 Mock 함수 (권장)

**장점**: 백엔드 없이 완전 독립 개발 가능

```javascript
/**
 * Mock AI 제안사항 생성기
 * 실제 AI처럼 5초마다 하나씩 제안사항 발행
 */
function connectMockAISuggestions(meetingId) {
  const mockSuggestions = [
    {
      id: crypto.randomUUID(),
      content: "신제품의 타겟 고객층을 20-30대로 설정하고, 모바일 우선 전략을 취하기로 논의 중입니다.",
      timestamp: "00:05:23",
      confidence: 0.92
    },
    {
      id: crypto.randomUUID(),
      content: "개발 일정: 1차 프로토타입은 11월 15일까지 완성, 2차 베타는 12월 1일 론칭",
      timestamp: "00:08:45",
      confidence: 0.88
    },
    {
      id: crypto.randomUUID(),
      content: "마케팅 예산 배분에 대해 SNS 광고 60%, 인플루언서 마케팅 40%로 의견이 나왔으나 추가 검토 필요",
      timestamp: "00:12:18",
      confidence: 0.85
    },
    {
      id: crypto.randomUUID(),
      content: "보안 요구사항 검토가 필요하며, 데이터 암호화 방식에 대한 논의가 진행 중입니다.",
      timestamp: "00:15:30",
      confidence: 0.90
    },
    {
      id: crypto.randomUUID(),
      content: "React로 프론트엔드 개발하기로 결정되었으며, TypeScript 사용을 권장합니다.",
      timestamp: "00:18:42",
      confidence: 0.93
    }
  ];

  let index = 0;
  const interval = setInterval(() => {
    if (index < mockSuggestions.length) {
      // EventSource의 addEventListener('ai-suggestion', ...) 핸들러를 모방
      const event = {
        data: JSON.stringify({
          suggestions: [mockSuggestions[index]]
        })
      };

      // 실제 핸들러 호출
      handleAISuggestion(event);
      index++;
    } else {
      clearInterval(interval);
      console.log('[MOCK] 모든 Mock 제안사항 발행 완료');
    }
  }, 5000); // 5초마다 하나씩

  console.log('[MOCK] Mock AI 제안사항 연결 시작');

  // 정리 함수 반환
  return {
    close: () => {
      clearInterval(interval);
      console.log('[MOCK] Mock 연결 종료');
    }
  };
}
```

### 방법 2: 환경 변수로 전환

```javascript
// 환경 변수로 Mock/Real 모드 전환
const USE_MOCK_AI = process.env.REACT_APP_USE_MOCK_AI === 'true';

function connectAISuggestions(meetingId) {
  if (USE_MOCK_AI) {
    console.log('[MOCK] Mock 모드로 실행');
    return connectMockAISuggestions(meetingId);
  } else {
    console.log('[REAL] 실제 AI 서비스 연결');
    return connectRealAISuggestions(meetingId);
  }
}

function connectRealAISuggestions(meetingId) {
  const url = `http://localhost:8086/api/v1/ai/suggestions/meetings/${meetingId}/stream`;
  const eventSource = new EventSource(url);

  eventSource.addEventListener('ai-suggestion', handleAISuggestion);

  eventSource.onerror = (error) => {
    console.error('[REAL] SSE 연결 오류:', error);
    eventSource.close();
  };

  return eventSource;
}

// 공통 핸들러
function handleAISuggestion(event) {
  const data = JSON.parse(event.data);

  data.suggestions.forEach(suggestion => {
    addSuggestionToUI(suggestion);
  });
}
```

---

## 🔧 개발 환경 설정

### `.env.local` 파일

```env
# Mock 모드 사용 (개발 중)
REACT_APP_USE_MOCK_AI=true

# 실제 AI 서비스 URL (STT 완료 후)
REACT_APP_AI_SERVICE_URL=http://localhost:8086
```

### `package.json` 스크립트

```json
{
  "scripts": {
    "start": "REACT_APP_USE_MOCK_AI=true react-scripts start",
    "start:real": "REACT_APP_USE_MOCK_AI=false react-scripts start",
    "build": "REACT_APP_USE_MOCK_AI=false react-scripts build"
  }
}
```

---

## 🎨 React 전체 예시

```typescript
import { useEffect, useState, useRef } from 'react';

interface Suggestion {
  id: string;
  content: string;
  timestamp: string;
  confidence: number;
}

interface MockConnection {
  close: () => void;
}

function useMockAISuggestions(meetingId: string) {
  const [suggestions, setSuggestions] = useState<Suggestion[]>([]);
  const [connected, setConnected] = useState(false);
  const connectionRef = useRef<MockConnection | null>(null);

  useEffect(() => {
    const mockSuggestions: Suggestion[] = [
      {
        id: crypto.randomUUID(),
        content: "신제품의 타겟 고객층을 20-30대로 설정하고...",
        timestamp: "00:05:23",
        confidence: 0.92
      },
      // ... 더 많은 Mock 데이터
    ];

    let index = 0;
    setConnected(true);

    const interval = setInterval(() => {
      if (index < mockSuggestions.length) {
        setSuggestions(prev => [mockSuggestions[index], ...prev]);
        index++;
      } else {
        clearInterval(interval);
      }
    }, 5000);

    connectionRef.current = {
      close: () => {
        clearInterval(interval);
        setConnected(false);
      }
    };

    return () => {
      connectionRef.current?.close();
    };
  }, [meetingId]);

  return { suggestions, connected };
}

function AISuggestionsPanel({ meetingId }: { meetingId: string }) {
  const USE_MOCK = process.env.REACT_APP_USE_MOCK_AI === 'true';

  const mockData = useMockAISuggestions(meetingId);
  const realData = useRealAISuggestions(meetingId); // 실제 SSE 연결

  const { suggestions, connected } = USE_MOCK ? mockData : realData;

  return (
    <div className="ai-panel">
      <div className="header">
        <h3>AI 제안사항</h3>
        <span className={`badge ${connected ? 'connected' : 'disconnected'}`}>
          {connected ? (USE_MOCK ? 'Mock 모드' : '연결됨') : '연결 끊김'}
        </span>
      </div>

      <div className="suggestions">
        {suggestions.map(s => (
          <SuggestionCard key={s.id} suggestion={s} />
        ))}
      </div>
    </div>
  );
}
```

---

## 🧪 테스트 시나리오

### 1. Mock 모드 테스트

```bash
# Mock 모드로 실행
REACT_APP_USE_MOCK_AI=true npm start
```

**확인 사항**:
- [ ] 5초마다 제안사항이 추가됨
- [ ] 총 5개의 제안사항이 표시됨
- [ ] 타임스탬프, 신뢰도가 정상 표시됨
- [ ] "추가" 버튼 클릭 시 회의록에 추가됨
- [ ] "무시" 버튼 클릭 시 제안사항이 제거됨

### 2. 실제 모드 테스트 (STT 완료 후)

```bash
# AI 서비스 시작
cd ai-python && ./start.sh

# 실제 모드로 실행
REACT_APP_USE_MOCK_AI=false npm start
```

**확인 사항**:
- [ ] SSE 연결이 정상적으로 됨
- [ ] 실제 AI 제안사항이 수신됨
- [ ] 회의 진행에 따라 동적으로 제안사항 생성됨

---

## 📊 Mock vs Real 비교

| 항목 | Mock 모드 | Real 모드 |
|------|----------|----------|
| **백엔드 필요** | 불필요 | 필요 (AI 서비스) |
| **제안 타이밍** | 5초 고정 간격 | 회의 진행에 따라 동적 |
| **제안 개수** | 5개 고정 | 무제한 (회의 종료까지) |
| **데이터 품질** | 하드코딩 샘플 | Claude AI 실제 분석 |
| **네트워크 필요** | 불필요 | 필요 |
| **개발 속도** | 빠름 | 느림 (백엔드 의존) |

---

## ⚠️ 주의사항

### 1. Mock 데이터 관리

```javascript
// ❌ 나쁜 예: 컴포넌트 내부에 하드코딩
function Component() {
  const mockData = [/* ... */];  // 재사용 불가
}

// ✅ 좋은 예: 별도 파일로 분리
// src/mocks/aiSuggestions.ts
export const MOCK_AI_SUGGESTIONS = [/* ... */];
```

### 2. 환경 변수 누락 방지

```javascript
// ❌ 나쁜 예: 하드코딩
const USE_MOCK = true;

// ✅ 좋은 예: 환경 변수 + 기본값
const USE_MOCK = process.env.REACT_APP_USE_MOCK_AI !== 'false';
```

### 3. 프로덕션 빌드 시 Mock 제거

```javascript
// ❌ 나쁜 예: 프로덕션에도 Mock 코드 포함
if (USE_MOCK) { /* mock logic */ }

// ✅ 좋은 예: Tree-shaking 가능하도록 작성
if (process.env.NODE_ENV !== 'production' && USE_MOCK) {
  /* mock logic */
}
```

---

## 🚀 다음 단계

### Phase 1: Mock으로 UI 개발 (현재)
- ✅ Mock 데이터 함수 구현
- ✅ UI 컴포넌트 개발
- ✅ 사용자 인터랙션 구현

### Phase 2: STT 연동 대기 (진행 중)
- 🔄 Backend에서 STT 개발 중
- 🔄 Event Hub 연동 개발 중

### Phase 3: 실제 연동 (STT 완료 후)
- [ ] Mock → Real 모드 전환
- [ ] 통합 테스트
- [ ] 성능 최적화

---

## 📞 문의

**Mock 데이터 관련**: 프론트엔드팀 (유진)
**STT 개발 현황**: 백엔드팀 (준호)
**AI 서비스**: AI팀 (서연)

---

**최종 업데이트**: 2025-10-27
