// src/services/voiceDiag/checks/port/_helpers.js // // Shared helpers for the port-hygiene check bucket. Each of the port // checks (portType, portVlan, portPoe, portEnabled) walks the same // per-phone / per-DECT-base list out of ctx.phoneStatus and reports // a per-device verdict. Centralising the walk + labelling here keeps // the individual check modules focused on their single signal. /** * Collect every device that could plausibly have a wired port. This * is desk phones + DECT basestations. DECT handsets are excluded — * they're radio-connected to their base, they don't have their own * switchport. Wireless desk phones aren't filtered out here; the * per-check `isWireless(d)` guard decides how to render them. * * @param {object} phoneStatus collectPhoneStatus() result * @returns {Array} each entry retains its full shape so * checks can reach `.meraki.*` freely. */ export function collectPortDevices(phoneStatus) { if (!phoneStatus) return []; const phones = Array.isArray(phoneStatus?.phones?.data) ? phoneStatus.phones.data : []; const dectBases = Array.isArray(phoneStatus?.dectBasestations) ? phoneStatus.dectBasestations : []; const tag = (kind) => (d) => ({ ...d, _voiceDiagKind: kind }); return [ ...phones.map(tag('phone')), ...dectBases.map(tag('dect-base')), ]; } /** True when the device is on wireless — no switchport to inspect. */ export function isWireless(dev) { const conn = String(dev?.meraki?.connectionType || '').toLowerCase(); if (conn === 'wireless') return true; return false; } /** * Global kill-switch for the port-hygiene bucket. Env * `VOICE_STANDARD_ENABLED=false` returns a short "port checks are * currently disabled" skip result that every port check can return * verbatim. Feature-config checks (DND, forwarding, etc.) are * intentionally *not* gated by this — those are unconditional * standards. Only the switchport bucket bows out. * * The check descriptor is passed in so the returned result carries * the caller's id / label without callers repeating themselves. */ export function maybeSkippedByKillSwitch(check) { const raw = String(process.env.VOICE_STANDARD_ENABLED ?? 'true').toLowerCase().trim(); const enabled = !(raw === 'false' || raw === '0' || raw === 'no' || raw === 'off'); if (enabled) return null; return { status: 'skipped', message: `${check.label} skipped — VOICE_STANDARD_ENABLED=false (port-hygiene checks are silenced).`, details: { killSwitch: 'VOICE_STANDARD_ENABLED', value: raw }, remediation: null, }; } /** Human labels used in per-device drilldowns. Kept short so * aggregate messages don't blow past Webex's chat readability. */ export function portLabelFor(dev) { const kind = dev?._voiceDiagKind || 'device'; const deviceLabel = dev?.name || dev?.mac || (kind === 'dect-base' ? 'DECT base' : 'Phone'); const switchName = dev?.meraki?.switchName || dev?.meraki?.deviceName || '—'; const portName = dev?.meraki?.portName || dev?.meraki?.port || '—'; return { kind, deviceLabel, switchName, portName, portLabel: `${switchName}:${portName}`, mac: dev?.mac || null, }; }