feat: supervisor module — team performance + active calls endpoints

- SupervisorService: aggregates Ozonetel agent summary across all agents,
  tracks active calls from real-time events
- GET /api/supervisor/team-performance — per-agent time breakdown + thresholds
- GET /api/supervisor/active-calls — current active call map
- POST /api/supervisor/call-event — Ozonetel event webhook
- POST /api/supervisor/agent-event — Ozonetel agent event webhook

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 13:53:49 +05:30
parent a35a7d70bf
commit 2e4f97ff1a
4 changed files with 137 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
import { Controller, Get, Post, Body, Query, Logger } from '@nestjs/common';
import { SupervisorService } from './supervisor.service';
@Controller('api/supervisor')
export class SupervisorController {
private readonly logger = new Logger(SupervisorController.name);
constructor(private readonly supervisor: SupervisorService) {}
@Get('active-calls')
getActiveCalls() {
return this.supervisor.getActiveCalls();
}
@Get('team-performance')
async getTeamPerformance(@Query('date') date?: string) {
const targetDate = date ?? new Date().toISOString().split('T')[0];
this.logger.log(`Team performance: date=${targetDate}`);
return this.supervisor.getTeamPerformance(targetDate);
}
@Post('call-event')
handleCallEvent(@Body() body: any) {
const event = body.data ?? body;
this.logger.log(`Call event: ${event.action} ucid=${event.ucid ?? event.monitorUCID} agent=${event.agent_id ?? event.agentID}`);
this.supervisor.handleCallEvent(event);
return { received: true };
}
@Post('agent-event')
handleAgentEvent(@Body() body: any) {
const event = body.data ?? body;
this.logger.log(`Agent event: ${event.action} agent=${event.agentId ?? event.agent_id}`);
this.supervisor.handleAgentEvent(event);
return { received: true };
}
}