mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 23:06:23 +00:00
주요 변경사항: - AI 서비스 Java → Python (FastAPI) 완전 마이그레이션 - 포트 변경: 8083 → 8086 - SSE 스트리밍 기능 구현 및 테스트 완료 - Claude API 연동 (claude-3-5-sonnet-20241022) - Redis 슬라이딩 윈도우 방식 텍스트 축적 - Azure Event Hub 연동 준비 (STT 텍스트 수신) 프론트엔드 연동 지원: - API 연동 가이드 업데이트 (Python 버전 반영) - Mock 데이터 개발 가이드 신규 작성 - STT 개발 완료 전까지 Mock 데이터로 UI 개발 가능 기술 스택: - Python 3.13 - FastAPI 0.104.1 - Anthropic Claude API 0.42.0 - Redis (asyncio) 5.0.1 - Azure Event Hub 5.11.4 - Pydantic 2.10.5 테스트 결과: - ✅ 서비스 시작 정상 - ✅ 헬스 체크 성공 - ✅ SSE 스트리밍 동작 확인 - ✅ Redis 연결 정상 다음 단계: - STT (Azure Speech) 서비스 연동 개발 - Event Hub를 통한 실시간 텍스트 수신 - E2E 통합 테스트 (STT → AI → Frontend) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
9.3 KiB
9.3 KiB
프론트엔드 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 함수 (권장)
장점: 백엔드 없이 완전 독립 개발 가능
/**
* 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: 환경 변수로 전환
// 환경 변수로 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 파일
# Mock 모드 사용 (개발 중)
REACT_APP_USE_MOCK_AI=true
# 실제 AI 서비스 URL (STT 완료 후)
REACT_APP_AI_SERVICE_URL=http://localhost:8086
package.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 전체 예시
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 모드 테스트
# Mock 모드로 실행
REACT_APP_USE_MOCK_AI=true npm start
확인 사항:
- 5초마다 제안사항이 추가됨
- 총 5개의 제안사항이 표시됨
- 타임스탬프, 신뢰도가 정상 표시됨
- "추가" 버튼 클릭 시 회의록에 추가됨
- "무시" 버튼 클릭 시 제안사항이 제거됨
2. 실제 모드 테스트 (STT 완료 후)
# 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 데이터 관리
// ❌ 나쁜 예: 컴포넌트 내부에 하드코딩
function Component() {
const mockData = [/* ... */]; // 재사용 불가
}
// ✅ 좋은 예: 별도 파일로 분리
// src/mocks/aiSuggestions.ts
export const MOCK_AI_SUGGESTIONS = [/* ... */];
2. 환경 변수 누락 방지
// ❌ 나쁜 예: 하드코딩
const USE_MOCK = true;
// ✅ 좋은 예: 환경 변수 + 기본값
const USE_MOCK = process.env.REACT_APP_USE_MOCK_AI !== 'false';
3. 프로덕션 빌드 시 Mock 제거
// ❌ 나쁜 예: 프로덕션에도 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