feat(ivr): dropdown de destino (fila/outro IVR) numa opção de menu, com bloqueio de ciclo (PHASE 67)
Mesmo gap que Rotas de Entrada já tinha resolvido na PHASE 62: uma opção dentro de um menu de IVR só sabia apontar pra ramal (bridge fixo). Novo IvrMenuOption.destinationType (EXTENSION/QUEUE/IVR) decide a action de cada branch em buildIvrDialplanExtensions, mesmo padrão de buildInboundRouteXml — QUEUE vira answer+callcenter, IVR vira transfer pro IVR_ENTRY_DESTINATION do menu alvo (efetivamente um sub-menu). Sem CALL_GROUP aqui de propósito: diferente de InboundRoute (resolvido a cada chamada), o dialplan de um IVR é compilado uma vez ao salvar — "quem está no grupo agora" ficaria desatualizado até a próxima edição. "Outro IVR" cria a primeira forma de um menu apontar pra outro (uma InboundRoute nunca é ela mesma um menu, nunca formava ciclo antes). assertNoIvrCycle monta o grafo com todos os menus do tenant antes de compilar e rejeita qualquer save que criaria um ciclo, em create e update. Os dois editores de IVR (form clássico e o editor visual de nós) ganharam o mesmo par de dropdowns "Tipo"/"Destino" já usado em Rotas de Entrada. Testado ponta a ponta com Playwright, tenant/fila/2 menus de IVR reais criados na hora: menu com opção Fila e menu com opção Outro IVR apontando pro primeiro, os dois persistindo certo depois de reload completo. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
This commit is contained in:
@@ -255,13 +255,48 @@ ramais) + um segundo dropdown listando as opções reais do tenant pra
|
||||
cada tipo (ramais cadastrados, menus de IVR, filas, ou os valores
|
||||
distintos de `callGroup` já usados em algum ramal).
|
||||
|
||||
## Dropdown de destino numa opção de IVR: ramal, fila ou outro IVR (PHASE 67)
|
||||
|
||||
Mesmo gap da seção acima, um nível abaixo: até aqui, uma OPÇÃO dentro de
|
||||
um menu de IVR só sabia apontar pra ramal (`bridge` fixo). Rota de
|
||||
entrada já suportava fila/grupo pra ENTRAR num menu, mas depois de
|
||||
entrar, cada dígito só discava um ramal.
|
||||
|
||||
`IvrMenuOption.destinationType` (novo enum próprio,
|
||||
`IvrOptionDestinationType`: `EXTENSION`/`QUEUE`/`IVR`) decide a action de
|
||||
cada branch em `buildIvrDialplanExtensions` (packages/telephony), mesmo
|
||||
padrão do `InboundRoute` acima:
|
||||
|
||||
- **EXTENSION**: inalterado — `bridge` direto pro ramal.
|
||||
- **QUEUE**: `answer` + `callcenter data="<queueId>@<domain>"`.
|
||||
- **IVR**: `transfer` pro `IVR_ENTRY_DESTINATION` do contexto do MENU
|
||||
ALVO — reaproveita a mesma entrada que uma `InboundRoute` usa pra
|
||||
entrar num IVR, então um menu vira efetivamente um sub-menu de outro.
|
||||
|
||||
**Sem `CALL_GROUP` aqui, de propósito** (diferente de `InboundRoute`,
|
||||
que tem os 4 tipos): o dialplan de um IVR é compilado UMA VEZ, ao salvar
|
||||
o menu (`compileAndActivateIvrDialplan`) — não resolvido a cada chamada
|
||||
como a resolução de `InboundRoute`. Um destino `CALL_GROUP` ficaria
|
||||
"quem estava no grupo no momento em que o menu foi salvo por último",
|
||||
uma defasagem silenciosa que ninguém pediu — melhor não oferecer do que
|
||||
oferecer errado.
|
||||
|
||||
**Ciclos**: "Outro IVR" cria a primeira forma de um menu apontar pra
|
||||
outro (uma `InboundRoute` nunca é ela mesma um menu, então nunca podia
|
||||
formar ciclo). `assertNoIvrCycle` (`ivr-menus.controller.ts`) monta o
|
||||
grafo com todos os menus do tenant antes de compilar e rejeita (409)
|
||||
qualquer save que criaria um ciclo (A→B→A, ou até A apontando pra si
|
||||
mesmo) — checado tanto em `create` quanto `update`.
|
||||
|
||||
Os dois editores de IVR (form clássico e o editor visual de nós, PHASE
|
||||
60/61) ganharam o mesmo par de dropdowns "Tipo"/"Destino" já usado em
|
||||
Rotas de Entrada. Testado ponta a ponta: menu A com opção tipo Fila,
|
||||
menu B com opção tipo Outro IVR apontando pro menu A — os dois
|
||||
persistiram certo depois de um reload completo da página.
|
||||
|
||||
## O que falta
|
||||
|
||||
- Sem TTS (texto→voz) — só upload de arquivo WAV já gravado.
|
||||
- Menu de IVR não suporta sub-menus (uma opção levando a OUTRO IVR) nem
|
||||
destino "fila" — só ramal, dentro do contexto `default`. Rota de
|
||||
entrada já suporta fila/grupo, mas um MENU de IVR ainda só bridge pra
|
||||
ramal.
|
||||
- Grupo de ramais só é alcançável por Rota de Entrada — não existe (e
|
||||
não foi pedido) um jeito de discar um grupo de dentro do próprio
|
||||
dialplan "default" via feature code.
|
||||
|
||||
Reference in New Issue
Block a user