Fluxo: Escalação¶
Visão Geral¶
Sistema de escalação automática de conversas baseado em regras configuráveis por agente.
Modelo de Dados¶
EscalationRule¶
Regras configuradas por agente:
| Campo | Tipo | Descrição |
|---|---|---|
| Keywords | string? | Palavras-chave (separadas por vírgula) |
| MaxMessages | int? | Número máximo de mensagens antes de escalar |
| MaxDurationMinutes | int? | Duração máxima em minutos |
| IsActive | bool | Se a regra está ativa |
Escalation¶
Registro de escalação:
| Campo | Tipo | Descrição |
|---|---|---|
| ConversationId | Guid | Conversa escalada |
| RuleId | Guid | Regra que disparou |
| Reason | string | Motivo da escalação |
| EscalatedAt | DateTime | Quando escalou |
| ResolvedAt | DateTime? | Quando foi resolvida |
| ResolvedBy | string? | Quem resolveu |
Tipos de Regras¶
Keywords¶
Escala quando a mensagem do usuário contém uma das palavras-chave:
Avaliação: Case-insensitive, busca substring.
MaxMessages¶
Escala após N mensagens do usuário na conversa:
Uso: Evitar conversas longas sem resolução.
MaxDurationMinutes¶
Escala após N minutos desde o início da conversa:
Uso: Garantir atendimento humano para conversas demoradas.
Fluxo de Avaliação¶
Mensagem recebida
│
▼
┌──────────────┐
│ Conversa tem │
│ agente? │
└──────┬───────┘
│ Sim
▼
┌──────────────┐
│ Busca regras │
│ ativas │
└──────┬───────┘
│
▼
┌──────────────┐
│ Avalia cada │
│ regra │
└──────┬───────┘
│
┌───┴───┐
│Dispara│
└───┬───┘
│ Sim
▼
┌──────────────┐
│ Cria registro│
│ Escalation │
└──────┬───────┘
│
▼
┌──────────────┐
│ Muda status │
│ p/ Escalated │
└──────┬───────┘
│
▼
┌──────────────┐
│ Notifica │
│ SignalR │
└──────────────┘
Ações Pós-Escalação¶
- Status da conversa muda para
Escalated - Notificação SignalR para o portal
- Registro de Escalation criado
- Conversa visível na área de escalações do portal
Resolução¶
Operador pode: 1. Atender a conversa (modo Manual) 2. Resolver com summary 3. Marcar escalação como resolvida
escalation.ResolvedAt = DateTime.UtcNow;
escalation.ResolvedBy = "Admin";
escalation.Notes = "Cliente atendido, problema resolvido.";
Configuração no Portal¶
Na página de detalhes do agente, aba de configurações:
- Adicionar regras de escalação
- Definir palavras-chave
- Definir limites de mensagens/tempo
- Ativar/desativar regras
Exemplo de Uso¶
Cenário 1: Palavra-chave¶
Regra: Keywords = "cancelar,desistir"
Mensagem: "Quero cancelar meu pedido"
Resultado: Conversa escalada - "Keyword match: cancelar"
Cenário 2: Limite de mensagens¶
Regra: MaxMessages = 5
Conversa com 5 mensagens do usuário
Resultado: Conversa escalada - "Max messages reached: 5"
Cenário 3: Duração¶
Regra: MaxDurationMinutes = 15
Conversa iniciada há 16 minutos
Resultado: Conversa escalada - "Max duration reached: 15 minutes"
Prioridade¶
Regras são avaliadas na ordem em que foram criadas. A primeira regra que dispara causa a escalação.
Escalação Automática por Desativação¶
Visão Geral¶
Além das regras de escalação baseadas em palavras-chave, mensagens e duração, o sistema também realiza troca automática de modo (AI para Manual) quando um agente é desativado/arquivado ou quando a configuração de IA de uma instância é desligada. Isso garante que nenhuma conversa fique "presa" em modo IA sem um agente ou configuração ativa para respondê-la.
Cenários¶
| Cenário | Filtro | Handler |
|---|---|---|
| Agente desativado (IsActive: true -> false) | Conversas do agente | UpdateAgentHandler |
| Agente arquivado (delete/archive) | Conversas do agente | DeleteAgentHandler |
| Instância com StartsWithAI desligado | Conversas da instância | UpdateInstanceHandler |
Serviço: IConversationModeSwitcher¶
A lógica compartilhada está centralizada no serviço IConversationModeSwitcher (ConversationModeSwitcher):
Task<int> SwitchToManualAsync(
Expression<Func<Conversation, bool>> filter,
Guid tenantId,
CancellationToken ct = default);
Comportamento:
1. Busca conversas que atendem ao filtro E estão com Status = Active E Mode = AI
2. Executa ExecuteUpdateAsync para alterar Mode para Manual e registrar ModeChangedAt
3. Envia notificação de escalação via SignalR para cada conversa afetada (NotifyConversationEscalatedAsync)
4. Retorna o total de conversas alteradas
Consistência Transacional¶
A troca de modo acontece DEPOIS do SaveChangesAsync da operação principal:
1. Handler persiste a alteração no agente/instância (SaveChangesAsync)
2. Somente após sucesso, chama _modeSwitcher.SwitchToManualAsync(...)
3. SwitchToManualAsync usa ExecuteUpdateAsync (operação atômica separada)
Essa ordem garante que: - Se o save da entidade falhar, nenhuma conversa é afetada - A troca de modo é uma operação independente após a persistência principal
Fluxo¶
Agente desativado / Instância StartsWithAI=false
│
▼
┌──────────────────┐
│ SaveChangesAsync │ (persiste agente/instância)
└──────┬───────────┘
│ Sucesso
▼
┌──────────────────┐
│ SwitchToManual │ (busca conversas AI ativas)
└──────┬───────────┘
│
▼
┌──────────────────┐
│ ExecuteUpdate │ (Mode = Manual, ModeChangedAt = now)
└──────┬───────────┘
│
▼
┌──────────────────┐
│ SignalR Notify │ (para cada conversa afetada)
└──────────────────┘
Arquivos Relacionados¶
| Arquivo | Descrição |
|---|---|
Ciba.Api/Services/IConversationModeSwitcher.cs |
Interface do serviço |
Ciba.Api/Services/ConversationModeSwitcher.cs |
Implementação |
Ciba.Api/Features/Agents/Delete/DeleteAgentHandler.cs |
Troca ao arquivar agente |
Ciba.Api/Features/Agents/Update/UpdateAgentHandler.cs |
Troca ao desativar agente |
Ciba.Api/Features/Instances/Update/UpdateInstanceHandler.cs |
Troca ao desligar StartsWithAI |
Observações¶
- Escalação é única por conversa (não escala novamente se já escalou)
- Conversa escalada ainda recebe mensagens normalmente
- Modo pode ser alterado para Manual após escalação
- Histórico de escalações fica vinculado à conversa
- Troca automática por desativação afeta todas as conversas ativas em modo AI do agente/instância