개요 — 무엇을 하나
InfraGuard의 상단 내비게이션은 역할(업무 영역)로 먼저 분기하고, 각 영역 안에서 업무 흐름으로 전개하는 "역할 우선 정보구조(IA)"입니다. 핵심 원칙 세 가지:
- 메뉴는 하드코딩이 아니라 DB로 구동됩니다. 모든 메뉴 노드는
infr_sitemap테이블(앱 소유·독립)에서 읽습니다. Blade에 메뉴를 박아두지 않습니다. - 역할 경계 = 권한 경계. 각 노드의
min_req(최소user_level)가 곧 접근 통제선입니다.user_level >= min_req일 때만 노드가 보이고, 서버측 라우트에서도 같은 기준으로 강제됩니다(이중 방어). - 라벨은 전부 번역 키를 경유합니다. 화면에 뜨는 텍스트는
__()/Locales::menuLabel()로 해석되어 8개 언어를 지원합니다.
지표(CPU·Load·5분 창 등)는 최상위 메뉴가 아니라 각 화면의 엔티티 탭·필터로 들어갑니다. "무엇을 보는가"가 아니라 "누가(어느 역할이) 무엇을 하는가"로 나눕니다.
이 문서에서 "도메인"은 오직 웹 TLD(
aaa.bbb.com)를 뜻합니다. 업무를 담당자 기준으로 나눈 구분은 "역할(role) / 영역(area)" 이라 부릅니다. 메뉴의 최상위 8개가 바로 이 "역할 영역"입니다.
언제 쓰나
- 처음 로그인해서 어디에 무엇이 있는지 파악할 때.
- 특정 화면이 안 보이는 이유(권한 부족인지, 언어 폴백인지)를 진단할 때.
- 메뉴를 추가·개편하고 시더를 다시 돌려야 할 때(관리자/개발자).
- 다른 등급의 사용자에게 무엇이 노출되는지 확인할 때.
화면 구성
메뉴는 상단 바(infr-topbar)에 가로로 배치됩니다. 왼쪽부터:
| 영역 | 내용 |
|---|---|
| 브랜드 | InfraGuard 로고(실드 + 모니터링 펄스) → 클릭 시 Overview(/) |
| 역할 메뉴 | infr-nav — 8개 역할 영역, hover 시 하위 항목 패널 |
| 우측 액션 | 모바일 메뉴 토글 · 언어 스위처 · 테마 토글 · 사용자 메뉴 |
각 최상위 항목은 아이콘(MDI) + 라벨 + (하위가 있으면) 셰브론으로 렌더되고, 하위 항목은 드롭다운 패널(infr-nav__panel)에 나옵니다. 현재 경로가 하위 항목과 매칭되면 해당 최상위 항목에 is-active 가 붙습니다(Overview는 경로가 정확히 / 일 때 활성).
8개 역할 영역
시더(SitemapSeeder)가 만드는 최상위 트리입니다. body_class 는 각 영역 진입 시 <body> 에 붙어 페이지별 스코프 스타일을 겁니다.
| 순서 | 역할 영역 | 담당 | body_class |
최소 user_level |
|---|---|---|---|---|
| 1 | Overview | 공통 | infr-overview |
1 |
| 2 | Infrastructure | 인프라 운영 | infr-infra |
1 |
| 3 | Service | 서비스 운영 | infr-service |
1 |
| 4 | Security | 보안 관제 | infr-security |
2 |
| 5 | Backup & Recovery | 인프라 겸임 | infr-backup |
2 |
| 6 | Assets | 공통 참조(CMDB) | infr-asset |
1 |
| 7 | Administration | 관리자 | infr-admin |
10 |
| 8 | Development | super_admin | infr-dev |
9 |
영역별 하위 항목
각 하위 항목은 자체 min_req 를 가집니다(대개 부모와 같으나 일부는 상향).
Infrastructure (min_req 1)
| 항목 | 경로 | min_req |
|---|---|---|
| Health | /infra/health |
1 |
| Servers | /infra/servers |
1 |
| Storage & RAID | /infra/storage |
1 |
| Port Connections | /infra/traffic/ports |
1 |
| IP Connections | /infra/traffic/ips |
1 |
| Traffic | /infra/traffic/net |
1 |
| Alerts | /infra/alert |
1 |
Service (min_req 1)
| 항목 | 경로 | min_req |
|---|---|---|
| Overview | /service |
1 |
| Web | /service/web |
1 |
| Database | /service/database |
1 |
| Sessions | /service/session |
1 |
| Catalog | /service/catalog |
1 |
| Projects | /service/projects |
1 |
| Problem Resolution | /service/resolution |
2 |
Security (min_req 2 — 전 항목 2)
| 항목 | 경로 |
|---|---|
| Overview | /security |
| Threats | /security/threats |
| Detections | /security/detections |
| Rulesets | /security/rulesets |
| Firewall | /security/firewall |
| Blocklist & Reputation | /security/blocklist |
| Whitelist | /security/whitelist |
| Security Diagnostics | /security/diagnostics |
| Problem Resolution | /security/resolution |
Backup & Recovery (min_req 2): Schedule Board /backup/board · Backup Scripts /backup/scripts · Vaults /backup/vaults · Recovery & Validation /backup/recovery.
Assets (min_req 1): Inventory /asset/inventory · Instances /asset/instances · Hardware /asset/hardware · Storage & Files /asset/storage.
Administration (min_req 10 — 전 항목 10): Users & Roles /admin/users · Collectors /admin/collectors · Operations Policy /admin/ops-policy · API Keys /admin/api-keys · Rules & Thresholds /admin/rules · Reputation API /admin/reputation-providers · AI Adapters /admin/ai-providers · Mail Adapters /admin/mail-providers · SMS Adapters /admin/sms-providers · Localization /admin/localization · Audit /admin/audit.
Development (min_req 9 — 전 항목 9): Dev Overview /dev · Doctor /dev/doctor · Runtime & Leader /dev/leader · Slow Queries/Requests/Jobs/Outgoing · Exceptions · Cache · Servers · Usage · Pulse /pulse · Horizon /horizon.
사용법
메뉴 이동
최상위 항목에 마우스를 올리면 하위 패널이 열립니다. 항목을 클릭하면 해당 화면으로 이동하고, 이동한 영역의 body_class 가 <body> 에 적용됩니다. 좁은 화면에서는 우측 상단 햄버거(data-nav-toggle)로 메뉴를 폅니다.
내 등급에서 보이는 것
로그인 시 InfrAuth 미들웨어가 users.user_level 을 세션 infr_user_level 로 동기화합니다. 렌더 시 Menu::for_user($level) 가 트리를 훑어 min_req > 내 레벨 인 노드를 재귀적으로 숨깁니다. 예:
- 레벨 1(데모): Overview · Infrastructure · Service · Assets 는 보이나, Security(2)·Backup(2)·Administration(10)·Development(9) 는 안 보임.
- 레벨 5(스탭): 위 + Security · Backup(둘 다 2) 까지.
- 레벨 10(관리자): 전부 + Administration(10) · Development(9).
Development(9)와 Administration(10)의 임계가 다릅니다. 정확히 레벨 9인 super_admin은 Development는 보지만 Administration은 못 봅니다. 관리자(10)는 둘 다 봅니다.
메뉴 추가·개편(관리자/개발자)
메뉴 편집 UI는 아직 없습니다. 트리의 SOT는 코드(database/seeders/SitemapSeeder.php)이며, 시더는 매 실행 시 전체 삭제 후 재생성(캐노니컬 재동기화)합니다.
# 트리를 고친 뒤 재동기화 (infr_sitemap 만 갱신 — 레거시 데이터 안전)
php artisan db:seed --class=SitemapSeeder
시더 마지막에 Menu::flush() 가 캐시를 비우므로 즉시 반영됩니다. 새 항목의 라벨이 원문(영문)으로 뜬다면 번역 키가 없는 것입니다 — resources/lang/{ko,en}/menu.php 에 Str::slug(name, '_') 규칙으로 키를 추가합니다(예: Storage & RAID → storage_raid).
migrate:fresh를 돌리지 말 것. InfraGuard는 레거시 stats-design MySQL과 커넥션을 공유합니다. 메뉴만 갱신할 때는 반드시db:seed --class=SitemapSeeder만 사용합니다.
데이터 소스
infr_sitemap 테이블
앱이 직접 소유하는 독립 테이블(레거시 무접두 sitemap 과 다름). 모델은 App\Models\Infr\InfrSitemap.
| 컬럼 | 의미 |
|---|---|
parent_id |
0=최상위, 그 외=부모 노드 id |
seq |
형제 간 정렬 순서 |
depth |
0=역할 영역, 1=하위 항목 |
name |
원문 이름(라벨 키의 소스) |
href |
링크 경로(# = 링크 없는 부모) |
icon |
MDI 글리프(예: mdi-server) |
body_class |
최상위에만 — 진입 시 <body> 클래스 |
is_view |
1이면 트리에 포함 |
min_req |
최소 user_level(권한 경계) |
App\Support\Menu — 트리 빌더 + 캐시
Menu::tree()—is_view=1행을seq,id순으로 읽어 재귀 트리로 조립,rememberForever로 캐시(키infr:menu:v2). Redis 미가용 시 캐시 없이build()폴백.Menu::for_user($level)— 트리를min_req > $level기준으로 재귀 필터.Menu::flush()— 캐시 무효화(시더가 호출).
캐시에는 원문
name이 담기고, 번역은 렌더 시점에Locales::menuLabel()로 해석됩니다. 그래서 언어를 바꿔도 캐시를 비울 필요가 없습니다. 반대로 노드를 추가·개명하면 재시드(→flush)가 필요합니다.
라벨 번역
App\Support\Locales::menuLabel($name) 이 menu. + Str::slug($name, '_') 키로 조회합니다. 키가 있으면 번역, 없으면 원문 그대로(안전 폴백). 팩은 resources/lang/{locale}/menu.php.
// 렌더에서 (nav.blade.php)
{{ \App\Support\Locales::menuLabel($top['name']) }}
// "Storage & RAID" → __('menu.storage_raid') → "스토리지 · RAID"
세션·미들웨어
InfrAuth— 인증 시users.user_level→ 세션infr_user_level동기화. 메뉴 필터의 입력값.InfrLevel(infr.level:N) — 라우트 게이트.infr_user_level < N이면 403(화면 숨김과 별개의 서버측 강제).InfrAdmin/InfrDev— 관리(≥10)·개발(≥9) 영역 라우트 보호.
권한
등급(user_level) |
별칭 | 메뉴에서 보이는 것 |
|---|---|---|
| 1 | demo/viewer | Overview · Infrastructure · Service · Assets(주로 읽기) |
| 5 | staff | + Security · Backup & Recovery |
| 9 | super_admin | + Development |
| 10 | admin | + Administration (그리고 Development 포함) |
- 메뉴 숨김은 편의이자 1차 방어일 뿐입니다. 진짜 통제는 라우트별
infr.level:N/InfrAdmin/InfrDev미들웨어가 서버에서 강제합니다(URL 을 직접 쳐도 403). - 파괴적·보안 작업(차단·복원·규칙 변경 등)은 대개 화면 안에서 별도의 쓰기 등급(예: 쓰기 ≥2, 관리 ≥10)으로 재게이팅되고 감사 로그에 남습니다.
자세한 등급 정의는 RBAC 등급, 역할·팀 관리는 역할 · 팀 참고.
문제해결 · FAQ
메뉴 항목이 안 보여요.
대개 등급 부족입니다. 내 user_level 이 그 노드의 min_req 이상인지 확인합니다(위 표). 등급은 관리자가 사용자 · 팀에서 조정합니다.
새로 추가한 메뉴가 영문(원문)으로 떠요.
menu.php 팩에 번역 키가 없는 것입니다. Str::slug(name,'_') 규칙으로 resources/lang/ko/menu.php 와 en/menu.php 양쪽에 키를 추가합니다. 키가 없어도 화면은 원문으로 안전하게 동작합니다.
시더를 돌렸는데 메뉴가 안 바뀌어요.
캐시 잔존일 수 있습니다. 시더는 끝에서 Menu::flush() 를 호출하지만, 수동으로 php artisan cache:clear 를 시도해 볼 수 있습니다. Redis 가 죽어 있으면 Menu 는 매 요청 build() 로 폴백하므로 캐시 문제는 사라집니다.
언어를 바꿨는데 메뉴 라벨만 안 바뀌어요.
라벨은 캐시가 아니라 렌더 시점 해석입니다. 해당 언어의 menu.php 에 키가 있는지 확인합니다. 없으면 다국어 페이지에서 언어 활성화/번역 상태를 점검합니다.
URL 을 직접 쳐서 상위 화면에 들어가지려나요?
아니다. 메뉴가 숨겨진 화면이라도 라우트 미들웨어(infr.level:N 등)가 서버에서 403 을 냅니다.
관련 항목
- RBAC 등급 —
user_level과min_req판정 원리 - 역할 · 팀 — 역할·팀·소유자 관리
- 다국어 — 언어 전환과 폴백
- 테마 — 라이트/다크 토큰
- 사용자 · 팀 관리 — 등급 조정(관리자)
- 개요(랜딩) — 첫 화면 통합 헬스

