collabSupport/integrations/atlas/checkStore.js
jmcqueen 5e54ea6f57 Add /atlasdiag live AZM diagnostic with source alerts and monitor auto-off.
Ports Atlas /check as /atlasdiag: Hub resolve, UI tunnel, WebSocket report
for sources/zones/accessories, low source dB warnings, and auto-disable of
the monitor speaker when left on after troubleshooting.

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

102 lines
2.9 KiB
JavaScript

// integrations/atlas/checkStore.js
// /atlasdiag orchestrator: resolve → tunnel → AZM report → markdown
import { openAuthenticatedTunnel } from './uiSession.js';
import { fetchAzmCheckReport, formatCheckMarkdown } from './azmWs.js';
import {
resolveStoreDevice,
isOffline,
deviceStatus,
} from './resolveStoreDevice.js';
import { getAtlasDeviceList, getAtlasDeviceDetail } from './devices.js';
import { XyteHttpError } from './errors.js';
/**
* Run a full store check against Atlas Hub + live AZM tunnel.
*
* @param {string|number} storeOrName
* @param {{ pollSeconds?: number }} [opts]
*/
export async function checkStore(storeOrName, { pollSeconds = 90 } = {}) {
const devices = await getAtlasDeviceList();
const resolved = resolveStoreDevice(devices, storeOrName);
if (!resolved.device) {
return {
ok: false,
markdown: `${resolved.error || 'Device not found'}`,
error: resolved.error,
code: resolved.code,
matches: resolved.matches,
storePadded: resolved.storePadded,
};
}
let device = resolved.device;
const storeDisplay = resolved.storePadded
? String(Number(resolved.storePadded))
: storeOrName;
try {
const fresh = await getAtlasDeviceDetail(device.id);
if (fresh) device = fresh;
} catch {
// Fall back to cached device if detail fetch fails.
}
if (isOffline(device)) {
const st = deviceStatus(device) || 'offline';
return {
ok: false,
markdown: `❌ **Store ${storeDisplay}** device **${device.name}** is ${st} — cannot open tunnel.`,
error: `Device offline (${st})`,
code: 'OFFLINE',
device,
storePadded: resolved.storePadded,
};
}
try {
const tunnel = await openAuthenticatedTunnel(device.id, { pollSeconds });
const result = await fetchAzmCheckReport(tunnel.wsUrl, {
cookie: tunnel.cookie,
origin: tunnel.redirectUrl,
sessionName: 'check',
storeNumber: storeDisplay,
deviceStatus: deviceStatus(device),
});
const markdown = result.markdown || formatCheckMarkdown(result.report, {
storeNumber: storeDisplay,
deviceStatus: deviceStatus(device),
monitorDisable: result.monitorDisable,
});
return {
ok: true,
markdown,
device,
storePadded: resolved.storePadded,
report: result.report,
monitorDisable: result.monitorDisable,
deviceLogin: result.deviceLogin,
tunnel: {
redirectUrl: tunnel.redirectUrl,
wsUrl: tunnel.wsUrl,
connected: tunnel.status?.connected,
},
};
} catch (err) {
const message = err instanceof XyteHttpError
? `${err.message}${err.status ? ` (${err.status})` : ''}`
: (err.message || String(err));
return {
ok: false,
markdown: `❌ **Store ${storeDisplay}** (${device.name}) check failed: ${message}`,
error: message,
code: err.code || 'CHECK_FAILED',
device,
storePadded: resolved.storePadded,
};
}
}