metis-desk/docs/architecture/auditoria-sistemas-operativos-activos-y-puestos.md
David 91f1d07e97 Add tests for current operating systems and workplace asset management
- Implement `current-operating-systems-ui.test.py` to validate the functionality of current operating systems in the UI, including tests for source and states, computer changes, responsive design, error handling, and version saving.
- Create `workplace-add-asset.test.py` to test the addition of assets to workstations, covering scenarios such as conflict resolution, responsive design on mobile, error handling during asset creation, and HTTP guards for asset management.
2026-10-25 13:46:06 +01:00

58 KiB
Raw Blame History

Auditoría arquitectónica — Sistemas operativos de activos y puestos de trabajo

Fecha: 25 de octubre de 2026. Estado: investigación y recomendación preliminar; no es una decisión aprobada ni una implementación.

1. Resumen ejecutivo

Metis Desk ya diferencia dos conceptos: el SO de fábrica se documenta mediante características textuales de cada activo; el SO operativo se registra como un recurso de uso os relacionado con el activo mediante el agregado SoftwareInstallation. Este último tiene UUID, estado, versión textual, licencia opcional e historial con actor y fecha. El puesto no posee ese dato: su ficha consulta las instalaciones de su ordenador principal. No hace falta crear una segunda entidad de instalación ni trasladar el SO al puesto [E01–E10, E17–E20].

La implementación puede mantener FreeDOS como información de compra y Windows 11 Pro como instalación, registrar SO distintos sobre un mismo activo y conservar sus revisiones. Sin embargo, no representa explícitamente «SO desconocido / ausencia confirmada / instalado», procedencia del dato, fecha efectiva de instalación, última verificación, arquitectura o instancia de arranque. Las reinstalaciones del mismo producto requieren cerrar la instalación anterior y crear otra, o quedan indistinguibles si se repiten exactamente los valores. La licencia es una referencia documental, sin cómputo de derechos o consumo [E04–E11].

El catálogo global implementado admite aplicaciones, no SO globales. Una plantilla global template:os no convierte sus recursos en productos globales: los recursos SO son particulares de compañía. Los flags de asociación global deben distinguirse de las capacidades del código y de su activación efectiva [E12–E16].

Recomendación preliminar: alternativa D acotada, apoyada en B ya implementada. Conservar origen en Assets, producto en Resources, instalación en Companies y consulta derivada en el puesto; decidir qué carencias justifican extensiones antes de diseñarlas. No se justifica hoy un catálogo paralelo, una relación SO–puesto ni un framework de plugins. Confianza alta en este diagnóstico de código, media en el alcance futuro y sin verificación del esquema/datos de una instalación desplegada.

2. Alcance y metodología

Se inspeccionaron dominio, Application, composición, rutas, schemas, persistencia, migraciones, consumidores React, pruebas y documentación normativa de Assets, Resources y Companies; también la composición del servidor y las decisiones R2.0–R2.6/D08.2 aplicables. Búsquedas con rg incluyeron SO, sistemas operativos, Windows, Linux, macOS, FreeDOS, firmware, Icecat, instalaciones y atributos dinámicos. Una ausencia significa «no localizado en el código activo examinado», no una afirmación sobre datos particulares existentes o sistemas externos.

Base: HEAD 0ceeb9658cc85c913a05bebf96a189424a754cea, con cambios locales previos. Las evidencias describen el árbol de trabajo inspeccionado, no solo HEAD. En particular, el hook compartido de software y el mapa visual del puesto estaban modificados o sin seguimiento al comenzar. No se atribuyen a esta auditoría ni se presume que estén desplegados.

Se comprobaron WSL/bash, directorio, Git, Node v24.20.0 y PNPM 11.25.0, concordantes con package.json. Se consultó rdx-solid y sus referencias de arquitectura y decisiones: responsabilidades según consumidores existentes, comparación explícita y separación de propuesta/evidencia. Se leyeron DESIGN y la matriz de skills frontend como contexto de presentación; no se realizó diseño ni auditoría UX y no se aplicaron criterios de skills visuales. No faltó ninguna skill necesaria para este alcance.

Grados de evidencia: verificado estáticamente = contrato y camino presentes en código; probado en esta auditoría = pruebas indicadas en §16; inferencia = combinación posible de contratos; propuesto = no implementado. Las matrices funcionales son evaluación arquitectónica, no un recorrido E2E de cada caso.

No se accedió a .env, secretos, datos reales ni bases existentes. No se arrancaron servicios, ejecutaron migraciones, prepararon fixtures SQL ni realizaron escrituras funcionales. archive/ y vendor permanecieron intactos. No se ejecutó Playwright: se describe presentación por lectura de componentes y pruebas de render, sin afirmar funcionamiento visual, teclado, foco o responsive en navegador.

3. Estado actual verificado e inventario

3.1. Activos, tipos y datos de origen

AssetCatalog contiene definiciones de campos, plantillas y relaciones. La tipología se expresa por templateId y especificación capturada en cada Asset; no hay una unión cerrada de clases físicas ni una entidad Computer separada. Las plantillas de serie incluyen portátil, PC de sobremesa, monitor, impresora, router, firewall, switch, punto de acceso, NAS, servidor, smartphone y SAI. Las propias pueden ampliarlas [E01, E02].

Portátil y sobremesa tienen field:factory_os; servidor contiene tanto field:factory_preloaded_os como field:factory_os, con etiquetas próximas. Esto es una duplicidad semántica real de las definiciones de serie, aunque no demuestra que haya valores contradictorios en una BD. No hay plantillas de serie específicas de VM, mini-PC o estación de trabajo de altas prestaciones; pueden documentarse con plantillas propias, sin semántica especializada verificada. NAS, móviles y dispositivos de infraestructura también pueden ejecutar SO/firmware: la política de instalación no restringe por plantilla de activo, sino por pertenencia y condición no retirado [E01, E06].

Marca tiene referencia opcional brandId; modelo, serie, MPN/código de producto, procesador, memoria, almacenamiento, compra, proveedor y garantía se resuelven con características de plantilla. No se localizó un catálogo de productos físicos o SKU que determine automáticamente la configuración de cada unidad. La plantilla define campos, no el SO de todos los equipos de un modelo. Las descripciones de seed son ejemplos/ayuda, no un inventario de modelos ni valores precargados obligatorios [E01–E03].

El formulario de activo y su controlador gestionan características por UUID de campo; las fichas e historial muestran valores y especificación. AssetUseCases, mapAssetInput y SequelizeAssetRepository coordinan validación, cambios e historial. Endpoints: GET/POST /api/assets/:companyId, POST /api/assets/:companyId/:id/update y /delete; catálogo en /api/asset-catalog/:scope y puestos bajo /api/assets/:companyId/workstations… [E21, E27].

3.2. Registro de los elementos relacionados con SO

Elemento real Persistencia y naturaleza Propietario / cardinalidad API y frontend Validación / historial
field:factory_os Definición en asset_definitions; valor de unidad en asset_characteristics.textValue, identificado por assetId,fieldId Assets / un valor por campo y activo; no relación a software API de activos; AssetFields, AssetCharacteristicControl, AssetDetailContent, AssetHistory Campo textual opcional de seed; validación por especificación; revisiones del activo [E01–E03, E21]
field:factory_preloaded_os Mismo mecanismo; UUID de campo diferente Assets / otro valor independiente en servidor Mismos consumidores No hay regla de igualdad con factory_os; historial genérico [E01–E03]
Recurso de plantilla template:os o usage: os resources, resource_characteristics, definiciones/especificación relacionales Resources / producto particular; un recurso puede ser referenciado por N instalaciones API de recursos y candidatos/resolución; editor de recursos y alta rápida de SO UUID, pertenencia, actividad y clasificación por plantilla; ResourceRevision [E12–E15, E28]
SoftwareInstallation software_installations: id,companyId,assetId,resourceId,licenseResourceId,version,state,notes,currentKey Companies / N instalaciones por activo y por recurso; pareja activo/recurso fija; máximo una abierta por pareja GET/POST /api/software-installations/:companyId, POST /:companyId/:id/update, /delete; SoftwareInstallationsPanel, formulario e historial Zod estricto, políticas de referencias/disponibilidad, transición, UUID, transacción y clave única [E04–E10]
SoftwareInstallationRevision software_installation_revisions: id,configurationId,position,actorId,recordedAt más snapshot de campos de instalación Companies / 1:N desde instalación Se devuelve dentro de history, sin endpoint de revisión independiente; SoftwareHistoryDialog UUID propio; orden único; mapper valida cronología, destino y última revisión [E07–E10]
licenseResourceId UUID nullable con FK a resources, en raíz y revisiones Instalación / 0..1 licencia actual; una licencia puede ser referenciada por N instalaciones Selector y enlaces de instalación/historial Uso license, misma compañía, activa/no caducada en nuevas dependencias; no calcula derechos [E06–E08, E13]
computerAssetId / assetIds workstations, workstation_assets, revisiones y miembros históricos Assets / 0..1 principal, hasta 200 miembros; máximo un puesto activo por activo API de puestos e inventario; ficha del puesto Principal debe ser miembro, pertenencia y exclusividad; historial de composición [E17, E18]
ApplicationConfiguration application_configurations y revisiones; profileId,resourceId,delivery,version,state,notes Companies / aplicación por perfil, no instalación del activo API de configuraciones y bloque de aplicaciones del perfil delivery: installed/web; recurso application, no os; historial y destino fijo [E19]

Las tablas/columnas anteriores son las declaradas por las migraciones y writers inspeccionados. Su existencia efectiva en una BD desplegada no se comprobó. Los atributos viajan como objetos en HTTP; en el esquema relacional actual se guardan en columnas tipadas, no en JSON [E02, E03, E07, E28].

4. Mapa de entidades y relaciones — modelo verificado

erDiagram
    COMPANY ||--o{ ASSET : posee
    ASSET_TEMPLATE ||--o{ ASSET : especifica
    ASSET ||--o{ ASSET_CHARACTERISTIC : contiene
    ASSET ||--|{ ASSET_REVISION : registra
    COMPANY ||--o{ WORKSTATION : organiza
    WORKSTATION ||--o{ WORKSTATION_MEMBER : agrupa
    ASSET ||--o{ WORKSTATION_MEMBER : referencia
    ASSET o|--o{ WORKSTATION : principal
    ASSET ||--o{ SOFTWARE_INSTALLATION : destino
    RESOURCE ||--o{ SOFTWARE_INSTALLATION : producto
    RESOURCE o|--o{ SOFTWARE_INSTALLATION : licencia_opcional
    SOFTWARE_INSTALLATION ||--|{ SOFTWARE_INSTALLATION_REVISION : registra
    PERSON ||--o{ WORK_PROFILE : utiliza
    ASSET ||--o{ WORK_PROFILE : aloja
    WORK_PROFILE ||--o{ APPLICATION_CONFIGURATION : configura
    RESOURCE ||--o{ APPLICATION_CONFIGURATION : aplicacion

RESOURCE tiene papeles diferentes de producto y licencia; el diagrama no permite intercambiarlos libremente. Omite especificaciones/revisiones secundarias para legibilidad. Un SO particular pertenece a una compañía; una aplicación global tiene scope: global, companyId: null, mientras sus instalaciones/configuraciones conservan compañía concreta. No hay FK desde instalación a puesto ni a perfil. La exclusividad de miembros activos, el tipo de recurso y el ámbito no se deducen solo de las líneas del diagrama: se aplican por políticas y restricciones [E06–E08, E12–E19].

5. Flujo actual de los datos

  1. Origen: catálogo de activos → plantilla/especificación → formulario de unidad → características y revisión de Asset. factory_os no se sincroniza con instalaciones.
  2. Producto: catálogo de definiciones de Resources → recurso SO particular con nombre/proveedor/edición/descripción. No existe entidad de versión de software: la versión operativa va en la instalación.
  3. Instalación: formulario → softwareApi con contrato de recursos 2 → ruta autenticada y schemas estrictos → SoftwareInstallationUseCases.save → mapper/policies y agregado → repositorio transaccional. El actor procede de la sesión.
  4. Persistencia: sesión pública del resolver Resources ligada a la transacción → coordinación de catálogo/compañía → inventarios públicos de Assets y Resources → validación por propósito/disponibilidad → raíz y revisiones en la misma transacción. currentKey único protege la pareja abierta; una actualización semánticamente igual no añade revisión.
  5. Consulta: GET devuelve todas las instalaciones de compañía y su historial; la ficha filtra por assetId === computerAssetId. Los nombres/tipos se obtienen del inventario local o resolver de referencias; el producto global no exige cargar un ResourceDTO particular. La UI invalida las query keys afectadas tras guardar [E04–E10, E14–E16, E20, E22].

Autenticación y pertenencia operativa son garantías diferentes. El espacio de soporte usa sesiones válidas y contexto de compañía compartido; no hay que presentar el rechazo de un recurso de B dentro de A como una ACL operador–compañía. Las FKs simples de instalación protegen existencia, no por sí solas la igualdad de compañía ni elegibilidad; estas se comprueban en aplicación/lectores transaccionales. Origen/CSRF están en el middleware común de escritura y sus negativos figuran en integración; no se ejecutaron aquí [E08, E10, E14, E23].

6. SO de fábrica frente a SO instalado

6.1. Información original

  1. ¿Campo original? Sí: factory_os y el segundo campo de servidor factory_preloaded_os.
  2. ¿Dónde? En características de cada unidad, según plantilla. No en una entidad producto físico ni en SoftwareInstallation.
  3. ¿Procedencia fabricante/manual? No hay procedencia por característica, evidencia de fabricante ni estado de confirmación. Actor/fecha de revisión acreditan registro en Metis, no quién certificó la especificación.
  4. ¿Sustitución? Guardar una instalación nueva no modifica características del activo. El operador debe cerrar/actualizar instalaciones según corresponda.
  5. ¿Preservación? Las revisiones conservan valores/especificación. El campo original sigue siendo editable: no es un registro inmutable de recepción. Su independencia de la instalación evita sobrescritura automática, no errores manuales.
  6. ¿Sin SO de fábrica? Puede escribirse «Sin SO precargado», que ya aparece como ejemplo de servidor. Eso es texto, sin estado normalizado de ausencia. Campo omitido y ausencia confirmada no se distinguen estructuralmente [E01–E03, E21].

No se localizaron integración Icecat, importador funcional de activos o sincronización automática de especificaciones comerciales en el área inspeccionada. No se atribuye a una plantilla la configuración de todas las variantes Lenovo ThinkPad T14. Modelo/MPN y SO de la unidad deben contrastarse individualmente.

6.2. Configuración operativa

Dato solicitado Capacidad verificada Límite
Producto SO resourceId a recurso os Particular; no SO global elegible
Edición Característica software_edition del recurso SO Texto de producto, sin entidad de edición ni snapshot de su revisión en instalación
Versión/build version, nullable, trim y máximo 100 caracteres Un único texto: no distingue versión/build ni valida semántica del fabricante
Arquitectura Sin campo específico de instalación Nombre/notas no equivalen a arquitectura estructurada
Fecha de instalación Sin fecha efectiva recordedAt fecha el registro/revisión, no demuestra cuándo se instaló
Estado pending/configured/removal_pending/removed/never_configured Ciclo documental; no estado global de conocimiento de SO del equipo
Origen / última verificación Sin campos específicos Actor y needsReview no sustituyen procedencia ni inspección técnica
SO anterior Revisiones o instalaciones cerradas Cambiar de producto requiere cerrar una raíz y crear otra; no vínculo de sucesión
Reinstalación Nuevo registro tras cerrar pareja No operación ni evento específico de reinstalación
Varios SO Varias parejas activo/recurso abiertas No varias instancias del mismo recurso; sin partición, disco, arranque preferente o virtualización

configured documenta una configuración declarada; no acredita descubrimiento automático. pending no debe reinterpretarse como «desconocido». never_configured cierra una intención concreta, no confirma que el equipo entero carezca de SO. Cero instalaciones tampoco permite inferir ausencia: puede faltar inventariado [E04–E09].

7. Software y licencias

Resources representa productos mediante recursos UUID y plantillas. El SO dispone de nombre de recurso y campos de proveedor, edición y descripción. Las aplicaciones de serie tienen proveedor, URL y descripción. No se encontraron entidades normalizadas de familia, fabricante de software, edición o versión; números y ediciones también pueden formar parte del nombre. La identidad UUID no demuestra que dos productos descritos de forma parecida sean equivalentes [E12–E15].

El catálogo de aplicaciones globales comparte producto entre compañías, conservando instalaciones/configuraciones particulares. El SO y la licencia globales quedan excluidos por elegibilidad real de template:application. R2.5 ya incorpora aplicaciones globales a perfiles: las limitaciones de perfil descritas como futuras en R2.4 son históricas y no el estado vigente. Los gates de catálogo, candidatos, software y perfil son independientes; no se leyeron variables locales ni se dedujo su activación [E12–E16, E19, E24].

La licencia es otro Resource particular, con producto licenciado, edición/plan, proveedor, modalidad, métrica, cantidad, contrato, caducidad, renovación y autorrenovación. Las opciones de serie de modalidad son Suscripción/Perpetua/OEM/Otra; volumen no tiene opción propia, aunque puede documentarse como Otra/notas o mediante configuración del catálogo. La métrica admite usuario/dispositivo/servidor/concurrente/corporativa/otro. Esto es documentación contractual; no un motor de cumplimiento [E13].

Una instalación admite una licencia actual nullable y revisiones con la licencia anterior. Se valida tipo, pertenencia, actividad y vigencia inclusiva UTC al crear/cambiar dependencias. Se permiten notas, desvinculación y retirada cuando referencias se vuelven no disponibles. needsReview indica falta de disponibilidad o retirada pendiente; no un inventario verificado. No hay reserva/consumo de plazas, validación producto–licencia, asignación efectiva por usuario/cuenta ni prueba de cobertura OEM. La misma licencia puede ser referenciada varias veces sin comprobar capacidad [E06–E08].

El historial guarda UUID del producto/licencia y versión/estado/notas de instalación; no enlaza una revisión inmutable del producto o del contrato. Cambiar el nombre/edición del recurso puede modificar cómo se interpreta una revisión de instalación al resolver su nombre actual. ResourceRevision aporta historia separada, sin reconstrucción temporal automática verificada. El borrado de instalación elimina también sus revisiones; no es auditoría inmutable ni archivo de desinstalación [E08, E09, E22].

8. Puestos y perfiles

Sí, Metis puede mostrar el SO del principal sin duplicarlo en el puesto; ya utiliza ese recorrido. Assets es dueño de Workstation, su composición y computerAssetId; Companies es dueño de WorkProfile, instalaciones y configuraciones. La relación principal exige pertenencia al conjunto, pero el mapper de puesto no verifica una categoría cerrada de «ordenador»: es una designación funcional del miembro [E17, E18].

El puesto puede agrupar varios activos; solo tiene un principal. Los demás se presentan como equipamiento, sin un rol estructurado de «ordenador adicional». Además, la guía de puestos establece que dos ordenadores se organizan en dos puestos: aunque el contrato genérico de miembros no impida elegir otro equipo informático como miembro, eso no acredita soporte funcional de varios ordenadores en un puesto. El software mostrado y el mapa local del puesto filtran exclusivamente por principal. El modelo de instalaciones acepta SO de los otros activos por API, pero la ficha no agrega sus SO. Tampoco existe un puesto propietario de una configuración SO independiente [E06, E20].

Los perfiles pertenecen a persona/dispositivo y pueden tener cuenta opcional. Alta/reactivación requieren dispositivo no retirado que sea principal de un puesto activo. La pareja persona/dispositivo es fija. Sustituir principal no mueve perfiles o instalaciones; el anterior conserva registros, y el puesto consulta los del nuevo. Desvincular un activo tampoco borra su software. La baja de puesto mediante decommission vacía responsable, principal y miembros actuales y conserva revisión previa: no confundirlo con un cambio de flag que conserva composición [E17–E20].

Las ApplicationConfiguration de perfil distinguen uso web/instalado y su ciclo. No son un catálogo de aplicaciones autorizadas, una política de compatibilidad de SO ni prueba de instalación en todo el dispositivo. No se generan a partir de SoftwareInstallation ni a la inversa. Puede haber dos registros sobre el mismo producto con ámbitos diferentes; no hay reconciliación automática, aunque eso no constituye por sí mismo una duplicidad de dominio [E19].

Dependencias para mostrar SO: inventario del activo, principal válido, consulta de instalaciones de compañía, catálogo/recursos para nombres y clasificación, y resolución pública para aplicaciones globales. Un fallo o referencia sin resolver no autoriza inferir «sin SO». La lectura actual carga instalaciones e historial de toda la compañía y filtra en cliente; el coste puede crecer con el volumen. No se midió rendimiento [E08, E20, E22].

9. Matriz de escenarios funcionales

«SOPORTADO» significa que el núcleo del caso dispone de contrato explícito; no certifica E2E ni todas las extensiones deseables. «PARCIALMENTE SOPORTADO» distingue un registro útil de la falta de semántica específica. No se asigna NO VERIFICADO a capacidades inspeccionadas solo por no haberlas probado en navegador; las limitaciones de ejecución aplican a toda la matriz.

Convenciones: O = características de origen; I = instalación/revisiones; Q = GET de instalaciones de compañía y filtro por activo; V = panel de software del principal; H = historial de instalación, borrable con su raíz. Las evidencias remiten al índice de §15.

ID y escenario Clasificación Almacenamiento / consulta / visualización Historial, integridad y límites Evidencia
SO-01 FreeDOS → Windows 11 Pro SOPORTADO O=FreeDOS; Resource SO=Windows 11 Pro; I=configured; Q/V H de Windows y revisiones de O independientes; no hay obligación de sustituir O ni relación de equivalencia E01–E10, E20
SO-02 Windows 11 Pro original conservado SOPORTADO O=Windows; I debe registrarse explícitamente con Resource Windows; Q/V No deduce instalación desde fábrica; FKs/policies e H. Coincidencia de textos no vincula ambos conceptos E01–E10
SO-03 Sin SO de fábrica → Ubuntu PARCIALMENTE SOPORTADO O admite texto de ausencia; Ubuntu en I; Q/V Instalación e H explícitos; ausencia original solo textual, sin estado normalizado E01, E04–E09
SO-04 Windows 10 Pro → Windows 11 Pro PARCIALMENTE SOPORTADO Si mismo producto: cambio de version; si productos distintos: cerrar I de 10 y crear I de 11; Q/V y cerradas H conserva cambios, pero no hay upgrade/sucesión ni atomicidad entre dos comandos; no cierra otro SO automáticamente E04–E10, E22
SO-05 Reinstalación limpia Windows 11 Pro PARCIALMENTE SOPORTADO Cerrar configurado→retirada pendiente→retirado, crear nueva I de la misma pareja; Q y cerradas Nueva UUID e H; sin operación específica, fecha efectiva o enlace de reinstalación. Repetir valores es no-op E04, E05, E08, E09
SO-06 Arranque dual Windows/Linux PARCIALMENTE SOPORTADO Dos recursos SO y dos I en el activo; Q/V admite varias filas La cardinalidad lo permite; no registra particiones/arranque ni sincroniza estados. Dos instancias del mismo Resource quedan bloqueadas E04–E09, E22
SO-07 Servidor físico Windows Server PARCIALMENTE SOPORTADO Plantilla servidor; Resource SO e I válidos por API; Q H/FKs genéricos; no exige puesto. Sin panel específico de software en ficha de activo localizado; V solo si es principal E01, E06, E08, E20, E21
SO-08 Hipervisor y varias VM PARCIALMENTE SOPORTADO Hipervisor como software; VM como activos de plantilla propia; relación genérica hosted; Q por activo Referencias e historial genéricos; no modelo de hipervisor/guest, topología validada ni vista de SO de todos los guests E01, E06, E25
SO-09 VM con SO propio PARCIALMENTE SOPORTADO Activo propio y Resource/I por API; Q; V si se designa principal Sin plantilla VM de serie o identidad del inventario externo; no se impide por tipo de activo E01, E06–E09, E17
SO-10 Cambio de ordenador principal SOPORTADO Cambia computerAssetId; Q/V pasan al nuevo; I del anterior no se reasigna Revisiones del puesto conservan composición; destinos de I/perfil fijos; no transfiere software, cuentas o licencias E05, E17–E20
SO-11 Activo deja de estar en un puesto SOPORTADO Se quita de miembros y se ajusta principal si corresponde; I sigue en activo; Q Historia del puesto y H independientes; V deja de mostrarlo. Principal no puede quedar fuera de miembros E06, E17, E18, E20
SO-12 SO desconocido NO SOPORTADO Cero I o campo omitido no tienen significado inequívoco; V vacío No estado explícito de conocimiento; no permite distinguir ausencia confirmada E01, E04, E20
SO-13 Equipo entregado sin SO PARCIALMENTE SOPORTADO O permite anotarlo; no crear Resource ficticio «sin SO»; V sin instalaciones No estructura que confirme ausencia actual ni quién/cuándo la verificó E01, E04–E09
SO-14 Cambio de edición/versión PARCIALMENTE SOPORTADO Versión en I; edición en Resource; otra edición/producto puede exigir nueva pareja; Q/V Versión conserva H. Editar edición del producto afecta consumidores; no evento específico ni snapshot de edición por I E04, E05, E09, E13, E22
SO-15 OEM, volumen o suscripción PARCIALMENTE SOPORTADO Resource licencia + licenseResourceId; selector/enlace e H OEM/suscripción tipadas; volumen sin opción propia. Sin derechos, cobertura/capacidad o asociación contractual comprobada E06–E09, E13, E22
SO-16 Instalado aún no inventariado/verificado NO SOPORTADO Sin I, Metis no conoce la instalación; pending no significa no verificado No descubrimiento ni estado de observación. Puede registrarse declarado como configured, sin acreditar verificación E04, E06, E08

En SO-08/09 el soporte parcial procede de contratos genéricos: no se ejecutó un flujo de virtualización. En SO-06 se verificó la regla de unicidad por pareja, no un caso E2E dual boot. Las relaciones hosted no prueban virtualización ni evitan por sí mismas configuraciones incoherentes de hipervisores.

10. Deficiencias y riesgos

Prioridad Hallazgo Consecuencia / condición
Alta Ausencia de conocimiento explícito a nivel activo Un vacío puede interpretarse erróneamente como «sin SO»; distinguir carga/error/vacío de estado técnico
Alta Ciclo de configuración usado como evidencia operativa configured, fecha de revisión o needsReview no prueban instalación ni inspección
Alta Dos campos de fábrica en servidor Posibles valores divergentes; inspeccionar datos y significado antes de unificar, sin migración automática
Media Reinstalación/upgrade sin identidad de sucesión ni fecha efectiva No reconstruye episodios automáticamente; dos comandos no son una operación atómica
Media Máximo una pareja abierta activo/recurso Impide inventariar dos instancias del mismo producto sobre el mismo activo sin duplicar recursos
Media Historial borrable y nombres/ediciones resueltos actuales No es trazabilidad forense ni snapshot completo de producto/licencia
Media SO global excluido Mismo producto SO puede repetirse entre compañías; no reutilizar global applications con una clasificación falsa
Media Licencia documental No acredita cumplimiento; una FK válida no garantiza compatibilidad ni disponibilidad contractual
Media Software visible solo para el principal Servidores sin puesto y equipos adicionales carecen de acceso equivalente localizado en ficha de activo
Media Consulta por compañía con historial completo Coste creciente posible; estudiar paginación/filtro servidor con evidencia, sin afirmación de lentitud
Baja No hay catálogo de SKU ni procedencia por campo Especificación comercial y unidad pueden confundirse si se automatiza en el futuro

Conflictos documentales: docs/software-del-ordenador.md describe correctamente la separación, instalaciones, licencias y dual boot documental. Su expresión «plantilla global» se refiere a la definición, no a un SO Resource global. R2.4 relata restricciones de perfiles que R2.5 ya amplió. docs/puestos-de-trabajo.md coincide con la baja mediante decommission, que vacía la composición; en cambio, la frase de docs/software-del-ordenador.md sobre perfiles que consultan la misma instalación no significa una relación instalación–perfil. La guía de puestos prescribe dos puestos para dos ordenadores, mientras que el contrato genérico de miembros no restringe su categoría: no se debe elevar esa permisividad a soporte funcional de múltiples ordenadores. Las afirmaciones históricas de pruebas/build/errores en R2.4 no son resultados de esta auditoría. D08.2 propone adopción/sucesión con nuevo terminal, pero declara que no está ratificada: superseded no existe en el ciclo actual [E04, E17, E24, E26].

11. Comparación de alternativas

A = SO actual directamente en activo; B = producto Resource + instalación en activo; C = SO propiedad del puesto; D = origen e instalación separados y puesto derivado, con requisitos de perfil opcionales.

Escala cualitativa: favorable, condicionada, desfavorable. Las valoraciones son inferencias arquitectónicas basadas en el inventario anterior, no métricas medidas. Se compara A como solución directa, B reutilizando la existente y D como evolución acotada; enriquecer A hasta tener instalaciones terminaría aproximándola a B.

Criterio A — Atributo B — Instalación C — Puesto D — Híbrido acotado
1. Coherencia de dominio Condicionada: simple para un SO declarado Favorable: configuración pertenece al activo Desfavorable: depende de una asignación mutable Favorable: distingue hechos de origen, operación y vista
2. Normalización Desfavorable si texto; condicionada con FK Favorable: producto UUID e instalación separados Condicionada en tablas; duplica hechos del equipo Favorable si evita copiar el SO a puesto/perfil
3. Catálogo existente Condicionada: habría que relacionarlo Favorable: ya consume Resource os Condicionada: otro consumidor para el mismo dato Favorable: conserva Resources como producto
4. Modularidad/extensiones Condicionada: nueva dependencia de Assets Favorable: puertos existentes Condicionada: Assets consultaría producto para escritura Favorable con composición actual, sin plugins nuevos
5. Servidores y VM Favorable por activo, sin semántica VM Favorable por API; presentación pendiente Desfavorable para equipos sin puesto Favorable por activo; VM especializada solo si se requiere
6. Varios SO Desfavorable en atributo escalar Condicionada: distintos productos sí, misma pareja no Desfavorable: ambiguo con varios ordenadores Condicionada a reglas de instancia, no resolverlas con arrays de texto
7. Historial/auditoría Condicionada: revisiones de activo, sin episodios Condicionada: revisiones existentes, borrado permitido Condicionada: historia del puesto confunde equipo y software Favorable en separación; retención/episodios aún pendientes
8. Licencias Desfavorable: exige relación paralela Condicionada: vínculo actual, sin derechos Desfavorable: vínculo cambia con equipo Condicionada: reutiliza vínculo sin prometer compliance
9. Inventario automático Condicionada: falta procedencia/verificación Condicionada: buen destino, faltan identidad externa y reconciliación Desfavorable: dispositivos sin puesto quedan fuera Favorable como dirección; necesita contrato de observación aprobado
10. Frontend Condicionada: editor fácil, duplica bloque actual Favorable: panel/editor/historial reutilizables Condicionada: formulario adicional y riesgo al reemplazar Favorable: extender vistas por activo, conservar puesto derivado
11. Backend/API Desfavorable: segunda fuente respecto a I Favorable: agregado/servicios existentes Desfavorable: nuevas escrituras y sincronización Condicionada: evolución pequeña si se aprueban datos faltantes
12. Migración Desfavorable: decidir cómo reducir N I a un valor Favorable: sin migración para el núcleo actual Desfavorable: activos sin puesto y múltiples asignaciones Condicionada: sin mover I; origen duplicado y estados requieren revisión
13. Duplicidad/divergencia Desfavorable si conserva I además del atributo Favorable: una fuente operativa; vigilar productos repetidos Desfavorable: sustituciones y reasignaciones Favorable: fuentes distintas por significado explícito
14. Mantenimiento Condicionada: baja solo si se elimina funcionalidad existente Favorable: coste incremental menor Desfavorable: sincronización permanente Condicionada: favorable si se limita a necesidades aprobadas

Fundamento: A/C empeoran la unicidad del hecho operativo y pierden capacidades de I [E04–E10]. B encaja con módulos y licencias existentes [E06–E16]. D refleja gran parte de lo ya implementado y conserva sus límites reales [E01, E17–E20]. No hay justificación actual para modelar requisitos de SO del perfil: sería una capacidad nueva, distinta de ApplicationConfiguration.

12. Impacto en arquitectura modular y extensibilidad

Propiedad que conviene conservar: Assets posee unidad física/lógica, características de origen y composición del puesto; Resources posee producto SO/aplicación y recurso licencia; Companies posee la instalación y su ciclo. Que el agregado esté en Companies no convierte al puesto en dueño del SO. Moverlo de módulo no es requisito de esta auditoría.

El servidor ya compone servicios públicos: assets.services.inventoryForTransaction, resources.services.inventoryForTransaction y resources.services.applicationReferences; Companies los recibe por inyección explícita. El repositorio de instalaciones accede a sus tablas y consulta activos/recursos mediante esas superficies. La recomendación no autoriza leer tablas ajenas desde nuevos servicios ni importar repositorios/ORM de otros módulos [E08, E14, E16].

Para mostrar software en una ficha de activo, reutilizar el consumidor web/panel existente o publicar una lectura de instalaciones con consumidor real; el servidor puede componer la proyección. Evitar que Assets importe internals de Companies y que Companies importe internals de Assets. Una lectura filtrada por activo sería una evolución contractual a evaluar por volumen, no un endpoint que ya exista. Tipos comunes/DTO Zod y servicios públicos deben exponer solo datos necesarios.

No hay un framework dinámico de plugins implementado que haya que extender. La normativa exige composition roots y prohíbe copiar el registro dinámico del ERP. Existe una infraestructura explícita de lectura de relaciones tipadas con proveedores reales de otras relaciones; no sustituye comandos/agregados ni registra automáticamente SoftwareInstallation. No se necesita un proveedor SO nuevo para resolver este caso. Valorar su reutilización solo si aparece un consumidor transversal concreto [E16, E25].

Para inventario automático harían falta decisiones sobre identificación de unidad/instancia, origen, fecha de observación, confianza, ausencia confirmada, concurrencia, idempotencia y conflicto manual/agente. No convertir una observación ausente o un escaneo fallido en retirada. Esos contratos pertenecen a los propietarios y deben entrar por servicios públicos, no por DML externo o escritura de características con nombres supuestos.

Habilitar SO global exigiría ampliar elegibilidad, proyecciones, seguridad, administración, selectores, gates y pruebas en Resources y consumidores. La infraestructura global existente es reutilizable, pero el permiso actual template:application no lo autoriza. Tampoco debe reciclarse D08 como migración de SO: su adopción de aplicaciones está pendiente y no ratificada [E12–E16, E26].

13. Recomendación preliminar y condiciones — modelo propuesto

Preferencia: D acotada sobre B, manteniendo los agregados existentes. No hay que «introducir instalaciones» porque ya existen. Primero fijar semántica de ausencia, verificación y reinstalación; solo después valorar contratos y columnas relacionales adicionales.

flowchart LR
    Origin["Assets: origen de la unidad\ncaracterísticas de fábrica existentes"] --> Asset["Assets: activo UUID"]
    Product["Resources: producto SO\nrecurso os existente"] --> Install["Companies: SoftwareInstallation\nexistente, extensión por decidir"]
    License["Resources: licencia particular\nvínculo documental existente"] -.-> Install
    Asset --> Install
    Knowledge["Propuesto: conocimiento del SO\ndesconocido / ausencia confirmada / presente\npropietario y reglas por decidir"] -.-> Asset
    Observation["Propuesto si se aprueba:\nprocedencia y verificación"] -.-> Install
    Station["Assets: puesto\nprincipal y miembros existentes"] --> View["Vista derivada por activo\nprincipal existente; otros equipos propuestos"]
    Install --> View
    Requirement["Opcional, sin requisito confirmado:\nSO requerido por perfil"] -.-> View

Modelo propuesto: cajas marcadas como propuestas y flechas discontinuas no afirman APIs/tablas instaladas; incluso la extensión de conocimiento necesita decidir su propietario. Las cajas existentes documentan reutilización. El requisito de perfil se muestra como opción diferida, sin añadir entidad ni inferir compatibilidad desde aplicaciones configuradas.

Condiciones para mantener esta recomendación:

  • Acordar una definición operativa de «instalado» y de «verificado»; no reinterpretar estados actuales silenciosamente.
  • Resolver si basta una instalación por producto o se necesita identidad de instancia, disco/VM/arranque.
  • Mantener información original y operativa independientes. Revisar los dos campos de fábrica de servidor con datos de prueba antes de cualquier consolidación.
  • Preservar UUID/revisiones existentes, valores desconocidos y NULL de licencias. No inventar instalaciones desde características de fábrica o configuraciones de perfil.
  • No introducir procedencia, compatibilidad, rights management o integración externa sin consumidores/requisitos aprobados. Si no se necesitan, conservar el núcleo existente.

Confianza alta en reutilizar B y mantener el puesto derivado; media en el diseño de futuras extensiones; no verificada en datos desplegados, rendimiento o UX real de esta revisión. Una decisión posterior debe convertir las condiciones en alcance y criterios de aceptación.

14. Decisiones pendientes

Decisión Pregunta que deben resolver responsables funcionales/arquitectónicos
Alcance de SO ¿Incluye hipervisores, firmware, NAS, móviles y SO de contenedores, o solo entornos arrancables de equipos/VM?
Origen ¿Se necesita configuración comercial del SKU, configuración de recepción de unidad o ambas? ¿Puede corregirse el dato original?
Campo duplicado ¿Son equivalentes factory_os y factory_preloaded_os en servidores? ¿Qué política aplicar si divergen?
Conocimiento ¿Qué acredita ausencia confirmada? ¿Quién la declara y caduca? ¿Puede coexistir con instalaciones pendientes?
Episodios ¿Reinstalación necesita nueva identidad y fecha efectiva? ¿Cómo se distingue corrección documental, upgrade y cambio físico?
Instancias ¿Dos Windows del mismo producto en discos diferentes son dos instalaciones? ¿Debe existir principal/preferida?
Verificación ¿Origen manual/agente, fecha observada y última verificación son obligatorios? ¿Cómo resolver conflictos y escaneos incompletos?
Producto global ¿Se aprueba ampliar catálogo a SO? ¿Qué identifica familia, edición y producto sin deducirlo por nombre?
Licencias ¿Basta la referencia actual o hacen falta asignaciones, capacidad, volumen y cobertura? ¿Qué reglas OEM/transferencia se necesitan?
Historial ¿Se permite borrar altas erróneas con sus revisiones? ¿Se requiere fijar revisión de producto/licencia o reconstrucción temporal?
Presentación ¿Dónde se gestiona software de servidor/VM sin puesto y equipos adicionales? ¿Qué dato debe resumirse en cada ficha?
Perfiles ¿Hay un requisito real de SO permitido/requerido? ¿Quién lo define y cómo se evalúa frente a múltiples equipos?
Seguridad/operación ¿Se mantiene espacio de soporte compartido? ¿Qué capacidades tendría un agente de inventario y bajo qué compañía/contexto?
Migración y aceptación ¿Qué datos heredados se revisarán manualmente y qué pruebas aisladas, de concurrencia, volumen y UI exigirán la aprobación?

15. Índice de evidencias de código y documentación

Los enlaces usan líneas del árbol inspeccionado; pueden desplazarse con los cambios locales pendientes. Una FK/migración citada es evidencia del diseño ejecutable, no de su ejecución en una BD. Las pruebas de integración se consultaron como contratos, sin ejecutarlas en esta auditoría.

ID Evidencia / interpretación Rutas, símbolos y líneas
E01 Campos y plantillas de serie de activos; fábrica duplicada en servidor asset-catalog-seed.ts:52; asset-catalog-seed.ts:122; asset-catalog-seed.ts:267
E02 Contrato, tipos y validación de características de activo asset-values.ts:19; asset-values.vo.ts:33; asset-definition.ts:23
E03 Persistencia relacional e historial del activo asset-relational-schema.ts:100; asset.model.ts:15; asset-revision-specifications.ts:39; asset.aggregate.ts:100
E04 Campos de instalación y máquina de estados software-installation-values.ts:5; software-installation-values.ts:22
E05 Identidad, igualdad, cierre y destino inmutable software-installation.aggregate.ts:24; software-installation.aggregate.ts:64; software-installation-values.vo.ts:52
E06 Ámbito, tipo, disponibilidad, licencia y duplicados abiertos software-installation-policy.ts:6; software-installation-input.mapper.ts:16; resource-inventory.service.ts:7
E07 Migración de instalaciones, snapshots, FKs e índices software-installation-migration.ts:6; software-installation-snapshot.ts:9
E08 Lectura por compañía, transacción, locks, guardado y borrado de historial sequelize-software-installation.repository.ts:32; sequelize-software-installation.repository.ts:102; sequelize-software-installation.repository.ts:220; software-installation-response.builder.ts:7
E09 Mapper y clave de pareja abierta software-installation-persistence.mapper.ts:43; software-installation-persistence.mapper.ts:125
E10 Contratos HTTP, actor de sesión y casos de uso software-installations.ts:19; software-installation.routes.ts:20; software-installation.use-cases.ts:38
E11 Tests de instalaciones e integración consultada software-installation.test.ts:53; software-installations.integration.ts:17; global-software.integration.test.ts:33
E12 Elegibilidad global: solo aplicación stock global-application-template-policy.ts:2; resource-reference-metadata.ts:104
E13 Producto SO, edición, atributos de licencia y uso explícito resource-catalog-seed.ts:96; resource-catalog-seed.ts:149; resource-definition.ts:40
E14 Resolver público transaccional, propósito y lectura de UUID resource-reference-service.ts:32; resource-reference-reader.ts:47; configuration-resource-references.ts:6
E15 Resource y propietario global/particular; definiciones no son productos resource.aggregate.ts:63; resource-scope.ts:5; resource-values.ts:40
E16 Composición e inyección; gates predeterminados cerrados para asociación identity-runtime.ts:30; resource-configuration-dependencies.ts:13; module.ts:149; resource-global-gates.ts:14; composicion-de-modulos.md:1
E17 Workstation, principal, igualdad e historial; baja vacía composición workstation-values.ts:3; workstation-values.vo.ts:49; workstation.aggregate.ts:56
E18 Pertenencia y exclusividad de activos del puesto workstation-input.mapper.ts:52; workstation.model.ts:18; workstation.test.ts:90
E19 Perfil frente a instalación, delivery y aplicaciones globales R2.5 work-profile-values.ts:3; work-profile-input.mapper.ts:16; application-configuration-values.ts:5; application-configuration-policy.ts:6; sequelize-application-configuration.repository.ts:83
E20 Consulta y representación del software por principal; cambios locales previos use-workstation-detail-controller.ts:41; use-workstation-software.ts:9; workstation-software.tsx:22; workplace-map-model.ts:30
E21 Edición, consulta e historial de activo; sin panel propio de instalaciones localizado asset.use-cases.ts:12; asset-fields.tsx:14; asset-detail-content.tsx:16; asset-history.tsx:21
E22 Panel filtrado, formulario, licencia, historial y API del navegador software-installations-panel.tsx:130; software-installation-form.tsx:20; software-history-dialog.tsx:33; software-api.ts:18
E23 Seguridad de sesión y alcance compartido; integración no ejecutada require-authenticated.ts:6; identity.routes.ts:102; 03-contrato-seguridad.md:7; global-software.integration.test.ts:232
E24 Documentación funcional y evolución R2.4–R2.6 software-del-ordenador.md:1; puestos-de-trabajo.md:43; 15-r2-4-software-global.md:40; 16-r2-5-configuraciones-globales.md:1; 17-r2-6-coexistencia-duplicados.md:46
E25 Relaciones genéricas y contratos de extensión de lectura, sin plugins dinámicos asset-catalog-seed.ts:359; asset-relationship.aggregate.ts:23; contratos-de-relaciones-tipadas.md:1; capas-del-servidor.md:29
E26 Adopción/sucesión todavía propuesta; no trasladar al ciclo instalado 19-d08-2-resolucion-ratificacion.md:3; 19-d08-2-resolucion-ratificacion.md:44
E27 Rutas públicas de activos, catálogo, puestos y recursos asset.routes.ts:21; asset-catalog.routes.ts:141; workstation.routes.ts:16; resource-application.routes.ts:102; resource.routes.ts:54
E28 Persistencia relacional de productos/atributos y revisiones de Resources resource.model.ts:19; resource-relational-schema.ts:107; resource-inventory-relational.ts:198; resource.aggregate.ts:120

16. Validaciones y límites de entrega

Se ejecutó una selección sin acceso a BD de siete archivos de pruebas: dominio de instalaciones, perfiles, configuraciones de aplicación, catálogo de recursos, activos y puestos; más render de software es/en. El runner node --import tsx --test … informó 7 archivos correctos. Se ejecutó además la importación explícita de esos siete archivos con node --import tsx -e con los imports siguientes: 38 pruebas, 38 correctas, cero fallos/canceladas/omitidas. Así se evita confundir la agregación por fichero con el número de casos.

Comando reproducible de los casos individuales (sin conexión a BD):

node --import tsx -e '
await import("./modules/companies/src/api/domain/software-installation.test.ts");
await import("./modules/companies/src/api/domain/work-profile.test.ts");
await import("./modules/companies/src/api/domain/application-configuration.test.ts");
await import("./modules/resources/src/api/domain/resource-catalog.test.ts");
await import("./modules/companies/src/web/software-installations/shared/software.test.tsx");
await import("./modules/assets/src/api/domain/workstation.test.ts");
await import("./modules/assets/src/api/domain/asset.test.ts");
'

Cubren contratos de referencia y tipo, destino fijo, versiones, revisiones, transiciones, licencia/vigencia/desvinculación, idempotencia, mapper de persistencia sin BD, perfiles, composición de puestos, características opcionales y render/localización. No equivalen a 16 escenarios E2E ni a ensayos con MariaDB. Se consultaron además software-installations.integration.ts y global-software.integration.test.ts para concurrencia, CSRF, aislamiento contextual, gates y migración; no se ejecutaron.

No se ejecutaron pnpm typecheck, pnpm lint, pnpm test, pnpm check ni pnpm build globales: el cambio propio es exclusivamente este documento y no se requiere compilar código de producción para entregarlo. No se certifica el estado global del árbol previo ni se reproducen como actuales los fallos de informes anteriores. Se revisaron referencias locales y se comprobó whitespace con git diff --no-index --check /dev/null <informe>: sin diagnósticos de whitespace (el código de salida 1 corresponde a que el archivo nuevo difiere de /dev/null). Se contrastaron huellas de 55 rutas modificadas/no seguidas previas: 52 no variaron y se observaron variaciones concurrentes en workplace-software-card.tsx, workstation-detail.test.tsx y scripts/workplace-visual-map.test.py. Esta tarea no escribió esos archivos. La única ruta nueva respecto de esa instantánea es este informe; las pruebas ejecutadas no certifican los cambios concurrentes posteriores.

Volumen realmente utilizado: fixtures pequeños en memoria definidos por las pruebas, sin carga de compañías/activos/personas/recursos en BD. El escenario aislado de 15 compañías y al menos 50 personas, activos y recursos de una principal queda pendiente para una futura validación funcional/visual; no se declara ejecutado aquí. Tampoco se midieron rendimiento, accesibilidad o navegación real.

Entrega autorizada: un informe Markdown. No se implementó ninguna recomendación, modelo, endpoint, migración o cambio de componente.

17. Decisión posterior a la auditoría

El 25 de octubre de 2026 el usuario aprobó implementar el resumen derivado del SO actual en activos y puestos, reutilizando SoftwareInstallation y Resources. El alcance, implementación y validaciones posteriores se documentan en Decisión aprobada — SO actual en activos y puestos. Esta sección no modifica retrospectivamente los hallazgos ni las validaciones originales del informe.