Cómo remediar una arquitectura fintech sin reescribirla
La remediación de arquitectura fintech es la reparación controlada de los límites de seguridad, datos y entrega de un producto financiero en funcionamiento, sin sustituir todo el sistema. La secuencia más segura consiste en crear hallazgos trazables, estabilizar el lenguaje y la persistencia, hacer explícitas las dependencias, cerrar las brechas de autorización e integridad financiera y demostrar el resultado en staging mediante puertas de lanzamiento.
Este artículo responde a la pregunta de remediación: ¿qué debe ocurrir después de que una revisión de arquitectura o seguridad encuentre problemas en un producto que mueve dinero? Para el diagnóstico previo, consulta nuestra guía de auditoría de software vibe-coded. Si también cambia el proveedor, utiliza el plan de 30 días para asumir un proyecto de software.
¿Cuál era la arquitectura inicial?
El producto combinaba un backend Node.js y Express, PostgreSQL, Redis, clientes web y móviles, una interfaz Next.js con rutas API del servidor, varias integraciones de identidad y pagos y rutas de transacción basadas en EVM. Parte del sistema había crecido mediante patrones heterogéneos y parcialmente generados por IA. El problema no era un módulo defectuoso. Existían varias formas rivales de construir servicios, consultar datos, identificar usuarios y procesar eventos externos.
| Límite | Patrón inicial observado | Por qué importaba |
|---|---|---|
| Contratos de aplicación | JavaScript sin tipos, formas amplias e interfaces locales | Las suposiciones incorrectas sobrevivían hasta ejecución. |
| Propiedad de servicios | Estáticos, instancias globales, construcción directa y localización de servicios | La ruta de dependencias viva era difícil de rastrear o simular. |
| Persistencia | SQL crudo, fachadas de modelo y varios patrones de acceso | Transacciones, esquema y propiedad de consultas podían divergir. |
| Identidad | Identificadores de usuario y objeto aportados por el cliente | Autenticar no siempre demostraba acceso al objeto objetivo. |
| Movimiento de dinero | Idempotencia, bloqueos y webhooks desiguales | Reintentos o fallos parciales podían aplicar el efecto financiero dos veces o ninguna. |
| Evidencia de lanzamiento | Cambios enormes y un staging en movimiento | Un hallazgo parecía resuelto mientras otra ruta seguía usando el flujo antiguo. |
Un informe puntual de un escáner no podía gobernar esta superficie. Wavect mantuvo identificadores estables, severidad, ubicación exacta, riesgo, dirección de remediación y criterios de retest entre sucesivas pasadas. Esto coincide con el Secure Software Development Framework de NIST, que trata la revisión de código, el triage y la remediación recomendada como actividades del flujo de desarrollo y no como una ceremonia final.
El orden de remediación en seis capas
El orden fue la decisión arquitectónica principal. Corregir errores de dominio mientras la construcción, la persistencia y la identidad seguían siendo ambiguas habría creado más implementaciones paralelas. Por eso cada capa tuvo evidencia clara de salida.
| Orden | Capa | Evidencia de salida |
|---|---|---|
| 1 | Base de riesgo trazable | IDs estables, mapa de rutas vivas y criterios explícitos de cierre |
| 2 | Fundamento tipado | TypeScript estricto, contexto de petición compartido, DTOs y errores tipados |
| 3 | Límites de dependencias y persistencia | Una raíz de composición, inyección por constructor, repositorios y arranque explícito |
| 4 | Autorización y minimización | Identidad derivada en servidor, comprobación de propiedad y tests de regresión |
| 5 | Integridad financiera y de proveedores | Idempotencia duradera, webhooks verificados, marcadores de conciliación y fallo cerrado |
| 6 | Staging y preparación de lanzamiento | Retest de flujos críticos, evidencia de recuperación y decisión escrita de salida |
1. Convertir informes en un sistema vivo de remediación
Cada elemento conservó el mismo identificador desde el descubrimiento hasta la implementación y el retest. Una nota de cierre debía apuntar al comportamiento realmente modificado, no al título de un pull request. Las pasadas posteriores separaron cuatro estados: corregido, corregido parcialmente, aún presente e implementación ausente. Así, un guard nuevo no contaba como solución si el router de producción todavía invocaba un controlador heredado.
La unidad práctica de revisión era una ruta o recorrido de usuario, no un archivo. Se seguía la petición desde autenticación hasta controlador, servicio, repositorio y efecto externo. Si coexistían varias implementaciones, la primera tarea era identificar cuál atendía tráfico real.
2. Establecer tipos antes de refactorizar el dominio
El backend pasó a TypeScript estricto con entidades, contexto de petición, envoltorios de respuesta, contratos de dominio y errores de aplicación compartidos. Los tipos salieron de los archivos de lógica de negocio y pasaron a módulos con propiedad clara. Los imports relativos profundos fueron sustituidos por aliases de dominio.
Esto no protegía el sistema por sí solo. Hacía visibles las suposiciones para poder revisarlas. Un ID de usuario, un evento de proveedor y un estado de transacción ya no podían adoptar una forma diferente en cada servicio sin que el compilador mostrara la discrepancia.
3. Hacer aburridas la construcción y la persistencia
La construcción de servicios se concentró en una raíz de composición HTTP. El código de dominio recibió dependencias por constructor. Se eliminaron instancias exportadas, métodos de negocio estáticos y resoluciones de contenedor dentro del dominio. Los controladores dejaron de recibir una fuente de datos global y recibieron únicamente el servicio o repositorio necesario.
La persistencia se consolidó tras entidades TypeORM y repositorios de dominio. Se mantuvo SQL controlado donde las consultas complejas lo justificaban. La inicialización de la base de datos pasó a ser responsabilidad explícita del arranque, la creación de esquema en ejecución salió de los flujos financieros y la sincronización automática quedó desactivada. La documentación de migraciones de TypeORM advierte que la sincronización automática suele ser insegura cuando una base de producción ya contiene datos reales y presenta las migraciones como alternativa controlada.
4. Derivar la identidad en el servidor y autorizar cada objeto
La autenticación responde quién hizo la petición. No responde si esa persona puede leer un grupo, cambiar una transacción o inspeccionar registros ajenos. La remediación clasificó operaciones personales, de miembro, administrativas y firmadas por proveedores, y estableció denegación por defecto.
IDs de usuario, teléfonos, wallets y transacciones enviados por el cliente pasaron a ser entradas de búsqueda, no pruebas de autoridad. El contexto autenticado aportó la identidad. Guards compartidos comprobaron identidad propia, membresía, rol y propiedad. Las respuestas se filtraron para entregar solo los campos de identidad y finanzas necesarios para ese recorrido.
Es exactamente la clase de problema que describe OWASP API1:2023 Broken Object Level Authorization: todo endpoint que acepta un identificador debe comprobar que el usuario autenticado puede realizar la acción solicitada sobre ese objeto. Los IDs impredecibles dificultan adivinar, pero no sustituyen la autorización.
5. Diseñar pagos para reintentos, duplicados y finalización parcial
Las APIs que mueven dinero fallan en lugares incómodos. Un proveedor puede reintentar después de que el sistema confirme un saldo pero pierda la respuesta. Dos eventos pueden describir el mismo resultado de negocio. Un estado posterior puede llegar antes que otro anterior. Un callback puede ser auténtico mientras falla la operación de base de datos.
La remediación introdujo registros de idempotencia por usuario, hashes del cuerpo, almacenamiento persistente de respuestas y fallo explícito en producción cuando la idempotencia duradera no estaba disponible. Un marcador separado distinguía entre “estado del evento guardado” y “efecto financiero aplicado”, por lo que un estado duplicado no suprimía trabajo pendiente sobre el saldo.
La verificación del webhook pasó delante del monitoreo y de cualquier mutación. Los callbacks operativos no confiables quedaron desactivados hasta disponer de un emisor y un secreto confiables. La documentación de webhooks de Stripe ilustra bien reglas independientes del proveedor: verificar firmas, esperar reintentos y duplicados, no depender del orden de los eventos y apartar el procesamiento complejo de la ruta de confirmación.
6. Demostrar el producto en staging
La pasada final ejercitó acciones de ciclo de vida, depósitos, retiradas, traspasos de wallet, fallos de proveedores, layouts responsivos y límites de confianza del backend. Registró IDs reproducibles, capturas, comportamientos validados y riesgos residuales. La revisión estática mostraba que existía una firma. Solo un flujo representativo mostraba si la ruta correcta la invocaba y si el usuario podía recuperarse de un fallo.
¿Qué cambió en el snapshot revisado?
| Medición | Resultado | Qué demostraba |
|---|---|---|
| Superficie TypeScript | 275 archivos entre aplicación, scripts y tests | La aplicación ya no se dividía entre implementaciones JavaScript y TypeScript. |
| Clases inyectables | 125 | Las dependencias tenían puntos explícitos de construcción. |
| Puntos de inyección por constructor | 317 | Las dependencias eran visibles para revisión y sustitución. |
| Resolución del contenedor | Limitada a composición de rutas y arranque | El dominio ya no ocultaba dependencias mediante service location. |
| Acceso a base de datos | Sin DataSource de aplicación en controladores ni servicios | La propiedad de persistencia quedó tras repositorios. |
| Métodos de negocio estáticos asíncronos | Ninguno en servicios o controladores | El comportamiento usaba instancias, no estado global. |
Son mediciones estructurales, no una afirmación de que desapareciera todo riesgo. La cobertura automatizada debía crecer, los proveedores externos aún podían fallar, la revisión de smart contracts seguía siendo una puerta separada y los servicios de dominio grandes requerían descomposición selectiva.
Por qué los pull requests pequeños importaron más que un diagrama limpio
Los primeros candidatos agrupaban decenas de hallazgos. Uno trataba 27 elementos en unas 85.000 líneas modificadas. Otro aún contenía alrededor de 50 hallazgos. La implementación asistida por IA producía código más rápido de lo que un humano podía verificar su comportamiento combinado.
El modelo cambió a dos o tres hallazgos relacionados por pull request y cerca de 20 archivos cuando era práctico. Las ramas de fundamento se apilaron según dependencias. Cada rama necesitó plan de implementación, evidencia de tests, revisión y nueva verificación del código después del merge. La rama final se revisó otra vez porque ramas correctas por separado pueden componer un sistema incorrecto.
Esto fue modernización incremental, no una excusa para conservar toda decisión antigua. La descripción del patrón Strangler Fig de Martin Fowler explica cómo el reemplazo gradual hace visibles inversión y resultados mientras el sistema existente sigue atendiendo usuarios. En este caso, las costuras fueron tipos, composición, repositorios, autorización y adaptadores de proveedor, no un reemplazo total de plataforma.
¿Cuándo está listo para lanzar un producto fintech?
- Cierre de hallazgos: cada blocker tenía cambio de código, retest y propietario del riesgo residual.
- Recorridos críticos: autenticación, ciclo de vida, depósito, retirada y recuperación pasaban en un entorno representativo.
- Integridad financiera: eventos duplicados, tardíos, inválidos o parciales tenían resultados deterministas y conciliación.
- Recuperación operativa: despliegue, rollback, monitoreo, incidentes y recuperación de datos tenían evidencia utilizable.
- Aseguramiento externo: riesgos de proveedores y smart contracts fuera del código tenían pruebas o revisión independiente.
No conviertas esta lista en una afirmación de cumplimiento normativo. Las obligaciones dependen del rol, mercado, datos y modelo de pagos. La remediación aporta evidencia técnica para evaluaciones cualificadas de seguridad, legales o regulatorias. No las sustituye.
¿Reparar, sustituir una parte o reconstruir?
| Decisión | Cuándo usarla | Primer paso comercial |
|---|---|---|
| Reparar in situ | Los flujos valiosos son sólidos y los límites pueden hacerse explícitos | Comprar una evaluación acotada de arquitectura y lanzamiento. |
| Sustituir selectivamente | Un límite de identidad, pagos o persistencia concentra el riesgo | Definir esa frontera con criterios de coexistencia, migración y rollback. |
| Reconstruir | El modelo central no representa el producto o coexistir cuesta más que sustituir | Exigir una comparación del riesgo total de migración basada en evidencia. |
El servicio de aseguramiento de calidad de software de Wavect puede convertir una base financiera en un programa trazable de riesgo y remediación. El caso de integración IKB aporta evidencia separada de trabajo en límites sensibles. La guía del prototipo vibe-coded a producción ayuda a definir la decisión de hardening. Si el sistema ya cruza dinero, identidad o callbacks, solicita una revisión independiente de arquitectura fintech.
¿Necesitas un orden de remediación que tu equipo pueda ejecutar sin detener el producto?
Dimensionar una revisión fintechPreguntas sobre remediación de arquitectura fintech
¿Qué es la remediación de arquitectura fintech?
¿Puede un producto fintech vibe-coded llegar a producción?
¿Debe reescribirse un backend fintech desde cero?
¿Qué debe entregar una evaluación de arquitectura fintech?
¿Por qué importa la idempotencia en pagos?
¿Cómo se verifica un arreglo arquitectónico?
Reflexiones finales
La alternativa útil a una reescritura no es parchear sin fin. Es un programa ordenado con una cadena de evidencia desde el hallazgo hasta el cambio, el test de regresión, el comportamiento en staging y la decisión de lanzamiento.
Estabiliza primero lenguaje y persistencia. Haz explícitas dependencias e identidad. Trata los reintentos y callbacks como condiciones normales. Mantén los pull requests lo bastante pequeños para verificarlos. Así el producto existente se vuelve más seguro y fácil de poseer mientras sigue sirviendo al negocio.
