collabSupport/utils/pendingDectActions.js
Joseph McQueen 7c7d0a898c Add /dectstatus command with full base dump and reboot cards.
Pulls complete status.xml from each reachable DBS-210 via the relay,
renders the full CLI-style dump, and posts per-base adaptive cards for
reboot and factory-reset (confirm flow + audit logging). Wired into
registry, help, and attachmentAction dispatch.
2026-07-21 15:51:07 -04:00

64 lines
1.5 KiB
JavaScript

// src/utils/pendingDectActions.js
//
// In-memory store for pending DECT base-station action confirmation
// cards (reboot / force-reboot / factory-reset / etc.). Same TTL
// sweep pattern as pendingIgmpFixes / pendingOffboards.
//
// Entries typically hold:
// {
// storeNum, baseIp, baseMac, baseName,
// dectAction, // 'reboot' | 'force-reboot' | ...
// requester, // from extractRequester(trigger)
// timestamp, // auto-set
// }
import { logger } from './logger.js';
const TTL_MS = 15 * 60 * 1000;
const SWEEP_INTERVAL_MS = 60 * 1000;
const _store = new Map();
export const pendingDectActions = {
set(cardId, data) {
_store.set(cardId, { ...data, timestamp: Date.now() });
return this;
},
get(cardId) {
return _store.get(cardId);
},
has(cardId) {
return _store.has(cardId);
},
delete(cardId) {
return _store.delete(cardId);
},
get size() {
return _store.size;
},
entries() {
return _store.entries();
},
};
const sweepHandle = setInterval(() => {
const now = Date.now();
for (const [cardId, data] of _store.entries()) {
const stamped = typeof data?.timestamp === 'number' ? data.timestamp : 0;
if (now - stamped > TTL_MS) {
logger(
'dect:cleanup',
`Expired card ${cardId} for store ${data?.storeNum || 'unknown'} ` +
`base ${data?.baseIp || 'unknown'} action ${data?.dectAction || 'unknown'}`,
);
_store.delete(cardId);
}
}
}, SWEEP_INTERVAL_MS);
sweepHandle.unref?.();