Files
B2BCall-dialer/apps/frontend/package.json
Matheus 0148b926a0 feat(ivr): editor visual do menu (canvas de nós, sem Node-RED)
Pedido do usuário: "ajusta o IVR para fazer o fluxo de maneira visual
usando nodeRED". Perguntei antes de construir: integrar Node-RED de
verdade significa rodar uma plataforma externa completa (motor de
execução próprio, nós "function" = execução de código arbitrário — o
mesmo tipo de risco corrigido no dialplan nesta sessão — e sem
multi-tenancy nativa), um projeto de vários dias com decisões de
arquitetura antes de começar a construir. O usuário escolheu a
alternativa: um editor visual próprio, sem dependência externa.

`@xyflow/react` (sucessor mantido do reactflow) — canvas de nós/setas
dentro da própria tela "Telefonia > IVR": 1 nó "Entrada" fixo conectado
a 1 nó por opção (dígito + select de ramal + descrição, editável direto
no nó, arrastável pro canvas). "Adicionar opção"/"Salvar alterações"
chamam o mesmo PATCH /ivr-menus/:id que já existia — nenhuma mudança de
backend necessária, só uma forma nova de editar o mesmo dado (o modelo
IvrMenu/IvrMenuOption continua sendo a fonte da verdade).

Testado ponta a ponta pela tela de verdade, não só leitura de código:
criado um menu real, enviado um prompt de VOZ real (WAV sintetizado com
espeak-ng dizendo uma saudação de verdade, não um tom sintético como nos
testes anteriores desta fase) e completada uma chamada real — a saudação
de ~6s tocou até o fim, o dígito foi capturado, o ramal certo atendeu
com áudio de verdade. Depois, uma segunda opção foi adicionada via PATCH
(a mesma chamada que o botão "Salvar" do editor visual faz) — confirmado
no banco que a versão 2 do dialplan compilou as duas opções
corretamente, superando a versão 1.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
2026-08-30 18:21:26 -03:00

41 lines
1.0 KiB
JSON

{
"name": "@b2bcall/frontend",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@radix-ui/react-avatar": "1.1.2",
"@radix-ui/react-dialog": "1.1.4",
"@radix-ui/react-dropdown-menu": "2.1.4",
"@radix-ui/react-slot": "1.1.1",
"@radix-ui/react-tooltip": "1.1.6",
"@tanstack/react-query": "5.62.7",
"@tanstack/react-table": "8.20.5",
"@xyflow/react": "^12.11.5",
"class-variance-authority": "0.7.1",
"clsx": "2.1.1",
"lucide-react": "0.469.0",
"next": "15.3.9",
"react": "19.1.0",
"react-dom": "19.1.0",
"recharts": "2.15.0",
"server-only": "0.0.1",
"socket.io-client": "4.8.3",
"tailwind-merge": "2.5.5"
},
"devDependencies": {
"@types/node": "^22.20.1",
"@types/react": "19.1.0",
"@types/react-dom": "19.1.0",
"autoprefixer": "10.4.20",
"postcss": "8.4.49",
"tailwindcss": "3.4.17",
"typescript": "^5.7.0"
}
}