hgzero/develop/dev/dev-ai-integration-guide.md
Minseo-Jo 14d03dcacf STT-AI 통합 작업 진행 중 변경사항 커밋
- AI 서비스 CORS 설정 업데이트
- 회의 진행 프로토타입 수정
- 빌드 리포트 및 로그 파일 업데이트

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 13:17:47 +09:00

7.3 KiB

AI 제안사항 프론트엔드 연동 가이드 (간소화 버전)

📋 개요

백엔드를 간소화하여 논의사항과 결정사항을 구분하지 않고, 단일 "AI 제안사항" 배열로 통합 제공합니다.


🔄 변경 사항 요약

Before (구분)

{
  "discussionTopics": [
    { "topic": "보안 요구사항 검토", ... }
  ],
  "decisions": [
    { "content": "React로 개발", ... }
  ]
}

After (통합)

{
  "suggestions": [
    {
      "id": "sugg-001",
      "content": "신제품의 타겟 고객층을 20-30대로 설정하고...",
      "timestamp": "00:05:23",
      "confidence": 0.92
    }
  ]
}

🎨 프론트엔드 통합 방법

1. 05-회의진행.html에 스크립트 추가

기존 </body> 태그 직전에 추가:

  <!-- AI 제안사항 SSE 연동 -->
  <script src="ai-suggestion-integration.js"></script>
</body>
</html>

2. 전체 플로우

[페이지 로드]
      ↓
   SSE 연결
      ↓
[회의 진행 중]
      ↓
AI 분석 완료 시마다
SSE로 제안사항 전송
      ↓
자동으로 카드 생성
      ↓
[회의 종료]
      ↓
  SSE 연결 종료

📡 SSE API 명세

엔드포인트

GET /api/suggestions/meetings/{meetingId}/stream

헤더

Accept: text/event-stream

응답 형식

event: ai-suggestion
id: 12345
data: {"suggestions":[{"id":"sugg-001","content":"...","timestamp":"00:05:23","confidence":0.92}]}

event: ai-suggestion
id: 12346
data: {"suggestions":[{"id":"sugg-002","content":"...","timestamp":"00:08:45","confidence":0.88}]}

🧪 테스트 방법

1. 로컬 테스트 (Mock 데이터)

백엔드가 아직 없어도 테스트 가능:

// 테스트용 Mock 데이터 전송
function testAiSuggestion() {
    const mockSuggestion = {
        suggestions: [
            {
                id: "test-001",
                content: "테스트 제안사항입니다. 이것은 AI가 생성한 제안입니다.",
                timestamp: "00:05:23",
                confidence: 0.95
            }
        ]
    };

    handleAiSuggestions(mockSuggestion);
}

// 콘솔에서 실행
testAiSuggestion();

2. curl로 SSE 연결 테스트

curl -N -H "Accept: text/event-stream" \
  "http://localhost:8083/api/suggestions/meetings/test-meeting-001/stream"

예상 출력:

event: ai-suggestion
data: {"suggestions":[...]}

3. 브라우저 DevTools로 확인

  1. Network 탭 → "EventStream" 필터
  2. /stream 엔드포인트 클릭
  3. Messages 탭에서 실시간 데이터 확인

💻 JavaScript API 사용법

초기화

// 자동으로 실행됨 (페이지 로드 시)
initializeAiSuggestions();

수동 연결 종료

closeAiSuggestions();

제안사항 수동 추가 (테스트용)

addSuggestionCard({
    id: "manual-001",
    content: "수동으로 추가한 제안사항",
    timestamp: "00:10:00",
    confidence: 0.9
});

🎨 UI 커스터마이징

신뢰도 표시 스타일

/* 05-회의진행.html의 <style> 태그에 추가 */
.ai-suggestion-confidence {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px dashed #E0E0E0;
}

.ai-suggestion-confidence span {
    font-size: 11px;
    color: var(--gray-500);
}

신뢰도에 따른 색상 변경

function getConfidenceColor(confidence) {
    if (confidence >= 0.9) return '#4CAF50'; // 녹색 (높음)
    if (confidence >= 0.7) return '#FFC107'; // 노란색 (중간)
    return '#FF9800'; // 주황색 (낮음)
}

// 카드에 적용
card.innerHTML = `
    ...
    <div class="ai-suggestion-confidence">
        <span style="color: ${getConfidenceColor(suggestion.confidence)};">
            신뢰도: ${Math.round(suggestion.confidence * 100)}%
        </span>
    </div>
`;

🔧 트러블슈팅

문제 1: SSE 연결이 안 됨

증상:

EventSource's response has a MIME type ("application/json") that is not "text/event-stream"

해결:

  • 백엔드에서 produces = MediaType.TEXT_EVENT_STREAM_VALUE 확인
  • SuggestionController.java:111 라인 확인

문제 2: CORS 오류

증상:

Access to XMLHttpRequest has been blocked by CORS policy

해결:

// SecurityConfig.java에 추가
@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("http://localhost:*"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST"));
    configuration.setAllowedHeaders(Arrays.asList("*"));

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/api/**", configuration);
    return source;
}

문제 3: 제안사항이 화면에 안 나타남

체크리스트:

  1. aiSuggestionList ID가 HTML에 있는지 확인
  2. 브라우저 콘솔에 에러가 없는지 확인
  3. Network 탭에서 SSE 데이터가 오는지 확인
  4. handleAiSuggestions 함수에 console.log 추가하여 디버깅

📊 성능 최적화

제안사항 개수 제한

너무 많은 카드가 쌓이면 성능 저하:

function addSuggestionCard(suggestion) {
    // 카드 추가 로직...

    // 최대 20개까지만 유지
    const listElement = document.getElementById('aiSuggestionList');
    const cards = listElement.querySelectorAll('.ai-suggestion-card');
    if (cards.length > 20) {
        cards[cards.length - 1].remove(); // 가장 오래된 카드 삭제
    }
}

중복 제안사항 필터링

const shownSuggestionIds = new Set();

function addSuggestionCard(suggestion) {
    // 이미 표시된 제안사항은 무시
    if (shownSuggestionIds.has(suggestion.id)) {
        console.log('중복 제안사항 무시:', suggestion.id);
        return;
    }

    shownSuggestionIds.add(suggestion.id);

    // 카드 추가 로직...
}

🚀 다음 단계

  1. SimpleSuggestionDto 생성 완료
  2. RealtimeSuggestionsDto 수정 완료
  3. ClaudeApiClient 프롬프트 간소화 완료
  4. SuggestionService 로직 수정 완료
  5. 프론트엔드 연동 코드 작성 완료

실제 테스트 준비

  1. 백엔드 서버 시작

    cd ai
    ./gradlew bootRun
    
  2. 프론트엔드 파일 열기

    design/uiux/prototype/05-회의진행.html
    
  3. 브라우저 DevTools 열고 Network 탭 확인

  4. SSE 연결 확인

    • EventStream 필터 활성화
    • /stream 엔드포인트 확인

📝 완료 체크리스트

  • SimpleSuggestionDto 생성
  • RealtimeSuggestionsDto 수정
  • ClaudeApiClient 프롬프트 간소화
  • SuggestionService Mock 데이터 수정
  • 프론트엔드 연동 JavaScript 작성
  • 05-회의진행.html에 스크립트 추가
  • 로컬 환경에서 테스트
  • Claude API 실제 연동 테스트

🎉 간소화 작업 완료!

이제 프론트엔드와 백엔드가 일치합니다. 05-회의진행.html에 스크립트만 추가하면 바로 사용 가능합니다.