feat(frontend): Relatórios (Filas/Agentes/Campanhas/IA) + PHASE 28 security review

Quatro páginas novas em /app/relatorios/*, uma rota por relatório (não abas de
uma página só, pra não quebrar o realce de "ativo" da sidebar quando vários
itens de menu apontam pro mesmo relatório) — reusa os endpoints de reports
que já existiam desde as fases de CDR/AI, nenhum backend novo.

Security quality gate (agente.md secao 224): revisão dedicada sobre todo o
diff desde origin/main (billing + frontend inteiro, 7 commits) não achou
nenhuma vulnerabilidade de alta confiança. Suítes de teste de isolamento
multi-tenant, autenticação/RBAC e rating engine reexecutadas do zero e
verdes. TODO.md documenta o escopo real ainda faltando (Agentes bloqueado
por falta de endpoint de listagem de usuários, Dialplan, Monitoramento em
tempo real, Gravações, IA CRUD, Relatórios > Chamadas/Consumo) em vez de
alegar a aplicação "finalizada".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
This commit is contained in:
2026-08-29 14:34:24 -03:00
parent de1e7ac49c
commit ca49504f0a
13 changed files with 528 additions and 4 deletions

View File

@@ -0,0 +1,56 @@
export interface QueueReport {
queueId: string;
received: number;
answered: number;
abandoned: number;
tme: number | null;
tma: number | null;
serviceLevel: number | null;
abandonRate: number | null;
}
export interface AgentReport {
agentId: string;
name: string;
loggedInSeconds: number;
availableSeconds: number;
reservedSeconds: number;
ringingSeconds: number;
inCallSeconds: number;
wrapUpSeconds: number;
pausedSeconds: number;
callsAnswered: number;
tma: number | null;
}
export interface CampaignReport {
campaignId: string;
name: string;
leads: number;
attempts: number;
answered: number;
agentConnected: number;
busy: number;
noAnswer: number;
failed: number;
callbacks: number;
answerRate: number | null;
contactRate: number | null;
abandonRate: number | null;
tme: number | null;
tma: number | null;
telefoniaValor: number | null;
iaValor: number | null;
}
export interface AIDashboardReport {
callsAnalyzed: number;
avgQualityScore: number | null;
avgScorecardScore: number | null;
sentimentBreakdown: Record<string, number>;
topTopics: { value: string; count: number }[];
topObjections: { value: string; count: number }[];
complianceAlerts: { callId: string; flags: string[] }[];
topAgents: { agentId: string; name: string; avgScore: number; calls: number }[];
bottomAgents: { agentId: string; name: string; avgScore: number; calls: number }[];
}