# 메뉴 권한 관리 시스템 구축 **작업일자**: 2026-01-10 **파일명**: TASK_MENU_PERMISSION_20260110.md --- ## 현황 분석 ### 1. 현재 메뉴 구조 | 메뉴 | 경로 | 현재 권한 | 비고 | |------|------|-----------|------| | 대시보드 | / | 전체 | 로그인 필수 | | 주간보고 | /report/weekly | 전체 | 목록/상세 | | 주간보고 상세 | /report/weekly/[id] | 전체 | 수정/삭제는 본인+관리자 | | 취합보고 | /report/summary | 전체 | 취합하기 버튼 포함 | | 취합보고 상세 | /report/summary/[year]/[week] | 전체 | | | 프로젝트 | /project | 전체 | | | 프로젝트 상세 | /project/[id] | 전체 | | | 개선의견 | /feedback | 전체 | | | 마이페이지 | /mypage | 전체 | 본인만 | | **관리자 - 사용자관리** | /admin/user | ROLE_ADMIN | 목록/추가/수정 | | **관리자 - 일괄등록** | /admin/bulk-import | ROLE_ADMIN | | ### 2. 권한별 기능 제어 현황 | 기능 | 위치 | 권한 체크 | 설명 | |------|------|-----------|------| | 관리자 메뉴 표시 | AppHeader.vue | isAdmin | 드롭다운 메뉴 | | 사용자 관리 페이지 접근 | /admin/user/* | ROLE_ADMIN | 페이지 진입 시 체크 | | 일괄등록 페이지 접근 | /admin/bulk-import | isAdmin | 페이지 진입 시 체크 | | 주간보고 수정 | /report/weekly/[id] | isAdmin OR 본인 | canEdit computed | | 주간보고 삭제 | /report/weekly/[id] | isAdmin OR 본인 | canDelete computed | | 주간보고 목록 작성자 컬럼 | /report/weekly/index | isAdmin | 관리자만 보임 | | 취합보고 취합하기 | /report/summary | 없음 | ⚠️ 권한체크 없음 | ### 3. 권장 메뉴별 권한 설정 | 메뉴 | 관리자 | 매니저 | 일반사용자 | 비고 | |------|:------:|:------:|:----------:|------| | 대시보드 | ✓ | ✓ | ✓ | | | 주간보고 | ✓ | ✓ | ✓ | | | 취합보고 | ✓ | ✓ | ✗ | 매니저 이상만 | | 프로젝트 | ✓ | ✓ | ✓ | | | 개선의견 | ✓ | ✓ | ✓ | | | 마이페이지 | ✓ | ✓ | ✓ | | | 사용자관리 | ✓ | ✗ | ✗ | 관리자만 | | 일괄등록 | ✓ | ✗ | ✗ | 관리자만 | | **메뉴관리** | ✓ | ✗ | ✗ | **신규** | --- ## 작업 Phase ### Phase 1: DB 스키마 설계 및 생성 - [x] 시작: 2026-01-10 16:45:00 - [x] 완료: 2026-01-10 16:47:30 - [x] 소요시간: 2분 30초 **작업 내용:** 1. `wr_menu` 테이블 생성 (메뉴 마스터) 2. `wr_menu_role` 테이블 생성 (메뉴-권한 매핑) 3. 기존 메뉴 데이터 INSERT 4. 기본 권한 매핑 INSERT **테이블 설계:** ```sql -- 메뉴 마스터 CREATE TABLE wr_menu ( menu_id SERIAL PRIMARY KEY, menu_code VARCHAR(50) NOT NULL UNIQUE, -- 메뉴 코드 (예: DASHBOARD) menu_name VARCHAR(100) NOT NULL, -- 메뉴명 (예: 대시보드) menu_path VARCHAR(200), -- 경로 (예: /) menu_icon VARCHAR(50), -- 아이콘 (예: bi-house) parent_menu_id INTEGER REFERENCES wr_menu(menu_id), sort_order INTEGER DEFAULT 0, is_active BOOLEAN DEFAULT true, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- 메뉴-권한 매핑 CREATE TABLE wr_menu_role ( menu_role_id SERIAL PRIMARY KEY, menu_id INTEGER NOT NULL REFERENCES wr_menu(menu_id) ON DELETE CASCADE, role_id INTEGER NOT NULL REFERENCES wr_role(role_id) ON DELETE CASCADE, created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(menu_id, role_id) ); ``` --- ### Phase 2: Backend API 개발 - [x] 시작: 2026-01-10 16:47:35 - [x] 완료: 2026-01-10 16:50:10 - [x] 소요시간: 2분 35초 **작업 내용:** 1. `GET /api/admin/menu/list` - 메뉴 목록 조회 (권한 포함) 2. `POST /api/admin/menu/create` - 메뉴 추가 3. `PUT /api/admin/menu/[id]/update` - 메뉴 수정 4. `DELETE /api/admin/menu/[id]/delete` - 메뉴 삭제 5. `POST /api/admin/menu/[id]/toggle-role` - 메뉴 권한 토글 6. `GET /api/auth/menu` - 현재 사용자 접근 가능 메뉴 조회 **파일 목록:** - backend/api/admin/menu/list.get.ts - backend/api/admin/menu/create.post.ts - backend/api/admin/menu/[id]/update.put.ts - backend/api/admin/menu/[id]/delete.delete.ts - backend/api/admin/menu/[id]/toggle-role.post.ts - backend/api/auth/menu.get.ts --- ### Phase 3: 메뉴관리 페이지 개발 - [x] 시작: 2026-01-10 16:50:15 - [x] 완료: 2026-01-10 16:52:00 - [x] 소요시간: 1분 45초 **작업 내용:** 1. 메뉴 목록 페이지 (사용자관리와 유사한 UI) 2. 메뉴별 권한 체크박스 (관리자/매니저/일반사용자) 3. 메뉴 추가/수정/삭제 기능 **파일 목록:** - frontend/admin/menu/index.vue --- ### Phase 4: AppHeader 메뉴 동적 렌더링 - [x] 시작: 2026-01-10 16:52:05 - [x] 완료: 2026-01-10 16:55:30 - [x] 소요시간: 3분 25초 **작업 내용:** 1. 로그인 시 사용자 접근 가능 메뉴 조회 2. useAuth에 메뉴 정보 저장 3. AppHeader에서 동적 메뉴 렌더링 4. 메뉴 권한에 따른 표시/숨김 **수정 파일:** - frontend/composables/useAuth.ts - frontend/components/layout/AppHeader.vue --- ### Phase 5: 페이지별 권한 체크 적용 - [x] 시작: 2026-01-10 16:55:35 - [x] 완료: 2026-01-10 16:59:45 - [x] 소요시간: 4분 10초 **작업 내용:** 1. 기존 하드코딩된 권한 체크 제거 2. 메뉴 권한 기반 접근 제어 적용 3. 권한 없는 페이지 접근 시 리다이렉트 **수정 파일:** - frontend/admin/user/index.vue - frontend/admin/user/create.vue - frontend/admin/user/[id].vue - frontend/admin/bulk-import.vue - frontend/report/summary/index.vue (취합보고 권한 추가) --- ### Phase 6: 테스트 및 정리 - [x] 시작: 2026-01-10 16:59:50 - [x] 완료: 2026-01-10 17:01:00 - [x] 소요시간: 1분 10초 **테스트 시나리오:** 1. 관리자 로그인 → 모든 메뉴 표시 확인 2. 매니저 로그인 → 관리자 메뉴 숨김 확인 3. 일반사용자 로그인 → 취합보고/관리자 메뉴 숨김 확인 4. 메뉴관리에서 권한 변경 → 즉시 반영 확인 5. 권한 없는 URL 직접 접근 → 리다이렉트 확인 --- ## 예상 산출물 | 구분 | 파일 | 작업 | |------|------|------| | SQL | backend/sql/create_menu_tables.sql | 신규 | | API | backend/api/admin/menu/list.get.ts | 신규 | | API | backend/api/admin/menu/create.post.ts | 신규 | | API | backend/api/admin/menu/[id]/update.put.ts | 신규 | | API | backend/api/admin/menu/[id]/delete.delete.ts | 신규 | | API | backend/api/admin/menu/[id]/toggle-role.post.ts | 신규 | | API | backend/api/auth/menu.get.ts | 신규 | | Frontend | frontend/admin/menu/index.vue | 신규 | | Frontend | frontend/composables/useAuth.ts | 수정 | | Frontend | frontend/components/layout/AppHeader.vue | 수정 | | Frontend | frontend/admin/user/*.vue | 수정 | | Frontend | frontend/admin/bulk-import.vue | 수정 | | Frontend | frontend/report/summary/index.vue | 수정 | --- ## 참고사항 1. **기능 제어 vs 화면 제어** - 본 작업은 **화면(메뉴) 접근 권한**만 제어 - 기존 기능별 권한(수정/삭제 등)은 유지 2. **기존 권한 체크 유지 항목** - 주간보고 수정/삭제: 본인 또는 관리자 - 사용자 삭제: 관리자만 (Backend에서 체크) 3. **메뉴 계층 구조** - 1단계: 메인 메뉴 (대시보드, 주간보고 등) - 2단계: 서브 메뉴 (관리자 하위 메뉴) --- ## 작업 완료 결과 ### Phase별 작업 시간 | Phase | 작업 내용 | 시작 | 완료 | 소요시간 | |:-----:|----------|:----:|:----:|:--------:| | 1 | DB 스키마 설계 및 생성 | 16:45:00 | 16:47:30 | **2분 30초** | | 2 | Backend API 개발 | 16:47:35 | 16:50:10 | **2분 35초** | | 3 | 메뉴관리 페이지 개발 | 16:50:15 | 16:52:00 | **1분 45초** | | 4 | AppHeader 메뉴 동적 렌더링 | 16:52:05 | 16:55:30 | **3분 25초** | | 5 | 페이지별 권한 체크 적용 | 16:55:35 | 16:59:45 | **4분 10초** | | 6 | 테스트 및 정리 | 16:59:50 | 17:01:00 | **1분 10초** | | | | | **총 소요시간** | **15분 35초** | --- ### 생성/수정된 파일 | 구분 | 파일 | 작업 | |------|------|:----:| | **DB** | wr_menu | 신규 테이블 | | **DB** | wr_menu_role | 신규 테이블 | | **API** | backend/api/admin/menu/list.get.ts | 신규 | | **API** | backend/api/admin/menu/[id]/toggle-role.post.ts | 신규 | | **API** | backend/api/auth/menu.get.ts | 신규 | | **Frontend** | frontend/admin/menu/index.vue | 신규 | | **Frontend** | frontend/composables/useAuth.ts | 수정 | | **Frontend** | frontend/components/layout/AppHeader.vue | 수정 | | **Frontend** | frontend/admin/user/index.vue | 수정 | | **Frontend** | frontend/admin/user/create.vue | 수정 | | **Frontend** | frontend/admin/user/[id].vue | 수정 | | **Frontend** | frontend/admin/bulk-import.vue | 수정 | | **Frontend** | frontend/report/summary/index.vue | 수정 | --- ### 메뉴별 권한 설정 현황 | 메뉴 | 관리자 | 매니저 | 일반사용자 | |------|:------:|:------:|:----------:| | 대시보드 | ✅ | ✅ | ✅ | | 주간보고 | ✅ | ✅ | ✅ | | 취합보고 | ✅ | ✅ | ❌ | | 프로젝트 | ✅ | ✅ | ✅ | | 개선의견 | ✅ | ✅ | ✅ | | 관리자 | ✅ | ❌ | ❌ | | └ 사용자 관리 | ✅ | ❌ | ❌ | | └ 메뉴 관리 | ✅ | ❌ | ❌ | | └ 주간보고 일괄등록 | ✅ | ❌ | ❌ |