feat: SSE agent state, UCID fix, maint module, QA bug fixes

- Fix outbound disposition: store UCID from dial API response (root cause of silent disposition failure)
- SSE agent state: real-time Ozonetel state drives status toggle (ready/break/calling/in-call/acw)
- Maint module with OTP-protected endpoints (force-ready, unlock-agent, backfill, fix-timestamps)
- Maint OTP modal with PinInput component, keyboard shortcuts (Ctrl+Shift+R/U/B/T)
- Force-logout via SSE: admin unlock pushes force-logout to connected browsers
- Silence JsSIP debug flood, add structured lifecycle logging ([SIP], [DIAL], [DISPOSE], [AGENT-STATE])
- Centralize date formatting with IST-aware formatters across 11 files
- Fix call history: non-overlapping aggregates (completed/missed), correct timestamp display
- Auto-dismiss CallWidget ended/failed state after 3 seconds
- Remove floating "Helix Phone" idle badge from all pages
- Fix dead code in agent-state endpoint (auto-assign was unreachable after return)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 22:03:48 +05:30
parent ae94a390df
commit 488f524f84
21 changed files with 462 additions and 107 deletions

View File

@@ -53,26 +53,24 @@ export function connectSip(config: SIPConfig): void {
if (state === 'ringing-in' && outboundPending) {
outboundPending = false;
outboundActive = true;
console.log('[SIP] Outbound bridge detected — auto-answering');
console.log('[SIP-MGR] Outbound bridge detected — auto-answering');
setTimeout(() => {
sipClient?.answer();
setTimeout(() => stateUpdater?.setCallState('active'), 300);
}, 500);
// Store UCID even for outbound bridge calls
if (ucid) stateUpdater?.setCallUcid(ucid);
return;
}
// Don't overwrite caller number on outbound calls — it was set by click-to-call
console.log(`[SIP-MGR] State: ${state} | caller=${number ?? 'none'} | ucid=${ucid ?? 'none'} | outboundActive=${outboundActive}`);
stateUpdater?.setCallState(state);
if (!outboundActive && number !== undefined) {
stateUpdater?.setCallerNumber(number ?? null);
}
// Store UCID if provided
if (ucid) stateUpdater?.setCallUcid(ucid);
// Reset outbound flag when call ends
if (state === 'ended' || state === 'failed') {
outboundActive = false;
outboundPending = false;
@@ -84,6 +82,7 @@ export function connectSip(config: SIPConfig): void {
}
export function disconnectSip(): void {
console.log('[SIP-MGR] Disconnecting SIP');
sipClient?.disconnect();
sipClient = null;
connected = false;