Files
soft_usite/rest/routes/hermes_vcard_test.go
T
Lizandro GuarnizoandClaude Opus 5 4135850e5b feat(api-v2): endpoint de generación de texto para la integración de VCard
El sistema de vCard necesitaba usar la IA configurada en /app/ai-config y el
único camino era /api/v1/ia/ollama-generate, que autentica con cookie de
sesión: incómodo para una llamada entre servidores y la razón de los 401.

Ahora hay POST /api/v2/vcard/ia, bajo el mismo scope y la misma API key
(Bearer + IP) que ya usa esa integración para los QR y los VCF. Manda prompt,
recibe texto.

La clave del proveedor no sale del servidor. La alternativa —devolverle la
configuración con la api_key adentro, como hace el Landing Generator— reparte
la credencial de OpenAI/Anthropic a cada aplicación que la quiera usar.

El módulo va fijo en "ia": si lo eligiera quien llama, una llave con scope
vcard podría usar la configuración del agente o la del Landing Generator.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 20:44:35 -05:00

74 lines
1.9 KiB
Go

package routes
import (
"strings"
"testing"
"github.com/gofiber/fiber/v2"
)
// Las rutas de VCard en /api/v2 son el camino que va a usar una integración
// externa. Un error de tipeo en un path no lo detecta el compilador — se
// descubre cuando el integrador recibe un 404. Esto lo fija.
func TestRutasVcardRegistradas(t *testing.T) {
app := fiber.New()
AdminApiRoutes(app)
registradas := map[string]bool{}
for _, capa := range app.Stack() {
for _, r := range capa {
registradas[r.Method+" "+r.Path] = true
}
}
esperadas := []string{
"POST /v2/vcard/qr-tmp",
"POST /v2/vcard/qr",
"POST /v2/vcard/qr-url",
"POST /v2/vcard/vcf",
"POST /v2/vcard/ia",
"POST /v2/vcard/dlocal/planes",
"GET /v2/vcard/dlocal/planes",
"GET /v2/vcard/dlocal/planes/:planID",
"PATCH /v2/vcard/dlocal/planes/:planID",
"PATCH /v2/vcard/dlocal/planes/:planId/suscripciones/:subscriptionId/desactivar",
"GET /v2/vcard/dlocal/suscripciones/:subscriptionId/ejecuciones/:invoiceId",
"POST /v2/vcard/dlocal/pagos",
"POST /v2/vcard/rapyd/wallets",
}
for _, e := range esperadas {
if !registradas[e] {
t.Errorf("falta la ruta %q", e)
}
}
}
// El spec de /api/v2 se mantiene a mano, así que se desincroniza en silencio.
// Este chequeo obliga a que cada ruta nueva de vcard aparezca documentada.
func TestSpecDocumentaLasRutasVcard(t *testing.T) {
app := fiber.New()
AdminApiRoutes(app)
var paths []string
for _, capa := range app.Stack() {
for _, r := range capa {
if strings.HasPrefix(r.Path, "/v2/vcard/") && r.Method != "HEAD" {
paths = append(paths, "/api"+r.Path)
}
}
}
if len(paths) == 0 {
t.Fatal("no se registró ninguna ruta de vcard")
}
spec, err := leerSpecComoTexto()
if err != nil {
t.Skipf("no se pudo leer el spec: %v", err)
}
for _, p := range paths {
if !strings.Contains(spec, p) {
t.Errorf("la ruta %q está registrada pero no figura en el spec de /api/v2", p)
}
}
}