Max v2 Route – Enrutamiento e Inicialización de Conversaciones MAX
Información del Servicio
Endpoint: /api/max/v2/route
Método: POST
Versión: v2
Categoría: Atención y Soporte
Documentación del Servicio
Descripción general
El servicio max-v2-route es un endpoint de enrutamiento e inicialización de conversaciones en la plataforma Luz de ETB. Este servicio permite obtener información completa de clientes, servicios, órdenes pendientes y PQRs (Peticiones, Quejas y Reclamos) asociadas a un cliente o servicio específico.
Categoría de negocio: Servicios de atención al cliente y gestión de conversaciones.
Casos de uso principales:
- Inicialización de conversaciones en el chatbot Luz
- Consulta de información completa del cliente
- Obtención de órdenes pendientes asociadas
- Consulta de PQRs activas
- Enrutamiento de conversaciones según el contexto del cliente
Especificación técnica
- Endpoint completo:
/api/max/v2/route
- Método HTTP: POST
- Capas involucradas:
- Controlador:
MaxController.Route_v2()
- Lógica de negocio:
MaxBusiness.Route_v2()
- Acceso a datos: Utilidades de CRM (CustomerUtil2, ServiceUtil2, OrderUtil2, PQRUtil2)
- Controlador:
Flujo de procesamiento:
- Validación de autenticación y autorización
- Conversión y validación de datos de entrada
- Obtención del origen de la petición
- Validación de configuración de API
- Consulta de información según criterios de búsqueda:
- Por documento de cliente
- Por cuenta de facturación
- Por número de teléfono
- Obtención paralela de órdenes y PQRs
- Construcción de respuesta
- Auditoría de salida
Dependencias principales:
MaxBusiness
- Lógica de negocio principalCustomerUtil2
- Utilidades de gestión de clientesServiceUtil2
- Utilidades de gestión de serviciosOrderUtil2
- Utilidades de gestión de órdenesPQRUtil2
- Utilidades de gestión de PQRsConfigurationUtil
- Gestión de configuracionesAuditUtil
- Auditoría de transacciones
Consideraciones de seguridad:
- Autenticación mediante atributo
[Authorize]
- Validación de origen de petición
- Auditoría completa de entrada y salida
- Validación de configuración de API activa/inactiva
Parámetros de entrada (Request)
Headers
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
Authorization | string | Sí | Token de autenticación Bearer |
Content-Type | string | Sí | application/json |
Body
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
WSRequestHeader | object | Sí | Cabecera de la petición con información del sistema |
WSRequestBody | object | Sí | Cuerpo de la petición con datos específicos |
Estructura WSRequestHeader:
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
System | object | Sí | Información del sistema solicitante |
Property | array | No | Propiedades adicionales de la petición |
Estructura System:
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
Name | string | Sí | Nombre del sistema solicitante |
CorrelationID | string | Sí | Identificador de correlación de la petición |
Estructura Property:
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
Name | string | Sí | Nombre de la propiedad |
Value | string | Sí | Valor de la propiedad |
Estructura WSRequestBody:
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
Audit | object | Sí | Información de auditoría de la aplicación |
Billing_Account | string | No* | Cuenta de facturación del servicio |
Customer | object | No* | Información del cliente |
Phone | string | No* | Número de teléfono del servicio |
*Al menos uno de estos campos debe estar presente: Billing_Account, Customer, o Phone.
Estructura Audit:
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
Application | string | Sí | Nombre de la aplicación |
User | string | Sí | Usuario que realiza la petición |
Estructura Customer:
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
Document_Type | string | Sí | Tipo de documento del cliente |
Document_Number | string | Sí | Número de documento del cliente |
Respuesta esperada (Response)
Headers
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
Content-Type | string | Sí | application/json |
Body
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
WSResponseHeader | object | Sí | Cabecera de la respuesta con información del sistema |
WSResponseBody | object | Sí | Cuerpo de la respuesta con datos específicos |
Estructura WSResponseHeader:
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
System | object | Sí | Información del sistema procesador |
Service | object | Sí | Información del estado del servicio |
Estructura System:
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
Name | string | Sí | Nombre del sistema procesador |
CorrelationID | string | Sí | Identificador de correlación de la petición |
ProcessingServer | string | Sí | Servidor que procesó la petición |
Estructura Service:
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
Status | string | Sí | Estado del procesamiento (OK/FAIL) |
ResponseDate | string | Sí | Fecha y hora de respuesta |
ProcessingServer | string | Sí | Servidor que procesó la petición |
StatusDetail | array | Sí | Detalles del estado y errores |
Estructura WSResponseBody:
Campo | Tipo | Obligatorio | Descripción |
---|---|---|---|
Customer | object | No | Información completa del cliente |
RecoverExperience | object | No | Información de experiencia de recuperación |
Service | object | No | Información completa del servicio |
Orders | array | No | Lista de órdenes pendientes |
PQRs | array | No | Lista de PQRs pendientes |
Manejo de errores
Código | Descripción | Ejemplo |
---|---|---|
ERROR_02 | No se pudo obtener el origen | "La solicitud {0} no fue exitosa. No fue posible obtener el origen" |
ERROR_03 | No se pudo validar la petición | "La solicitud {0} no fue exitosa. No fue posible validar la petición" |
ERROR_04 | Objetos no acordes a la petición | "La solicitud {0} no fue exitosa. Fueron enviados objetos no acordes a la petición" |
ERROR_06 | No se encontró información válida | "La solicitud {0} no fue exitosa. No se encontró información válida" |
ERROR_07 | Cliente o servicio no encontrado | "La solicitud {0} no fue exitosa. Cliente o servicio no encontrado" |
OK_01 | Procesamiento exitoso | "La solicitud {0} fue exitosa" |
Análisis de Componentes
Modelos y componentes
Modelos base utilizados:
BaseRequest
- Clase base para todas las peticionesBaseResponse
- Clase base para todas las respuestasBotBaseRequestHeader
- Cabecera estándar de peticiónBotBaseResponseHeader
- Cabecera estándar de respuestaBotBaseResponseService
- Información de estado del servicioBotBaseResponseStatusDetail
- Detalles de estado y errores
Utilidades y servicios comunes:
ConfigurationUtil
- Gestión de configuraciones y tipologíasAuditUtil
- Auditoría de transaccionesCustomerUtil2
- Operaciones de clientesServiceUtil2
- Operaciones de serviciosOrderUtil2
- Operaciones de órdenesPQRUtil2
- Operaciones de PQRs
Patrones de diseño implementados:
- Singleton Pattern:
MaxBusiness.GetInstance
- Factory Pattern: Utilidades de CRM
- Template Method: Flujo de procesamiento estándar
- Strategy Pattern: Diferentes estrategias de consulta según criterios
Componentes reutilizados:
- Modelos de CRM (
CustomerModel
,ServiceModel
,OrderModel
,PQRModel
) - Utilidades de configuración y auditoría
- Filtros de consulta (
CustomerFilter
,ServiceFilter
,OrderFilter
,PQRFilter
)
Referencias cruzadas:
- Endpoint relacionado:
/api/max/v1/route
(versión anterior) - Servicios de CRM para consulta de información
- Sistema de auditoría compartido
Ejemplos de Request/Response
Solicitud (request)
{
"WSRequestHeader": {
"System": {
"name": "MAX",
"correlationID": "LUZ-0.1813156884341699",
"processingServer": null
},
"Property": []
},
"WSRequestBody": {
"Phone": "",
"Customer": {
"Document_Type": "CC",
"Document_Number": "1234567890"
},
"Audit": {
"Canal": "whatsapp",
"Date": "2025-07-12",
"Hour": "17:00:04"
}
}
}
Respuesta exitosa
{
"WSResponseHeader": {
"System": {
"name": "MAX",
"correlationID": "LUZ-0.1813156884341699",
"processingServer": null
},
"Service": {
"status": "OK",
"responseDate": "2025-07-12T17:00:05.0765152Z",
"processingServer": null,
"statusDetail": [
{
"errorCode": "OK_01",
"errorDetailCode": "La solicitud LUZ-0.35358949387322314 fue exitosa. Se el cliente / servicio",
"errorMessage": "La solicitud fue exitosa",
"errorMessageUser": null
}
]
},
"Property": []
},
"WSResponseBody": {
"Customer": {
"Address": "CL 0 0 0 SMZ 10 MADRID MZ 2 CA 6",
"Addresses": null,
"Billings": null,
"City": {
"Country": {
"Id": "593b0ac99a8e4177d410df4d",
"Name": "Colombia"
},
"Department": {
"Id": "50",
"Name": "META"
},
"Home_Coverage": true,
"Home_Coverage_Type": "NOGIS",
"Localities": null,
"Mobile_Coverage": true,
"Mobile_Coverages": [
{
"Days": "2",
"Hours": "0",
"Operator": "DHL",
"Type": "BASICA"
}
],
"Id": "50001",
"Name": "VILLAVICENCIO"
},
"Civil_Status": null,
"Contacts": null,
"Creation_Date": {
"Date": "2023-08-10T15:42:25.182Z",
"Format_1": "10/08",
"Format_2": "10/08/2023",
"Format_3": "10/08/2023 15:42:25",
"Format_4": "10/08/2023 03:42:25 PM",
"Day": {
"Format_1": "10",
"Format_2": "Jue.",
"Format_3": "Jueves"
},
"Month": {
"Format_1": "08",
"Format_2": "Ago.",
"Format_3": "Agosto"
},
"Year": {
"Format_1": "23",
"Format_2": "2023",
"Format_3": "02023"
},
"Hour": {
"Format_1": "15:42:25",
"Format_2": "03:42:25 PM",
"Format_3": "15",
"Format_4": "03 PM",
"Format_5": "42",
"Format_6": "25"
}
},
"Customer_Type": null,
"Department": {
"Cities": [
{
"Id": "50110",
"Name": "BARRANCA DE UPIA"
},
{
"Id": "50006",
"Name": "ACACIAS"
},
{
"Id": "50223",
"Name": "CUBARRAL"
},
{
"Id": "50226",
"Name": "CUMARAL"
},
{
"Id": "50124",
"Name": "CABUYARO"
},
{
"Id": "50270",
"Name": "EL DORADO"
},
{
"Id": "50606",
"Name": "RESTREPO"
},
{
"Id": "50313",
"Name": "GRANADA"
},
{
"Id": "50245",
"Name": "EL CALVARIO"
},
{
"Id": "50330",
"Name": "MESETAS"
},
{
"Id": "50568",
"Name": "PUERTO GAITAN"
},
{
"Id": "50686",
"Name": "SAN JUANITO"
},
{
"Id": "50251",
"Name": "EL CASTILLO"
},
{
"Id": "50350",
"Name": "LA MACARENA"
},
{
"Id": "50450",
"Name": "PUERTO CONCORDIA"
},
{
"Id": "50325",
"Name": "MAPIRIPAN"
},
{
"Id": "50590",
"Name": "PUERTO RICO"
},
{
"Id": "50318",
"Name": "GUAMAL"
},
{
"Id": "50400",
"Name": "LEJANIAS"
},
{
"Id": "50577",
"Name": "PUERTO LLERAS"
},
{
"Id": "50683",
"Name": "SAN JUAN DE ARAMA"
},
{
"Id": "50680",
"Name": "SAN CARLOS DE GUAROA"
},
{
"Id": "50689",
"Name": "SAN MARTIN"
},
{
"Id": "50287",
"Name": "FUENTE DE ORO"
},
{
"Id": "50370",
"Name": "URIBE"
},
{
"Id": "50150",
"Name": "CASTILLA LA NUEVA"
},
{
"Id": "50711",
"Name": "VISTAHERMOSA"
},
{
"Id": "50573",
"Name": "PUERTO LOPEZ"
},
{
"Id": "50006",
"Name": "ACACÍAS"
},
{
"Id": "50325",
"Name": "MAPIRIPÁN"
},
{
"Id": "50110",
"Name": "BARRANCA DE UPÍA"
},
{
"Id": "50001",
"Name": "VILLAVICENCIO"
},
{
"Id": "50400",
"Name": "LEJANÍAS"
},
{
"Id": "50689",
"Name": "SAN MARTÍN"
},
{
"Id": "50287",
"Name": "FUENTEDEORO"
},
{
"Id": "50568",
"Name": "PUERTO GAITÁN"
},
{
"Id": "50573",
"Name": "PUERTO LÓPEZ"
}
],
"Country": {
"Id": "593b0ac99a8e4177d410df4d",
"Name": "Colombia"
},
"Coverage": true,
"Id": "50",
"Name": "META"
},
"Directv_Subscription": null,
"Gender": null,
"Habeas_Data": null,
"MiETBUser": null,
"Phone": "6013777777",
"State": "PENDIENTE",
"Update_Date": {
"Date": "2023-08-11T08:42:58.628Z",
"Format_1": "11/08",
"Format_2": "11/08/2023",
"Format_3": "11/08/2023 08:42:58",
"Format_4": "11/08/2023 08:42:58 AM",
"Day": {
"Format_1": "11",
"Format_2": "Vie.",
"Format_3": "Viernes"
},
"Month": {
"Format_1": "08",
"Format_2": "Ago.",
"Format_3": "Agosto"
},
"Year": {
"Format_1": "23",
"Format_2": "2023",
"Format_3": "02023"
},
"Hour": {
"Format_1": "08:42:58",
"Format_2": "08:42:58 AM",
"Format_3": "08",
"Format_4": "08 AM",
"Format_5": "42",
"Format_6": "58"
}
},
"ATDP": {
"Channel": "Portal Fija",
"Date": {
"Date": "2023-08-10T20:43:33.886Z",
"Format_1": "10/08",
"Format_2": "10/08/2023",
"Format_3": "10/08/2023 20:43:33",
"Format_4": "10/08/2023 08:43:33 PM",
"Day": {
"Format_1": "10",
"Format_2": "Jue.",
"Format_3": "Jueves"
},
"Month": {
"Format_1": "08",
"Format_2": "Ago.",
"Format_3": "Agosto"
},
"Year": {
"Format_1": "23",
"Format_2": "2023",
"Format_3": "02023"
},
"Hour": {
"Format_1": "20:43:33",
"Format_2": "08:43:33 PM",
"Format_3": "20",
"Format_4": "08 PM",
"Format_5": "43",
"Format_6": "33"
}
},
"Decision": "AUTORIZA",
"PQR": "64d54bb0c7c6a3141802b8e7",
"User": "braylopo"
},
"Birthday": null,
"Business": null,
"Collection_Communications": null,
"Document_Number": "1234567890",
"Document_Type": "CC",
"Email": "pruebamailcliente@gmail.com",
"Mobile_Phone": "3058337166",
"Mobile_Phone2": "",
"Name": {
"Complete_Name": "ANA FRANCISCA SILVA",
"First_Name": "ANA",
"First_Surname": "SILVA",
"Names": "ANA FRANCISCA",
"Second_Name": "FRANCISCA",
"Second_Surname": "",
"Surnames": "SILVA "
},
"Segmentation": {
"Attention_Scheme": null,
"Category": "PLATA",
"Profile": null,
"Segment": "Hogares",
"UEN": "Hogares y MiPymes",
"Segment_UEN": "Hogares"
},
"Validation_Code": {
"Is_Blocked": false,
"Is_Enabled": false,
"Last_Try": {
"Date": "0001-01-01T00:00:00",
"Format_1": null,
"Format_2": null,
"Format_3": null,
"Format_4": null,
"Day": null,
"Month": null,
"Year": null,
"Hour": null
},
"Reset_Date": null,
"Retries": 0,
"Retries_Remain": null
}
},
"RecoverExperience": null,
"Service": null,
"Orders": null,
"PQRs": null
}
}
Respuesta de error
{
"WSResponseHeader": {
"System": {
"Name": "LUZ_CHATBOT",
"CorrelationID": "123456789",
"ProcessingServer": "BOTAPP-SRV-01"
},
"Service": {
"Status": "FAIL",
"ResponseDate": "2024-01-15T10:30:00-05:00",
"ProcessingServer": "BOTAPP-SRV-01",
"StatusDetail": [
{
"ErrorCode": "ERROR_07",
"ErrorDetailCode": "Cliente o servicio no encontrado",
"ErrorMessage": "La solicitud 123456789 no fue exitosa. Cliente o servicio no encontrado",
"ErrorMessageUser": "La solicitud 123456789 no fue exitosa. Cliente o servicio no encontrado"
}
]
}
},
"WSResponseBody": {
"Customer": null,
"Service": null,
"Orders": null,
"PQRs": null
}
}
Diagramas Técnicos
3.1 Flujo de datos
graph TD
A[Cliente envía petición] --> B[MaxController.Route_v2]
B --> C[Validación de autenticación]
C --> D[Conversión de datos]
D --> E[Obtención de origen]
E --> F[Validación de API activa]
F --> G{¿Qué criterio usar?}
G -->|Documento| H[Consulta por cliente]
G -->|Cuenta facturación| I[Consulta por servicio]
G -->|Teléfono| J[Consulta por teléfono]
H --> K[Obtener órdenes y PQRs]
I --> K
J --> K
K --> L[Construir respuesta]
L --> M[Auditoría de salida]
M --> N[Respuesta al cliente]
style A fill:#e1f5fe
style N fill:#c8e6c9
style G fill:#fff3e0
3.2 Arquitectura de clases
classDiagram
class MaxController {
+Route_v2(BaseRequestRoute_v2) Task~BaseResponseRoute_v2~
}
class MaxBusiness {
+GetInstance MaxBusiness
+Route_v2(BaseRequest, string) Task~BaseResponseRoute_v2~
}
class BaseRequestRoute_v2 {
+WSRequestHeader BotBaseRequestHeader
+WSRequestBody RouteRequest_v2
}
class RouteRequest_v2 {
+Audit Audit
+Billing_Account string
+Customer RouteRequestCustomer_v2
+Phone string
}
class BaseResponseRoute_v2 {
+WSResponseHeader BotBaseResponseHeader
+WSResponseBody RouteResponse_v2
}
class RouteResponse_v2 {
+Customer CustomerModel
+RecoverExperience CustomerRecoverExperience
+Service ServiceModel
+Orders List~OrderModel~
+PQRs List~PQRModel~
}
class CustomerUtil2 {
+GetInstance CustomerUtil2
+GetById(RequestModel, string, string, CustomerFilter) Task~CustomerModel~
+GetRecoverExperience(RequestModel, CustomerModel, string) Task~CustomerRecoverExperience~
}
class ServiceUtil2 {
+GetInstance ServiceUtil2
+GetByBilling(RequestModel, string, ServiceFilter) Task~ServiceModel~
+GetByPhone(RequestModel, string, ServiceFilter) Task~ServiceModel~
}
MaxController --> MaxBusiness
MaxController --> BaseRequestRoute_v2
MaxController --> BaseResponseRoute_v2
MaxBusiness --> CustomerUtil2
MaxBusiness --> ServiceUtil2
BaseRequestRoute_v2 --> RouteRequest_v2
BaseResponseRoute_v2 --> RouteResponse_v2
3.3 Secuencia de ejecución
sequenceDiagram
participant Client as Cliente
participant Controller as MaxController
participant Business as MaxBusiness
participant CustomerUtil as CustomerUtil2
participant ServiceUtil as ServiceUtil2
participant OrderUtil as OrderUtil2
participant PQRUtil as PQRUtil2
participant Audit as AuditUtil
Client->>Controller: POST /api/max/v2/route
Controller->>Audit: Save_Request_Async (entrada)
Controller->>Business: Route_v2()
Business->>Business: Validar datos de entrada
Business->>Business: Obtener origen
Business->>Business: Validar API activa
alt Consulta por documento
Business->>CustomerUtil: GetById()
CustomerUtil-->>Business: CustomerModel
Business->>OrderUtil: GetByCustomer()
Business->>PQRUtil: GetByCustomer()
else Consulta por cuenta facturación
Business->>ServiceUtil: GetByBilling()
ServiceUtil-->>Business: ServiceModel
Business->>OrderUtil: GetByService()
Business->>PQRUtil: GetByService()
else Consulta por teléfono
Business->>ServiceUtil: GetByPhone()
ServiceUtil-->>Business: ServiceModel
Business->>CustomerUtil: GetRecoverExperience()
Business->>OrderUtil: GetByService()
Business->>PQRUtil: GetByService()
end
Business->>Business: Construir respuesta
Business-->>Controller: BaseResponseRoute_v2
Controller->>Audit: Save_Request_Async (salida)
Controller-->>Client: Respuesta JSON
Políticas y Consideraciones
Políticas de seguridad
Mecanismos de autenticación y autorización:
- Autenticación mediante token Bearer en header Authorization
- Validación de origen de petición mediante
ConfigurationUtil.Get_Origin()
- Verificación de permisos del sistema solicitante
Validaciones de seguridad implementadas:
- Validación de estructura de datos de entrada
- Verificación de campos obligatorios según criterio de búsqueda
- Validación de configuración de API activa/inactiva
- Auditoría completa de transacciones
Límites de tasa (rate limits):
- No se implementan límites específicos de tasa en este servicio
- Se recomienda implementar rate limiting basado en el sistema solicitante
SLAs aplicables:
- Tiempo de respuesta esperado: < 5 segundos
- Disponibilidad: 99.9%
- Tolerancia a fallos: Circuit breaker pattern recomendado
Recomendaciones y mejores prácticas
Puntos de mejora específicos en el código:
- Manejo de excepciones: Implementar manejo más granular de excepciones específicas
- Validación de entrada: Agregar validaciones de formato para campos como teléfono y documento
- Caché: Implementar caché para consultas frecuentes de clientes y servicios
- Logging: Mejorar el logging estructurado para facilitar el debugging
Optimizaciones posibles:
- Consultas paralelas: Ya implementado para órdenes y PQRs, considerar extender a otras consultas
- Paginación: Implementar paginación para listas grandes de órdenes y PQRs
- Compresión: Habilitar compresión gzip para respuestas grandes
- Connection pooling: Optimizar el pool de conexiones a bases de datos
Consideraciones de mantenimiento importantes:
- Monitoreo: Implementar métricas de rendimiento y disponibilidad
- Alertas: Configurar alertas para errores críticos y degradación de rendimiento
- Documentación: Mantener actualizada la documentación de cambios en el servicio
- Testing: Implementar pruebas automatizadas para validar el comportamiento del servicio
Sugerencias de seguridad aplicables:
- Rate limiting: Implementar límites de tasa por IP y usuario
- Validación de entrada: Sanitizar y validar todos los campos de entrada
- Auditoría: Mantener logs detallados de todas las operaciones
- Encriptación: Asegurar que los datos sensibles se transmitan encriptados
- Timeouts: Configurar timeouts apropiados para evitar ataques de denegación de servicio
Notas adicionales:
- El servicio utiliza MongoDB como base de datos principal para consultas de CRM
- Se implementa el patrón Singleton para las utilidades de negocio
- Las consultas de órdenes y PQRs se ejecutan en paralelo para optimizar el rendimiento
- El servicio es compatible con la versión anterior v1 del endpoint