# WING 메뉴 탭 추가 가이드
새로운 메뉴 탭을 추가할 때 필요한 절차를 설명합니다.
## 메뉴 시스템 구조
```
DB: AUTH_SETTING (menu.config JSON)
↕ GET/PUT /api/menus
Backend: settingsService.ts (DEFAULT_MENU_CONFIG, VALID_MENU_IDS)
↕ API
Frontend: menuStore.ts → TopBar.tsx (탭 렌더링)
→ App.tsx (renderView 라우팅)
```
- **DB**가 메뉴 정의의 단일 소스 (id, label, icon, enabled, order)
- **TopBar**는 `enabled && hasPermission` 조건으로 탭을 필터링하고 `order` 순 정렬
- **App.tsx**의 `renderView`가 탭 ID에 따라 뷰 컴포넌트를 매핑
- **admin** 탭은 메뉴 관리 대상에서 제외 (TopBar에서 별도 아이콘 버튼으로 접근)
## 수정 파일 요약
| 순서 | 파일 | 작업 | 필수 |
|------|------|------|------|
| 1 | `frontend/src/tabs/{탭명}/components/XxxView.tsx` | 뷰 컴포넌트 생성 | O |
| 2 | `frontend/src/tabs/{탭명}/index.ts` | re-export 생성 | O |
| 3 | `frontend/src/App.tsx` | MainTab 타입 + import + renderView | O |
| 4 | `backend/src/settings/settingsService.ts` | DEFAULT_MENU_CONFIG에 항목 추가 | O |
| 5 | `database/auth_init.sql` | menu.config 초기 JSON에 추가 | O |
| 6 | 관리자 UI | 메뉴 관리에서 활성화 | O |
## Step 1: 뷰 컴포넌트 생성
`frontend/src/tabs/{탭명}/components/` 에 새 뷰 컴포넌트를 생성합니다.
```tsx
// frontend/src/tabs/monitoring/components/MonitoringView.tsx
export function MonitoringView() {
return (
)
}
```
`index.ts`에서 re-export합니다:
```tsx
// frontend/src/tabs/monitoring/index.ts
export { MonitoringView } from './components/MonitoringView'
```
기존 탭(`@tabs/prediction`, `@tabs/weather` 등)의 레이아웃 패턴을 참고하세요.
공통 모듈은 `@common/` alias로 import합니다.
## Step 2: App.tsx 탭 등록
3가지를 수정합니다.
### 2-1. MainTab 타입에 ID 추가
```tsx
// frontend/src/App.tsx (line 20)
// Before
export type MainTab = 'prediction' | 'hns' | ... | 'admin'
// After
export type MainTab = 'prediction' | 'hns' | ... | 'monitoring' | 'admin'
```
### 2-2. 뷰 컴포넌트 import
```tsx
import { MonitoringView } from '@tabs/monitoring'
```
### 2-3. renderView switch에 case 추가
```tsx
const renderView = () => {
switch (activeMainTab) {
// ... 기존 case들 ...
case 'monitoring':
return
// ...
}
}
```
## Step 3: 백엔드 메뉴 설정 등록
`backend/src/settings/settingsService.ts`의 `DEFAULT_MENU_CONFIG` 배열에 항목을 추가합니다.
```typescript
const DEFAULT_MENU_CONFIG: MenuConfigItem[] = [
// ... 기존 10개 메뉴 ...
{ id: 'monitoring', label: '실시간 모니터링', icon: '📡', enabled: true, order: 11 },
]
```
`VALID_MENU_IDS`는 `DEFAULT_MENU_CONFIG`에서 자동 파생되므로 별도 수정 불필요합니다.
```typescript
const VALID_MENU_IDS = DEFAULT_MENU_CONFIG.map(m => m.id) // 자동 포함됨
```
> **주의**: `updateMenuConfig()`은 `VALID_MENU_IDS.length` 개수 전체가 포함되어야 저장을 허용합니다.
> 기존 운영 DB에 새 메뉴가 없는 상태에서도 `getMenuConfig()`의 fallback이 DEFAULT_MENU_CONFIG을 반환하므로 정상 동작합니다.
## Step 4: DB 초기 데이터 업데이트
`database/auth_init.sql`의 `menu.config` 초기 JSON에 새 항목을 추가합니다.
```sql
INSERT INTO AUTH_SETTING (SETTING_KEY, SETTING_VAL, SETTING_DC, MDFCN_DTM) VALUES
('menu.config', '[
{"id":"prediction","label":"유출유 확산예측","icon":"🛢️","enabled":true,"order":1},
...기존 메뉴들...
{"id":"monitoring","label":"실시간 모니터링","icon":"📡","enabled":true,"order":11}
]', '메뉴 구성 설정', NOW())
ON CONFLICT (SETTING_KEY) DO NOTHING;
```
> **참고**: 이 SQL은 신규 설치 시에만 적용됩니다. 기존 운영 DB는 관리자 UI에서 메뉴를 관리합니다.
## Step 5: 관리자 메뉴 관리에서 활성화
코드 배포 후:
1. 관리자 계정으로 로그인
2. 관리자 패널(⚙️) → 메뉴 관리 탭
3. 새 메뉴가 목록에 표시됨
4. 활성/비활성 토글, 순서, 라벨, 아이콘을 설정
5. "변경사항 저장" 클릭
> 기존 DB에 새 메뉴 ID가 없으면 `getMenuConfig()`가 DEFAULT_MENU_CONFIG fallback을 사용하여 새 메뉴가 자동으로 목록에 나타납니다.
## 실전 예시: "모니터링" 탭 추가
### 1. 뷰 컴포넌트 생성
```bash
# frontend/src/components/views/MonitoringView.tsx 파일 생성
```
### 2. App.tsx 수정 (3곳)
```diff
+ import { MonitoringView } from './components/views/MonitoringView'
- export type MainTab = 'prediction' | 'hns' | 'rescue' | 'reports' | 'aerial' | 'assets' | 'scat' | 'incidents' | 'board' | 'weather' | 'admin'
+ export type MainTab = 'prediction' | 'hns' | 'rescue' | 'reports' | 'aerial' | 'assets' | 'scat' | 'incidents' | 'board' | 'weather' | 'monitoring' | 'admin'
const renderView = () => {
switch (activeMainTab) {
// ...
+ case 'monitoring':
+ return
case 'admin':
return
}
}
```
### 3. settingsService.ts 수정
```diff
const DEFAULT_MENU_CONFIG: MenuConfigItem[] = [
// ... 기존 메뉴들 ...
{ id: 'incidents', label: '통합조회', icon: '🔍', enabled: true, order: 10 },
+ { id: 'monitoring', label: '실시간 모니터링', icon: '📡', enabled: true, order: 11 },
]
```
### 4. auth_init.sql 수정
menu.config JSON에 새 항목 추가 (신규 설치용)
### 5. 배포 후 관리자 UI에서 활성화
## 체크리스트
- [ ] 뷰 컴포넌트 생성 (`frontend/src/components/views/`)
- [ ] `MainTab` 타입 업데이트 (`App.tsx`)
- [ ] import 및 renderView switch case 추가 (`App.tsx`)
- [ ] `DEFAULT_MENU_CONFIG`에 추가 (`settingsService.ts`)
- [ ] `menu.config` 초기 JSON 업데이트 (`auth_init.sql`)
- [ ] TypeScript 컴파일 통과 (`cd frontend && npx tsc --noEmit`)
- [ ] ESLint 통과 (`cd frontend && npx eslint .`)
- [ ] 관리자 메뉴 관리에서 새 메뉴 표시 확인