Arquitectura: dos bloques, no uno
La decisión de diseño clave. El RFP exige latencia voz-a-voz < 800 ms, así que separamos las llamadas pesadas del turno conversacional.
"Antes de marcar" · Pre-call enrichment
Se ejecuta en el nodo de enriquecimiento (n8n) antes de la llamada. Llena todas las variables del prompt. El asistente arranca ya sabiendo quién es y cuánto debe.
- 1.
POST /v2/auth→token + organizationId - 2.
GET identification→transactionId - 3.
GET applicant→nombre y contacto - 4.
GET loan/customer→lista de obligaciones - 5.
GET pastdue/latest→días de mora → variante de prompt - 6.
POST debt_calculator→monto de salida de mora
"Durante / después" · Tool-calls en vivo
Solo lo que depende de la conversación. Se mantiene al mínimo para no comprometer la latencia del turno.
- 1.Negociación
POST debt_calculatorsi el cliente pide recalcular a otra fecha - 2.Cierre
POST certificate_base_payment(total o parcial) con el monto y fecha acordados - 3.Cierre
GET certificate→ PDF Base64 → enviar por el canal acordado - 4.Post-llamadaTipificación y promesa de pago → sin endpoint (gap §5)gap
Inventario de endpoints
0 endpoints agrupados por la pregunta de negocio que responden. Todos (menos auth) usan Authorization: Bearer {token} + header x-juno-organizationid.
| # | M | Endpoint | Propósito | Devuelve | Estado |
|---|---|---|---|---|---|
| 1 | POST | /v2/auth | Login del usuario de sistema → token (JWT 60 min) | token, idsLender[] | 500 bloqueado |
| 2 | GET | /v2/person/identification/{doc}/{tipo}/transaction | ¿Quién es? Transacción activa por documento | transactionId, amount, status | requiere auth |
| 3 | GET | /v2/person/transaction/{id}/applicant | Datos del titular | firstName, email, mobileNumber | requiere auth |
| 4 | GET | /loan/customer/{id} | ¿Cuánto debe? Obligaciones del cliente | loanId[], loanNumber, loanTypeName | requiere auth |
| 5 | GET | /pastdue/loan/{loanId}/latest | Posición de mora más reciente | daysPastDue, amountToInstalment | requiere auth |
| 6 | POST | /private/projection/debt_calculator | ¿Cuánto paga para salir de mora? Simulación (MORA_CURE) | projection.totalPayment | requiere auth + rol |
| 7 | GET | /loan/projections/customer/{id} | Proyecciones aptas para certificado | projectionIds[] | requiere auth |
| 8 | POST | /projection/projections/certificate_base_payment | Certificado de deuda total (PDF, 10 días) | certificateNumber | requiere auth |
| 9 | POST | /projection/partial/certificate_base_payment | Certificado parcial (monto negociado, ≤ 30 días) | certificateNumber | requiere auth |
| 10 | GET | /projection/certificate_base_payment/{n} | PDF del certificado en Base64 | string Base64 → WhatsApp/correo | requiere auth |
| 11 | POST | /v2/customer/validate-incorporation-date | Verificación de identidad reforzada | isMatch | opcional |
| 12 | GET | /v2/customer/{id}/first-name | Primer nombre para el saludo | primer nombre | opcional |
| 13 | POST | /debt-clearance | Paz y Salvo (préstamos cerrados) — fuera de mora | PDF Base64 | fuera de alcance |
| 14 | POST | /projection | Crear proyección si no existe (previo al cert. total) | — | body sin documentar |
En qué momento se llama cada endpoint
Mapeo de los endpoints a las fases de la conversación.
Árbol de decisiones: guion ⇄ endpoints
Cada rama del diálogo y qué llamada a la API dispara. ■ verde = funciona con auth; ■ ámbar = decisión de negocio; ■ rojo = gap sin endpoint.
La cascada de negociación asume hoy 2 obligaciones (Kala + KOALA); el RFP contempla hasta 9 — debe volverse dinámica sobre la lista loanId[].