metis-desk/docs/normalizacion-de-la-persistencia.md

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_fields y resource_specification_field_choices: definición congelada al crear el recurso.
  • resource_characteristics y resource_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 }).

  1. Se añaden columnas y tablas de destino sin borrar el origen.
  2. Se valida el documento anterior mediante el esquema de dominio, incluidas las referencias ya persistidas.
  3. La transferencia de valores se realiza en una transacción.
  4. Se reconstruye el destino y se compara con el origen antes de retirar las columnas antiguas.
  5. 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/procedure de 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 locale en 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.