기능구현중
This commit is contained in:
105
server/api/meeting/[id]/analyze.post.ts
Normal file
105
server/api/meeting/[id]/analyze.post.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
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<any>(`
|
||||
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 분석 실패' })
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user