import { getDb } from '../../../utils/db' export default defineEventHandler(async (event) => { const query = getQuery(event) const { year, month, week } = query as { year?: string, month?: string, week?: string } if (!year || !month || !week) { return { error: 'year, month, week are required' } } // 해당 월의 첫날과 마지막날 const y = parseInt(year) const m = parseInt(month) const w = parseInt(week) // 해당 월의 첫날 const firstDayOfMonth = new Date(y, m - 1, 1) const firstDayWeekday = firstDayOfMonth.getDay() // 0=일, 1=월, ... // 주차의 시작일 계산 (월요일 기준) // 1주차: 1일이 포함된 주 const mondayOffset = firstDayWeekday === 0 ? -6 : 1 - firstDayWeekday const firstMondayOfMonth = new Date(y, m - 1, 1 + mondayOffset) // 선택한 주차의 월요일 const weekStart = new Date(firstMondayOfMonth) weekStart.setDate(weekStart.getDate() + (w - 1) * 7) // 주차의 일요일 const weekEnd = new Date(weekStart) weekEnd.setDate(weekEnd.getDate() + 6) // 해당 주의 날짜 목록 생성 const weekDates: string[] = [] for (let i = 0; i < 7; i++) { const d = new Date(weekStart) d.setDate(d.getDate() + i) const dateStr = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}` weekDates.push(dateStr) } const db = getDb() // 시작/종료 날짜 const startDate = weekDates[0] const endDate = weekDates[6] // 1시간 단위 성공률 조회 const heatmapData = db.prepare(` SELECT date(checked_at) as date, strftime('%H', checked_at) || ':00' as time_slot, COUNT(*) as total_count, SUM(CASE WHEN is_success = 1 THEN 1 ELSE 0 END) as success_count, ROUND(SUM(CASE WHEN is_success = 1 THEN 1.0 ELSE 0.0 END) / COUNT(*) * 100, 1) as success_rate FROM pubnet_logs WHERE date(checked_at) >= ? AND date(checked_at) <= ? GROUP BY date, time_slot ORDER BY date, time_slot `).all(startDate, endDate) // 해당 월의 주차 수 계산 const lastDayOfMonth = new Date(y, m, 0) const lastDate = lastDayOfMonth.getDate() // 마지막 날이 몇 주차인지 계산 const lastDayFromFirstMonday = Math.floor((lastDayOfMonth.getTime() - firstMondayOfMonth.getTime()) / (1000 * 60 * 60 * 24)) const totalWeeks = Math.ceil((lastDayFromFirstMonday + 1) / 7) return { heatmapData, weekDates, totalWeeks: Math.max(totalWeeks, 1), year: y, month: m, week: w } })