02 · Producto B2B para bancos · Configuración
Configurar un sistema que ya está corriendo.
El módulo donde un banco define los objetivos de su fuerza comercial, los asigna a cada período y fija cuánto se paga por cumplirlos. Lo difícil no era la cantidad de campos. Era que cada cambio cae sobre un período que puede estar cerrado, en curso o todavía sin empezar.
El problema
Todo banco que compra una plataforma de incentivos ya tiene una forma de cargar sus datos. Algunos usan planillas, otros un software propio, y casi siempre el sistema con el que cargan no es el mismo con el que después miran los resultados. Esa forma de trabajar no se cambia porque llegue un producto nuevo.
Y hay una segunda capa, que es la que vuelve difícil al módulo. Un incentivo no es una configuración estática: es una regla que corre sobre un período, y los períodos tienen estados. Mientras un administrador configura abril, marzo está en curso y febrero ya cerró con gente que cobró según lo que decía esa configuración. Cualquier cambio tiene un alcance temporal, y si el usuario no lo entiende antes de confirmar, el error se descubre cuando alguien cobra de menos.
Separar qué se mide, cuándo se mide y cuánto se paga
La decisión estructural fue no tratar la configuración como una sola cosa. El módulo está partido en tres capas que se configuran por separado y se combinan después.
Los objetivos son un catálogo propio del banco: nombre, identificador interno, categoría, unidad de medida, y si forma parte de un objetivo compuesto. Se crean una vez y se reutilizan. La asignación por período toma objetivos de ese catálogo y los pone a correr sobre un mes, un trimestre, un cuatrimestre o un año. Los tramos definen cuánto se cobra según el nivel de cumplimiento.
La separación no es cosmética: es lo que permite que un objetivo que el banco ya usó en enero vuelva a usarse en abril sin volver a definirlo, y que cambiar cuánto se paga no obligue a tocar qué se mide. El producto lo dice de frente en el estado vacío: primero se crean los objetivos y después se asocian a un período.
Tres preguntas distintas (qué se mide, cuándo, y cuánto se paga) no entran en un mismo formulario sin volverse un laberinto.
Una consecuencia de haber separado así: un objetivo del catálogo no se elimina, se desactiva. Un objetivo que ya participó de un período cerrado es parte de un resultado que alguien cobró, y borrarlo dejaría ese resultado sin explicación.
El período como unidad, y el tiempo como estado
La asignación se organiza por frecuencia (mensual, trimestral, cuatrimestral, anual) y dentro de cada una, por año y por período.
Cada período de la lista muestra en qué estado del tiempo está, y de ese estado depende lo que se puede hacer con él. Los períodos ya cerrados quedan con su acción apagada y solo se consultan. El período en curso se puede mirar pero no reconfigurar. El próximo es el único que está habilitado para configurar, y los que vienen después todavía no. El usuario no tiene que acordarse de en qué mes está: la lista se lo muestra.
Sobre eso hay un aviso permanente, no un mensaje de error: los cambios no se aplican a períodos ya configurados. Es la regla más importante del módulo y por eso está arriba de todo y siempre visible, antes de que el usuario toque nada.
Donde la configuración se pone densa: los tramos
Las dos primeras capas se resuelven con listas y estados. La tercera no, y es el mejor ejemplo de lo que costaba hacer entendible.
Un incentivo se paga por tramos: de tal nivel de cumplimiento a tal otro corresponde tal cálculo. Los tramos tienen que cubrir todo el umbral, sin huecos y sin superposiciones; donde termina uno arranca el siguiente, exactamente. Y esa condición se rompe sola cada vez que alguien agrega o elimina un tramo del medio.
La forma convencional es pedir los dos extremos de cada tramo y validar después, lo que le deja al usuario la tarea de mantener la cadena coherente. Lo invertí: se edita un solo valor por tramo, el final. El inicio del siguiente se deriva de ahí. Si el valor coincide con el máximo del umbral, ese es el último tramo; si es menor, el sistema crea el siguiente ya encadenado. Al eliminar uno, la cadena se reconstruye sola. Los extremos quedan abiertos hacia abajo y hacia arriba para que ningún valor caiga afuera, y el primer tramo se crea solo al definir el umbral y no se puede borrar.
El resultado es que el estado inválido no existe. No hay validación que avise de un hueco, porque el hueco no se puede construir.
La misma pantalla resuelve otra cosa: no muestra el problema entero. Arranca con el nombre, el tipo y el umbral; la sección de tramos no está hasta que el umbral queda definido, y aparece con el primer tramo ya creado. Al costado, un resumen se arma en paralelo y funciona como indicador de avance: lo que falta es lo que todavía no está en la lista.
La carga: que el banco siga cargando como ya carga
Sobre esas tres capas va el otro problema, el de la migración. La solución fue encontrarse con el banco donde el banco ya está: una plantilla que se descarga, se completa en la herramienta que ya usa y se vuelve a subir. No le pedimos que cambie su forma de trabajar; le pedimos el mismo archivo que ya arma, con la estructura que el sistema necesita.
La plantilla cambia según el módulo contratado: si el banco ya calcula sus resultados y la plataforma solo los muestra, pide valores finales; si el cálculo lo hace la plataforma, pide los datos crudos.
Pero cargar objetivos no es subir un archivo. Son tres, y tienen dependencia entre sí: primero los objetivos, después los componentes que los integran, y al final los eventos que los disparan. No se puede asignar un componente a un objetivo que todavía no existe.
En vez de explicar esa dependencia con instrucciones, la puse en la interfaz: los tres pasos están a la vista desde el principio, numerados, pero solo el primero está habilitado. Los otros dos se activan cuando el anterior se completa. El administrador ve el camino entero antes de empezar (sabe cuánto falta) y al mismo tiempo no puede equivocarse de orden.
El archivo subido se valida y los problemas se muestran sobre las filas que los tienen, no como un error general.
Verificar qué quedó cargado
Subir un archivo y confiar no es una opción cuando lo que se carga define cuánto cobra la gente. Por eso la carga no termina en el archivo: termina en una vista donde el administrador ve el resultado de lo que subió.
El período muestra primero un resumen de lo que quedó asignado, y debajo la tabla de asignaciones: quién tiene qué objetivo, con qué meta, en qué estado. Tiene búsqueda, filtros y exportación, y cada fila se puede abrir para ver el detalle completo de esa asignación.
Es el paso que cierra el ciclo. El administrador carga desde afuera, pero verifica adentro, y puede hacerlo antes de que el período arranque.
El resultado
La v1 se implementó y quedó en uso. El banco pasó a configurar sus propios períodos, en lugar de mandar una planilla para que la cargara el proveedor, que era el modelo anterior y el que impedía que el producto creciera a más clientes sin hacer crecer al mismo tiempo al equipo que cargaba datos.
Lo que todavía no cerró
La v1 exigía capacitación. Un administrador no podía sentarse solo frente al módulo y configurar un período de punta a punta; había que explicárselo.
La segunda iteración ataca eso. El diagnóstico salió del uso real: el usuario entraba y salía de los períodos para hacer cosas distintas, porque adentro de un período convivían la carga de archivos, la edición y la consulta. La reorganización separa las dos cosas, la carga de datos se unifica en un solo lugar y el período queda para lo que de verdad pertenece a ese período. Está en desarrollo y todavía no llegó a manos de clientes.
Diseñé un módulo que necesitaba una capacitación para usarse y durante un tiempo me pareció razonable, porque el dominio es complejo de verdad. No lo es: si el producto se vende para que el cliente se maneje solo, una capacitación obligatoria es una funcionalidad faltante disfrazada de servicio. La segunda versión arranca por ahí.