Initial Commit
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
'use strict';
|
||||
const { Router } = require('express');
|
||||
const { getAllTests, getConfig } = require('../db');
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
const tests = getAllTests();
|
||||
|
||||
// ── Overall ───────────────────────────────────────────────────────────────
|
||||
const totalCompleted = tests.filter(t => t.completed).length;
|
||||
const overall = {
|
||||
total: tests.length,
|
||||
completed: totalCompleted,
|
||||
completionRate: tests.length > 0 ? totalCompleted / tests.length : 0,
|
||||
};
|
||||
|
||||
// ── Per device ────────────────────────────────────────────────────────────
|
||||
const deviceMap = new Map();
|
||||
for (const t of tests) {
|
||||
if (!t.device) continue;
|
||||
if (!deviceMap.has(t.device)) deviceMap.set(t.device, { total: 0, completed: 0 });
|
||||
const d = deviceMap.get(t.device);
|
||||
d.total++;
|
||||
if (t.completed) d.completed++;
|
||||
}
|
||||
const devices = Array.from(deviceMap.entries())
|
||||
.sort(([a], [b]) => a.localeCompare(b))
|
||||
.map(([name, d]) => ({
|
||||
name,
|
||||
total: d.total,
|
||||
completed: d.completed,
|
||||
completionRate: d.total > 0 ? d.completed / d.total : 0,
|
||||
}));
|
||||
|
||||
// ── Elapsed = sum of individual test durations ────────────────────────────
|
||||
const elapsedSeconds = tests.reduce((sum, t) => {
|
||||
return t.completed && t.duration_seconds != null ? sum + t.duration_seconds : sum;
|
||||
}, 0);
|
||||
|
||||
// ── Per-type averages and remaining counts ────────────────────────────────
|
||||
const TYPES = ['COE', 'P2P', 'P3P'];
|
||||
const byType = {};
|
||||
let estimatedRemainingSeconds = 0;
|
||||
let estimatePossible = true;
|
||||
|
||||
for (const type of TYPES) {
|
||||
const typeTests = tests.filter(t => t.interference === type);
|
||||
const completed = typeTests.filter(t => t.completed);
|
||||
const withDuration = completed.filter(t => t.duration_seconds != null);
|
||||
const remaining = typeTests.length - completed.length;
|
||||
|
||||
const calcAvg = withDuration.length > 0
|
||||
? withDuration.reduce((s, t) => s + t.duration_seconds, 0) / withDuration.length
|
||||
: null;
|
||||
|
||||
const manualValue = getConfig(`avg_time_${type.toLowerCase()}`);
|
||||
|
||||
let avgSeconds = null;
|
||||
let avgSource = null;
|
||||
|
||||
if (manualValue !== null) {
|
||||
avgSeconds = parseFloat(manualValue);
|
||||
avgSource = calcAvg !== null ? 'manual_override' : 'manual';
|
||||
} else if (calcAvg !== null) {
|
||||
avgSeconds = calcAvg;
|
||||
avgSource = 'calculated';
|
||||
}
|
||||
|
||||
byType[type] = {
|
||||
total: typeTests.length,
|
||||
completed: completed.length,
|
||||
remaining,
|
||||
avgSeconds,
|
||||
avgSource,
|
||||
};
|
||||
|
||||
if (remaining > 0) {
|
||||
if (avgSeconds !== null) {
|
||||
estimatedRemainingSeconds += avgSeconds * remaining;
|
||||
} else {
|
||||
estimatePossible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res.json({
|
||||
overall,
|
||||
devices,
|
||||
timing: {
|
||||
elapsedSeconds,
|
||||
estimatedRemainingSeconds: estimatePossible ? estimatedRemainingSeconds : null,
|
||||
byType,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
Reference in New Issue
Block a user