collabSupport/services/voiceDiag/checks/wan/wanMos.js
jmcqueen b802383441 Add Prisma SD-WAN voice-quality enrichment for /phonestatus + /voicediag
Introduces a full Palo Alto Prisma SD-WAN integration (dual-mode SASE
OAuth 2.0 / legacy CloudGenix auth, pagination, 429 backoff, session
priming) that surfaces per-path latency/jitter/loss/MOS, site
healthscore, link state, and alarm data for a store. Wired into the
/phonestatus WAN follow-up and eight new /voicediag WAN checks graded
against ITU-T G.114 / RFC 3550 defaults (env-overridable via
WAN_STANDARD_*).

Also adds a shape-aware detail renderer for /voicediag (per-link
tables with verdict icons instead of a stringified JSON dump) and a
--window flag (15m / 1h / 6h / 24h / 1d, env default via
WAN_STANDARD_WINDOW_MINUTES) so operators can widen the look-back
without redeploying. scripts/prismaProbe.js is bundled as a CLI for
schema iteration against a live tenant.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 09:45:29 -04:00

55 lines
1.4 KiB
JavaScript

// src/services/voiceDiag/checks/wan/wanMos.js
//
// Per-path Mean Opinion Score (MOS, 1.0-5.0). MOS is Prisma's
// composite quality score derived from LQM latency+jitter+loss;
// it's the number to correlate with user-reported "voice sounds
// bad" tickets because it factors all the physical-layer signals
// into one number.
//
// - >= 4.0 : good ("toll quality")
// - 3.5-4.0: warn ("acceptable, users notice")
// - < 3.5 : error ("degraded, users struggle")
//
// Unlike latency/jitter/loss, MOS is inverted: LOW is bad. The
// shared evaluator honours the `lowIsBad: true` flag.
import {
maybeSkippedByKillSwitch,
getLinks,
getMosWarn,
getMosError,
evaluatePerLinkMetric,
} from './_helpers.js';
export const WAN_MOS_STANDARDS = Object.freeze({
minWarn: 4.0,
minError: 3.5,
unit: '',
reference: 'ITU-T P.800 MOS scale',
});
export const wanMosCheck = {
id: 'wanMos',
label: 'SD-WAN MOS (per path)',
requires: ['sdwanSite'],
scope: null,
standards: WAN_MOS_STANDARDS,
async run(ctx) {
const skip = maybeSkippedByKillSwitch(wanMosCheck);
if (skip) return skip;
const warnThresh = getMosWarn();
const errorThresh = getMosError();
return evaluatePerLinkMetric({
links: getLinks(ctx),
metricKey: 'mos',
label: 'MOS',
unit: '',
warnThresh,
errorThresh,
lowIsBad: true,
standardLabel: `warn < ${warnThresh}, error < ${errorThresh}`,
});
},
};