mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-11 18:28:15 +00:00
192 lines
6.8 KiB
Markdown
192 lines
6.8 KiB
Markdown
# 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: "<sidecar-webhook-url>", agentEventsURL: "<sidecar-webhook-url>" }`
|
|
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 |
|