Switch worker to the Ookla CLI (jitter, packet loss, server, ISP, shareable result URL, bytes). Migration 028 enriches speedtest_results + adds a generic app_settings store. New /speedtest page: KPIs, throughput + latency charts, window stats, configurable schedule (reschedulable cron) & low-speed alert threshold, history table. SV card gains ping/jitter + a link through to the page. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
52 lines
2.0 KiB
JavaScript
52 lines
2.0 KiB
JavaScript
import { pool } from '../pool.js';
|
|
|
|
export async function record(r = {}) {
|
|
const { rows } = await pool.query(
|
|
`INSERT INTO speedtest_results
|
|
(down_mbps, up_mbps, ping_ms, jitter_ms, packet_loss, server_name, server_id,
|
|
isp, result_url, down_bytes, up_bytes, ok, error)
|
|
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13) RETURNING *`,
|
|
[r.down_mbps ?? null, r.up_mbps ?? null, r.ping_ms ?? null, r.jitter_ms ?? null,
|
|
r.packet_loss ?? null, r.server_name ?? null, r.server_id ?? null, r.isp ?? null,
|
|
r.result_url ?? null, r.down_bytes ?? null, r.up_bytes ?? null, r.ok ?? true, r.error ?? null]);
|
|
return rows[0];
|
|
}
|
|
|
|
export async function history(limit = 30) {
|
|
const { rows } = await pool.query(
|
|
`SELECT * FROM speedtest_results ORDER BY ran_at DESC LIMIT $1`, [limit]);
|
|
return rows;
|
|
}
|
|
|
|
// Rows within the last N hours (ascending for charting), capped.
|
|
export async function range(hours = 168, limit = 1000) {
|
|
const { rows } = await pool.query(
|
|
`SELECT * FROM (
|
|
SELECT * FROM speedtest_results
|
|
WHERE ran_at >= now() - ($1 || ' hours')::interval
|
|
ORDER BY ran_at DESC LIMIT $2
|
|
) t ORDER BY ran_at ASC`, [hours, limit]);
|
|
return rows;
|
|
}
|
|
|
|
export async function latest() {
|
|
const { rows } = await pool.query(
|
|
`SELECT * FROM speedtest_results WHERE ok ORDER BY ran_at DESC LIMIT 1`);
|
|
return rows[0] || null;
|
|
}
|
|
|
|
export async function stats(hours = 24) {
|
|
const { rows } = await pool.query(
|
|
`SELECT count(*) FILTER (WHERE ok) AS n,
|
|
count(*) FILTER (WHERE NOT ok) AS failures,
|
|
avg(down_mbps) FILTER (WHERE ok) AS avg_down,
|
|
min(down_mbps) FILTER (WHERE ok) AS min_down,
|
|
max(down_mbps) FILTER (WHERE ok) AS max_down,
|
|
avg(up_mbps) FILTER (WHERE ok) AS avg_up,
|
|
avg(ping_ms) FILTER (WHERE ok) AS avg_ping,
|
|
max(ping_ms) FILTER (WHERE ok) AS max_ping
|
|
FROM speedtest_results
|
|
WHERE ran_at >= now() - ($1 || ' hours')::interval`, [hours]);
|
|
return rows[0];
|
|
}
|