101 lines
2.6 KiB
TypeScript
101 lines
2.6 KiB
TypeScript
import { callOpenAI } from '../../../utils/openai'
|
|
|
|
interface TaskInput {
|
|
taskId: number
|
|
requestTitle: string
|
|
requestContent?: string
|
|
taskType: string
|
|
resolutionContent?: string
|
|
}
|
|
|
|
interface GenerateBody {
|
|
tasks: TaskInput[]
|
|
projectName?: string
|
|
}
|
|
|
|
/**
|
|
* 유지보수 업무를 주간보고 실적 문장으로 변환
|
|
* POST /api/maintenance/report/generate-text
|
|
*/
|
|
export default defineEventHandler(async (event) => {
|
|
const body = await readBody<GenerateBody>(event)
|
|
|
|
if (!body.tasks || body.tasks.length === 0) {
|
|
throw createError({ statusCode: 400, message: '업무 목록이 필요합니다.' })
|
|
}
|
|
|
|
// 유형별 그룹화
|
|
const grouped: Record<string, TaskInput[]> = {}
|
|
for (const task of body.tasks) {
|
|
const type = task.taskType || 'other'
|
|
if (!grouped[type]) grouped[type] = []
|
|
grouped[type].push(task)
|
|
}
|
|
|
|
// OpenAI 프롬프트
|
|
const taskList = body.tasks.map((t, i) =>
|
|
`${i+1}. [${t.taskType}] ${t.requestTitle}${t.resolutionContent ? ' → ' + t.resolutionContent : ''}`
|
|
).join('\n')
|
|
|
|
const prompt = `다음 유지보수 업무 목록을 주간보고 실적으로 작성해주세요.
|
|
|
|
업무 목록:
|
|
${taskList}
|
|
|
|
작성 가이드:
|
|
1. 유사한 업무는 하나로 병합 (예: "XX 관련 버그 수정 3건")
|
|
2. 주간보고에 적합한 간결한 문장으로 작성
|
|
3. 기술적 용어는 유지하되 명확하게
|
|
4. 각 실적은 한 줄로 작성
|
|
|
|
JSON 형식으로 응답:
|
|
{
|
|
"tasks": [
|
|
{
|
|
"description": "실적 문장",
|
|
"sourceTaskIds": [원본 task_id 배열],
|
|
"taskType": "bug|feature|inquiry|other"
|
|
}
|
|
]
|
|
}`
|
|
|
|
try {
|
|
const response = await callOpenAI([
|
|
{ role: 'system', content: '주간보고 작성 전문가입니다. 유지보수 업무를 간결하고 명확한 실적 문장으로 변환합니다.' },
|
|
{ role: 'user', content: prompt }
|
|
], true)
|
|
|
|
const parsed = JSON.parse(response)
|
|
|
|
return {
|
|
success: true,
|
|
generatedTasks: parsed.tasks || []
|
|
}
|
|
} catch (e) {
|
|
console.error('OpenAI error:', e)
|
|
|
|
// 실패 시 기본 변환
|
|
const defaultTasks = body.tasks.map(t => ({
|
|
description: `[${getTypeLabel(t.taskType)}] ${t.requestTitle}`,
|
|
sourceTaskIds: [t.taskId],
|
|
taskType: t.taskType
|
|
}))
|
|
|
|
return {
|
|
success: true,
|
|
generatedTasks: defaultTasks,
|
|
fallback: true
|
|
}
|
|
}
|
|
})
|
|
|
|
function getTypeLabel(type: string): string {
|
|
const labels: Record<string, string> = {
|
|
bug: '버그수정',
|
|
feature: '기능개선',
|
|
inquiry: '문의대응',
|
|
other: '기타'
|
|
}
|
|
return labels[type] || '기타'
|
|
}
|