Resumen: qué hace
La navegación superior de InfraGuard es una arquitectura de información (IA) orientada a roles: primero se ramifica por rol (área de trabajo) y después se despliega en flujos de tarea dentro de cada área. Tres principios:
- El menú se gobierna desde la base de datos, no está codificado a mano. Cada nodo del menú se lee de la tabla
infr_sitemap(propiedad de la aplicación, independiente). Nada queda incrustado en Blade. - Límite de rol = límite de permisos. El
min_reqde cada nodo (eluser_levelmínimo) es la línea de control de acceso. Un nodo solo se muestra cuandouser_level >= min_req, y la misma regla se aplica en el servidor sobre la ruta (defensa en profundidad). - Las etiquetas siempre pasan por claves de traducción. El texto en pantalla se resuelve mediante
__()/Locales::menuLabel()para los 8 idiomas.
Las métricas (CPU, carga, ventanas de 5 minutos, …) no son elementos de menú de primer nivel: viven como pestañas de entidad y filtros dentro de cada pantalla. La división es «quién (qué rol) hace qué», no «qué métrica».
En InfraGuard, «dominio» significa únicamente un TLD web (
aaa.bbb.com). El reparto del trabajo por responsabilidad se denomina «rol / área». Los 8 elementos de menú de primer nivel son esas áreas de rol.
Cuándo usarlo
- En el primer inicio de sesión, para aprender dónde está cada cosa.
- Para diagnosticar por qué falta una pantalla (nivel insuficiente frente a repliegue de idioma).
- Cuando hay que añadir o reestructurar el menú y volver a ejecutar el sembrador (administración/desarrollo).
- Para verificar qué queda expuesto a usuarios de otro nivel.
Disposición
El menú se sitúa horizontalmente en la barra superior (infr-topbar). De izquierda a derecha:
| Zona | Contenido |
|---|---|
| Marca | Logotipo de InfraGuard (escudo + pulso de monitorización) → lleva a Resumen (/) |
| Menú de roles | infr-nav: 8 áreas de rol; al pasar el ratón se despliega un panel de subelementos |
| Acciones de la derecha | conmutador de menú móvil · selector de idioma · conmutador de tema · menú de usuario |
Cada elemento de primer nivel se dibuja como icono MDI + etiqueta + (si tiene hijos) un galón; los hijos aparecen en un panel desplegable (infr-nav__panel). Cuando la ruta actual coincide con el href de un hijo, el elemento de primer nivel recibe is-active (Resumen solo está activo cuando la ruta es exactamente /).
Las 8 áreas de rol
Este es el árbol de primer nivel que construye SitemapSeeder. La body_class se aplica a <body> al entrar en un área, acotando los estilos de la página.
| # | Área de rol | Responsable | body_class |
user_level mínimo |
|---|---|---|---|---|
| 1 | Resumen | común | infr-overview |
1 |
| 2 | Infraestructura | operaciones de infraestructura | infr-infra |
1 |
| 3 | Servicio | operaciones de servicio | infr-service |
1 |
| 4 | Seguridad | operaciones de seguridad | infr-security |
2 |
| 5 | Copias y recuperación | infraestructura (también) | infr-backup |
2 |
| 6 | Activos | referencia común (CMDB) | infr-asset |
1 |
| 7 | Administración | administración | infr-admin |
10 |
| 8 | Desarrollo | super_admin | infr-dev |
9 |
Subelementos por área
Cada subelemento lleva su propio min_req (normalmente el mismo que el del padre, a veces más alto).
Infraestructura (min_req 1)
| Elemento | Ruta | min_req |
|---|---|---|
| Estado | /infra/health |
1 |
| Servidores | /infra/servers |
1 |
| Almacenamiento y RAID | /infra/storage |
1 |
| Conexiones de puerto | /infra/traffic/ports |
1 |
| Conexiones IP | /infra/traffic/ips |
1 |
| Tráfico | /infra/traffic/net |
1 |
| Alertas | /infra/alert |
1 |
Servicio (min_req 1)
| Elemento | Ruta | min_req |
|---|---|---|
| Resumen | /service |
1 |
| Web | /service/web |
1 |
| Base de datos | /service/database |
1 |
| Sesiones | /service/session |
1 |
| Catálogo | /service/catalog |
1 |
| Proyectos | /service/projects |
1 |
| Resolución de problemas | /service/resolution |
2 |
Seguridad (min_req 2; todos los elementos, 2)
| Elemento | Ruta |
|---|---|
| Resumen | /security |
| Amenazas | /security/threats |
| Detecciones | /security/detections |
| Conjuntos de reglas | /security/rulesets |
| Cortafuegos | /security/firewall |
| Lista de bloqueo y reputación | /security/blocklist |
| Lista blanca | /security/whitelist |
| Diagnóstico de seguridad | /security/diagnostics |
| Resolución de problemas | /security/resolution |
Copias y recuperación (min_req 2): Panel de programación /backup/board · Scripts de copia /backup/scripts · Almacenes /backup/vaults · Recuperación y validación /backup/recovery.
Activos (min_req 1): Inventario /asset/inventory · Instancias /asset/instances · Hardware /asset/hardware · Almacenamiento y archivos /asset/storage.
Administración (min_req 10; todos los elementos, 10): Usuarios y roles /admin/users · Recolectores /admin/collectors · Política de operaciones /admin/ops-policy · Claves API /admin/api-keys · Reglas y umbrales /admin/rules · API de reputación /admin/reputation-providers · Adaptadores de IA /admin/ai-providers · Adaptadores de correo /admin/mail-providers · Adaptadores SMS /admin/sms-providers · Localización /admin/localization · Auditoría /admin/audit.
Desarrollo (min_req 9; todos los elementos, 9): Dev Overview /dev · Doctor /dev/doctor · Runtime & Leader /dev/leader · Slow Queries/Requests/Jobs/Outgoing · Exceptions · Cache · Servers · Usage · Pulse /pulse · Horizon /horizon.
Cómo se usa
Navegar
Pase el ratón sobre un elemento de primer nivel para abrir su panel. Al hacer clic en un elemento se navega a la pantalla y se aplica la body_class de esa área a <body>. En pantallas estrechas, la hamburguesa de la esquina superior derecha (data-nav-toggle) despliega el menú.
Qué ve su nivel
Al iniciar sesión, el middleware InfrAuth sincroniza users.user_level con la clave de sesión infr_user_level. Al renderizar, Menu::for_user($level) recorre el árbol y oculta de forma recursiva todo nodo con min_req > your level. Por ejemplo:
- Nivel 1 (demo): ve Resumen · Infraestructura · Servicio · Activos, pero no Seguridad (2), Copias (2), Administración (10) ni Desarrollo (9).
- Nivel 5 (staff): lo anterior más Seguridad · Copias y recuperación (ambas, 2).
- Nivel 10 (admin): todo, incluidas Administración (10) y Desarrollo (9).
Desarrollo (9) y Administración (10) tienen umbrales distintos. Un super_admin con nivel exactamente 9 ve Desarrollo pero no Administración. Un administrador (10) ve ambas.
Añadir o reestructurar el menú (administración/desarrollo)
Todavía no hay una interfaz de edición del menú. La fuente de verdad del árbol es el código (database/seeders/SitemapSeeder.php), y el sembrador borra todas las filas y las vuelve a crear en cada ejecución (resincronización canónica).
# Tras editar el árbol, resincronice (solo toca infr_sitemap; los datos heredados están a salvo)
php artisan db:seed --class=SitemapSeeder
El sembrador llama a Menu::flush() al final, así que los cambios surten efecto de inmediato. Si un elemento nuevo muestra su nombre en bruto (en inglés), le falta una clave de traducción: añádala en resources/lang/{ko,en}/menu.php siguiendo la regla Str::slug(name, '_') (por ejemplo, Storage & RAID → storage_raid).
Nunca ejecute
migrate:fresh. InfraGuard comparte conexión con la MySQL heredada de stats-design. Para refrescar únicamente el menú, use exclusivamentedb:seed --class=SitemapSeeder.
Fuentes de datos
La tabla infr_sitemap
Una tabla independiente, propiedad de la aplicación (distinta de la sitemap heredada sin prefijo). Modelo: App\Models\Infr\InfrSitemap.
| Columna | Significado |
|---|---|
parent_id |
0 = primer nivel; si no, id del nodo padre |
seq |
orden entre hermanos |
depth |
0 = área de rol, 1 = subelemento |
name |
nombre en bruto (origen de la clave de etiqueta) |
href |
ruta del enlace (# = padre sin enlace) |
icon |
glifo MDI (por ejemplo, mdi-server) |
body_class |
solo primer nivel: clase de <body> al entrar |
is_view |
1 para incluirlo en el árbol |
min_req |
user_level mínimo (límite de permisos) |
App\Support\Menu: constructor del árbol + caché
Menu::tree(): lee las filas conis_view=1ordenadas porseq,id, ensambla un árbol recursivo y lo cachea conrememberForever(claveinfr:menu:v2). Si Redis no está disponible, repliega a unbuild()sin caché.Menu::for_user($level): filtra el árbol de forma recursiva pormin_req > $level.Menu::flush(): invalida la caché (lo llama el sembrador).
La caché guarda el
nameen bruto; la traducción ocurre en el renderizado medianteLocales::menuLabel(). Por eso cambiar de idioma no requiere vaciar la caché. En cambio, añadir o renombrar nodos exige volver a sembrar (lo que sí vacía la caché).
Traducción de etiquetas
App\Support\Locales::menuLabel($name) busca la clave menu. + Str::slug($name, '_'). Si la clave existe, traduce; si no, devuelve el nombre en bruto (repliegue seguro). Los paquetes están en resources/lang/{locale}/menu.php.
// En el renderizado (nav.blade.php)
{{ \App\Support\Locales::menuLabel($top['name']) }}
// "Storage & RAID" → __('menu.storage_raid') → "Storage & RAID" (en) / "Almacenamiento y RAID" (es)
Sesión y middleware
InfrAuth: al autenticar, sincronizausers.user_level→ sesióninfr_user_level. Es la entrada del filtro del menú.InfrLevel(infr.level:N): puerta de ruta. Devuelve 403 siinfr_user_level < N(aplicación en el servidor, independiente de la ocultación del menú).InfrAdmin/InfrDev: protegen los grupos de rutas de Administración (≥10) y Desarrollo (≥9).
Acceso
Nivel (user_level) |
Alias | Visible en el menú |
|---|---|---|
| 1 | demo/viewer | Resumen · Infraestructura · Servicio · Activos (casi todo de lectura) |
| 5 | staff | + Seguridad · Copias y recuperación |
| 9 | super_admin | + Desarrollo |
| 10 | admin | + Administración (y Desarrollo) |
- Ocultar el menú es solo una comodidad y una primera línea de defensa. El control real lo aplica el servidor mediante el middleware por ruta
infr.level:N/InfrAdmin/InfrDev(escribir la URL directamente sigue devolviendo 403). - Las acciones destructivas o de seguridad (bloqueos, restauraciones, cambios de reglas, …) suelen volver a filtrarse dentro de cada pantalla con un nivel de escritura aparte (por ejemplo, escritura ≥2, administración ≥10) y quedan registradas en el registro de auditoría.
Para las definiciones de nivel, consulte Niveles RBAC; para la gestión de roles y equipos, Roles y equipos.
Resolución de problemas y preguntas frecuentes
Falta un elemento del menú.
Normalmente es un nivel insuficiente. Compruebe que su user_level sea ≥ el min_req de ese nodo (véanse las tablas anteriores). Los administradores ajustan los niveles en Usuarios y equipos.
Un elemento de menú recién añadido muestra su nombre en inglés (en bruto).
Al paquete menu.php le falta una clave de traducción. Añádala tanto en resources/lang/ko/menu.php como en en/menu.php siguiendo la regla Str::slug(name,'_'). Si la clave no existe, la pantalla sigue funcionando con seguridad usando el nombre en bruto.
Ejecuté el sembrador, pero el menú no cambió.
Es posible que la caché esté obsoleta. El sembrador llama a Menu::flush() al final, pero también puede probar php artisan cache:clear. Si Redis está caído, Menu repliega a build() en cada petición, de modo que la caché no puede ser la culpable.
Cambié de idioma, pero solo las etiquetas del menú no cambiaron.
Las etiquetas se resuelven en el renderizado, no se cachean. Verifique que el menu.php del idioma de destino tenga la clave. Si no, revise el estado de activación y traducción en la página de Localización.
¿Puede alguien llegar a una pantalla oculta escribiendo la URL?
No. Aunque el menú esté oculto, el middleware de ruta (infr.level:N, etc.) devuelve 403 desde el servidor.
Relacionado
- Niveles RBAC: cómo se evalúan
user_levelymin_req - Roles y equipos: roles, equipos y propietarios
- Localización: cambio de idioma y repliegue
- Tema: tokens claro/oscuro
- Usuarios y equipos (administración): ajustar niveles
- Resumen (portada): la pantalla de inicio con el estado unificado

