7.1 KiB
Normalización de activos
Objetivo
La persistencia de activos no utiliza JSON para definiciones, características ni historial. La flexibilidad del catálogo se representa mediante relaciones, no mediante columnas creadas dinámicamente.
Catálogo
asset_definitions contiene los atributos comunes de una definición: identidad, catálogo, compañía opcional, origen, tipo (field, template o relation), nombre, descripción y estado. Sus atributos específicos se almacenan en columnas tipadas:
- un campo usa
fieldTypeyunit; - una relación usa
inverseNameysymmetric; - una plantilla se compone mediante sus tablas relacionadas.
Las opciones de un campo de lista se guardan en asset_field_choices. Las secciones de una plantilla se guardan en asset_template_sections. asset_template_fields une plantilla y campo, e incluye obligatoriedad, posición y sección opcional.
Inventario
assets guarda las propiedades estables: compañía, plantilla, sede, marca, nombre, estado y notas. Las características variables se almacenan en asset_characteristics, una fila por activo y campo, con columnas tipadas para texto, número, fecha o booleano.
Una instantánea de la plantilla se conserva mediante asset_specification_sections, asset_specification_fields y asset_specification_field_choices. De este modo, editar posteriormente el catálogo no altera la interpretación de un activo existente.
asset_revisions conserva las propiedades estables de cada revisión. Sus características se guardan en asset_revision_characteristics, vinculadas a la instantánea del activo.
Migración
La migración crea las tablas normalizadas, lee una única vez los datos JSON existentes, valida su estructura con los schemas de dominio y crea las filas correspondientes dentro de una transacción. Solo elimina las columnas JSON después de una transferencia íntegra. Cualquier dato que no cumpla el contrato detiene el arranque sin descartar el origen.
Relaciones entre activos
asset_relationships guarda sus extremos, tipo, nombre e inverso capturados, simetría, notas y auditoría en columnas. Se conservan sus UUID, clave de relación activa, autor y fechas de creación y retirada. Los nombres capturados no cambian cuando se renombra el tipo en el catálogo.
Integridad y contratos
Las FK compuestas impiden asignar una sección de otra plantilla, usar un campo que no esté en la instantánea del activo o asociar una característica histórica a una revisión de otro activo. Los CHECK limitan los tipos de definición, estados y valores tipados: exactamente una columna de valor debe estar informada y corresponder al tipo declarado. La fecha se almacena como DATE; la lectura la convierte explícitamente a ISO sin depender de la zona horaria del proceso.
sectionsDefined y brandDefined conservan la distinción del contrato entre una propiedad ausente, una lista vacía y una marca nula en datos históricos. Una marca no nula siempre implica brandDefined=1.
El catálogo global, los particulares de compañía, disponibilidad, secciones, orden y campos obligatorios mantienen su comportamiento. Dominio, DTO y HTTP continúan utilizando objetos values y specification; estos objetos se ensamblan desde las tablas normalizadas y no se almacenan como JSON. Se adaptan también las lecturas de dashboard y asistencia técnica.
Ejecución y recuperación
Las migraciones se ejecutan antes de exponer las rutas durante createAssetModule. Primero crean las estructuras necesarias y transfieren datos dentro de transacciones. La lectura desde el destino se compara con el origen antes de retirar sus columnas. Se valida el historial completo, además de los valores actuales. Un dato inválido detiene la transferencia y conserva las columnas originales.
MariaDB confirma las operaciones DDL de forma independiente: la migración no promete rollback del esquema completo. Cada paso comprueba el estado existente y permite repetir un arranque, incluido el corte entre la retirada del JSON de las revisiones y la del activo. No se deben mantener escritores de versiones antiguas funcionando durante una actualización del esquema.
Antes de aplicar cambios a la BD de desarrollo puede ejecutarse bash scripts/backup-assets-normalization.sh. La copia SQL completa se guarda fuera del repositorio en /home/david/.local/state/metis-desk/backups, con permisos restringidos. Contiene datos privados y no debe versionarse.
Alcance
Esta entrega normaliza catálogo de activos, inventario, especificaciones, revisiones y relaciones entre activos. No cambia la persistencia de recursos, puestos de trabajo, asistencia técnica, tickets ni los otros módulos que todavía tienen JSON. Su normalización requiere migraciones específicas posteriores; no se introduce JSON nuevo para guardar valores en el diseño de activos.
Verificación
apps/server/src/asset-normalization.integration.ts, incluido en pnpm --filter @metis/server test, reconstruye el formato anterior únicamente en metis_desk_test y comprueba transferencia, dato inválido sin descarte del origen, idempotencia, recuperación de DDL interrumpido y restricciones de valores. Cubre los cinco tipos, cero, falso, campos omitidos, secciones congeladas, marcas, identidades y revisiones existentes. La integración HTTP habitual verifica catálogo global/local, creación y edición, relaciones, puestos, asistencia y dashboards.
Esquema de relaciones
erDiagram
asset_catalogs ||--o{ asset_definitions : contiene
asset_definitions ||--o{ asset_field_choices : opciones
asset_definitions ||--o{ asset_template_sections : secciones
asset_definitions ||--o{ asset_template_fields : plantilla_y_campo
asset_template_sections o|--o{ asset_template_fields : agrupa
asset_definitions ||--o{ asset_availability : disponibilidad_por_compania
asset_definitions ||--o{ assets : plantilla
asset_brands o|--o{ assets : marca
assets ||--o{ asset_specification_sections : captura
assets ||--|{ asset_specification_fields : captura
asset_specification_sections o|--o{ asset_specification_fields : agrupa
asset_specification_fields ||--o{ asset_specification_field_choices : captura_opciones
asset_specification_fields ||--o{ asset_characteristics : valor_actual
assets ||--|{ asset_revisions : historial
asset_revisions ||--o{ asset_revision_characteristics : valores_historicos
asset_specification_fields ||--o{ asset_revision_characteristics : interpreta
assets ||--o{ asset_relationships : origen_o_destino
asset_definitions ||--o{ asset_relationships : tipo
La tabla asset_template_fields referencia asset_definitions dos veces: plantilla y campo. asset_relationships referencia assets dos veces: origen y destino. Las cardinalidades de valor por campo se interpretan dentro de cada activo o revisión; los campos opcionales pueden no tener fila.
En desarrollo se comprobó la lectura de las tres compañías y la conservación de 52 definiciones, 5 activos, 6 revisiones y 1 relación. La copia previa de esta ejecución se guardó en /home/david/.local/state/metis-desk/backups/pre-normalizacion-activos-20261010-113023.sql.