- Added UsersIcon to UserManagement for better visual representation. - Updated Spanish localization for "noValue" to use a dash instead of "Sin datos". - Introduced LayoutTemplateIcon in ResourceCatalogPage for improved UI. - Integrated LayersIcon in ResourcesPage to enhance user experience. - Updated package.json test scripts to include new test files. - Enhanced DetailSection component to support accordion functionality. - Modified EntityListHeader to accept an icon prop for better UI consistency. - Added new CountBadge and TimeLine components for better data representation. - Implemented asset workstation action logic and UI components for asset management. - Created tests for CountBadge and TimeLine components to ensure functionality.
19 KiB
Puestos de trabajo
Uso
La sección Puestos de trabajo de cada compañía agrupa los activos utilizados habitualmente como un conjunto. Un puesto tiene UUID v7, nombre, estado activo/inactivo, sede, responsable opcional y hasta 200 activos sin duplicados. El alta exige al menos un activo y un ordenador principal. Los puestos antiguos o desactivados pueden conservar una composición vacía hasta completarlos. Una persona puede tener varios puestos. Los puestos no contienen otros puestos.
Nuevo puesto abre un modal desde la cabecera derecha; Editar abre otro modal con los datos existentes. Al crear, el resumen propone el nombre «{sede} · {ordenador principal}»; el técnico puede modificarlo o borrarlo antes de guardar y esa edición manual no se sobrescribe al retroceder, cambiar la sede o el ordenador y volver al resumen. Mientras el nombre no se haya editado, la propuesta se recalcula al avanzar con las selecciones actuales; el responsable no interviene en ella. El formulario ofrece selectores con «+» para dar de alta sedes, personas y activos sin perder sus datos. Guardar un elemento relacionado lo selecciona o incorpora al puesto; cancelarlo mantiene el formulario principal. Los elementos guardados sobreviven si posteriormente se cancela el puesto. El alta de activo desde un puesto usa plantillas y sedes existentes para evitar un tercer modal.
La ayuda aparece inmediatamente antes de Guardar y Cancelar. El listado permite buscar por nombre, persona o sede. Historial del puesto muestra las versiones completas, con estado, asignación y composición, fecha y responsable. La ficha de cada activo muestra los puestos vigentes en los que se utiliza.
Reglas
Un activo solo puede pertenecer a un puesto activo. El formulario marca como ocupados los activos reservados por otros puestos. El servidor valida la reserva bajo bloqueo de compañía en una transacción y la base de datos la protege con una clave única. Dos altas concurrentes no pueden reservar el mismo activo.
La operación de desactivación vacía la composición actual y libera sus reservas; conserva las revisiones. Un puesto inactivo anterior puede conservar composición. Reconstruirlo y reactivarlo comprueba de nuevo la disponibilidad de sus activos. Retirar un activo del puesto no elimina el activo ni sus relaciones.
Persona, sede y activos deben pertenecer a la misma compañía. Una persona debe estar activa para una nueva asignación. Si se desactiva después, se conserva la asignación anterior para revisión y puede retirarse. La persona no recibe acceso a Metis Desk.
El responsable del puesto no cambia automáticamente la sede ni el estado de cada activo, ni identifica a todos sus usuarios. Tampoco se crean conexiones entre equipos automáticamente: se registran mediante relaciones entre activos. Los activos averiados o en mantenimiento pueden permanecer en una composición para revisión y reparación. Las nuevas asociaciones activas requieren activos operativos. Para retirar un activo se desvincula primero de los puestos activos; las composiciones históricas se conservan.
La eliminación definitiva se realiza mediante una operación explícita con confirmación; véase Baja y eliminación. Guardar valores normalizados equivalentes no añade una revisión; cambiar solo el orden de selección de activos tampoco. Cambiar nombre, estado, sede, persona o composición registra una instantánea nueva con UUID propio y conserva el UUID del puesto.
Arquitectura y API
Workstation es un agregado; WorkstationRevision es una entidad interna. WorkstationValues es un Value Object inmutable con nombres Name, referencias UniqueID y opcionales Maybe. Infrastructure reconstruye y valida los valores, la última revisión, la auditoría y el ámbito.
Las tablas workstations y workstation_revisions mantienen raíces y revisiones con claves foráneas a compañía, sede, persona y actor. workstation_assets es una proyección técnica de las referencias utilizadas en todo el historial y de sus reservas vigentes; no representa otra entidad de negocio. Conserva claves foráneas a activos históricos; la composición activa genera la reserva vigente. Conserva claves compuestas para la pertenencia a compañía y una clave única nullable para la reserva. Las migraciones son idempotentes.
El repositorio del inventario carga los puestos y serializa sus escrituras con el bloqueo de catálogo y compañía ya utilizado por activos y relaciones. Conserva revisiones existentes y solo inserta las nuevas.
GET /api/assets/:companyId incluye workstations junto a assets y relationships. POST /api/assets/:companyId/workstations y POST /api/assets/:companyId/workstations/:id/update reciben values. Las escrituras requieren sesión, origen válido y CSRF; el actor procede de la sesión y no se admite en el cuerpo.
Las pruebas verifican identidad, composición opcional, límites, igualdad, historial, ámbito, ausencia de anidación, desactivación y reactivación, personas inactivas, concurrencia y persistencia. La comprobación de navegador incluye altas rápidas, cancelación, composición, activos ocupados e historial.
Perfiles de usuario
Un puesto agrupa equipos y recursos; el perfil de usuario registra la persona en un dispositivo concreto. La composición no crea conexiones físicas, permisos ni perfiles automáticamente. La asignación de un activo no representa propiedad personal: todos los activos del inventario pertenecen a su compañía.
Responsable y ordenador principal
La relación opcional personId identifica al responsable del puesto, no a todos sus usuarios. No se propaga a los perfiles. Estos identifican a cada persona que utiliza el ordenador, de modo que un puesto compartido puede tener varios perfiles.
computerAssetId identifica el único ordenador principal entre los activos del puesto. No se deduce por nombre de plantilla ni por orden de selección. El resto de activos se registra como periféricos. Dos ordenadores se organizan en dos puestos. El ordenador principal se persiste como columna con clave foránea en el puesto y sus revisiones; un cambio conserva historial. Los puestos existentes mantienen su composición y necesitan designar el ordenador antes de crear nuevos perfiles. Retirarlo de la composición limpia la selección del ordenador principal.
La ficha reúne únicamente perfiles del ordenador principal, incluidos los archivados cuando corresponda. Los periféricos no aportan perfiles. El entorno actual y la consulta del perfil utilizan el mismo criterio. Cambiar el ordenador principal no reasigna perfiles automáticamente: los perfiles vigentes que dejan de tener un puesto activo requieren revisión.
La ficha consulta también el software del ordenador, incluido el sistema operativo actual, por computerAssetId. Las instalaciones permanecen vinculadas al activo al cambiar el ordenador principal.
Presentación de la ficha
El título de la ficha permite cambiar el nombre mediante un botón de lápiz, sin abrir el formulario completo. La edición ofrece Guardar y Cancelar; Enter guarda y Escape cancela. El campo recibe el foco y lo devuelve al botón al terminar. El borrador se conserva si se actualizan los datos en segundo plano. Mientras guarda, se bloquean el campo y sus acciones; los errores permanecen en el editor y solo se cierra tras confirmar el guardado. Los nombres vacíos o demasiado largos se rechazan con el schema existente. Un nombre equivalente tras normalizar espacios no genera otra escritura.
El guardado reutiliza la actualización del puesto y su historial. Antes relee los valores vigentes para no enviar sede, responsable o composición capturados al abrir el editor. La respuesta confirmada actualiza la caché de inventario y después invalida esa consulta; no se invalidan perfiles ni software porque sus referencias no cambian.
La ficha separa Información, Software e Historial con pestañas accesibles y desplazables en espacios estrechos. Bajo el nombre, la cabecera muestra estado, sede y responsable si existe, con enlaces a sede y persona. A la derecha aparece Editar puesto y un menú de acciones con Desactivar y Eliminar definitivamente, manteniendo sus confirmaciones. Nuevo perfil se sitúa en la cabecera del panel Perfiles y se habilita únicamente para un puesto activo con un ordenador principal incluido en su composición y no retirado; el bloqueo explica cómo completar el puesto.
Información reúne activos, personas y perfiles. Destaca el ordenador principal y muestra
los demás activos como periféricos
mediante AssetSummaryCard, sin duplicados. Sus nombres enlazan las fichas de activos,
que conservan el detalle técnico completo. Las personas se presentan con avatar, con el
responsable primero y una única aparición por persona. La carga o el error de perfiles
no se confunde con ausencia de personas. El panel Perfiles en Información reúne los del ordenador
principal, incluidos los archivados, mediante la tabla común con búsqueda, ordenación
y paginación. Conserva los enlaces y avisos de revisión, sin repetir el mismo ordenador
en cada fila. El software se carga al abrir su pestaña y mantiene la gestión existente.
Los paneles de activos, personas y perfiles reutilizan DetailPanel de @repo/rdx-ui.
El diseño responde al ancho disponible y mantiene accesibles contenidos y acciones en
móvil y escritorio. Véase Componentes de interfaz.
La pestaña Historial muestra las revisiones registradas del puesto, de más reciente a
más antigua: fecha y hora, autor, nombre, estado, sede, responsable, ordenador principal
y activos de cada revisión. Los nombres de las referencias se resuelven con los datos
disponibles; las referencias ausentes muestran —. Las instantáneas mantienen sus
identificadores y valores originales; no se reconstruye un historial de cambios de
nombre de activos o sedes que el contrato no registra. WorkstationHistory comparte
la presentación entre la ficha y el diálogo del listado mediante TimeLine de
@repo/rdx-ui/components/time-line. No se añaden consultas ni nuevas escrituras.
Desactivación y eliminación
El listado y la ficha completa ofrecen Desactivar y Eliminar definitivamente, mediante un mismo diálogo reutilizable con confirmación y resultado de servidor.
Desactivar deja el puesto inactivo, vacía sus activos y retira el ordenador principal y responsable. Conserva nombre, sede, UUID e historial. Las asociaciones anteriores permanecen en las revisiones, pero no reservan activos ni representan usos vigentes. Repetir la desactivación no añade revisiones. También se puede aplicar a un puesto ya inactivo que conserve composición. Se puede editar posteriormente para reconstruirlo y reactivarlo, comprobando las reservas actuales.
Eliminar definitivamente borra el puesto, revisiones y asociaciones técnicas en una transacción y libera sus reservas, incluso si seguía activo. Conserva los activos, personas y sedes. Las referencias externas declaradas mediante claves foráneas impiden la eliminación con WORKSTATION_IN_USE; la alternativa es desactivar. La comprobación utiliza las claves foráneas declaradas para proteger también futuras referencias. Un error no elimina parcialmente la composición ni sus reservas.
El puesto mantiene un único conjunto de activos. Los perfiles de usuario, correo, permisos, certificados y software pertenecen a personas, cuentas o al ordenador, y no son asignaciones directas del puesto. La desactivación libera la composición del puesto; conserva esos registros y no simula desinstalaciones ni retirada de accesos externos. Los perfiles sin un puesto vigente permanecen para revisión. La ficha actualiza los datos después de confirmar la operación; tras eliminar vuelve al listado.
POST /api/assets/:companyId/workstations/:id/decommission y POST /api/assets/:companyId/workstations/:id/delete reciben cuerpo vacío {}. Requieren sesión, origen y CSRF; compañía y puesto se validan en servidor. La desactivación registra actor de sesión y fecha en la revisión. Ambas operaciones comparten los bloqueos de catálogo y compañía con las reservas de activos. La desactivación conserva las referencias históricas; la eliminación elimina las asociaciones internas mediante las claves foráneas y las revisiones, sin desactivar restricciones ni persistir JSON.
Las pruebas cubren desactivación activa/inactiva, liberación de reservas, ordenador y responsable, historial e idempotencia, eliminación activa/inactiva, referencias externas, rollback lógico, pertenencia a compañía, cuerpo estricto y protección CSRF/origen.
El estado mostrado del activo se calcula desde su estado técnico y los puestos activos, según Inventario de activos. La desactivación libera composición y reservas sin cambiar el estado técnico de sus activos.
Alta en cuatro pasos
- Sede y responsable. Si existe una única sede se selecciona automáticamente. El responsable es opcional; las altas relacionadas conservan el formulario.
- Activos. Un diálogo con listado, búsqueda rápida y pestañas por plantilla permite añadir varios a la vez. Es obligatorio añadir al menos uno; se impiden duplicados, activos ocupados y nuevas asociaciones no operativas.
- Ordenador principal. Se elige pulsando una de las fichas
AssetSummaryCardde los activos seleccionados, sin abrir otro diálogo. Solo una tarjeta puede estar marcada; el borde y el radio identifican la elegida. El grupo conserva navegación por teclado mediante flechas y Espacio. Si solo queda uno se asigna automáticamente; al retirar el ordenador se limpia la selección o se asigna el único restante. - Resumen. Muestra sede, responsable, composición y ordenador principal. El ordenador principal reutiliza
AssetSummaryCarddel paso 3, a ancho completo y con el mismo borde destacado: nombre, plantilla, icono, características y estado, sin controles de selección. La lista de activos excluye el ordenador principal para evitar duplicarlo; si no quedan otros activos muestra—. El nombre propuesto por sede y ordenador principal se puede editar antes de Guardar.
El diálogo de alta utiliza tamaño medio, cabecera con icono decorativo y
FormDialog layout="stable". Su altura exterior depende de la ventana y se conserva
al cambiar de paso o añadir/retirar activos. El cuerpo tiene scroll interno y reserva
espacio para la barra; cabecera y pie permanecen visibles. Los grupos
reutilizan FormSection variant="plain"; asociaciones y resumen responden al ancho
del contenedor, con dos columnas cuando caben y una en espacios estrechos. Los activos
seleccionados se muestran con AssetSummaryCard: fichas compactas con icono, plantilla,
características y estado, en una o dos columnas según el espacio. El resumen reutiliza
las mismas fichas sin acciones de retirada. El nombre del
resumen ocupa el ancho completo y los valores ausentes muestran —. La edición conserva
el diálogo grande con altura estable y los mismos grupos, conforme al patrón de diálogos.
Anterior conserva valores y Siguiente valida los requisitos del paso. Guardar solo aparece en el resumen y no se envía el alta desde pasos intermedios. La edición mantiene un formulario único y permite conservar/completar puestos anteriores o desactivados. Cancelar permanece en el pie del modal y la ayuda se mantiene anclada inmediatamente encima, fuera del scroll de campos. Los ejemplos extensos tienen desplazamiento propio limitado al espacio disponible.
Se elimina sharedAssetIds de contratos, dominio, reservas y vistas. La migración explícita removeSharedWorkstationAssets, ejecutada durante la preparación del esquema, elimina las asociaciones de tipo compartido tanto actuales como históricas y limpia sus referencias técnicas cuando no existe ninguna asociación exclusiva histórica. No convierte activos compartidos en exclusivos, no borra activos ni revisiones y no genera reservas conflictivas. Es transaccional e idempotente. Las composiciones exclusivas e identidades se conservan.
Crear y consultar puestos desde el inventario
La columna Puesto del inventario muestra un botón visible «Crear puesto de trabajo» para portátiles, PC de
sobremesa y servidores operativos y sin asignación. Este acceso rápido identifica
estos tipos mediante el icono configurado en la plantilla (laptop, desktop,
server); no utiliza nombres traducidos ni cambia las restricciones del dominio.
Si falta el catálogo o no se reconoce el tipo, no ofrece crear.
La acción abre el mismo formulario de cuatro pasos, con el activo incorporado como ordenador principal y su sede preseleccionada si está activa. Conserva la propuesta de nombre por sede y ordenador; permite revisar sede, responsable y composición antes de guardar. Cancelar no crea puestos. Guardar utiliza el caso de uso existente, invalida el inventario y abre la ficha del nuevo puesto; no transforma ni duplica el activo.
Si el activo está en la composición vigente de un puesto, la columna muestra su nombre como enlace a la ficha independientemente de su papel como ordenador principal o periférico y de su estado técnico. Incluye puestos inactivos que todavía conservan composición; si hay varios, cada uno conserva su propio enlace. La acción de crear sigue visible fuera del menú de edición y eliminación. Las asociaciones que solo aparecen en revisiones históricas no se consideran vigentes. Se preservan las comprobaciones de compañía, reservas y estado operativo del formulario y del servidor ante concurrencia.
Alta desde una persona
El menú de cada persona activa ofrece «Nuevo puesto de trabajo». La acción navega al
listado de puestos de la compañía y abre el mismo formulario de alta mediante la
navegación de creación existente, aportando personId como contexto. El diálogo y
el formulario reciben initialPersonId: el responsable comienza con esa persona si
está activa y aparece en los datos de la compañía. El usuario puede cambiarlo o
retirarlo. Un identificador desconocido o de una persona inactiva no se preselecciona.
La edición conserva siempre el responsable guardado del puesto. Se mantienen las
altas relacionadas de sede y persona, los cuatro pasos y las validaciones de servidor.
El listado de Personas muestra la columna «Puestos bajo su responsabilidad», con un
enlace por puesto activo cuyo responsable actual sea esa persona. Reutiliza el mismo
criterio que la ficha de persona: no incluye puestos usados solo mediante un perfil,
responsabilidades históricas, puestos desactivados ni registros de otra compañía.
La ausencia de puestos muestra —; el inventario se consulta una vez por compañía
mediante la caché compartida, con estado de carga y recuperación explícita de errores.