feat: edição de rotas de entrada, fix de 2 bugs reais no ESL, diagnóstico de NAT/áudio e softphone WebRTC (PHASE 65/66)
Três achados reportados pelo usuário numa mensagem só: (1) Rotas de Entrada não tinha edição depois de criada — implementada no mesmo padrão de Filas; (2) telas de Platform > Infraestrutura sempre davam "Timeout no ESL" nesta VM — não era limitação permanente como o comentário antigo dizia, e sim ESL_HOST=freeswitch (nome DNS que só existe dentro da rede do Docker) mais um segundo bug independente (`show gateways as json` não é comando válido nesta versão do FreeSWITCH); (3) ramal externo registrava mas sem áudio — diagnosticado com contadores de pacote do iptables: a VM está atrás de um roteador sem port-forward pra faixa de RTP, achado de infraestrutura de rede, não bug de código. Também integra o softphone WebRTC (handphone.js/OpenSIPS, já em produção): código-fonte encontrado em git.falehandix.com.br/Handix/handphone-2.0, patch mínimo pra aceitar o endereço do proxy em runtime (era build-time), nova config global (Platform > Infraestrutura > Softphone WebRTC) e widget na topbar do tenant que pega usuário/domínio/senha do ramal vinculado ao agente logado. Adiciona docs/QA_SETUP.md — runbook completo pra subir o ambiente do zero numa máquina nova (Docker, migrations, seed, systemd), e completa o .env.example que estava faltando a maioria das variáveis reais. Testado ponta a ponta com Playwright: edição de rota (criar/editar/F5), as 3 telas de Infraestrutura com dado real, e um tenant/ramal/agente de teste criados na hora confirmando que o script do softphone recebe as credenciais certas. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
This commit is contained in:
@@ -65,11 +65,48 @@ imagem, só injetada via variável de ambiente do container. O entrypoint falha
|
||||
alto (`set -eu` + `${ESL_PASSWORD:?...}`) se a variável não estiver definida —
|
||||
nunca sobe com a senha padrão por engano.
|
||||
|
||||
Porta 8021 **não é publicada no host** (`ports:` ausente no compose) — só
|
||||
alcançável por outros containers na rede interna do Docker Compose
|
||||
(`b2bcall_default`), pelo nome de serviço `freeswitch`. Isso satisfaz
|
||||
"NÃO pública... acesso somente pela aplicação autorizada" sem precisar de ACL
|
||||
adicional por enquanto (ACL fica como hardening futuro, ver TODO).
|
||||
Porta 8021 **nunca publicada pra rede** — só em loopback do próprio host
|
||||
(`"127.0.0.1:8021:8021"` no `docker-compose.yml`, desde a PHASE 65, ver seção
|
||||
abaixo). Isso satisfaz "NÃO pública... acesso somente pela aplicação
|
||||
autorizada" (agente.md secao 22) sem abrir a porta pra ninguém além do próprio
|
||||
host.
|
||||
|
||||
## Achados na sessão de PHASE 65 (Platform > Infraestrutura)
|
||||
|
||||
Duas telas de `platform/infraestrutura` (FreeSWITCH, SIP Profiles, Nodes)
|
||||
sempre mostravam "Timeout conectando no ESL do FreeSWITCH" nesta VM. A
|
||||
suposição registrada até então (agora corrigida) era que isso seria uma
|
||||
limitação permanente: "`apps/api` roda fora do Docker, a porta nunca é
|
||||
publicada, então este endpoint sempre falha aqui". Isso estava incompleto.
|
||||
|
||||
**Causa real**: `ESL_HOST=freeswitch` no `.env` — um nome DNS que só resolve
|
||||
dentro da rede interna do Docker Compose (embedded DNS), nunca a partir do
|
||||
resolver do próprio host (confirmado: `getent hosts freeswitch` falha no host
|
||||
com exit code 2). Não era uma questão de porta publicada — testado e
|
||||
confirmado que o **host sempre alcança o IP de qualquer container na rede
|
||||
bridge do Docker diretamente** (`docker inspect` + `/dev/tcp` bateram), mesmo
|
||||
sem nenhuma porta publicada. Só outras *máquinas* são bloqueadas sem
|
||||
`ports:` — o host nunca foi.
|
||||
|
||||
**Fix**: publicar 8021 só em loopback (`127.0.0.1:8021:8021`) e trocar
|
||||
`ESL_HOST` pra `127.0.0.1` no `.env` — resolve o DNS sem abrir a porta pra
|
||||
rede nenhuma (confirmado via `ss -tlnp`: `docker-proxy` escutando em
|
||||
`127.0.0.1`, não `0.0.0.0`). Os serviços que rodam DENTRO do Docker
|
||||
(`fs-events`, `fs-config`, `predictive-dialer`) continuam com
|
||||
`ESL_HOST=freeswitch` fixo no próprio `docker-compose.yml` — não dependem do
|
||||
`.env` pra isso, então a troca não afeta eles.
|
||||
|
||||
**Segundo bug, achado na mesma investigação**: a tela "Nodes" continuava
|
||||
mostrando `error: ""` (string vazia) mesmo depois do fix acima.
|
||||
`getGateways()` (`packages/telephony/src/freeswitch-provider.ts`) rodava
|
||||
`show gateways as json` — **não é um sub-comando válido** de `show` nesta
|
||||
versão do FreeSWITCH (`fs_cli -x "show gateways as json"` devolve
|
||||
`-USAGE: codec|endpoint|application|...`). O pacote `esl` trata qualquer
|
||||
reply começando com `-` como erro de protocolo e rejeita a promise com um
|
||||
`FreeSwitchError` cujo `.message` pode vir vazio — daí o `""` na tela em vez
|
||||
de uma mensagem útil. Fix: `getGateways()` agora roda `sofia status` (mesmo
|
||||
comando já usado pela tela de SIP Profiles) — gateways aparecem como linhas
|
||||
`type=gateway` no texto puro, sem variante JSON dedicada nesta versão.
|
||||
|
||||
## O que NÃO foi feito nesta fase (fica para as próximas, por design)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user