Mejora en contextualización y flexibilización al cliente en operaciones de Posventa

Mauricio Cuba
Despegar Ingeniería
7 min readOct 6, 2022

Introducción

Una vez que un cliente realiza la compra de un producto en Despegar y se le confirma la reserva, este puede realizar solicitudes de posventa que deben ser manejadas correctamente. Entre estas solicitudes, que pueden ser concurrentes o no, se encuentran: cancelación, cambio, consultas, etc.

Con la finalidad de manejar esto de forma correcta, desde hace un tiempo que en Despegar estamos realizando una actualización del proceso de orquestación, y así poder dar más detalle al cliente de la operación a realizar y permitir una mayor flexibilización evitando que la arquitectura con la que se resuelven los problemas definan qué se puede hacer y qué no.

¿Cómo se resolvía antes?

Este proceso se dividía en 2 disparadores principales:

  1. ¿Qué solicitudes se podían realizar?
  2. ¿Cómo orquestaban estas solicitudes?
  • ¿Qué solicitudes se podían realizar?

Anteriormente, cada vez que un cliente accedía hasta la botonera de operaciones de posventa, se le deshabilitaban los botones de las operaciones que no se podían realizar y quedaban solamente habilitadas las que sí. De modo más técnico, esto significaba que quién necesitara dibujar esta botonera, realizaba un request a una aplicación que se encargaba de revisar el producto y las reglas que aplicaban para cada operación. Ésta decidía la factibilidad de las operaciones y respondía un catálogo de operaciones informando cuales se podían realizar y cuáles no.

Esto traía como consecuencia que, por ejemplo, si el cliente intentaba realizar un cambio de un producto y este proceso no era válido, simplemente el botón de esta operación se deshabilitara sin informar el porqué, generando dudas y una posterior llamada al call center para conocer en detalle el motivo de la solicitud no disponible.

  • ¿Cómo se orquestaban las solicitudes?

Anteriormente, se manejaba un esquema de suspensiones que dependía directamente de un ordenamiento arbitrario, donde se definía una precedencia de operaciones entre ellas. Si existía una operación previa y el cliente quería realizar una nueva, se verificaba contra esta tabla cuál tenía mayor “prioridad” y a partir de eso se decidía cuál de las dos operaciones continuaba. La otra operación se suspendía, esperando el final de la que se ejecutase para luego despertar y decidir si su ejecución tenía sentido o no. Esto generaba que, algunas veces, no se realizara específicamente lo que el cliente quería, sino que se dependía de esta tabla donde se definía la prioridad de cada operación.

Mejora en contextualización

Con la finalidad de evitar simplemente grisar un botón cuando una operación no estaba disponible, se agregó el concepto de simulación de operaciones.

A partir de esto, se cambió el paradigma y todas las operaciones pasaron a estar siempre habilitadas para el cliente, garantizando siempre su acceso hasta una pantalla previa a la operación que busca realizar (conocida desde aquí en más, como pantalla cero).

Desde aquí se dispara una simulación a una aplicación que se encarga de verificar las condiciones para la factibilidad de la operación. También informa el motivo por el cuál esto no pudiera realizarse, permitiendo a esta pantalla cero, explicar el motivo del bloqueo.

Flexibilización de operaciones

Entre las validaciones que se realizan en el servicio de simulación, se incluye también una verificación de operaciones cruzadas. Si un cliente tiene una operación en proceso pero prefiere realizar otra en su reemplazo, en lugar de que la decisión se tome a partir de una tabla de prioridades como pasaba anteriormente, este nuevo orquestador se encarga de verificar si este flujo que bloquea puede finalizarse para permitir el paso a la nueva solicitud que el cliente desea realizar. Si este flujo pudiera finalizarse de manera anticipada, se informará que es factible realizar esta nueva operación finalizando la anterior, quedando así la decisión en manos del cliente.

Esto se comunicará en la pantalla cero para que el cliente cuente con una contextualización adecuada para la toma de decisiones acerca de cuál solicitud desea realizar.

Cambio de paradigma para poder obtener mejores métricas

Para poder llevar hacia adelante este desarrollo, nos pusimos también como objetivo reemplazar la aplicación que funcionaba como repositorio de solicitudes de posventa.

Esta aplicación derivaba los requests que recibía y consultaba a cada uno de los posibles flujos para ese producto si contaba con alguna solicitud abierta. A partir de todas las respuestas obtenidas, este “repositorio” unificaba el mismo modelo para cada solicitud y retornaba una lista incluyendo cada una de estas, pero no las persistía de su lado.

Esto generaba algunos problemas como por ejemplo:

  • Las solicitudes no estaban persistidas con un modelo unificado, lo que hacía difícil obtener métricas de forma general para todas las solicitudes.
  • Se multiplexaban request. Por cada pegada que se recibía en esta aplicación, se generaban consultas a por lo menos 5 o 6 aplicaciones diferentes para poder calcular la respuesta, lo que agregaba posibles puntos de falla y hacía además que la velocidad de la respuesta sea tan rápida como la consulta más lenta realizada.

Decidimos entonces que la nueva aplicación que la reemplazara tendría que persistir la información de su lado y consultar a su propia base, en lugar de ir a buscar información a cada uno de los flujos en el momento de recibir una consulta.

Para poder lograr este cometido, cada flujo que se crea o modifica debe ser informado en tiempo real al nuevo repo, que se encarga de persistir la información con un mismo modelo estandarizado para todos los flujos.

Un punto no menos importante es que cuando se realizó este rollout para reemplazar este repo, era necesario no perder acceso a todas las solicitudes históricas, por lo que se tuvieron que procesar varios años de solicitudes para que se persistieran en el nuevo modelo estandarizado.

Para lograr esto hicimos lo siguiente:

  1. Se wrappeó con la nueva aplicación a su antecesor haciendo que cada request que se recibía pasara por la nueva primero y que esta consultara a la anterior, para que cuando tuviera la respuesta en su mano, en un Thread paralelo persistiera la info obtenida. Así evitaba penalizar con el tiempo de persistencia a su cliente.
  2. Se pidió a todos los flujos existentes que informaran de forma sincrónica las solicitudes creadas/modificadas, logrando que desde este punto en adelante se tuviera toda la información.
  3. Para poder contar con toda la historia de solicitudes creadas, se realizó una carga de información masiva a partir de scripts de bash que pegaban contra un servicio de esta nueva aplicación que guardaba la información recibida. Esta data fue obtenida desde desde un data lake de las tablas correspondientes a cada uno de los flujos, evitando generar carga sobre las aplicaciones y bases productivas.

A partir de todo esto, se logró bajar el tiempo de respuesta de esta aplicación, hacerla más estable evitando muchos posibles puntos de falla y además tenemos ahora la posibilidad de obtener métricas generales sobre las solicitudes de posventa, como por ejemplo las siguientes:

Solicitudes sobre vuelos generadas en la última semana distribuidos por originante
Solicitudes sobre hoteles en estado pendiente del cliente
Solicitudes creadas por clientes finalizadas en la última semana agrupado por tipo de flujo y producto

Agregamos también algunas muestras de cómo bajaron la cantidad de requests recibidos por algunas de las aplicaciones de los flujos que respondían a las consultas generadas.

Reducción de un 50% del tráfico
Reducción de un 66% del tráfico
Reducción 90% del tráfico
Reducción 53% del tráfico — Después

Como conclusión, conseguimos flexibilizar algunas operaciones que antes desde el lado del cliente no se podían realizar, agregando además una contextualización en las operaciones para permitir al cliente contar con una mayor cantidad de información en el momento de la toma de decisiones para solicitudes de posventa.

En el mismo proceso reemplazamos una aplicación legacy por una nueva app que resuelve de una forma más eficiente, y que además nos da la posibilidad de obtener métricas valiosas. Como último punto, pero no menos importante, redujimos el tráfico de otras aplicaciones del stack en porcentajes mayores al 50%.

--

--