Files
factorio-signal-exporter/web/app/api/ups/route.ts
Caesar2011 20ed6ee9fb Initial web
2026-05-17 19:55:53 +02:00

59 lines
1.9 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import pool from '@/lib/db';
import { withAuth } from '@/lib/apiHelpers';
export const GET = withAuth(async (req: NextRequest) => {
const p = req.nextUrl.searchParams;
const combinator = p.get('combinator');
const from = p.get('from') ? new Date(p.get('from')!) : new Date(Date.now() - 86_400_000);
const to = p.get('to') ? new Date(p.get('to')!) : new Date();
const conditions = ['real_time BETWEEN $1 AND $2'];
const values: unknown[] = [from, to];
if (combinator) {
conditions.push('combinator = $3');
values.push(combinator);
}
const result = await pool.query<{
real_time: Date; game_tick: string; combinator: string;
}>(
`SELECT real_time, game_tick, combinator
FROM tick_timing
WHERE ${conditions.join(' AND ')}
ORDER BY real_time ASC`,
values,
);
const rows = result.rows;
if (rows.length < 2) return NextResponse.json([]);
const byCombi = new Map<string, typeof rows>();
for (const row of rows) {
const arr = byCombi.get(row.combinator) ?? [];
arr.push(row);
byCombi.set(row.combinator, arr);
}
const points: { real_time: string; game_tick: number; combinator: string; ups: number }[] = [];
for (const [combi, combiRows] of byCombi) {
for (let i = 1; i < combiRows.length; i++) {
const prev = combiRows[i - 1];
const curr = combiRows[i];
const deltaRealMs = curr.real_time.getTime() - prev.real_time.getTime();
const deltaTicks = parseInt(curr.game_tick, 10) - parseInt(prev.game_tick, 10);
// Skip session gaps and bad data
if (deltaRealMs > 30 * 60 * 1000 || deltaRealMs <= 0 || deltaTicks <= 0) continue;
points.push({
real_time: curr.real_time.toISOString(),
game_tick: parseInt(curr.game_tick, 10),
combinator: combi,
ups: Math.round((deltaTicks / deltaRealMs) * 1000 * 10) / 10,
});
}
}
return NextResponse.json(points);
});