feat: activate mod_xml_curl with b2bcall-fs-config (agente.md secao 26)

- apps/freeswitch-config (b2bcall-fs-config): Fastify service implementing
  the mod_xml_curl HTTP protocol (form-encoded POST -> XML response),
  containerized, no host port published
- reactivated mod_xml_curl in FreeSWITCH, binding restricted to
  directory|dialplan only (configuration was removed after testing showed
  it firing several unnecessary HTTP round-trips at boot for module
  configs we don't need dynamic — matches agente.md's own 'don't put every
  critical config through XML Curl' guidance)
- no extensions/dialplan tables exist yet (next phases), so the service
  always answers 'not found' for now — this phase only proves the wire
  protocol works without breaking the static vanilla config fallback
- verified end-to-end: user/8888 (nowhere) -> SUBSCRIBER_ABSENT via
  fs-config; user/1000 (static vanilla extension) -> USER_NOT_REGISTERED,
  proving FreeSWITCH correctly falls through to static XML when xml_curl
  says not found
- docs/XML_CURL.md, including the not-yet-authenticated endpoint note (fine
  while it only returns not-found; needs gateway-credentials before serving
  real directory/dialplan data)
This commit is contained in:
2026-08-28 07:07:05 -03:00
parent 60e9f6838e
commit d2ea83c06a
11 changed files with 240 additions and 7 deletions

View File

@@ -0,0 +1,17 @@
# syntax=docker/dockerfile:1.7
FROM node:22-slim
RUN corepack enable && corepack prepare pnpm@11.24.0 --activate
WORKDIR /repo
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml tsconfig.base.json ./
COPY packages/types packages/types
COPY packages/shared packages/shared
COPY apps/freeswitch-config apps/freeswitch-config
RUN pnpm install --frozen-lockfile --filter @b2bcall/freeswitch-config...
WORKDIR /repo/apps/freeswitch-config
CMD ["pnpm", "exec", "tsx", "src/main.ts"]

View File

@@ -0,0 +1,21 @@
{
"name": "@b2bcall/freeswitch-config",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "tsx watch src/main.ts",
"build": "tsc -p tsconfig.json",
"start": "node dist/main.js",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@b2bcall/shared": "workspace:*",
"@fastify/formbody": "^8.0.1",
"fastify": "5.12.1"
},
"devDependencies": {
"@types/node": "^22.0.0",
"tsx": "^4.23.12",
"typescript": "^5.7.0"
}
}

View File

@@ -0,0 +1,58 @@
import Fastify from "fastify";
import formbody from "@fastify/formbody";
import { createLogger } from "@b2bcall/shared";
const logger = createLogger("b2bcall-fs-config");
/**
* Resposta padrão do protocolo XML Curl pra "não achei nada aqui" — o
* FreeSWITCH cai de volta pras outras fontes XML registradas (a config
* estática vanilla continua funcionando normalmente).
*/
const NOT_FOUND_XML = `<?xml version="1.0" encoding="UTF-8"?>
<document type="freeswitch/xml">
<section name="result">
<result status="not found"/>
</section>
</document>`;
interface XmlCurlBody {
section?: string;
tag_name?: string;
key_name?: string;
key_value?: string;
purpose?: string;
user?: string;
domain?: string;
[key: string]: unknown;
}
async function main() {
const app = Fastify({ logger: false });
await app.register(formbody);
app.post<{ Body: XmlCurlBody }>("/", async (request, reply) => {
const { section, purpose, user, domain } = request.body ?? {};
logger.info("requisicao xml_curl recebida", { section, purpose, user, domain });
// Nenhuma tabela de extensions/dialplan existe ainda (fases Extensions/
// Trunks/Dialplan, agente.md secao 232). Por enquanto respondemos
// sempre "not found" — prova o encanamento (FreeSWITCH -> mod_xml_curl
// -> este servico -> XML valido) sem afetar a config estatica vanilla,
// que continua sendo consultada como fallback.
reply.header("Content-Type", "text/xml");
return NOT_FOUND_XML;
});
app.get("/health", async () => ({ status: "ok" }));
const port = Number(process.env.PORT ?? 8080);
await app.listen({ port, host: "0.0.0.0" });
logger.info(`b2bcall-fs-config ouvindo na porta ${port}`);
}
main().catch((err) => {
logger.error("falha fatal ao iniciar b2bcall-fs-config", { error: String(err) });
process.exit(1);
});

View File

@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"types": ["node"]
},
"include": ["src"]
}