- 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.
58 KiB
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
- Origen: catálogo de activos → plantilla/especificación → formulario de unidad → características y revisión de
Asset.factory_osno se sincroniza con instalaciones. - 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.
- Instalación: formulario →
softwareApicon contrato de recursos2→ ruta autenticada y schemas estrictos →SoftwareInstallationUseCases.save→ mapper/policies y agregado → repositorio transaccional. El actor procede de la sesión. - 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. - Consulta:
GETdevuelve todas las instalaciones de compañía y su historial; la ficha filtra porassetId === 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
- ¿Campo original? Sí:
factory_osy el segundo campo de servidorfactory_preloaded_os. - ¿Dónde? En características de cada unidad, según plantilla. No en una entidad producto físico ni en
SoftwareInstallation. - ¿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.
- ¿Sustitución? Guardar una instalación nueva no modifica características del activo. El operador debe cerrar/actualizar instalaciones según corresponda.
- ¿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.
- ¿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.
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.