Docker 파일

This commit is contained in:
2025-12-28 14:31:12 +09:00
parent ba7a208da9
commit 6196c03e46
23 changed files with 302 additions and 355 deletions

View File

@@ -1,36 +1,29 @@
import { getDb } from '../../../utils/db'
import { query } from '../../../utils/db'
export default defineEventHandler(async (event) => {
const query = getQuery(event)
const { year, month, week } = query as { year?: string, month?: string, week?: string }
const queryParams = getQuery(event)
const { year, month, week } = queryParams 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=월, ...
const firstDayWeekday = firstDayOfMonth.getDay()
// 주차의 시작일 계산 (월요일 기준)
// 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)
@@ -39,31 +32,23 @@ export default defineEventHandler(async (event) => {
weekDates.push(dateStr)
}
const db = getDb()
// 시작/종료 날짜
const startDate = weekDates[0]
const endDate = weekDates[6]
// 1시간 단위 성공률 조회
const heatmapData = db.prepare(`
const heatmapData = await query(`
SELECT
date(checked_at) as date,
strftime('%H', checked_at) || ':00' as time_slot,
TO_CHAR(checked_at::timestamp, 'YYYY-MM-DD') as date,
TO_CHAR(checked_at::timestamp, 'HH24: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) <= ?
WHERE checked_at::date >= $1 AND checked_at::date <= $2
GROUP BY date, time_slot
ORDER BY date, time_slot
`).all(startDate, endDate)
`, [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)

View File

@@ -1,8 +1,8 @@
import { getDb } from '../../../utils/db'
import { query } from '../../../utils/db'
export default defineEventHandler(async (event) => {
const query = getQuery(event)
const { year, month, day, hour } = query as {
const queryParams = getQuery(event)
const { year, month, day, hour } = queryParams as {
year?: string, month?: string, day?: string, hour?: string
}
@@ -10,13 +10,10 @@ export default defineEventHandler(async (event) => {
return { error: 'year, month, day, hour are required' }
}
const db = getDb()
// 해당 시간대 로그 조회
const startTime = `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')} ${hour.padStart(2, '0')}:00:00`
const endTime = `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')} ${hour.padStart(2, '0')}:59:59`
const logs = db.prepare(`
const logs = await query(`
SELECT
l.id,
l.checked_at,
@@ -25,9 +22,9 @@ export default defineEventHandler(async (event) => {
t.url as target_url
FROM pubnet_logs l
JOIN pubnet_targets t ON l.target_id = t.id
WHERE l.checked_at >= ? AND l.checked_at <= ?
WHERE l.checked_at >= $1 AND l.checked_at <= $2
ORDER BY l.checked_at DESC
`).all(startTime, endTime)
`, [startTime, endTime])
return { logs }
})

View File

@@ -1,11 +1,8 @@
import { getDb } from '../../../utils/db'
import { query, queryOne } from '../../../utils/db'
import { pubnetScheduler } from '../../../utils/pubnet-scheduler'
export default defineEventHandler(() => {
const db = getDb()
// 현재 상태 조회
const status = db.prepare(`
export default defineEventHandler(async () => {
const status = await queryOne(`
SELECT
ps.*,
pt.name as last_target_name,
@@ -13,10 +10,9 @@ export default defineEventHandler(() => {
FROM pubnet_status ps
LEFT JOIN pubnet_targets pt ON ps.last_target_id = pt.id
WHERE ps.id = 1
`).get()
`)
// 최근 10개 로그
const recentLogs = db.prepare(`
const recentLogs = await query(`
SELECT
pl.*,
pt.name as target_name,
@@ -25,17 +21,16 @@ export default defineEventHandler(() => {
JOIN pubnet_targets pt ON pl.target_id = pt.id
ORDER BY pl.checked_at DESC
LIMIT 10
`).all()
`)
// 활성 타겟 수
const targetCount = db.prepare(`
const targetCount = await queryOne<{ cnt: number }>(`
SELECT COUNT(*) as cnt FROM pubnet_targets WHERE is_active = 1
`).get() as { cnt: number }
`)
return {
status,
recentLogs,
targetCount: targetCount.cnt,
targetCount: targetCount?.cnt || 0,
schedulerRunning: pubnetScheduler.getIsRunning()
}
})

View File

@@ -1,10 +1,9 @@
import { getDb } from '../../../../utils/db'
import { execute } from '../../../../utils/db'
export default defineEventHandler((event) => {
const db = getDb()
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id')
db.prepare(`DELETE FROM pubnet_targets WHERE id = ?`).run(id)
await execute(`DELETE FROM pubnet_targets WHERE id = $1`, [id])
return { success: true }
})

View File

@@ -1,7 +1,6 @@
import { getDb } from '../../../../utils/db'
import { execute } from '../../../../utils/db'
export default defineEventHandler(async (event) => {
const db = getDb()
const id = getRouterParam(event, 'id')
const body = await readBody(event)
@@ -14,11 +13,11 @@ export default defineEventHandler(async (event) => {
})
}
db.prepare(`
await execute(`
UPDATE pubnet_targets
SET name = ?, url = ?, is_active = ?, updated_at = datetime('now', 'localtime')
WHERE id = ?
`).run(name, url, is_active ? 1 : 0, id)
SET name = $1, url = $2, is_active = $3, updated_at = TO_CHAR(NOW(), 'YYYY-MM-DD HH24:MI:SS')
WHERE id = $4
`, [name, url, is_active ? 1 : 0, id])
return {
id: Number(id),

View File

@@ -1,12 +1,10 @@
import { getDb } from '../../../../utils/db'
import { query } from '../../../../utils/db'
export default defineEventHandler(() => {
const db = getDb()
const targets = db.prepare(`
export default defineEventHandler(async () => {
const targets = await query(`
SELECT * FROM pubnet_targets
ORDER BY id ASC
`).all()
`)
return targets
})

View File

@@ -1,7 +1,6 @@
import { getDb } from '../../../../utils/db'
import { queryOne } from '../../../../utils/db'
export default defineEventHandler(async (event) => {
const db = getDb()
const body = await readBody(event)
const { name, url, is_active } = body
@@ -13,13 +12,14 @@ export default defineEventHandler(async (event) => {
})
}
const result = db.prepare(`
const result = await queryOne<{ id: number }>(`
INSERT INTO pubnet_targets (name, url, is_active)
VALUES (?, ?, ?)
`).run(name, url, is_active ? 1 : 0)
VALUES ($1, $2, $3)
RETURNING id
`, [name, url, is_active ? 1 : 0])
return {
id: result.lastInsertRowid,
id: result?.id,
name,
url,
is_active: is_active ? 1 : 0