39 KiB
L04.2 — Adopción de listados en catálogos y configuraciones
Fecha: 24 de octubre de 2026. Entrega limitada a L04.2; L04.3/L04.4 siguen pendientes. Fuentes: DESIGN, matriz de skills, L01, L03.1, L03.2, L03.3, L04.1, columnas, estados, listados, componentes, rutas y Playwright.
1. Resumen ejecutivo y alcance
Ambos bloques están implementados y verificados: 17 métodos MCP nuevos y 30 regresiones seleccionadas correctos. Catálogos navegables y Procesos conservan consulta y retorno; las configuraciones modales mantienen estado local con ámbito y estados de consulta coherentes. Las comprobaciones propias pasan; las limitaciones globales se detallan en §14.
Auditoría dirigida y matrices preparadas antes de modificar producción. Adoptar los contratos existentes según el ciclo real de cada consumidor. No convertir un editor modal en una ficha ni aplicar q/sort/page del padre a un sublistado independiente. El estado remoto continúa en TanStack Query; URL para consulta navegable, History para scroll/foco, preferencias existentes para tamaño/columnas y estado local para modales.
Skill principal: ux-tables (comparación, identidad, estados y manipulación a volumen). Complementarias consultadas: ux-navigation/search (ámbitos/retorno/criterios), ux-empty-states/error-recovery (vacío, coincidencias y errores), microcopy (mensajes), shadcn (API Base UI), composición y React best practices (responsabilidades/estado derivado). Se mantienen DESIGN y patrones propios frente a recomendaciones genéricas. Los auditores ux-*-audit y orchestration-policy no están instalados; no se instalan ni se finge su ejecución.
2. Diagnóstico previo
Los catálogos de Assets/Resources tienen q/tab en URL y key por pestaña; orden/página son locales y se pierden al salir o recargar. Las pestañas ejecutan dos replaces (tab y búsqueda por separado). Tabla con loading/unavailable básico más error externo; no compone refetch/error posterior. Marcas conserva todo local; plantillas de procesos oculta la tabla cuando carga o falla. Sus operaciones son modales/expansiones, sin detalle navegable. Accesos tiene q/kind/environmentId/resourceId en URL; metadatos/columnas dependen de kind; orden/página son locales y la tabla solo se monta con data.
Configuraciones de carpetas/correo/certificados/aplicaciones/impresoras/teletrabajo/remotos mantienen q local, sort/page de EntityTable y editores/historiales modales. Los filtros initialProfileId/initialPersonId limitan el conjunto y no son criterios limpiables. Varias tablas desaparecen ante refetch fallido o esperan solo una parte de sus referencias. Procesos tiene q/closed URL y detalle real, con orden/página locales y sin retorno de lista. Software es un sublistado por ordenador, dentro de fichas/diálogos: q/closed locales; referencias recursos/catálogo indispensables y enlace a recurso real.
3. Matriz A — Catálogos, antes de implementar
Todos usan EntityTable, nombre/identidad protegidos, acciones por fila y tamaño compartido entity-page-size. Ninguno de estos consumidores tenía clave propia de columnas ni contrato controlado sort/page. Nombre asciende por defecto, con comparador común; búsqueda normalizada. Las definiciones de secciones/campos dentro de editores de plantilla son composición ordenada, no catálogos independientes: conservan su orden de dominio y su editor.
| Consumidor / módulo / controlador | Ruta, datos y ámbito | Existente y diferencia legítima | Cambio pertinente / clasificación | No necesario / pruebas |
|---|---|---|---|---|
| AssetCatalogPage · Assets · useAssetCatalogPageController | /catalogs/assets y /companies/:id/catalogs/assets; catalogApi.get(scope) | q/tab, plantillas/campos/relaciones; nombre buscable; heredado/builtin y effectiveActive; acciones copia/estado/edición/detalle modal/borrado elegible | Adopción directa de navegación de consulta y estados; adaptación por pestaña/scope | Sin rutas de editor ni filtros nuevos. Recarga, cambio de pestaña, inválidos, herencia/retirada y cancelar |
| ResourceCatalogPage · Resources · useResourceCatalogPageController | /catalogs/resources y /companies/:id/catalogs/resources; catalogApi.get(scope) | q/tab, plantillas/campos; nombre buscable; procedencia y estado efectivo; permisos de gestión global actuales | Igual, conservando el ámbito y las restricciones reales del backend | Sin nuevos permisos/acciones ni cambios al modelo de recursos. Catálogo global/compañía y cancelación |
| BrandCatalogPage · Assets · useBrandCatalogPageController | /catalogs/brands; brandApi.list; global | Búsqueda de EntityTable por sus columnas comparables; status local; editor/borrado modal; builtin restringe borrar | Corrección de estados inicial/refetch/error, manteniendo consulta/orden/página locales | URL y History nuevos no necesarios: no existe ficha. Volumen, filtro, cancelar, carga/error y foco modal |
| ProcessTemplatesPage · Companies · useProcessTemplatesPageController | /catalogs/process-templates; listProcessTemplates (API /processes/templates); global | Búsqueda de tabla, orden/página locales; tipo/estado/instrucciones/historial inline; edición/copia modal | Adopción directa de estados estables | Sin URL de editor ni modificación de instrucciones. Volumen, historial expandido, cancelar y errores |
| AccessWorkspacePage · Companies · useAccessWorkspacePageController | /catalogs/access; getAccess(global) | q/kind; sistemas/tipos/permisos según accessKinds; nombre por accessLabel; campos dinámicos; edición/historial/ayuda modal | Adopción con validación de columnas según kind y limpieza atómica al cambiar colección | No heredar orden incompatible ni crear catálogo universal. Pestañas, inválidos, recarga y vacío |
| AccessWorkspacePage de compañía | /companies/:id/access; getAccess(id), people | Además cuentas/entornos/grupos/recursos/necesidades/asignaciones; environmentId/resourceId son ámbito explícitamente quitables con sus acciones propias | Adaptación por compañía/kind; conservar restricciones al limpiar búsqueda | No convertir ámbitos en filtros descartables. Permisos, identidad local, enlaces y retorno |
4. Matriz B — Configuraciones, antes de implementar
Ruta autónoma de compañía y, en las cinco primeras familias, subruta de perfil real /companies/:id/work-profiles/:profileId/. Los DTO y sus estados/periodos/relaciones no se homogeneizan. Los editores tienen su propia selección provisional y validación.
| Consumidor / controlador | Fuentes imprescindibles y campos buscables actuales | Ámbito / acciones / navegación | Cambio pertinente / clasificación | Diferencia preservada / pruebas |
|---|---|---|---|---|
| FolderMappingsPage / useFolderMappingsPageController | folderApi, access, profiles; path, perfil, nombre de carpeta | Compañía o perfil; edición/historial/borrado modal; configuración distinta de necesidad SMB | Estado agregado; consulta/orden/página locales, excepción modal justificada | initialProfileId no se limpia; sin nuevas relaciones. Volumen, vacío, error de referencia, editor/historial |
| MailConfigurationsPage / useMailConfigurationsPageController | mailApi, inventory, profiles, mailboxes; dirección y destinatario | Compañía/perfil y legacy; configuraciones y buzones distintos; edición/historial/borrado modal | Estado agregado; esperar las cuatro fuentes, conservar consulta local | Conservar legacy/revisión/estados. Página 3, perfil obligatorio, cancelar y refetch |
| CertificateConfigurationsPage / useCertificateConfigurationsPageController | certificateApi, profiles, inventory, resources; recurso y etiqueta del perfil | Compañía/perfil; canCreate depende de perfil activo; editor/historial/borrado modal | Igual | Perfil, certificado/recurso y vigencia no cambian. Datos poblados y carga/error |
| ApplicationConfigurationsPage / useApplicationConfigurationsPageController | applicationApi, profiles, inventory, resources; recurso y etiqueta | Compañía/perfil; canCreate y ciclo de vida existentes | Igual | No confundir instalación del equipo con configuración del perfil. Editor e historial |
| PrinterConfigurationsPage / usePrinterConfigurationsPageController | printerApi, profiles, inventory; impresora y etiqueta | Compañía/perfil; impresora es activo; editor/historial/borrado | Igual | Perfil obligatorio y activo elegible. Búsqueda, páginas, cierre y referencias |
| RemoteConnectionsPage / useRemoteConnectionsPageController | remoteApi, assets, resources; persona/origen/destino/método | Compañía/persona; closed local, vigencia/estados; editor/historial/borrado | Estado agregado y consulta local; closed sigue siendo voluntario | initialPersonId no se limpia. Sin copiar filtros del perfil. Refetch/finalizados/foco |
| TeleworkAuthorizationsPage / useTeleworkAuthorizationsPageController | teleworkApi y company.people; persona | Compañía/persona; edición/historial/borrado, periodos | Estado estable de una fuente; consulta local | No reinterpretar autorización como acceso remoto. Carga/error, ámbito y cancelación |
| ProcessesPage / useProcessesPageController | getProcesses y company.people; nombre/persona/tipo traducido | Compañía; q/closed URL; ficha real; alta/edición/cierre/borrado existentes | Adopción de URL completa, retorno y tabla estable | No alterar pasos/cierre/permisos. Detalle/Atrás/retorno explícito, retirada GET, refetch y filtros |
| SoftwareInstallationsPanel | softwareApi, resources, catálogo; nombre del recurso/versión | Ordenador obligatorio en ficha/diálogo; q/closed local; editor/historial/borrado y enlace al recurso | Corrección de estados agregados; excepción funcional legítima para URL local | No absorber q/page del padre ni perder assetId al limpiar. Editor, vacío/refetch/error y enlace |
5. Diagnóstico HTTP 401/404, previo a cambios
Preflight MCP con sesión ordinaria sintética existente, sin escrituras: tres rutas retiradas /api/tickets, /api/interventions y /api/intervention-templates/global devuelven 404 con y sin sesión. /api/dashboard/work devuelve 401 anónimo y 404 autenticado. Evidencia local: .artifacts/playwright/l04-2/preflight.json.
identity.test.ts:82 recorre esas cuatro rutas con fetch sin cookie, antes de preparar su usuario/sesión. createApp instala primero sesión y módulos, y al final el fallback 404. registerDashboardRoutes monta authenticate en /api/dashboard antes de resolver /work; requireAuthenticated responde 401 sin sesión y no llama next. Con sesión válida se llega al router sin /work y después al fallback 404. No es un recurso inexistente resuelto antes de autenticación ni un fallo de credenciales del navegador de auditoría.
Se confirma el origen de la discrepancia entre expectativa del test y orden de middleware, y su presencia antes de L04.2. L04.1 ya conservó el fallo en test.log y no modificó servidor. No se dispone aquí de una ejecución histórica anterior a L04.1 que permita fechar su introducción: no se afirma preexistencia histórica universal. No se modifican seguridad, endpoint, expectativa ni fixture para hacerlo pasar.
Precisión de la matriz B tras revisar las celdas
Las siete familias de configuración no contienen enlaces de navegación en sus filas: los nombres abren historial y las acciones abren editores/confirmaciones. La vista de perfil vuelve al entorno mediante el botón del contenedor. Por ello, conservan consulta, orden y página locales durante los diálogos; no necesitan nuevos parámetros URL. Se verificará que limpiar no elimina initialProfileId/initialPersonId y que cambiar de perfil no reutiliza la instancia local del anterior. Procesos sí tiene ficha y enlace navegable: adopta URL/History. Software tiene un enlace a recurso dentro de una ficha/modal; volver no convierte la apertura efímera del modal en una ruta nueva.
6. Bloque A — Implementación y resultados parciales
Catálogos de activos/recursos y Accesos adoptan useListLocation, useListReturn y estado agregado de consulta. Cambio de pestaña/kind limpia q/orden/página en una sola operación, conservando el comportamiento previo de reiniciar búsqueda y evitando aplicar un orden a columnas incompatibles. Limpiar búsqueda conserva scope, tab/kind, environmentId y resourceId; esos ámbitos mantienen sus acciones explícitas independientes.
Columnas: claves asset-catalog-columns:<scope>:<kind>,
resource-catalog-columns:<scope>:<kind> y access-columns:<scope>:<kind>; evitan perder
la selección al navegar/recargar y no mezclan pestañas ni compañías. No se añaden grupos
artificiales. Marcas y plantillas de procesos mantienen consulta, orden y página locales;
sus tablas dejan de desaparecer al cargar/refrescar/fallar y conservan recuperación.
Se reutiliza companyListQueryState mediante un hook de presentación con mensajes i18n, sin DTO, consultas nuevas ni otra máquina de estados. Estados de catálogo se adaptan a sus propias clases de error; 403/401 no dejan filas de caché accesibles en la tabla. Las acciones de mutación y su feedback permanecen específicos de cada catálogo.
Incompatibilidad de composición detectada y resuelta
El caso de recarga guardaba Y=150, restauraba el foco con preventScroll y terminaba en Y=78. Las mediciones completas muestran que la altura del catálogo y las fuentes ya estaban estables: el mensaje de carga externo del directorio desaparecía y reducía 72 px el contenedor, provocando anclaje de scroll. Se descarta la hipótesis inicial de fuentes y se retira el cambio exploratorio al hook. Core/History queda sin modificaciones.
La composición suministra layoutReady, derivado del estado real de las consultas
propietarias del contenedor, a los tres catálogos navegables; solo condiciona restauración,
no bloquea sus filas ni cambia el shell. Default true conserva los consumidores embebidos.
No hay temporizadores, estado remoto duplicado ni comprobaciones de DOM basadas en textos.
Se añade un caso con la consulta del contenedor retenida, además del de fuente retenida.
Las dos suites SSR de catálogo fallan antes de implementar orden/página y pasan después. Pruebas dirigidas de Assets catálogo/Marcas, Resources catálogo y Companies Accesos/procesos: 5/5 archivos correctos. Tipos y formato se comprueban por paquetes afectados. Las pruebas MCP y resultados restantes se incorporan al cerrar cada bloque.
7. Bloque B — Implementación y diferencias preservadas
Las siete familias de configuración conservan montada EntityTable desde la carga inicial. El estado agregado incorpora todas las fuentes imprescindibles de la matriz B; no basta con que llegue la colección principal. Un fallo posterior conserva filas, consulta y herramientas; una denegación oculta las filas y no ofrece un reintento engañoso. Reintentar espera las consultas reales y delega su resultado en TanStack Query, sin promesas rechazadas sin gestionar ni cerrar editores. No se alteran mutaciones, query keys ni invalidaciones.
Las configuraciones mantienen búsqueda/orden/página locales porque sus filas abren edición o historial modal. La identidad de la instancia depende de compañía y perfil/persona en CompanySection, de perfil/persona en ProfileConfigurations y del ordenador en el modal de software. Cambiar de ámbito no arrastra criterios de otra colección. Limpiar modifica solo los criterios voluntarios; el perfil/persona/ordenador sigue restringiendo los datos.
Procesos incorpora useListLocation, enlaces con la consulta completa y useListReturn.
La referencia de retorno pertenece exclusivamente al bloque del listado: se desconecta
en la ficha aunque el controlador siga montado. Conserva q/closed, instrucciones,
seguimiento y acciones existentes. La ausencia confirmada ofrece retorno mediante
BrowserLink; una entrada directa sin History válido usa el fallback existente.
Software conserva su ámbito obligatorio y estado local. Se comprueban el editor anidado, cancelación y enlace real al recurso contextual V01.4. Atrás vuelve a la ficha de origen; no reabre automáticamente la ventana efímera de gestión de software. Esta diferencia está deliberadamente fuera del contrato de una lista con ficha propia.
Columnas, filtros y selección por familia
Se conservan los IDs y renderizadores existentes. Nombre/identidad y acciones siguen protegidos; no se añade selección de filas ni grupos artificiales a tablas pequeñas.
| Familia | Columnas (IDs, además de actions) | Filtros voluntarios / identidad |
|---|---|---|
| Activos y recursos: catálogos | name, origin, details, state | q y tab; name obligatorio; details cambia de significado según pestaña |
| Marcas | logo, name, status, origin | Búsqueda de tabla y status local; name obligatorio |
| Plantillas de procesos | name, kind, state, steps, history | Búsqueda de tabla; name obligatorio; instrucciones e historial son composición inline |
| Accesos | name, campos de accessFields[kind], localOwner cuando corresponde, state, review | q/kind; resourceId/environmentId con eliminación explícita; name obligatorio |
| Carpetas | name, profile, path, drive, permissions, accessAccount, accountCoverage, state, review | q local; name obligatorio |
| Correo | name, profile, method, state | q local; name obligatorio |
| Certificados | name, profile, state, location, expiry, review | q local; name obligatorio |
| Aplicaciones | name, profile, state, delivery, version, review | q local; name obligatorio |
| Impresoras | name, profile, state, connection, default, review | q local; name obligatorio |
| Remotos | person, method, details, state | q y closed locales; person obligatorio |
| Teletrabajo | person, state, start, end, details | q local; person obligatorio |
| Procesos | name, person, kind, state, progress | q/closed navegables; name obligatorio |
| Software | name, type, version, license, state | q/closed locales; name obligatorio |
8. Contratos de URL y preferencias
| Consumidor | Consulta navegable | Preferencias / estado efímero |
|---|---|---|
| Catálogos Assets/Resources | q, tab (ausente = templates; fields/relations según catálogo), sort, direction, page | Columnas por scope y kind interno; tamaño compartido existente; editor/detalle local |
| Accesos global/compañía | q, kind, resourceId, environmentId, sort, direction, page | Columnas por scope/kind; editores/historial/ayuda locales |
| Procesos | q, closed=true, sort, direction, page, también en enlace de ficha | processes-columns:; alta/seguimiento locales |
| Marcas / plantillas de procesos | No se añaden parámetros | Búsqueda/estado/orden/página locales; tamaño existente |
| Siete configuraciones / software | No se añaden parámetros de consulta | Consulta/orden/página locales, closed donde existía; perfil/persona/ordenador obligatorios |
Solo se controlan orden/página cuando la ruta coincide con el consumidor. Se reutiliza la validación de columnas ordenables y páginas de L03.1: parámetros inválidos se corrigen al disponer de datos, sin certificar una página con datos parciales. Búsqueda y filtros reinician página; Limpiar conserva orden/columnas/tamaño. Cambiar tab/kind descarta q/sort/direction/page incompatibles en un único replace, sin crear una entrada por pulsación. Los filtros de ámbito conservan sus reglas anteriores, incluida la salida explícita de environmentId al cambiar a colecciones que no admiten ese contexto.
No se guardan DTO, cookies ni datos remotos en URL/History/localStorage. Las claves nuevas
de columnas usan IDs, no nombres traducidos. No cambia entity-page-size ni el contrato
no controlado de EntityTable; Core y rdx-ui no reciben cambios funcionales de L04.2.
9. Ámbitos, permisos y dependencias
Global, compañía, heredado y retirado conservan su semántica. Los elementos de serie y heredados mantienen las restricciones de edición/copia/borrado existentes; la retirada no elimina instantáneas ni se interpreta como ausencia. La revisión documental y los estados pendientes/configurados/finalizados se representan con sus etiquetas anteriores.
La matriz B identifica las referencias imprescindibles. Datos de compañía/personas proceden del contenedor real; las consultas de inventario, perfiles, buzones, recursos y accesos siguen en sus módulos. Las configuraciones no se transforman en recursos, activos ni permisos. No se añaden relaciones ni nuevos privilegios. Una respuesta 401/403 de cualquier fuente obligatoria impide presentar sus filas almacenadas como accesibles.
10. Retorno, foco y estabilidad del contenedor
History registra scroll vertical, scroll horizontal y foco de fila, con el scope y la
consulta del listado. Se restaura después de que la colección y su contenedor estén
disponibles. layoutReady?: boolean (default true) es una señal de composición de los
catálogos y Procesos: CompaniesWorkspace y CompanyDetail la derivan de sus consultas.
No es un segundo estado remoto ni un cambio a los breakpoints o estructura del shell.
Se reproduce y corrige el desplazamiento de 72 px descrito en §6, sin cambiar Core ni relajar las aserciones de coordenadas. Si desaparece un proceso, el foco vuelve a búsqueda; si hay refetch al regresar, no se declara válida prematuramente la fila de caché. Con URL directa, orden/página se validan y el retorno usa el fallback seguro.
En modales se conserva la tabla y Base UI devuelve el foco al control originario. El editor de software es un diálogo anidado: el padre permanece montado aunque Base UI lo excluya temporalmente del árbol accesible. No se crean entradas History para editar, cancelar ni consultar historial local. No se persiste la apertura del modal al seguir un enlace a otro recurso.
11. Carga, actualización, error y vacío
Se reutilizan entityListState y companyListQueryState; el nuevo
useCompanyListState solo aporta textos traducidos para las consultas que recibe.
No carga datos ni sustituye TanStack Query. Las tablas muestran estructura inicial,
marcadores y herramientas; conservan datos durante actualización y ante error posterior.
Error inicial, denegación, ausencia de registros y ausencia de coincidencias siguen siendo
estados diferentes. Las acciones de alta respetan disponibilidad de referencias y permisos.
Los reintentos usan refetch sin throwOnError; un error permanece en su contexto de consulta. No se capturan fallos para hacerlos desaparecer. El feedback de mutación y los errores de validación de cada editor no se mezclan con los errores de lectura de la tabla.
12. Accesibilidad e inspección visual
Se verifican aria-sort, controles con nombre, columna de identidad protegida, búsqueda, limpieza por teclado, foco inicial/retorno y diálogos anidados. La tabla conserva scroll horizontal propio y acciones ancladas; no se cambia a tarjetas ni se modifica vendor. Las capturas representativas abiertas incluyen catálogo a 1440/320, Procesos a 320, Software a 1440, Correo a 320 y Correo en inglés a 390. Se inspeccionan texto de estados, identidad, procedencia/retirada y foco visible; no se introducen tokens o colores nuevos.
La captura en inglés a 390 muestra que el rango del toolbar puede quedar excesivamente estrecho junto al selector largo de orden, partiéndose en muchas líneas. El layout común de herramientas no se ha modificado aquí; se registra para la revisión de densidad y responsive restante. No se afirma que toda la interfaz esté libre de problemas visuales, ni conformidad WCAG general, compatibilidad con lectores de pantalla o todos los temas.
13. Playwright MCP: cobertura y evidencias
Runner reproducible: scripts/catalog-configuration-ui.test.py. Reutiliza los clientes
MCP Docker y helpers existentes; no añade framework ni navegador en WSL. Recibe
METIS_PLAYWRIGHT_STORAGE_STATE del preparador, conserva los archivos privados ignorados
y bloquea escrituras desde el navegador. Las fixtures GET se validan con los schemas
reales antes de ejecutar escenarios; no son una prueba de persistencia del servidor.
Para repetir con una instalación sintética mantenida y volumen preparado:
La compañía debe disponer de al menos 50 personas/activos/recursos, 50 aplicaciones,
un certificado activo y una impresora operativa. El runner comprueba estas referencias
reales y falla explícitamente si faltan; visual-audit-volume.py prepara el volumen base,
pero por sí solo no garantiza todos los escenarios especializados. Completar esas
referencias únicamente en la instalación desechable antes de ejecutar el bloque B.
METIS_PLAYWRIGHT_STORAGE_STATE=.artifacts/playwright/authenticated-<ejecución>/session.json \
python3 scripts/catalog-configuration-ui.test.py
Por defecto, load_tests selecciona los 17 métodos nuevos (61–69 y 71–78), aunque reutiliza la preparación de L04.1. También permite indicar nombres completos de métodos para ejecuciones dirigidas; los resultados de esta entrega se obtuvieron por bloques. Las rutas reales y respuestas de sesión se obtienen del informe privado del preparador. No incorporar session.json al informe ni a Git.
Bloque A: nueve métodos 61–69 correctos
| Métodos | Verificación ejecutada |
|---|---|
| 61 | Diez combinaciones global/compañía y plantillas/campos/relaciones; URL, orden descendente, página 3 y recarga con scroll/foco exactos |
| 62 | Cambio de pestaña atómico, ADMINISTRACION/Pena, cancelar edición y teclado; sin pérdida de consulta |
| 63 | Accesos global/compañía: kind, orden/página, ámbito environmentId y limpieza |
| 64 | 50 marcas y 50 plantillas de proceso: sort/página 3 y modal sin crecimiento de History |
| 65 | Catálogo de compañía en las siete resoluciones; definiciones propias/heredadas/retiradas |
| 66 | Cinco catálogos: refetch 503 conserva tabla y 403 oculta caché, sin pageerror |
| 67–69 | Fuente y consulta externa retenidas, restauración sin salto prematuro; preferencias por pestaña y parámetros inválidos |
Resultados verdes repartidos entre browser-a-layout-ready.log (61/62) y
browser-a-tail.log (63–69). Los intentos fallidos anteriores no se borran: hay errores
de selector/etiqueta del test, además del fallo real de scroll corregido en §6.
Bloque B: ocho métodos 71–78 correctos
| Métodos | Verificación ejecutada |
|---|---|
| 71 | Las siete familias con 50 registros: orden/página 3, edición/cancelación, historial, sin resultados y limpieza con foco |
| 72 | Restricciones por perfil/persona, cambio a ámbito compañía y retorno al entorno; no se borra la restricción obligatoria |
| 73 | Las siete familias: dependencia pendiente, 503 con datos y reintento, 403 sin filas/reintento ni pageerror |
| 74 | Errores iniciales y recuperación, vacío real y sin coincidencias en tres familias representativas |
| 75 | Procesos: listado/ficha/Atrás o retorno explícito, siete resoluciones con URL/filas/página/sort/scroll/foco exactos |
| 76 | Procesos: recarga, retirada GET simulada, regreso durante refetch, limpieza, inválidos, editor cancelado y URL directa ausente |
| 77 | Software: 50 instalaciones, página 3, editor anidado/cancelación y enlace al recurso; Atrás vuelve al puesto |
| 78 | Correo en siete resoluciones y limpieza por teclado en inglés a 390, conservando perfil y foco |
Logs: browser-b-first.log (71–74), browser-b-navigation.log (75/76),
browser-b-final-tail.log (72 ampliado) y browser-b-software-capacity.log (77/78).
Los reintentos de 77 corrigieron instrumentación: contar diálogos con includeHidden
para el padre inerte y esperar la ficha contextual de recurso, en vez de una página que
el producto no tiene. No se añadió una ficha nueva ni se cambió el producto para el test.
Datos y límites de transporte
Primera instalación reutilizada: 15 compañías, 59 personas, 137 activos y 73 recursos reales sintéticos. Grafos GET adicionales: 50 sedes, 50 puestos, 50 perfiles, 50 definiciones por colección y 50 registros por familia de configuración/software/procesos. Hay nombres largos/tildes/ñ, distintos estados y referencias coherentes a DTO reales. Enriquecer GET no modifica esa base ni crea datos en otra compañía.
Login/sesión reales; HTML, JavaScript, CSS y componentes reales. Para aislar trabajo concurrente se desactiva HMR en el cliente, se capturan secuencialmente referencias GET reales y se reproducen en lectura. Las respuestas de volumen y fallos son interceptaciones GET declaradas. Esto no certifica el comportamiento concurrente de todas las APIs ni sus mutaciones. Los fallos esperados de red generan mensajes de consola; se distinguen de pageerror y de errores de transporte del entorno.
La primera instalación se cerró externamente durante las regresiones posteriores. Se conservan ECONNREFUSED y session.json ausente como pruebas interrumpidas, no como regresiones del producto. Se comprobó y reutilizó otra instalación existente, ordinaria, con 15 compañías, 50 personas, 51 activos y 66 recursos; no se inició otro entorno visual.
Las capturas/mediciones y logs están en .artifacts/playwright/l04-2/, ignorados por Git.
El índice local identifica resultados verdes, diagnósticos y repeticiones; estas imágenes
no son evidencia portable por el mero enlace Markdown al repositorio.
14. Pruebas dirigidas, regresiones y comprobaciones técnicas
Las suites existentes de catálogo de Assets/Resources incorporan URL de q/tab/sort/page con datos parseados y búsqueda sin tildes; la prueba falla antes de la implementación y pasa después. Procesos incorpora 30 procesos válidos para URL directa, orden/página y enlaces con consulta. Correo verifica que una referencia obligatoria pendiente conserva la estructura y no se interpreta como vacío. Las fixtures no reemplazan la validación de los schemas reales.
Regresiones MCP: 30 métodos seleccionados correctos
| Entrega | Métodos / log válido | Resultado |
|---|---|---|
| L04.1 | 41, 42, 43, 45, 46 · regression-adoption.log | 5/5; Puestos/Perfiles/Compañías, retornos, filtros, columnas y modales |
| L03.1 | 01, 04, 05 · regression-context.log; 06, 08, 13 · regression-context-active.log | 6/6; Activos/Recursos/Personas, retirada GET, refetch y aislamiento |
| L03.2 | 17, 18, 19 · regression-search.log | 3/3; Unicode/ñ, catálogos y puntuación técnica |
| L03.3 | 25, 26, 27, 31 · regression-filters-active.log | 4/4; limpieza, ámbito y parámetros inválidos |
| L02.3 | 02, 03, 04 · regression-states-active.log | 3/3; dependencias, caché, error/vacío/denegación y recuperación |
| L02.2 | 03, 06, 07 · regression-columns-active.log | 3/3; preferencias, consumidores simples, campos compartidos y foco |
| L02.1 | 01, 03, 07 · regression-pickers-active.log | 3/3; capacidad, teclado, selección provisional, activos/perfil/dominio |
| V01 | resource_routes_and_explicit_detail · regression-responsive.log; responsive_resize_focus_and_modality e inventory_resize_focus_and_actions · regression-responsive-volume.log | 3/3; resize, foco, panel/diálogo, edición cancelada y ficha |
No se repiten todas las suites visuales históricas. V02/V03/V06/V09 mantienen sus componentes; la muestra comprueba foco, modales anidados, i18n, cabeceras y estados, sin certificar contraste general ni todos los asistentes. La selección se limita al alcance de composición afectado y a las regresiones exigidas.
Los primeros tres fallos de filtros proceden de totales fijados en los tests. El runner ahora obtiene people/assets/resources de las respuestas reales, conserva la exigencia de volumen mínimo y compara totales exactos. Los 50 registros creados solo por GET para sedes/perfiles/software siguen teniendo expectativas específicas. Una repetición quedó interrumpida por la retirada externa del entorno, antes de ejecutarse sus comprobaciones. En dos casos V01 el activo conocido dejó de estar en la primera página a causa del volumen: el adaptador lo hace visible con q=AUDIT-PORT-01, conservando las aserciones originales de foco/resize/panel. No se modifica el producto ni se rebajan esas aserciones.
Comprobaciones técnicas
| Comando / alcance | Resultado ejecutado |
|---|---|
| pnpm exec tsc --build, proyectos Companies/Assets/Resources/Core/rdx-ui | Correcto; scoped-types.exit=0 |
| pnpm exec biome check, 51 archivos TS/TSX/JSON propios | Correcto, sin supresiones ni cambios adicionales; scoped-check-final.exit=0 |
| pnpm exec eslint, TS/TSX propios | Correcto; dos separaciones entre funciones de Procesos corregidas; scoped-spacing-final.exit=0 |
| Suites de Assets, Core y rdx-ui | 27/27, 3/3 y 13/13 archivos-suite correctos |
| Suites de Companies | 47/48 archivos-suite; fallan las dos aserciones de companies-page.test.tsx:180/210 descritas abajo |
| Suites de Resources | Catálogo/recursos y restantes contratos correctos; el primer HTTP falla por listen EPERM del sandbox; repetido con permiso localhost: 2/2 subtests HTTP correctos |
| pnpm typecheck global | Falla en vendor calendar.tsx:165 (locale opcional / exactOptionalPropertyTypes); mismo diagnóstico que baseline-typecheck.log |
| pnpm lint / pnpm check | Fallan; línea base 37/213 errores, ejecución posterior 15/171. Ningún diagnóstico en los 51 archivos propios; detalle completo en lint/check-complete.log |
| pnpm build | Correcto, 2/2 tareas recuperadas de caché Turbo; no se presenta como recompilación forzada |
| pnpm test --continue=always, MariaDB temporal separada | 8/10 tareas correctas; únicamente fallan Companies (243/245) y servidor (8/8 iniciales, 18/19 de integración) |
| Sintaxis Python | Correcta en los tres scripts propios/adaptados, sin instalar herramientas |
Los recuentos de Node bajo --test corresponden a archivos-suite; no se convierten en un número inventado de aserciones. La ejecución agregada inicial con pnpm --filter se detuvo tras el fallo de Resources y no ejecutó todos sus dependientes; se ejecutaron después los cinco scripts de paquete individualmente. Resource HTTP se diagnosticó con ejecución directa: listen EPERM 127.0.0.1, y pasó con el mismo código al permitir el socket local.
Las dos aserciones SSR de Companies esperan «Personas (1)» y «Esta persona no tiene acceso a Metis Desk». Se reproducen mediante Node directo en company-failure-direct.log y ya figuran en las evidencias de L04.1; no se modifican expectativas ni UI ajenas a L04.2. Los diagnósticos completos de lint/check incluyen skills, código de fotos/procesos y barrels/formatos fuera del alcance. La línea base está truncada; no se afirma correspondencia uno a uno para diagnósticos que entonces no se imprimieron. La reducción de recuentos durante trabajo concurrente tampoco se atribuye íntegramente a esta entrega.
La suite global se ejecutó realmente con una MariaDB propia, exclusivamente metis_desk_test, retirada automáticamente. La repetición final confirma Assets 146/146, Resources 95/95, Core 11/11, rdx-ui 78/78 y los fallos de Companies y servidor indicados. El único fallo de servidor en esa repetición es identity.test.ts:82, HTTP 401 frente a 404, exactamente el escenario diagnosticado antes de implementar (§5). No se alteran autenticación, endpoints ni fixtures.
La primera ejecución global también falló al importar resource-application.response.dto.ts:15, ResourceSpecificationSchema no definido, en typed-relationships/windows-domains-ui. Ese DTO estaba siendo modificado fuera de L04.2; su importación se corrigió externamente antes de la repetición. Ambos logs se conservan (test.log y test-repeat.log); estos dos fallos no se presentan como deuda histórica confirmada ni se ocultan bajo el 401/404. Tipos dirigidos comprobados nuevamente tras ese cambio: scoped-types-final.exit=0. Las dos MariaDB propias se retiraron con código 0.
Archivos y revisión documental
Inventario propio: 62 archivos (51 TS/TSX/JSON: Assets 8, Resources 6, Companies 37;
3 scripts y 8 documentos). Controladores/vistas adaptados, hook de presentación,
composición de layout/ámbitos, traducciones y cuatro suites existentes son los cambios
principales. scripts/adoption-ui.test.py solo admite un directorio de evidencias opcional,
con su default anterior; scripts/filter-ui.test.py elimina totales fijos de la base real.
Lista completa local: archivos modificados y índice de evidencias. El workspace ya tenía cambios extensos de otras entregas; el inventario no atribuye a L04.2 todo el diff de esos archivos. Hay copia previa de 42 archivos de código propios; otros ocho archivos de composición y el nuevo hook se identifican separadamente en baseline-not-copied.txt.
Se conservan las observaciones históricas y se añaden seguimientos en DESIGN, L01, L03.1, L04.1, patrón, componentes y rutas. Los enlaces nuevos resuelven. El único enlace roto del barrido es el histórico de L01 a workstation-people.tsx, ya presente en la copia inicial; no se modifica una referencia histórica ajena para aparentar un barrido sin incidencias.
git diff --check es correcto. No quedan clientes MCP propios activos ni bases de
integración propias; se confirma la retirada por sus dos nombres exactos. La instalación
visual reutilizada y su sesión quedan a cargo de su propietario: no se detienen ni borran.
15. Limitaciones y frontera de la entrega
No se guardan formularios ni se ejecutan bajas/retiradas reales de negocio. Se comprueba apertura/cancelación y lectura de historiales, no la persistencia positiva de cada editor. No se reauditan la seguridad de producción, todas las combinaciones administrativas ni todos los enlaces posibles. Denegaciones del servidor se simulan mediante GET para verificar la UI, sin sustituir pruebas de autorización del backend.
El diagnóstico 401/404 está en §5; no se cambia para obtener checks verdes. La deuda de vendor y los cambios simultáneos ajenos se mantienen identificados por sus logs. No se modifican dependencias, migraciones, HTTP, modelos ni paquetes vendor por L04.2.
16. Pendientes para L04.3 y cierre de fase
L04.3/L04.4 conservan su alcance pendiente: sublistados/consumidores restantes y cierre transversal documental, según L01. No se declara L04 ni V05 resueltos universalmente. La revisión de densidad del toolbar largo, auditoría de accesibilidad ampliada y guardados positivos requieren escenarios propios; no se presentan como comprobados aquí.
Seguimiento L04.3
L04.3 distingue software en modal (consulta local) de software en ficha navegable (estado de lectura de esa entrada). Conserva las restricciones de perfil/persona y los contratos de catálogos/configuraciones. La nueva composición de relaciones reutiliza el contrato de estados y retorno; los resultados y fallos globales históricos aquí documentados permanecen como evidencia anterior.