# XML Curl `b2bcall-fs-config` (`apps/freeswitch-config`) responde às consultas HTTP que `mod_xml_curl` faz ao FreeSWITCH pra Directory e Dialplan (agente.md secao 26). ## Fluxo ``` FreeSWITCH → mod_xml_curl → http://fs-config:8080/ → (nesta fase: sempre "not found") ``` O binding cobre só `directory|dialplan` (não `configuration`) — inicialmente incluí `configuration` também, mas isso disparava várias chamadas HTTP desnecessárias no boot do FreeSWITCH pra configs de módulo que não precisamos controlar dinamicamente (contraria a seção 26: "Não colocar todas as configurações críticas via XML Curl"). ## Por que "not found" pra tudo, por enquanto Não existe tabela `extensions` nem `dialplans` ainda — essas são as próximas fases (Extensions, Trunks, Dialplan). O objetivo desta fase era só provar o encanamento: FreeSWITCH consegue mesmo chamar nosso serviço e interpretar a resposta corretamente, **sem quebrar a config estática vanilla que continua valendo como fallback**. Isso foi verificado assim: ```bash # Usuario inexistente em qualquer lugar -> vai ate o fs-config, recebe "not # found", FreeSWITCH reporta erro correto: fs_cli -x "originate user/8888 &park()" # -ERR SUBSCRIBER_ABSENT # Usuario 1000 (extensao estatica da config vanilla) -> mod_xml_curl retorna # "not found", FreeSWITCH cai pro XML estatico e ACHA o usuario (so nao tem # telefone registrado, que e' o esperado sem SIP real ainda): fs_cli -x "originate user/1000 &park()" # -ERR USER_NOT_REGISTERED (nao SUBSCRIBER_ABSENT) ``` A diferença entre as duas mensagens de erro é a prova de que o fallback pra config estática funciona corretamente. ## Segurança Sem autenticação no endpoint HTTP por enquanto — a única proteção é isolamento de rede (porta não publicada no host, só o FreeSWITCH na mesma rede do Docker Compose alcança). Isso é aceitável **enquanto o serviço só responde "not found"** (não há nada de valor pra proteger ainda). `mod_xml_curl` suporta `gateway-credentials` (HTTP Basic) nativamente — adicionar isso **antes** deste serviço passar a devolver directory/dialplan reais (fase Extensions/Trunks/Dialplan), já que a partir daí ele vira fonte de verdade para autenticação SIP. ## Próxima fase (Extensions) Quando a tabela `extensions` existir, o handler `section === "directory"` passa a consultar o Postgres e devolver o XML real de usuário (senha SIP, context, etc.) em vez de "not found" fixo.