# Supervisor Module — Team Performance, Live Call Monitor, Master Data **Date**: 2026-03-24 **Jira**: PP-5 (Team Performance), PP-6 (Live Call Monitor) **Status**: Approved design --- ## Principle No hardcoded/mock data. All data from Ozonetel APIs or platform GraphQL queries. --- ## 1. Admin Sidebar Nav Restructure ``` SUPERVISOR Dashboard → / (existing team-dashboard.tsx — summary) Team Performance → /team-performance (new — full PP-5) Live Call Monitor → /live-monitor (new — PP-6) DATA & REPORTS Lead Master → /leads (existing all-leads.tsx) Patient Master → /patients (existing patients.tsx) Appointment Master → /appointments (existing appointments.tsx) Call Log Master → /call-history (existing call-history.tsx) Call Recordings → /call-recordings (new — filtered calls with recordings) Missed Calls → /missed-calls (new — standalone missed call table) ``` **Files**: `sidebar.tsx` (admin nav config), `main.tsx` (routes) --- ## 2. Team Performance Dashboard (PP-5) **Route**: `/team-performance` **Page**: `src/pages/team-performance.tsx` ### Section 1: Key Metrics Bar - Active Agents / On Call Now → sidecar (from active calls tracking) - Total Calls → platform `calls` count by date range - Appointments → platform `appointments` count - Missed Calls → platform `calls` where `callStatus: MISSED` - Conversion Rate → appointments / total calls - Time filter: Today | Week | Month | Year | Custom ### Section 2: Call Breakdown Trends - Left: Inbound vs Outbound line chart (ECharts) by day - Right: Leads vs Missed vs Follow-ups by day - Data: platform `calls` grouped by date + direction ### Section 3: Agent Performance Table | Column | Source | |--------|--------| | Agent | Agent entity `name` | | Calls | Platform `calls` filtered by `agentName` | | Inbound | Platform `calls` where `direction: INBOUND` | | Missed | Platform `calls` where `callStatus: MISSED` | | Follow-ups | Platform `followUps` filtered by `assignedAgent` | | Leads | Platform `leads` filtered by `assignedAgent` | | Conv% | Derived: appointments / calls | | NPS | Agent entity `npsscore` | | Idle | Ozonetel `getAgentSummary` API | Sortable columns. Own time filter (Today/Week/Month/Year/Custom). ### Section 4: Time Breakdown - Team average: Active / Wrap / Idle / Break totals - Per-agent horizontal stacked bars - Data: Ozonetel `getAgentSummary` per agent - Agents with idle > `maxidleminutes` threshold highlighted red ### Section 5: NPS + Conversion Metrics - NPS donut chart (average of all agents' `npsscore`) - Per-agent NPS horizontal bars - Call→Appointment % card (big number) - Lead→Contact % card (big number) - Per-agent conversion breakdown below cards ### Section 6: Performance Alerts - Compare actual metrics vs Agent entity thresholds: - `maxidleminutes` → "Excessive Idle Time" - `minnpsthreshold` → "Low NPS" - `minconversionpercent` → "Low Lead-to-Contact" - Red-highlighted alert cards with agent name, alert type, value ### Sidecar Endpoint `GET /api/supervisor/team-performance?date=YYYY-MM-DD` - Aggregates Ozonetel `getAgentSummary` across all agents - Returns per-agent time breakdown (active/wrap/idle/break in minutes) - Uses Agent entity to get list of all agent IDs --- ## 3. Live Call Monitor (PP-6) **Route**: `/live-monitor` **Page**: `src/pages/live-monitor.tsx` ### KPI Cards - Active Calls count - On Hold count - Avg Duration ### Active Calls Table | Column | Source | |--------|--------| | Agent | Ozonetel event `agent_id` → mapped to Agent entity name | | Caller | Event `caller_id` → matched against platform leads/patients | | Type | Event `call_type` (InBound/Manual) | | Department | From matched lead's `interestedService` or "—" | | Duration | Live counter from `event_time` | | Status | active / on-hold | | Actions | Listen / Whisper / Barge buttons (disabled until API confirmed) | ### Data Flow 1. Sidecar subscribes to Ozonetel real-time events on startup - `POST https://subscription.ozonetel.com/events/subscribe` - Body: `{ callEventsURL: "", agentEventsURL: "" }` 2. Sidecar receives events at `POST /webhooks/ozonetel/call-event` 3. In-memory map: `ucid → { agentId, callerNumber, callType, startTime, status }` - `Calling` / `Answered` → add/update entry - `Disconnect` → remove entry 4. `GET /api/supervisor/active-calls` → returns current map 5. Frontend polls every 5 seconds ### Sidecar Changes - New module: `src/supervisor/` - `supervisor.controller.ts` — team-performance + active-calls endpoints - `supervisor.service.ts` — Ozonetel event subscription, active call tracking - `supervisor.module.ts` - New webhook: `POST /webhooks/ozonetel/call-event` - Ozonetel event subscription on `onModuleInit` --- ## 4. Master Data Pages ### Call Recordings (`/call-recordings`) **Page**: `src/pages/call-recordings.tsx` - Query: platform `calls` where `recording` is not null - Table: Agent, Caller, Type, Date, Duration, Recording Player - Search by agent/phone + date filter ### Missed Calls (`/missed-calls`) **Page**: `src/pages/missed-calls.tsx` - Query: platform `calls` where `callStatus: MISSED` - Table: Caller, Date/Time, Branch (`callsourcenumber`), Agent, Callback Status, SLA - Tabs: All | Pending | Attempted | Completed (filter by `callbackstatus`) - Not filtered by agent — supervisor sees all --- ## 5. Agent Entity Fields (Already Configured) | GraphQL Field | Type | Purpose | |---|---|---| | `ozonetelagentid` | Text | Ozonetel agent ID | | `sipextension` | Text | SIP extension | | `sippassword` | Text | SIP password | | `campaignname` | Text | Ozonetel campaign | | `npsscore` | Number | Agent NPS score | | `maxidleminutes` | Number | Idle time alert threshold | | `minnpsthreshold` | Number | NPS alert threshold | | `minconversionpercent` | Number | Conversion alert threshold | All custom fields use **all-lowercase** GraphQL names. --- ## 6. File Map ### New Files | File | Purpose | |------|---------| | `helix-engage/src/pages/team-performance.tsx` | PP-5 dashboard | | `helix-engage/src/pages/live-monitor.tsx` | PP-6 active call monitor | | `helix-engage/src/pages/call-recordings.tsx` | Call recordings master | | `helix-engage/src/pages/missed-calls.tsx` | Missed calls master | | `helix-engage-server/src/supervisor/supervisor.controller.ts` | Supervisor endpoints | | `helix-engage-server/src/supervisor/supervisor.service.ts` | Event subscription + active calls | | `helix-engage-server/src/supervisor/supervisor.module.ts` | Module registration | ### Modified Files | File | Change | |------|--------| | `helix-engage/src/components/layout/sidebar.tsx` | Admin nav restructure | | `helix-engage/src/main.tsx` | New routes | | `helix-engage-server/src/app.module.ts` | Import SupervisorModule |