BookinglyTech News
Software

na2axl publica un motor de flujos multi-paso sobre controladores de Laravel

El paquete laravel-api-flow convierte cada paso de un flujo (login, KYC, 2FA) en una ruta real y deja el estado en el servidor, para que el cliente no decida el orden.

3 min de lecturaDev.to0 vistas

El equipo de Zeney Pay, una fintech de transferencias internacionales, ha publicado na2axl/laravel-api-flow, un paquete para Laravel que ataca un problema conocido: los flujos que no caben en una sola petición HTTP. Login con doble factor, registro, KYC, cambio de PIN. La idea central del diseño es que el backend sea la única autoridad sobre en qué paso está el usuario.

El problema: dos fuentes de verdad

Antes de escribir el paquete, el equipo tenía los flujos repartidos. En el backend, un mismo proceso vivía en varios controladores (AuthController@login, OtpController@verify, PinController@check) y cada endpoint tenía que deducir por su cuenta si el llamante había pasado por los pasos anteriores. En el móvil, la app decidía qué pantalla venía después, cuándo saltarse el OTP y qué significaba "atrás".

El resultado: cambiar el orden de dos pasos exigía desplegar backend y publicar una versión nueva de la app, con la revisión de la tienda por medio, y las versiones antiguas seguían aplicando el orden viejo. Cada comprobación de "¿puede este usuario llamar aquí ahora?" se escribía a mano, salía distinta cada vez y a veces se olvidaba.

El giro, según el autor, fue entender que estaban metiendo requisitos de negocio en restricciones técnicas. Las peticiones no eran independientes: eran transiciones de una máquina de estados.

Cinco criterios y un paquete

El diseño parte de cinco exigencias. Que el backend conozca todos los pasos y cómo procesarlos, que sepa en qué punto está el flujo, que el estado recogido (quién entra, si pasó el doble factor, qué OTP se envió) viva en el servidor, que el cliente sepa a qué pasos puede ir y volver, y que el backend rechace cualquier transición ilegal por construcción.

En la práctica, un flujo es un controlador que hereda de FlowController. Cada método stepXxx es un paso, y Route::flow() refleja sobre la clase y registra una ruta por paso: stepInitiate queda como GET /sign-in/initiate y stepCheckMfa como POST /sign-in/check-mfa. Cada paso repite tres movimientos: validateStep(), el trabajo, y answer().

Las respuestas incluyen next_steps y back_steps, y el estado se guarda bajo una flow_key. Si el cliente intenta saltarse un paso recibe un 409 con el código FLOW_UNEXPECTED_STEP; si la clave ha caducado, un 410 con FLOW_EXPIRED. El tiempo de vida por defecto del estado son 15 minutos, configurable.

Hay un detalle que ilustra el enfoque: cuando el usuario retrocede al paso del correo, el hook onRewind puede anular el plan elegido después, para que volver atrás no deje estado incoherente.

Qué implica

Un motor genérico así encaja en cualquier sitio donde el orden de los pasos sea parte de la seguridad y no un detalle de interfaz. El autor lo dice sin rodeos: si un cliente puede llegar a check-pin sin pasar por check-mfa, lo que hay es una forma de saltarse el segundo factor.

Queda por ver cómo se comporta fuera del caso que lo originó. El material publicado no trae benchmarks ni comparaciones con lo que ya existe en el ecosistema de Laravel para gestión de estado y validación de transiciones.