2026-07-08 14:35:15 +08:00

50 lines
1.5 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import {
upsertPublicTrafficRollups,
type PublicTrafficRollupInput,
} from '@/lib/public-traffic-stats'
export const runtime = 'nodejs'
export const dynamic = 'force-dynamic'
const MAX_ROWS_PER_REQUEST = 2000
function readInternalToken(request: NextRequest) {
const bearer = request.headers.get('authorization')?.match(/^Bearer\s+(.+)$/i)?.[1]
return bearer || request.headers.get('x-internal-job-token') || ''
}
function normalizeRows(payload: unknown): PublicTrafficRollupInput[] {
if (!payload || typeof payload !== 'object') return []
const rows = (payload as { rows?: unknown }).rows
return Array.isArray(rows) ? rows.slice(0, MAX_ROWS_PER_REQUEST) as PublicTrafficRollupInput[] : []
}
export async function POST(request: NextRequest) {
const expectedToken = process.env.PUBLIC_TRAFFIC_ROLLUP_TOKEN
if (!expectedToken) {
return NextResponse.json({ error: '公网流量汇总写入未启用' }, { status: 404 })
}
if (readInternalToken(request) !== expectedToken) {
return NextResponse.json({ error: '无权限写入公网流量汇总' }, { status: 403 })
}
const payload = await request.json().catch(() => null)
const rows = normalizeRows(payload)
if (rows.length === 0) {
return NextResponse.json({ error: '没有可写入的公网流量汇总行' }, { status: 400 })
}
const startedAt = Date.now()
const result = await upsertPublicTrafficRollups(rows)
return NextResponse.json({
ok: true,
durationMs: Date.now() - startedAt,
...result,
})
}