feat(ivr): upload de áudio pro prompt do IVR
Pedido do usuário: "adiciona upload de áudio pro prompt do IVR" — até aqui o prompt era só texto livre (na prática, sempre um tom padrão, nunca voz de verdade). `POST /ivr-menus/:id/prompt` (multipart via @fastify/multipart — primeiro upload de arquivo binário desta API) só aceita WAV (cabeçalho RIFF/WAVE validado antes de gravar; esta implantação do FreeSWITCH não tem mod_shout, então MP3 nunca funcionaria de qualquer forma). Gravado num bind mount NOVO (./data/ivr-prompts no host ↔ /ivr-prompts no container freeswitch) — mesma convenção já usada 3x neste projeto pra arquivo que o FreeSWITCH precisa enxergar de verdade (gateways externos, filas do callcenter, spool de gravação), mas na direção contrária: apps/api (host) escreve o que o usuário sobe, o FreeSWITCH lê ao vivo durante play_and_get_digits. Um fetch em rede (S3/HTTP) durante uma chamada ativa foi descartado de propósito — latência/confiabilidade desnecessárias pra um prompt de poucos segundos. GET /ivr-menus/:id/prompt (autenticado) serve o preview — mesmo princípio do player de gravações, nunca uma URL direta pro storage. Achado real corrigido antes de commitar: minha primeira versão do delete de menu deixava o .wav órfão no disco — agora deletar o menu ou trocar/remover o prompt sempre limpa o arquivo, confirmado com um teste real de upload+delete. Tela "Telefonia > IVR" ganhou upload/troca/remoção de áudio por menu + player de preview. Testado ponta a ponta com um WAV real de 44.1kHz/mono (não o formato "nativo" de telefonia, de propósito, pra confirmar que funciona com o que uma pessoa qualquer gravaria): softphone externo discou o DID, play_and_get_digits abriu e tocou o arquivo até o fim duas vezes (mod_sndfile resample automático, sem erro no log), colheu o dígito real e bridged corretamente com o ramal de destino. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
This commit is contained in:
38
TODO.md
38
TODO.md
@@ -2141,10 +2141,40 @@ tela de IVR no frontend")
|
||||
colheu o dígito com DTMF real (`uuid_recv_dtmf`) e bridged com o
|
||||
ramal certo — confirma que o compilador produz XML funcionalmente
|
||||
idêntico ao testado manualmente na PHASE 56
|
||||
- [ ] Sem pipeline de upload/TTS de prompt de áudio (texto livre/tom
|
||||
padrão só); sem sub-menu (IVR dentro de IVR) nem destino "fila";
|
||||
"Rotas de Entrada" ainda não tem um seletor dedicado de "IVR" como
|
||||
destino (usuário copia contexto/`ivr_entry` da tela de IVR)
|
||||
- [ ] Sem TTS (texto→voz); sem sub-menu (IVR dentro de IVR) nem destino
|
||||
"fila"; "Rotas de Entrada" ainda não tem um seletor dedicado de
|
||||
"IVR" como destino (usuário copia contexto/`ivr_entry` da tela de IVR)
|
||||
|
||||
## PHASE 59 — Upload de áudio pro prompt do IVR (pedido do usuário:
|
||||
"adiciona upload de áudio pro prompt do IVR")
|
||||
- [x] `POST /ivr-menus/:id/prompt` (multipart, `@fastify/multipart` —
|
||||
primeiro upload de arquivo binário desta API) — só aceita WAV
|
||||
(cabeçalho RIFF/WAVE validado; sem `mod_shout` nesta implantação,
|
||||
MP3 nunca funcionaria). Gravado num bind mount NOVO
|
||||
(`./data/ivr-prompts` no host ↔ `/ivr-prompts` no container
|
||||
freeswitch) — mesmo raciocínio já usado 3x neste projeto pra
|
||||
arquivo que o FreeSWITCH precisa enxergar de verdade (gateways
|
||||
externos, filas do callcenter, spool de gravação), mas na direção
|
||||
contrária: `apps/api` (host) escreve, o FreeSWITCH lê ao vivo
|
||||
durante `play_and_get_digits`. Um fetch em rede (S3/HTTP) durante
|
||||
a chamada foi descartado de propósito — latência desnecessária
|
||||
pra um prompt de poucos segundos
|
||||
- [x] `GET /ivr-menus/:id/prompt` (autenticado, `ivr.view`) serve o
|
||||
preview — mesmo princípio do player de gravações, nunca uma URL
|
||||
direta pro storage/disco. Deletar o menu ou trocar/remover o
|
||||
prompt sempre limpa o arquivo do disco (achado real: minha
|
||||
primeira versão do delete de menu deixava o .wav órfão — corrigido
|
||||
antes de commitar, confirmado com teste real de upload+delete)
|
||||
- [x] Tela "Telefonia > IVR" ganhou upload/troca/remoção de áudio por
|
||||
menu + player `<audio>` de preview (proxy autenticado, mesmo
|
||||
padrão de `/api/recordings/[id]/audio`)
|
||||
- [x] Testado ponta a ponta com um WAV real de 44.1kHz/mono (não o
|
||||
formato "nativo" de telefonia, de propósito): softphone externo
|
||||
discou o DID, `play_and_get_digits` abriu e tocou o arquivo até o
|
||||
fim duas vezes (`mod_sndfile` resample automático, sem erro no
|
||||
log), colheu o dígito real e bridged corretamente com o ramal —
|
||||
confirma que áudio de qualquer sample rate/formato WAV comum
|
||||
funciona sem transcodificação manual
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user