10 KiB
Normalización de la persistencia
Se mantiene Sequelize 6 y MariaDB. El criterio del proyecto es almacenar datos de negocio en columnas y relaciones, sin documentos JSON. Los objetos values del dominio y el JSON del contrato HTTP no implican columnas JSON.
Estado de la normalización
La normalización completa todavía está en curso. La revisión anterior extendió el modelo relacional de activos a recursos, puestos, asistencia y configuraciones de perfiles. La continuación incorpora tickets, intervenciones y plantillas de intervención. No representa el cierre de la auditoría de toda la base.
| Ámbito | Persistencia actual |
|---|---|
| Compañías, personas, departamentos, sedes, usuarios y marcas | Columnas y relaciones existentes |
| Catálogo e inventario de activos | Definiciones, campos tipados, especificaciones y revisiones normalizados previamente |
| Catálogo e inventario de recursos | Definiciones, opciones, secciones, especificaciones congeladas, valores tipados e integración en columnas/tablas |
| Puestos de trabajo | Nombre, estado y referencias en columnas; activos exclusivos/compartidos por puesto y revisión en tablas |
| Asistencia técnica de activos | Destino, VPN, preferencia, estado y notas en columnas actuales e históricas |
| Perfiles de usuario | Nombre, estado, notas y referencias en columnas actuales e históricas |
| Teletrabajo | Estado, periodo, notas y persona en columnas actuales e históricas |
| Aplicaciones, certificados, impresoras y carpetas del perfil | Valores escalares y referencias en columnas actuales e históricas |
| Cuentas y accesos | Pendiente: catálogo discriminado, asignaciones, permisos, grupos y necesidades |
| Correo | Pendiente: proyecciones de buzones, usos y configuraciones, incluido su formato histórico anterior |
| Accesos remotos | Pendiente |
| Procesos y plantillas de procesos | Pendiente: pasos y revisiones |
| Tickets e intervenciones | Columnas actuales e históricas; afectados, pasos, procedimientos congelados y plantillas en tablas relacionadas |
| Sesiones HTTP | Pendiente de evaluar el contrato del almacén de sesiones existente; no se introduce una excepción nueva para JSON |
Las columnas data de fotos y logotipos son datos binarios; no son documentos JSON de negocio.
Recursos
Las tablas existentes resource_definitions, resource_template_fields, resources y resource_revisions mantienen sus identidades. Se añaden:
resource_field_choices: opciones ordenadas de cada campo.resource_template_sections: secciones ordenadas, identificadas por(templateId, id); copiar una plantilla puede conservar los identificadores internos de sus secciones.resource_specification_sections,resource_specification_fieldsyresource_specification_field_choices: definición congelada al crear el recurso.resource_characteristicsyresource_revision_characteristics: valores actuales e históricos con columnas independientes de texto, número, booleano y fecha.
La ausencia de una característica se representa mediante ausencia de fila. Una cadena vacía, 0 y false siguen siendo valores y se conservan. Las fechas se leen como fechas ISO. La especificación congelada no se reemplaza por el estado actual del catálogo.
Los vínculos de integración con buzones y accesos se conservan en columnas con claves foráneas. Eliminar una referencia externa no debe eliminar en cascada el recurso ni sus revisiones. Las proyecciones de compatibilidad de correo/accesos siguen existiendo hasta normalizar sus consumidores.
Puestos, perfiles y configuraciones
workstation_members conserva la composición actual del puesto, con tipo exclusive o shared y posición. workstation_revision_members conserva la composición de cada revisión. workstation_assets sigue siendo la proyección técnica que protege referencias históricas y reserva activos exclusivos de puestos vigentes; no es otra asignación de negocio.
Los perfiles y configuraciones mantienen sus reglas de unicidad, transiciones y cierre. El cambio de persistencia no modifica rutas, formularios, DTO, contadores, permisos, identidad ni comportamiento funcional. Las referencias de las revisiones se conservan mediante claves foráneas.
Tickets, intervenciones y plantillas
Los seis registros principales (tickets, ticket_revisions, interventions, intervention_revisions, intervention_templates, intervention_template_revisions) ya no almacenan values en JSON. Asunto, descripción, estados, prioridad, canal, modalidad, fechas, minutos, diagnóstico, trabajo realizado, resolución, nombre y estado de la plantilla tienen columnas tradicionales según la entidad. plannedDate es una fecha SQL; los instantes ISO conservan su representación exacta en columnas de texto para no perder precisión del historial.
Se añaden diez tablas:
| Información | Actual | Histórica |
|---|---|---|
| Afectados de tickets | ticket_targets |
ticket_revision_targets |
| Afectados de intervenciones | intervention_targets |
intervention_revision_targets |
| Ejecución de pasos | intervention_steps |
intervention_revision_steps |
| Pasos de plantillas | intervention_template_steps |
intervention_template_revision_steps |
| Procedimiento congelado | intervention_procedures |
Procedencia inmutable de la intervención |
| Pasos originales del procedimiento | intervention_procedure_steps |
Copia independiente del catálogo |
Un afectado tiene exactamente una referencia: persona, puesto, activo o recurso, con clave foránea real para cada tipo. Las asociaciones se identifican por propietario y posición; los pasos mantienen su UUID y un orden único dentro de cada propietario. Las claves foráneas restringen eliminar destinos referenciados, mientras que las filas dependientes pertenecen a su ticket, revisión, plantilla o procedimiento y se eliminan en cascada con su propietario.
El procedimiento conserva plantilla, revisión concreta, nombre, descripción, estado original y pasos. La base comprueba que la revisión pertenece a esa plantilla. No se sustituye esa copia por el catálogo vigente. Una intervención sencilla puede no tener procedimiento, pasos, técnico o ticket, según las reglas existentes.
Los repositorios reconstruyen los mismos Value Objects y agregados. Se mantienen las rutas, DTO, UUID, autores, fechas, contadores, reintentos idempotentes, revisión esperada, conflictos concurrentes y reglas para cerrar o reabrir. Los lectores del dashboard consultan las columnas normalizadas tanto del estado actual como de las revisiones.
Migraciones
Las migraciones se ejecutan explícitamente al inicializar los módulos; no se utiliza sync({ alter: true }).
- Se añaden columnas y tablas de destino sin borrar el origen.
- Se valida el documento anterior mediante el esquema de dominio, incluidas las referencias ya persistidas.
- La transferencia de valores se realiza en una transacción.
- Se reconstruye el destino y se compara con el origen antes de retirar las columnas antiguas.
- Se eliminan las columnas JSON transferidas y se refuerzan las restricciones.
El DDL de MariaDB no es transaccional. Una interrupción puede dejar columnas de preparación, pero el origen se conserva hasta verificar la transferencia. Las migraciones de tickets, intervenciones y plantillas permiten reconstruir conjuntamente registros legados y normalizados si el DDL se interrumpe entre columnas. La migración de recursos admite también el corte en el que las revisiones ya se transfirieron y el recurso aún conserva sus columnas de origen. Repetir las migraciones no añade revisiones ni duplica datos.
Las pruebas de integración utilizan exclusivamente metis_desk_test. Comprueban origen inválido, conservación de UUID/historial/orden/valores, referencias incompatibles, idempotencia, arranque vacío y mantenimiento del comportamiento HTTP. Las fixtures SQL que antes escribían JSON se adaptan a las tablas nuevas.
Continuación pendiente
Antes de dar por terminada la normalización hay que implementar y verificar las filas pendientes del inventario, adaptar sus lectores de dashboard/procesos y proyecciones de compatibilidad, y repetir una auditoría del esquema real y del código de persistencia. No basta con cambiar una columna JSON a LONGTEXT ni con renombrar los documentos serializados.
Verificación de la revisión anterior
- Suite completa: 277 pruebas superadas; espaciado: 3 pruebas superadas.
- Typecheck de servidor, activos, compañías y recursos: correcto.
- Build: correcto; mantiene el aviso de tamaño de bundles del frontend.
- Biome y ESLint sobre los ficheros modificados en esta revisión: correctos.
- Arranque y migraciones sobre una base de pruebas vacía: correctos.
- Inicialización de desarrollo: comprobada después de guardar una copia SQL externa al repositorio en
/home/david/backups/metis-desk/.
El typecheck global sigue encontrando el problema anterior de locale en packages/shadcn-ui/src/components/calendar.tsx. El lint/check global conserva errores de otros ficheros (principalmente código de fotos y formato pendiente). No se modifica código vendor ni cambios de interfaz ajenos a esta normalización.
Verificación de tickets e intervenciones
- Suite completa: 277 pruebas superadas, incluida la integración HTTP/MariaDB y la transferencia del formato legado; 3 pruebas de espaciado superadas.
- Typecheck de servidor y compañías, build, Biome y ESLint de todos los ficheros modificados: correctos.
- La prueba de integración reconstruye el origen JSON exclusivamente en
metis_desk_test, rechaza documentos y referencias incoherentes, conserva las instantáneas y contadores, comprueba restricciones de destinos y repite la migración después de simular un corte entre raíz y revisiones. También se ha ejercitado el arranque desde una base de pruebas vacía. - Base de desarrollo migrada e inicialización verificada. Auditoría del esquema: desaparecen las columnas
values/procedurede los seis registros principales y existen las diez tablas relacionadas. Copia previa:/home/david/backups/metis-desk/20261010-133639-tickets-intervenciones.sql. - Los chequeos globales mantienen el error previo de
localeen el calendario de shadcn/ui y errores de lint/formato en otros ficheros. No se modifica el código vendor ni cambios de interfaz realizados simultáneamente.