62 lines
1.9 KiB
TypeScript
62 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);
|
|
});
|