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
37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
"use server";
|
|
|
|
import { revalidatePath } from "next/cache";
|
|
import { requireSession } from "@/lib/session";
|
|
import { apiFetch, ApiError } from "@/lib/api";
|
|
import type { WebrtcProxyConfig } from "@/lib/platform-types";
|
|
|
|
function extractErrorMessage(err: unknown): string {
|
|
if (err instanceof ApiError) {
|
|
try {
|
|
const parsed = JSON.parse(err.message);
|
|
if (Array.isArray(parsed.message)) return parsed.message.join(" ");
|
|
if (typeof parsed.message === "string") return parsed.message;
|
|
} catch {
|
|
// corpo não era JSON
|
|
}
|
|
return err.message || "Falha inesperada na API.";
|
|
}
|
|
return "Falha inesperada. Tente novamente.";
|
|
}
|
|
|
|
export async function updateWebrtcProxy(
|
|
url: string,
|
|
): Promise<{ ok: true; config: WebrtcProxyConfig } | { ok: false; error: string }> {
|
|
const session = await requireSession();
|
|
try {
|
|
const config = await apiFetch<WebrtcProxyConfig>("/platform/webrtc-proxy", session.accessToken, {
|
|
method: "PUT",
|
|
body: JSON.stringify({ url }),
|
|
});
|
|
revalidatePath("/platform/infraestrutura/softphone");
|
|
return { ok: true, config };
|
|
} catch (err) {
|
|
return { ok: false, error: extractErrorMessage(err) };
|
|
}
|
|
}
|