mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-11 18:28:15 +00:00
docs: supervisor module spec + implementation plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
191
docs/superpowers/specs/2026-03-24-supervisor-module.md
Normal file
191
docs/superpowers/specs/2026-03-24-supervisor-module.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# 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 |
|
||||
Reference in New Issue
Block a user