import { queryOne, execute } from '../../../utils/db' import { requireAuth } from '../../../utils/session' import { callOpenAI } from '../../../utils/openai' /** * 회의록 AI 분석 * POST /api/meeting/[id]/analyze */ export default defineEventHandler(async (event) => { await requireAuth(event) const meetingId = parseInt(event.context.params?.id || '0') if (!meetingId) { throw createError({ statusCode: 400, message: '회의록 ID가 필요합니다.' }) } // 회의록 조회 const meeting = await queryOne(` SELECT m.*, p.project_name FROM wr_meeting m LEFT JOIN wr_project_info p ON m.project_id = p.project_id WHERE m.meeting_id = $1 `, [meetingId]) if (!meeting) { throw createError({ statusCode: 404, message: '회의록을 찾을 수 없습니다.' }) } if (!meeting.raw_content) { throw createError({ statusCode: 400, message: '분석할 회의 내용이 없습니다.' }) } // AI 프롬프트 const systemPrompt = `당신은 회의록 정리 전문가입니다. 아래 회의 내용을 분석하여 JSON 형식으로 정리해주세요. ## 출력 형식 (JSON만 출력, 다른 텍스트 없이) { "agendas": [ { "no": 1, "title": "안건 제목", "content": "상세 내용 요약", "status": "DECIDED | PENDING | IN_PROGRESS", "decision": "결정 내용 (결정된 경우만)", "todos": [ { "title": "TODO 제목", "assignee": "담당자명 또는 null", "reason": "TODO로 추출한 이유" } ] } ], "summary": "전체 회의 요약 (2-3문장)" } ## 규칙 1. 안건은 주제별로 분리하여 넘버링 2. 결정된 사항은 DECIDED, 추후 논의는 PENDING, 진행중은 IN_PROGRESS 3. 미결정/진행중 사항 중 액션이 필요한 것은 todos로 추출 4. 담당자가 언급되면 assignee에 기록 (없으면 null) 5. JSON 외 다른 텍스트 출력 금지` const userPrompt = `## 회의 정보 - 제목: ${meeting.meeting_title} - 프로젝트: ${meeting.project_name || '없음 (내부업무)'} - 일자: ${meeting.meeting_date} ## 회의 내용 ${meeting.raw_content}` try { const result = await callOpenAI([ { role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt } ], true, 'gpt-4o-mini') // JSON 파싱 let aiResult: any try { // JSON 블록 추출 (```json ... ``` 형태 처리) let jsonStr = result.trim() if (jsonStr.startsWith('```')) { jsonStr = jsonStr.replace(/^```json?\n?/, '').replace(/\n?```$/, '') } aiResult = JSON.parse(jsonStr) } catch (e) { console.error('AI result parse error:', result) throw createError({ statusCode: 500, message: 'AI 응답 파싱 실패' }) } // DB 저장 await execute(` UPDATE wr_meeting SET ai_summary = $1, ai_status = 'PENDING', ai_processed_at = NOW() WHERE meeting_id = $2 `, [JSON.stringify(aiResult), meetingId]) return { success: true, result: aiResult } } catch (e: any) { console.error('AI analyze error:', e) throw createError({ statusCode: 500, message: e.message || 'AI 분석 실패' }) } })