144 lines
7.6 KiB
Markdown
144 lines
7.6 KiB
Markdown
|
|
# Arquitectura y evolución de sistemas heredados (Legacy)
|
||
|
|
|
||
|
|
> Referencia especializada del skill `rdx-solid`. Consulta [arquitectura.md](arquitectura.md) y el documento del ámbito afectado: [arquitectura-backend.md](arquitectura-backend.md), [arquitectura-frontend.md](arquitectura-frontend.md) o [arquitectura-shared.md](arquitectura-shared.md).
|
||
|
|
|
||
|
|
## 1. Propósito
|
||
|
|
|
||
|
|
Modernizar y mantener sistemas existentes con seguridad, preservando comportamientos y contratos requeridos. «Legacy» no significa necesariamente código de baja calidad: puede ser software estable, valioso y escasamente documentado.
|
||
|
|
|
||
|
|
**Prioridad:** comprender antes de cambiar; verificar antes de declarar el cambio correcto. No imponer patrones o nomenclaturas nuevas de forma masiva.
|
||
|
|
|
||
|
|
## 2. Reconocimiento inicial
|
||
|
|
|
||
|
|
1. Identifica límites del sistema, ejecutables, servicios y consumidores.
|
||
|
|
2. Revisa dependencias, versiones, compilación y despliegue.
|
||
|
|
3. Localiza contratos públicos, formatos de intercambio y persistencia.
|
||
|
|
4. Identifica comportamientos implícitos, trabajos programados y efectos secundarios.
|
||
|
|
5. Comprueba las pruebas existentes y los mecanismos de recuperación.
|
||
|
|
6. Delimita la tarea, sus riesgos y los componentes afectados.
|
||
|
|
|
||
|
|
No presupongas que un comportamiento aparentemente extraño es un error: puede ser un requisito histórico o un contrato con consumidores externos.
|
||
|
|
|
||
|
|
## 3. Caracterización del comportamiento
|
||
|
|
|
||
|
|
Cuando falten especificaciones o pruebas, utiliza ejemplos de entrada y salida, datos anonimizados, consultas, trazas o pruebas de caracterización para describir el comportamiento actual.
|
||
|
|
|
||
|
|
Distingue:
|
||
|
|
|
||
|
|
- **Comportamiento a conservar:** contratos y resultados vigentes necesarios.
|
||
|
|
- **Defecto a corregir:** fallo confirmado respecto al comportamiento esperado.
|
||
|
|
- **Cambio funcional:** nuevo requisito que modifica la semántica.
|
||
|
|
|
||
|
|
No conviertas automáticamente un fallo conocido en una obligación permanente mediante una prueba de caracterización.
|
||
|
|
|
||
|
|
## 4. Refactorización incremental
|
||
|
|
|
||
|
|
- Realiza cambios pequeños y reversibles cuando sea posible.
|
||
|
|
- Separa las correcciones funcionales de las refactorizaciones generales.
|
||
|
|
- Introduce pruebas de regresión en torno a comportamientos críticos cuando sea viable.
|
||
|
|
- No renombres, reformatees o muevas grandes áreas ajenas a la tarea.
|
||
|
|
- Conserva convenciones y límites de módulos existentes salvo necesidad justificada.
|
||
|
|
- Utiliza adaptadores temporales si permiten migrar consumidores gradualmente.
|
||
|
|
- Evita reescrituras completas sin evaluación de costes, riesgos y continuidad del servicio.
|
||
|
|
|
||
|
|
La ausencia de pruebas no prohíbe todo cambio: exige mecanismos de verificación proporcionales, mayor cautela y documentación de incertidumbres.
|
||
|
|
|
||
|
|
## 5. Estrategias de modernización
|
||
|
|
|
||
|
|
| Estrategia | Cuándo considerarla | Riesgo a controlar |
|
||
|
|
|---|---|---|
|
||
|
|
| Refactorización localizada | Corregir estructura sin cambiar contratos | Regresiones involuntarias |
|
||
|
|
| Adaptador / fachada | Aislar un contrato antiguo | Traducción semántica incorrecta |
|
||
|
|
| Capa anticorrupción | Separar modelos de dominio antiguo y nuevo | Complejidad de mapeo |
|
||
|
|
| Strangler Fig | Sustituir capacidades progresivamente | Enrutamiento y coexistencia |
|
||
|
|
| Migración por etapas | Cambiar persistencia o infraestructura | Consistencia y reversión |
|
||
|
|
| Sustitución completa | Sistema realmente inviable de mantener | Alcance, datos y paridad funcional |
|
||
|
|
|
||
|
|
Escoge la opción con menor riesgo y coste total razonable; no asumas que reescribir equivale a mejorar.
|
||
|
|
|
||
|
|
## 6. Capas de adaptación y anticorrupción
|
||
|
|
|
||
|
|
Una capa anticorrupción evita que el nuevo dominio adopte conceptos o errores del modelo antiguo.
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface CustomerDirectory {
|
||
|
|
findCustomer(id: CustomerId): Promise<Customer | null>;
|
||
|
|
}
|
||
|
|
|
||
|
|
class LegacyCustomerAdapter implements CustomerDirectory {
|
||
|
|
constructor(private readonly legacyApi: LegacyCustomerApi) {}
|
||
|
|
|
||
|
|
async findCustomer(id: CustomerId): Promise<Customer | null> {
|
||
|
|
const legacyRecord = await this.legacyApi.readCustomer(id.value);
|
||
|
|
return legacyRecord ? mapLegacyCustomer(legacyRecord) : null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Los tipos y colaboradores son ilustrativos. Verifica diferencias de identificación, nulos, fechas, moneda, errores y codificación: un mapeo estructural no garantiza equivalencia semántica.
|
||
|
|
|
||
|
|
No crees una capa anticorrupción cuando un adaptador sencillo sea suficiente.
|
||
|
|
|
||
|
|
## 7. Migración de datos y persistencia
|
||
|
|
|
||
|
|
- Determina esquemas, claves, restricciones, volumen y dependencias.
|
||
|
|
- Diseña migraciones reproducibles con validaciones de integridad.
|
||
|
|
- Evalúa ventanas de mantenimiento, backups y recuperación.
|
||
|
|
- Considera expansión-contracción para cambios de esquema compatibles.
|
||
|
|
- Si existe doble escritura, define fallos, reconciliación y fuente de verdad; no la adoptes sin necesidad.
|
||
|
|
- Verifica volumen, rendimiento y compatibilidad con versiones desplegadas.
|
||
|
|
- Evita transformaciones destructivas sin un procedimiento probado o adecuado de recuperación.
|
||
|
|
|
||
|
|
## 8. Contratos, compatibilidad y despliegue
|
||
|
|
|
||
|
|
Identifica qué consumidores pueden quedar afectados: clientes externos, informes, procesos por lotes, integraciones, archivos de intercambio, aplicaciones móviles o servicios anteriores.
|
||
|
|
|
||
|
|
- Mantén formatos y significado de campos cuando sea requerido.
|
||
|
|
- Utiliza versionado o adaptadores si los consumidores no pueden migrar a la vez.
|
||
|
|
- Controla coexistencia de versiones y despliegues escalonados.
|
||
|
|
- Define condiciones de reversión cuando el riesgo lo exija.
|
||
|
|
- No elimines endpoints o campos aparentemente no usados sin verificar consumidores externos.
|
||
|
|
|
||
|
|
## 9. Dependencias y tecnologías obsoletas
|
||
|
|
|
||
|
|
- Determina compatibilidad y riesgos de seguridad de runtimes, librerías y drivers.
|
||
|
|
- No actualices todas las dependencias durante una corrección puntual sin necesidad.
|
||
|
|
- Prioriza vulnerabilidades o incompatibilidades relevantes según su impacto.
|
||
|
|
- Realiza actualizaciones por etapas y verifica sus contratos.
|
||
|
|
- Documenta dependencias no sustituibles y mecanismos de mitigación.
|
||
|
|
|
||
|
|
## 10. Pruebas y seguimiento
|
||
|
|
|
||
|
|
- Pruebas de caracterización para comportamiento existente.
|
||
|
|
- Regresión para defectos corregidos.
|
||
|
|
- Integración para adaptadores y persistencia.
|
||
|
|
- Contrato para consumidores externos y coexistencia.
|
||
|
|
- E2E para flujos de negocio críticos.
|
||
|
|
- Comparación controlada de resultados antiguo/nuevo cuando sea viable.
|
||
|
|
|
||
|
|
Evita utilizar exclusivamente métricas de cobertura como garantía de migración. Observa errores, tiempos de respuesta, integridad de datos y resultados funcionales tras un cambio cuando el entorno lo permita.
|
||
|
|
|
||
|
|
## 11. Señales de alerta
|
||
|
|
|
||
|
|
- Reescribir todo antes de conocer el comportamiento existente.
|
||
|
|
- Confundir limpieza estética con mejora arquitectónica necesaria.
|
||
|
|
- Modificar contratos sin inventariar consumidores.
|
||
|
|
- Migrar datos sin validar integridad ni recuperación.
|
||
|
|
- Repartir reglas inconsistentes entre implementación antigua y nueva.
|
||
|
|
- Eliminar lógica aparentemente redundante con efectos históricos desconocidos.
|
||
|
|
- Introducir frameworks nuevos para una corrección localizada.
|
||
|
|
- Declarar paridad funcional sin pruebas o evidencias suficientes.
|
||
|
|
|
||
|
|
## 12. Lista de comprobación
|
||
|
|
|
||
|
|
- [ ] ¿Conozco comportamiento, contratos y consumidores afectados?
|
||
|
|
- [ ] ¿He distinguido defectos de comportamientos históricos a conservar?
|
||
|
|
- [ ] ¿La estrategia de migración es proporcional al riesgo?
|
||
|
|
- [ ] ¿Existe verificación antes y después del cambio?
|
||
|
|
- [ ] ¿La integridad de los datos y la compatibilidad están protegidas?
|
||
|
|
- [ ] ¿Se han previsto reversión o recuperación cuando corresponda?
|
||
|
|
- [ ] ¿He evitado reestructuraciones ajenas a la tarea?
|
||
|
|
- [ ] ¿He comunicado incertidumbres y verificaciones pendientes?
|
||
|
|
|
||
|
|
**Principio final:** modernizar significa reducir el riesgo y mejorar la capacidad de evolución, no reescribir por preferencia tecnológica.
|