352 lines
9.0 KiB
Markdown
352 lines
9.0 KiB
Markdown
|
|
# 메뉴 회사별 필터링 개선 완료
|
||
|
|
|
||
|
|
## 📋 개요
|
||
|
|
|
||
|
|
**문제점**: SUPER_ADMIN이 좌측 사이드바에서 모든 회사의 메뉴를 보게 되어 혼란스러움
|
||
|
|
|
||
|
|
**해결책**:
|
||
|
|
|
||
|
|
- **좌측 사이드바**: 모든 사용자(SUPER_ADMIN 포함)가 **공통 메뉴만** 표시
|
||
|
|
- **메뉴 관리 화면**: SUPER_ADMIN만 **전체 메뉴** 관리 가능
|
||
|
|
|
||
|
|
## 🎯 개선 내용
|
||
|
|
|
||
|
|
### 핵심 차이점
|
||
|
|
|
||
|
|
| 화면 유형 | SUPER_ADMIN | COMPANY_ADMIN | 일반 사용자 |
|
||
|
|
| ------------------ | -------------- | ----------------- | -------------- |
|
||
|
|
| **좌측 사이드바** | 공통 메뉴만 ✅ | 공통 메뉴만 ✅ | 공통 메뉴만 ✅ |
|
||
|
|
| **메뉴 관리 화면** | 전체 메뉴 ✅ | 자기 회사 메뉴 ✅ | 접근 불가 ❌ |
|
||
|
|
|
||
|
|
### 1. 좌측 사이드바 (`menuType=0` 또는 `menuType=1`)
|
||
|
|
|
||
|
|
**모든 사용자**: 공통 메뉴만 표시 (`company_code IS NULL`)
|
||
|
|
|
||
|
|
```sql
|
||
|
|
-- 모든 사용자 공통
|
||
|
|
WHERE STATUS = 'active'
|
||
|
|
AND MENU.COMPANY_CODE IS NULL -- 공통 메뉴만
|
||
|
|
```
|
||
|
|
|
||
|
|
**이유**:
|
||
|
|
|
||
|
|
- SUPER_ADMIN도 일반 업무 시에는 공통 메뉴만 사용
|
||
|
|
- 다른 회사 메뉴가 섞여 보이면 혼란스러움
|
||
|
|
- 메뉴 관리는 별도 화면에서 수행
|
||
|
|
|
||
|
|
### 2. 메뉴 관리 화면 (`menuType=undefined`)
|
||
|
|
|
||
|
|
#### SUPER_ADMIN
|
||
|
|
|
||
|
|
- **모든 회사의 메뉴** 표시 및 관리 가능
|
||
|
|
|
||
|
|
```sql
|
||
|
|
WHERE STATUS = 'active' -- 필터 없음
|
||
|
|
```
|
||
|
|
|
||
|
|
#### COMPANY_ADMIN
|
||
|
|
|
||
|
|
- **자기 회사 메뉴 + 공통 메뉴** 표시 및 관리
|
||
|
|
|
||
|
|
```sql
|
||
|
|
WHERE STATUS = 'active'
|
||
|
|
AND (MENU.COMPANY_CODE = '사용자회사코드' OR MENU.COMPANY_CODE IS NULL)
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🔧 수정된 코드
|
||
|
|
|
||
|
|
### `adminService.ts` - getAdminMenuList()
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// 좌측 사이드바 관리자 메뉴는 모든 사용자가 공통 메뉴만 표시
|
||
|
|
// SUPER_ADMIN도 좌측 사이드바에서는 공통 메뉴만 보임
|
||
|
|
// 메뉴 관리 화면(menuType 없음)에서만 전체 메뉴 조회
|
||
|
|
if (menuType === undefined) {
|
||
|
|
// 메뉴 관리 화면: SUPER_ADMIN은 전체, 나머지는 자기 회사만
|
||
|
|
if (userType === "SUPER_ADMIN" && userCompanyCode === "*") {
|
||
|
|
logger.info("✅ 메뉴 관리 화면 (SUPER_ADMIN): 모든 메뉴 표시");
|
||
|
|
companyFilter = "";
|
||
|
|
} else {
|
||
|
|
logger.info(
|
||
|
|
`✅ 메뉴 관리 화면: 회사 ${userCompanyCode} 메뉴 + 공통 메뉴 표시`
|
||
|
|
);
|
||
|
|
companyFilter = `AND (MENU.COMPANY_CODE = $${paramIndex} OR MENU.COMPANY_CODE IS NULL)`;
|
||
|
|
queryParams.push(userCompanyCode);
|
||
|
|
paramIndex++;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
// 좌측 사이드바: 모든 사용자가 공통 메뉴만
|
||
|
|
logger.info("✅ 좌측 사이드바 (관리자): 공통 메뉴만 표시");
|
||
|
|
companyFilter = `AND MENU.COMPANY_CODE IS NULL`;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### `adminService.ts` - getUserMenuList()
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// 좌측 사이드바 메뉴는 모든 사용자가 공통 메뉴만 표시
|
||
|
|
// (SUPER_ADMIN도 좌측 사이드바에서는 공통 메뉴만 보임)
|
||
|
|
// 메뉴 관리 화면에서는 별도로 전체 메뉴 조회
|
||
|
|
|
||
|
|
// 모든 사용자: 공통 메뉴만 (company_code IS NULL)
|
||
|
|
companyFilter = `AND MENU.COMPANY_CODE IS NULL`;
|
||
|
|
logger.info("✅ 좌측 사이드바: 공통 메뉴만 표시");
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🧪 테스트 시나리오
|
||
|
|
|
||
|
|
### 시나리오 1: SUPER_ADMIN 로그인
|
||
|
|
|
||
|
|
#### 좌측 사이드바
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# ✅ 공통 메뉴만 표시
|
||
|
|
- 공통 대시보드
|
||
|
|
- 공통 설정
|
||
|
|
- 공통 보고서
|
||
|
|
|
||
|
|
# ❌ 표시되지 않음
|
||
|
|
- ILSHIN 전용 메뉴
|
||
|
|
- VEXPLOR 전용 메뉴
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 메뉴 관리 화면 (`/admin/menus`)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# ✅ 모든 회사 메뉴 표시
|
||
|
|
- ILSHIN 전용 메뉴 (company_code='ILSHIN')
|
||
|
|
- VEXPLOR 전용 메뉴 (company_code='VEXPLOR')
|
||
|
|
- 공통 메뉴 (company_code IS NULL)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 시나리오 2: COMPANY_ADMIN (ILSHIN) 로그인
|
||
|
|
|
||
|
|
#### 좌측 사이드바
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# ✅ 공통 메뉴만 표시
|
||
|
|
- 공통 대시보드
|
||
|
|
- 공통 설정
|
||
|
|
- 공통 보고서
|
||
|
|
|
||
|
|
# ❌ 표시되지 않음
|
||
|
|
- ILSHIN 전용 메뉴
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 메뉴 관리 화면 (`/admin/menus`)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# ✅ ILSHIN 메뉴 + 공통 메뉴 표시
|
||
|
|
- ILSHIN 전용 메뉴 (company_code='ILSHIN')
|
||
|
|
- 공통 메뉴 (company_code IS NULL)
|
||
|
|
|
||
|
|
# ❌ 표시되지 않음
|
||
|
|
- VEXPLOR 전용 메뉴
|
||
|
|
```
|
||
|
|
|
||
|
|
### 시나리오 3: 일반 사용자 로그인
|
||
|
|
|
||
|
|
#### 좌측 사이드바
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# ✅ 공통 메뉴만 표시
|
||
|
|
- 공통 대시보드
|
||
|
|
- 공통 설정
|
||
|
|
- 공통 보고서
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 메뉴 관리 화면
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# ❌ 접근 불가 (권한 없음)
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📝 로그 확인
|
||
|
|
|
||
|
|
### 좌측 사이드바 접근 시
|
||
|
|
|
||
|
|
```log
|
||
|
|
# 관리자 메뉴 (menuType=0)
|
||
|
|
✅ 좌측 사이드바 (관리자): 공통 메뉴만 표시
|
||
|
|
|
||
|
|
# 사용자 메뉴 (menuType=1)
|
||
|
|
✅ 좌측 사이드바: 공통 메뉴만 표시
|
||
|
|
```
|
||
|
|
|
||
|
|
### 메뉴 관리 화면 접근 시
|
||
|
|
|
||
|
|
```log
|
||
|
|
# SUPER_ADMIN
|
||
|
|
✅ 메뉴 관리 화면 (SUPER_ADMIN): 모든 메뉴 표시
|
||
|
|
|
||
|
|
# COMPANY_ADMIN
|
||
|
|
✅ 메뉴 관리 화면: 회사 ILSHIN 메뉴 + 공통 메뉴 표시
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📊 API 응답 예시
|
||
|
|
|
||
|
|
### 좌측 사이드바 (모든 사용자 동일)
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// GET /api/admin/menus?menuType=1
|
||
|
|
|
||
|
|
{
|
||
|
|
"success": true,
|
||
|
|
"data": [
|
||
|
|
{
|
||
|
|
"objid": "1",
|
||
|
|
"menu_name_kor": "공통 대시보드",
|
||
|
|
"company_code": null // ✅ 공통 메뉴만
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"objid": "2",
|
||
|
|
"menu_name_kor": "공통 설정",
|
||
|
|
"company_code": null // ✅ 공통 메뉴만
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 메뉴 관리 화면 (SUPER_ADMIN)
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// GET /api/admin/menus (menuType 없음)
|
||
|
|
|
||
|
|
{
|
||
|
|
"success": true,
|
||
|
|
"data": [
|
||
|
|
{ "menu_name_kor": "ILSHIN 메뉴", "company_code": "ILSHIN" }, // ✅ 전체
|
||
|
|
{ "menu_name_kor": "VEXPLOR 메뉴", "company_code": "VEXPLOR" }, // ✅ 전체
|
||
|
|
{ "menu_name_kor": "공통 메뉴", "company_code": null } // ✅ 전체
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 메뉴 관리 화면 (COMPANY_ADMIN, ILSHIN)
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// GET /api/admin/menus (menuType 없음)
|
||
|
|
|
||
|
|
{
|
||
|
|
"success": true,
|
||
|
|
"data": [
|
||
|
|
{ "menu_name_kor": "ILSHIN 메뉴", "company_code": "ILSHIN" }, // ✅ 자기 회사
|
||
|
|
{ "menu_name_kor": "공통 메뉴", "company_code": null } // ✅ 공통
|
||
|
|
// ❌ VEXPLOR 메뉴 없음
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🎨 사용자 경험 개선
|
||
|
|
|
||
|
|
### Before (문제점)
|
||
|
|
|
||
|
|
```
|
||
|
|
SUPER_ADMIN 로그인
|
||
|
|
└─ 좌측 사이드바
|
||
|
|
├─ ILSHIN 대시보드 ← 혼란스러움
|
||
|
|
├─ ILSHIN 보고서 ← 혼란스러움
|
||
|
|
├─ VEXPLOR 대시보드 ← 혼란스러움
|
||
|
|
├─ VEXPLOR 보고서 ← 혼란스러움
|
||
|
|
└─ 공통 설정
|
||
|
|
```
|
||
|
|
|
||
|
|
### After (개선)
|
||
|
|
|
||
|
|
```
|
||
|
|
SUPER_ADMIN 로그인
|
||
|
|
└─ 좌측 사이드바
|
||
|
|
├─ 공통 대시보드 ← 깔끔함
|
||
|
|
├─ 공통 설정 ← 깔끔함
|
||
|
|
└─ 공통 보고서 ← 깔끔함
|
||
|
|
|
||
|
|
└─ 메뉴 관리 화면 (/admin/menus)
|
||
|
|
├─ ILSHIN 대시보드 ← 관리 목적
|
||
|
|
├─ ILSHIN 보고서 ← 관리 목적
|
||
|
|
├─ VEXPLOR 대시보드 ← 관리 목적
|
||
|
|
├─ VEXPLOR 보고서 ← 관리 목적
|
||
|
|
└─ 공통 설정
|
||
|
|
```
|
||
|
|
|
||
|
|
## ✅ 완료 체크리스트
|
||
|
|
|
||
|
|
- [x] getAdminMenuList() 수정 (menuType 조건 분기)
|
||
|
|
- [x] getUserMenuList() 수정 (공통 메뉴만 필터링)
|
||
|
|
- [x] 로그 메시지 개선
|
||
|
|
- [x] 린트 에러 해결
|
||
|
|
- [x] 문서 작성
|
||
|
|
- [ ] 실제 테스트
|
||
|
|
- [ ] SUPER_ADMIN - 좌측 사이드바
|
||
|
|
- [ ] SUPER_ADMIN - 메뉴 관리 화면
|
||
|
|
- [ ] COMPANY_ADMIN - 좌측 사이드바
|
||
|
|
- [ ] COMPANY_ADMIN - 메뉴 관리 화면
|
||
|
|
|
||
|
|
## 🚨 주의사항
|
||
|
|
|
||
|
|
### 공통 메뉴 (`company_code IS NULL`)
|
||
|
|
|
||
|
|
- 모든 회사에서 공통으로 사용하는 메뉴
|
||
|
|
- 예: 대시보드, 설정, 공지사항 등
|
||
|
|
- **반드시 `company_code`를 `NULL`로 설정**해야 좌측 사이드바에 표시됨
|
||
|
|
|
||
|
|
### 회사 전용 메뉴
|
||
|
|
|
||
|
|
- 특정 회사에서만 사용하는 메뉴
|
||
|
|
- `company_code`에 회사 코드 지정 (예: `ILSHIN`, `VEXPLOR`)
|
||
|
|
- 좌측 사이드바에는 표시되지 않음
|
||
|
|
- 메뉴 관리 화면에서만 표시됨
|
||
|
|
|
||
|
|
## 🔮 향후 개선 사항
|
||
|
|
|
||
|
|
### 1. 회사 전환 기능
|
||
|
|
|
||
|
|
SUPER_ADMIN이 특정 회사 컨텍스트로 전환하여 해당 회사 메뉴를 볼 수 있는 기능:
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
// 헤더에 회사 선택 드롭다운
|
||
|
|
<Select value={currentCompany} onChange={switchCompany}>
|
||
|
|
<option value="*">전체 (관리자 모드)</option>
|
||
|
|
<option value="ILSHIN">ILSHIN</option>
|
||
|
|
<option value="VEXPLOR">VEXPLOR</option>
|
||
|
|
</Select>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. 메뉴 타입 추가
|
||
|
|
|
||
|
|
- 공통 메뉴 (company_code IS NULL)
|
||
|
|
- 회사 전용 메뉴 (company_code 지정)
|
||
|
|
- **부서 전용 메뉴** (향후 추가)
|
||
|
|
|
||
|
|
### 3. 동적 메뉴 표시
|
||
|
|
|
||
|
|
사용자 권한에 따라 메뉴 항목의 표시 여부 결정:
|
||
|
|
|
||
|
|
```sql
|
||
|
|
-- 권한 기반 메뉴 필터링 (향후 개선)
|
||
|
|
SELECT * FROM get_user_menus_with_permissions('user_id', 'company_code');
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🎉 결론
|
||
|
|
|
||
|
|
### 개선 효과
|
||
|
|
|
||
|
|
1. **사용자 경험 개선**
|
||
|
|
|
||
|
|
- SUPER_ADMIN도 좌측 사이드바에서 깔끔한 UI 제공
|
||
|
|
- 다른 회사 메뉴가 섞이지 않아 혼란 방지
|
||
|
|
|
||
|
|
2. **권한 분리**
|
||
|
|
|
||
|
|
- 일반 업무: 공통 메뉴만 사용
|
||
|
|
- 관리 업무: 메뉴 관리 화면에서 전체 메뉴 관리
|
||
|
|
|
||
|
|
3. **확장성**
|
||
|
|
- 향후 회사별 메뉴 추가 시에도 좌측 사이드바는 깔끔하게 유지
|
||
|
|
- 메뉴 관리 화면에서만 복잡한 메뉴 구조 관리
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**문서 작성일**: 2025-01-XX
|
||
|
|
**작성자**: AI Assistant
|
||
|
|
**버전**: 2.0 (개선판)
|