Skip to content

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)

Flujo de procesamiento:

  1. Validación de autenticación y autorización
  2. Conversión y validación de datos de entrada
  3. Obtención del origen de la petición
  4. Validación de configuración de API
  5. 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
  6. Obtención paralela de órdenes y PQRs
  7. Construcción de respuesta
  8. Auditoría de salida

Dependencias principales:

  • MaxBusiness - Lógica de negocio principal
  • CustomerUtil2 - Utilidades de gestión de clientes
  • ServiceUtil2 - Utilidades de gestión de servicios
  • OrderUtil2 - Utilidades de gestión de órdenes
  • PQRUtil2 - Utilidades de gestión de PQRs
  • ConfigurationUtil - Gestión de configuraciones
  • AuditUtil - 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

CampoTipoObligatorioDescripción
AuthorizationstringToken de autenticación Bearer
Content-Typestringapplication/json

Body

CampoTipoObligatorioDescripción
WSRequestHeaderobjectCabecera de la petición con información del sistema
WSRequestBodyobjectCuerpo de la petición con datos específicos

Estructura WSRequestHeader:

CampoTipoObligatorioDescripción
SystemobjectInformación del sistema solicitante
PropertyarrayNoPropiedades adicionales de la petición

Estructura System:

CampoTipoObligatorioDescripción
NamestringNombre del sistema solicitante
CorrelationIDstringIdentificador de correlación de la petición

Estructura Property:

CampoTipoObligatorioDescripción
NamestringNombre de la propiedad
ValuestringValor de la propiedad

Estructura WSRequestBody:

CampoTipoObligatorioDescripción
AuditobjectInformación de auditoría de la aplicación
Billing_AccountstringNo*Cuenta de facturación del servicio
CustomerobjectNo*Información del cliente
PhonestringNo*Número de teléfono del servicio

*Al menos uno de estos campos debe estar presente: Billing_Account, Customer, o Phone.

Estructura Audit:

CampoTipoObligatorioDescripción
ApplicationstringNombre de la aplicación
UserstringUsuario que realiza la petición

Estructura Customer:

CampoTipoObligatorioDescripción
Document_TypestringTipo de documento del cliente
Document_NumberstringNúmero de documento del cliente

Respuesta esperada (Response)

Headers

CampoTipoObligatorioDescripción
Content-Typestringapplication/json

Body

CampoTipoObligatorioDescripción
WSResponseHeaderobjectCabecera de la respuesta con información del sistema
WSResponseBodyobjectCuerpo de la respuesta con datos específicos

Estructura WSResponseHeader:

CampoTipoObligatorioDescripción
SystemobjectInformación del sistema procesador
ServiceobjectInformación del estado del servicio

Estructura System:

CampoTipoObligatorioDescripción
NamestringNombre del sistema procesador
CorrelationIDstringIdentificador de correlación de la petición
ProcessingServerstringServidor que procesó la petición

Estructura Service:

CampoTipoObligatorioDescripción
StatusstringEstado del procesamiento (OK/FAIL)
ResponseDatestringFecha y hora de respuesta
ProcessingServerstringServidor que procesó la petición
StatusDetailarrayDetalles del estado y errores

Estructura WSResponseBody:

CampoTipoObligatorioDescripción
CustomerobjectNoInformación completa del cliente
RecoverExperienceobjectNoInformación de experiencia de recuperación
ServiceobjectNoInformación completa del servicio
OrdersarrayNoLista de órdenes pendientes
PQRsarrayNoLista de PQRs pendientes

Manejo de errores

CódigoDescripciónEjemplo
ERROR_02No se pudo obtener el origen"La solicitud {0} no fue exitosa. No fue posible obtener el origen"
ERROR_03No se pudo validar la petición"La solicitud {0} no fue exitosa. No fue posible validar la petición"
ERROR_04Objetos no acordes a la petición"La solicitud {0} no fue exitosa. Fueron enviados objetos no acordes a la petición"
ERROR_06No se encontró información válida"La solicitud {0} no fue exitosa. No se encontró información válida"
ERROR_07Cliente o servicio no encontrado"La solicitud {0} no fue exitosa. Cliente o servicio no encontrado"
OK_01Procesamiento exitoso"La solicitud {0} fue exitosa"

Análisis de Componentes

Modelos y componentes

Modelos base utilizados:

  • BaseRequest - Clase base para todas las peticiones
  • BaseResponse - Clase base para todas las respuestas
  • BotBaseRequestHeader - Cabecera estándar de petición
  • BotBaseResponseHeader - Cabecera estándar de respuesta
  • BotBaseResponseService - Información de estado del servicio
  • BotBaseResponseStatusDetail - Detalles de estado y errores

Utilidades y servicios comunes:

  • ConfigurationUtil - Gestión de configuraciones y tipologías
  • AuditUtil - Auditoría de transacciones
  • CustomerUtil2 - Operaciones de clientes
  • ServiceUtil2 - Operaciones de servicios
  • OrderUtil2 - Operaciones de órdenes
  • PQRUtil2 - 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)

json
{
  "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

json
{
  "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

json
{
  "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

mermaid
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

mermaid
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

mermaid
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:

  1. Manejo de excepciones: Implementar manejo más granular de excepciones específicas
  2. Validación de entrada: Agregar validaciones de formato para campos como teléfono y documento
  3. Caché: Implementar caché para consultas frecuentes de clientes y servicios
  4. Logging: Mejorar el logging estructurado para facilitar el debugging

Optimizaciones posibles:

  1. Consultas paralelas: Ya implementado para órdenes y PQRs, considerar extender a otras consultas
  2. Paginación: Implementar paginación para listas grandes de órdenes y PQRs
  3. Compresión: Habilitar compresión gzip para respuestas grandes
  4. Connection pooling: Optimizar el pool de conexiones a bases de datos

Consideraciones de mantenimiento importantes:

  1. Monitoreo: Implementar métricas de rendimiento y disponibilidad
  2. Alertas: Configurar alertas para errores críticos y degradación de rendimiento
  3. Documentación: Mantener actualizada la documentación de cambios en el servicio
  4. Testing: Implementar pruebas automatizadas para validar el comportamiento del servicio

Sugerencias de seguridad aplicables:

  1. Rate limiting: Implementar límites de tasa por IP y usuario
  2. Validación de entrada: Sanitizar y validar todos los campos de entrada
  3. Auditoría: Mantener logs detallados de todas las operaciones
  4. Encriptación: Asegurar que los datos sensibles se transmitan encriptados
  5. 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