Maint shortcuts (Unlock Agent / Force Ready) used to read agentId from the CC-agent's localStorage config — supervisors had no such config and the endpoint 400'd. New flow: after OTP passes, modal calls /api/maint/session-status and renders a two-bucket picker (Locked selectable / Free informational 'Already free'). Orphan locks surface with an explicit label.
- use-maint-shortcuts: agentPickerEndpoint flag on forceReady + unlockAgent
- maint-otp-modal: two-phase — OTP gate, then picker, then submit; OTP
held in state across phases so the operator doesn't re-enter it
AI chat panel: supervisor context now shows supervisor-appropriate quick actions (Agent performance / Call summary / Campaign stats / Who needs attention?) that map 1:1 to the supervisor tool set on the sidecar. Agent flow keeps the theme-token quick actions (doctors/clinics/packages).
Ramaiah's product team owns their setup; end-user admins shouldn't see a dead-end Settings nav + Resume Setup banner. Flag is read from /api/config/ui-flags at app boot.
- use-ui-flags: module-scoped cache + useUiFlags hook + getUiFlags
helper for non-component callers
- main.tsx: /setup redirects when managed; RequireSelfServeSetup
guard blocks /settings/*
- resume-setup-banner: suppressed when managed
- login.tsx: skip first-run /setup redirect when managed
- settings.tsx: remove orphan popup-modal scaffolding left over
from an earlier 'contact product team' approach
- section-card: support onClick-or-href (kept for future use)
usePerformanceAlerts now fetches /api/supervisor/performance-alerts
every 60s instead of computing client-side. Dismiss + dismiss-all hit
the sidecar so state survives reload. Toast fires when new alerts arrive.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. notification-bell: drop the DEMO_ALERTS fallback (Riya Mehta etc.).
Empty state ("No active alerts") shows when the live computation
returns nothing — which is the truthful state until thresholds are
set on Agent records.
2. use-performance-alerts: bucket calls by c.agentId === agent.id when
the relation is set; fall back to legacy agentName matching only for
un-enriched rows. Fixes conversion% calc going to 0 after backfill.
3. agent-table: Link target uses agent.id (UUID or "legacy:NAME") so
the URL is a stable identifier instead of a display string.
4. agent-detail: parse the route param into UUID vs legacy:NAME, filter
calls by c.agentId or c.agentName accordingly, and resolve display
name via the platform Agents list.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extended MaintAction with needsPreStep + clientSideHandler
- MaintOtpModal supports pre-step content before OTP (campaign selection)
- Removed standalone ClearCampaignLeadsModal — all maint actions go through one modal
- 4-step import wizard with Untitled UI Select for mapping
- DynamicTable className passthrough
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- SIP connection only for users with Agent entity (no env var fallback)
- Supervisor no longer intercepts CC agent calls
- Auth controller checks Agent entity for ALL roles, not just cc-agent
- Token refresh handles GraphQL UNAUTHENTICATED errors (200 with error body)
- Token refresh handles sidecar 400s from expired upstream tokens
- Network quality indicator in sidebar (offline/unstable/good)
- Ozonetel IDLE event mapped to ready state (fixes stuck calling after canceled call)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Missed call queue with FIFO auto-assignment, dedup, SLA tracking
- Status sub-tabs (Pending/Attempted/Completed/Invalid) in worklist
- missedCallId passed through disposition flow for callback tracking
- Login page redesigned: centered white card on blue background
- Disposition button changed to content-width
- NavAccountCard popover close fix on menu item click
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CC Agent:
- Call transfer (CONFERENCE + KICK_CALL) with inline transfer dialog
- Recording pause/resume during active calls
- Missed calls API (Ozonetel abandonCalls)
- Call history API (Ozonetel fetchCDRDetails)
Live Call Assist:
- Deepgram Nova STT via raw WebSocket
- OpenAI suggestions every 10s with lead context
- LiveTranscript component in sidebar during calls
- Browser audio capture from remote WebRTC stream
Worklist:
- Redesigned table: clickable phones, context menu (Call/SMS/WhatsApp)
- Last interaction sub-line, source column, improved SLA
- Filtered out rows without phone numbers
- New missed call notifications
Brand:
- Logo on login page
- Blue scale rebuilt from logo blue rgb(32, 96, 160)
- FontAwesome duotone CSS variables set globally
- Profile menu icons switched to duotone
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Context panel now collapsible via toggle button (sidebar icon in status bar)
- Fixed width 400px when open, full-width worklist when closed
- Worklist and Today's Calls as separate tabs instead of stacked
- Fix missed calls callerNumber transform (PHONES composite → array)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Collapsible sidebar with Jotai atom (icon-only mode, persisted to localStorage)
- 2-panel call desk: worklist (60%) + context panel (40%) with AI + Lead 360 tabs
- Inline AI call prep card — known lead summary or unknown caller script
- Active call card with compact Answer/Decline buttons
- Worklist panel with human-readable labels, priority badges, click-to-select
- Context panel auto-switches to Lead 360 when lead selected or call incoming
- Browser ringtone via Web Audio API on incoming calls
- Sonner + Untitled UI IconNotification for toast system
- apiClient pattern: centralized post/get/graphql with auto-toast on errors
- Remove duplicate avatar from top bar, hide floating widget on call desk
- Fix Link routing in collapsed sidebar (was using <a> causing full page reload)
- Fix GraphQL field names: adStatus→status, platformUrl needs subfield selection
- Silent mode for DataProvider queries to prevent toast spam
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace mock DataProvider with real GraphQL queries through sidecar
- Add queries.ts and transforms.ts for platform field name mapping
- Migrate SIP state from React Context to Jotai atoms (React 19 compat)
- Add singleton SIP manager to survive StrictMode remounts
- Remove hardcoded Olivia/Sienna accounts from nav menu
- Add password eye toggle, remember me checkbox, forgot password link
- Fix worklist hook to transform platform field names
- Add seed scripts for clinics, health packages, lab tests
- Update test harness for new doctor→clinic relation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>