collabSupport/services/callTest/sessionStore.js
Joseph McQueen 7aa8c37d1d Add Twilio /calltest for store and direct-dial voice path testing.
Enables outbound PSTN probes via TwiML webhooks with Webex result cards, status polling, and optional store CDR enrichment.
2026-07-23 17:59:10 -04:00

75 lines
1.7 KiB
JavaScript

// services/callTest/sessionStore.js
// In-memory call-test sessions (TTL ~30 min).
import { logger } from '../../utils/logger.js';
const TTL_MS = 30 * 60 * 1000;
const SWEEP_INTERVAL_MS = 60 * 1000;
/** @typedef {'store'|'dial'} CallTestMode */
/** @typedef {'pending'|'in_progress'|'completed'|'failed'} CallTestStatus */
const _store = new Map();
/**
* @param {string} testId
* @param {object} data
*/
export function createSession(testId, data) {
const session = {
testId,
status: 'pending',
createdAt: Date.now(),
events: {},
lastStep: null,
reachedCore: false,
failedAt: null,
callSid: null,
...data,
};
_store.set(testId, session);
return session;
}
export function getSession(testId) {
return _store.get(testId) || null;
}
export function updateSession(testId, patch) {
const cur = _store.get(testId);
if (!cur) return null;
const next = { ...cur, ...patch };
_store.set(testId, next);
return next;
}
export function listActiveByDestination(dialNumber) {
const norm = String(dialNumber || '').trim();
const out = [];
for (const [, s] of _store) {
if (s.dialNumber !== norm) continue;
if (s.status === 'pending' || s.status === 'in_progress') out.push(s);
}
return out;
}
export function allSessions() {
return [..._store.values()];
}
const sweepHandle = setInterval(() => {
const now = Date.now();
for (const [id, s] of _store.entries()) {
const ts = s.createdAt || 0;
if (now - ts > TTL_MS) {
logger('calltest:cleanup', `Expired session ${id} (store=${s.storeNum || 'n/a'})`);
_store.delete(id);
}
}
}, SWEEP_INTERVAL_MS);
if (typeof sweepHandle.unref === 'function') sweepHandle.unref();
export function _clearAllSessionsForTests() {
_store.clear();
}