# 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 |
