Files
weeklyreport/backend/api/report/summary/aggregate.post.ts
2026-01-04 20:58:47 +09:00

109 lines
3.3 KiB
TypeScript

import { query, queryOne, insertReturning, execute } from '../../../utils/db'
import { getClientIp } from '../../../utils/ip'
import { getCurrentUserEmail } from '../../../utils/user'
interface AggregateBody {
projectId: number
reportYear: number
reportWeek: number
}
/**
* 수동 취합 실행
* POST /api/report/summary/aggregate
*/
export default defineEventHandler(async (event) => {
const userId = getCookie(event, 'user_id')
if (!userId) {
throw createError({ statusCode: 401, message: '로그인이 필요합니다.' })
}
const body = await readBody<AggregateBody>(event)
const clientIp = getClientIp(event)
const userEmail = await getCurrentUserEmail(event)
if (!body.projectId || !body.reportYear || !body.reportWeek) {
throw createError({ statusCode: 400, message: '프로젝트, 연도, 주차를 선택해주세요.' })
}
// 해당 프로젝트/주차의 제출된 보고서 조회 (새 구조)
const reports = await query<any>(`
SELECT
r.report_id,
r.author_id,
r.week_start_date,
r.week_end_date,
rp.detail_id
FROM wr_weekly_report r
JOIN wr_weekly_report_project rp ON r.report_id = rp.report_id
WHERE rp.project_id = $1
AND r.report_year = $2
AND r.report_week = $3
AND r.report_status IN ('SUBMITTED', 'AGGREGATED')
ORDER BY r.report_id
`, [body.projectId, body.reportYear, body.reportWeek])
if (reports.length === 0) {
throw createError({ statusCode: 400, message: '취합할 보고서가 없습니다.' })
}
const reportIds = [...new Set(reports.map(r => r.report_id))]
const weekStartDate = reports[0].week_start_date
const weekEndDate = reports[0].week_end_date
// 기존 취합 보고서 확인
const existing = await queryOne<any>(`
SELECT summary_id FROM wr_aggregated_report_summary
WHERE project_id = $1 AND report_year = $2 AND report_week = $3
`, [body.projectId, body.reportYear, body.reportWeek])
let summaryId: number
if (existing) {
// 기존 취합 업데이트
await execute(`
UPDATE wr_aggregated_report_summary
SET report_ids = $1,
member_count = $2,
aggregated_at = NOW(),
updated_at = NOW(),
updated_ip = $3,
updated_email = $4
WHERE summary_id = $5
`, [reportIds, reportIds.length, clientIp, userEmail, existing.summary_id])
summaryId = existing.summary_id
} else {
// 새 취합 생성
const newSummary = await insertReturning<any>(`
INSERT INTO wr_aggregated_report_summary (
project_id, report_year, report_week, week_start_date, week_end_date,
report_ids, member_count,
created_ip, created_email, updated_ip, updated_email
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $8, $9)
RETURNING summary_id
`, [
body.projectId, body.reportYear, body.reportWeek,
weekStartDate, weekEndDate,
reportIds, reportIds.length,
clientIp, userEmail
])
summaryId = newSummary.summary_id
}
// 개별 보고서 상태 업데이트
await execute(`
UPDATE wr_weekly_report
SET report_status = 'AGGREGATED',
updated_at = NOW(),
updated_ip = $1,
updated_email = $2
WHERE report_id = ANY($3)
`, [clientIp, userEmail, reportIds])
return {
success: true,
summaryId,
memberCount: reportIds.length
}
})