109 lines
3.3 KiB
TypeScript
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
|
|
}
|
|
})
|