Replace /phonestatus follow-ups with /voicestatus, /wanstatus, /phonediag, and /dectdiag; extend /voicediag with relay probes and section-based MPP diagnostics. Co-authored-by: Cursor <cursoragent@cursor.com>
77 lines
2.4 KiB
JavaScript
77 lines
2.4 KiB
JavaScript
// src/commands/wanStatus.js
|
||
//
|
||
// /wanstatus <store> [--window 24h]
|
||
//
|
||
// Prisma SD-WAN diagnostics for a store: healthscore, per-path LQM,
|
||
// voice traffic quality (when configured), and active alarms.
|
||
|
||
import { collectSdwanForStore } from '../services/enrichment/sdwanEnrichment.js';
|
||
import { renderWanDiagnosticsMarkdown } from '../services/renderers/wanDiagnosticsRenderer.js';
|
||
import { findSdwanSiteForStore, siteNameForStore } from '../integrations/paloalto/sites.js';
|
||
import { pickWindowArg, parseWindowMinutes } from '../utils/windowArgs.js';
|
||
import { logger } from '../utils/logger.js';
|
||
|
||
export async function handleWanStatus(bot, trigger) {
|
||
const query = trigger.query || {};
|
||
const args = trigger.args || [];
|
||
const storeNum = (args[0]?.trim() || query.storeNum || query.store || query.s || '').trim();
|
||
|
||
const windowRaw = pickWindowArg(args) ?? query.window ?? null;
|
||
const windowMinutes = parseWindowMinutes(windowRaw);
|
||
if (windowRaw && windowMinutes == null) {
|
||
await bot.say(
|
||
'markdown',
|
||
`Unrecognised window \`${windowRaw}\`. Use \`15m\`, \`1h\`, \`6h\`, \`24h\`, \`1d\`, or \`7d\`.`,
|
||
);
|
||
return;
|
||
}
|
||
|
||
if (!storeNum || !/^\d{2,4}$/.test(storeNum)) {
|
||
await bot.say(
|
||
'markdown',
|
||
'Please provide a 2–4 digit store number.\n' +
|
||
'Examples:\n' +
|
||
'- `/wanstatus 782`\n' +
|
||
'- `/wanstatus 782 --window 24h`\n' +
|
||
'HTTP: `?storeNum=782&window=7d`',
|
||
);
|
||
return;
|
||
}
|
||
|
||
logger('wan:status', `Collecting WAN status for store ${storeNum}`);
|
||
|
||
let site;
|
||
try {
|
||
site = await findSdwanSiteForStore(storeNum);
|
||
} catch (err) {
|
||
logger('wan:status', `Site lookup failed for store ${storeNum}: ${err.message}`, 'warn');
|
||
await bot.say(
|
||
'markdown',
|
||
`❌ WAN lookup failed for store ${storeNum}: ${err.message}`,
|
||
);
|
||
return;
|
||
}
|
||
|
||
if (!site) {
|
||
const expected = safeSiteName(storeNum);
|
||
await bot.say(
|
||
'markdown',
|
||
`Store ${storeNum} is not Prisma SD-WAN managed (expected site \`${expected}\`).`,
|
||
);
|
||
return;
|
||
}
|
||
|
||
await bot.say('markdown', `⏳ Collecting WAN metrics for store ${storeNum}…`);
|
||
|
||
const data = await collectSdwanForStore(storeNum, { windowMinutes });
|
||
const md = renderWanDiagnosticsMarkdown(data, { storeNum });
|
||
await bot.say('markdown', md || 'No WAN data available.');
|
||
}
|
||
|
||
function safeSiteName(storeNum) {
|
||
try {
|
||
return siteNameForStore(storeNum);
|
||
} catch {
|
||
return '<invalid store number>';
|
||
}
|
||
}
|