50 lines
1.5 KiB
TypeScript
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,
|
|
})
|
|
}
|