p2ns.admin updates

This commit is contained in:
Raven Scott
2026-05-30 19:45:56 -04:00
parent 6d94b9c16b
commit 841d814f13
19 changed files with 3488 additions and 1344 deletions
@@ -73,7 +73,7 @@ function getAdminHealthPayload() {
};
}
async function buildStatsPageSnapshot(minutes = 1440) {
async function buildStatsPageSnapshot(minutes = 5) {
const [stats, historical] = await Promise.all([
collectAdminStats(),
Promise.resolve(collectHistoricalMinutes(minutes))
+77 -1
View File
@@ -1,8 +1,48 @@
const fs = require('fs');
const path = require('path');
const { trackRequestWithTiming, trackRequest } = require('../../../maintenance/metrics');
const { logError } = require('../../../infrastructure/logger');
const { createErrorResponse } = require('../../../infrastructure/error_handler');
const { collectAdminStats, collectHistoricalMinutes } = require('../stats-collector');
const statsUIPrefsFile = './cache/statsUIPreferences.json';
const VALID_STATS_MINUTES = [1, 5, 15, 30, 60, 360, 1440, 2880];
const VALID_STATS_INTERVALS = [1000, 2000, 5000, 10000, 30000];
const DEFAULT_STATS_UI_PREFS = {
minutes: 5,
intervalMs: 2000,
autoRefresh: true
};
function normalizeStatsUIPrefs(input) {
const prefs = {
...DEFAULT_STATS_UI_PREFS,
...(input && typeof input === 'object' ? input : {})
};
const minutes = Number(prefs.minutes);
const intervalMs = Number(prefs.intervalMs);
prefs.minutes = VALID_STATS_MINUTES.includes(minutes) ? minutes : DEFAULT_STATS_UI_PREFS.minutes;
prefs.intervalMs = VALID_STATS_INTERVALS.includes(intervalMs) ? intervalMs : DEFAULT_STATS_UI_PREFS.intervalMs;
prefs.autoRefresh = prefs.autoRefresh !== false;
return prefs;
}
function readStatsUIPrefsFromDisk() {
if (!fs.existsSync(statsUIPrefsFile)) {
return { ...DEFAULT_STATS_UI_PREFS };
}
const data = fs.readFileSync(statsUIPrefsFile, 'utf8');
return normalizeStatsUIPrefs(JSON.parse(data));
}
function writeStatsUIPrefsToDisk(prefs) {
const cacheDir = path.dirname(statsUIPrefsFile);
if (!fs.existsSync(cacheDir)) {
fs.mkdirSync(cacheDir, { recursive: true });
}
fs.writeFileSync(statsUIPrefsFile, JSON.stringify(normalizeStatsUIPrefs(prefs), null, 2));
}
async function handleStatsRoutes(req, res) {
const urlPath = req.urlPath || new URL(req.url, `https://${req.headers.host}`).pathname;
const method = req.method;
@@ -27,7 +67,7 @@ async function handleStatsRoutes(req, res) {
if (method === 'GET' && urlPath === '/api/stats/historical') {
try {
let minutes = 60;
let minutes = 5;
if (req.url.includes('?')) {
const queryString = req.url.split('?')[1];
const params = new URLSearchParams(queryString);
@@ -52,6 +92,42 @@ async function handleStatsRoutes(req, res) {
return true;
}
if (method === 'GET' && urlPath === '/api/stats-ui-preferences') {
try {
const prefs = readStatsUIPrefsFromDisk();
trackRequest('/api/stats-ui-preferences', true);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(prefs));
} catch (err) {
logError('Admin', `Error in /api/stats-ui-preferences: ${err.message}`, err);
trackRequest('/api/stats-ui-preferences', false);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(DEFAULT_STATS_UI_PREFS));
}
return true;
}
if (method === 'POST' && urlPath === '/api/save-stats-ui-preferences') {
let body = '';
req.on('data', (chunk) => { body += chunk; });
req.on('end', () => {
try {
const prefs = normalizeStatsUIPrefs(JSON.parse(body || '{}'));
writeStatsUIPrefsToDisk(prefs);
trackRequest('/api/save-stats-ui-preferences', true);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(prefs));
} catch (err) {
logError('Admin', `Error in /api/save-stats-ui-preferences: ${err.message}`, err);
trackRequest('/api/save-stats-ui-preferences', false);
const errorResponse = createErrorResponse(err, 500);
res.writeHead(errorResponse.statusCode, errorResponse.headers);
res.end(errorResponse.body);
}
});
return true;
}
return false;
}
@@ -322,8 +322,8 @@ async function collectAdminStats() {
function collectHistoricalMinutes(minutes) {
let m = parseInt(minutes, 10);
if (isNaN(m) || m < 1) m = 60;
if (m > 1440) m = 1440;
if (isNaN(m) || m < 1) m = 5;
if (m > 2880) m = 2880;
return getHistoricalData(m);
}
@@ -13,8 +13,9 @@ let statsBroadcastInterval = null;
let statsBroadcastInFlight = false;
let statsBroadcastIntervalMs = 0;
const DEFAULT_MINUTES = 1440;
const DEFAULT_INTERVAL_MS = 5000;
const DEFAULT_MINUTES = 5;
const MAX_HISTORICAL_MINUTES = 2880;
const DEFAULT_INTERVAL_MS = 2000;
const MIN_INTERVAL_MS = 1000;
function normalizeIntervalMs(value) {
@@ -37,7 +38,7 @@ function getMinSubscriberIntervalMs() {
function parseMinutes(value) {
const m = parseInt(value, 10);
if (isNaN(m) || m < 1) return DEFAULT_MINUTES;
if (m > 1440) return 1440;
if (m > MAX_HISTORICAL_MINUTES) return MAX_HISTORICAL_MINUTES;
return m;
}