- DepartmentPermissionService 생성 (역할 권한 관리 패턴 적용) - 부서별 메뉴 권한 매트릭스 관리 - 하위 부서 권한 자동 전파 기능 - 전체 허용/거부/초기화 기능 - HTMX 기반 실시간 권한 토글 - Department 모델의 HasRoles trait 활용 - model_has_permissions 테이블 사용 주요 파일: - app/Services/DepartmentPermissionService.php - app/Http/Controllers/DepartmentPermissionController.php - app/Http/Controllers/Api/Admin/DepartmentPermissionController.php - resources/views/department-permissions/index.blade.php - resources/views/department-permissions/partials/*.blade.php - routes/web.php, routes/api.php 라우트 추가 - sidebar 부서 권한 관리 메뉴 활성화
35 KiB
SAM MNG 작업 현황
2025-11-20 (수) - Phase 1-1: 인증 시스템 구현 완료
주요 작업
- MNG 프로젝트 인증 시스템 구현 (Laravel Sanctum 기반)
- DaisyUI를 사용한 로그인 UI 구현
- Service-First 아키텍처 적용
추가된 파일:
app/Services/AuthService.php- 인증 비즈니스 로직 (login, logout, createToken)app/Http/Requests/Auth/LoginRequest.php- 로그인 검증 FormRequestapp/Http/Controllers/Auth/LoginController.php- 로그인 컨트롤러 (세션 인증)resources/views/auth/login.blade.php- DaisyUI 기반 로그인 화면resources/views/dashboard/index.blade.php- 임시 대시보드CURRENT_WORKS.md- 작업 이력 추적 파일
수정된 파일:
routes/web.php- 인증 라우트 추가 (login, logout, dashboard)postcss.config.js- Tailwind CSS 4.x 대응 (@tailwindcss/postcss)
작업 내용:
-
DB 스키마 분석
- API 프로젝트의 공유 DB 구조 확인 (users, personal_access_tokens, sessions)
- Multi-tenant 구조 파악 (tenant_id, user_tenants)
-
인증 시스템 설계
- Service-First 패턴 적용
- FormRequest를 통한 검증 분리
- 세션 기반 웹 인증 (향후 API 토큰 인증 준비)
-
구현 완료
- AuthService: 비즈니스 로직 캡슐화
- LoginRequest: 이메일/비밀번호 검증 및 한글 메시지
- LoginController: 로그인/로그아웃 처리
- Blade 템플릿: DaisyUI 단순 디자인
-
Vite/PostCSS 설정
- Tailwind CSS 4.x PostCSS 플러그인 설치
- 프로덕션 빌드 완료 (public/build/)
테스트 결과:
- ✅ 라우트 등록 확인:
/login(GET, POST),/logout(POST),/dashboard(GET) - ✅ 로그인 페이지 접근: https://mng.sam.kr/login (200 OK)
- ✅ Vite 빌드 성공: CSS (7.97 KB), JS (102.67 KB)
다음 단계:
- Phase 1-2: User 모델 생성 및 DB 연결 테스트
- Phase 1-3: 실제 로그인 테스트 (테스트 사용자 생성)
- Phase 2: 대시보드 구현 (메뉴, 사이드바)
- Phase 3: 사용자 관리 기능
Git 커밋:
- ✅
ece1f28"feat: MNG 인증 시스템 구현" - ✅
b71e85a"fix: Tailwind 3.x 다운그레이드 및 DaisyUI 적용"
이슈 해결:
- 문제: Tailwind CSS 4.x에서 DaisyUI 플러그인 미적용
- 원인: DaisyUI가 Tailwind 4.x를 완전히 지원하지 않음
- 해결: Tailwind 3.4.17로 다운그레이드, PostCSS 설정 수정
- 결과: DaisyUI 클래스 정상 적용 (74.82 KB CSS)
문서 업데이트 (2025-11-20):
- api/CLAUDE.md: shared/ 모델 참조 제거
- 변경 사항:
- 저장소 구조: 5개 → 3개 (api, admin, mng 독립 운영)
- 모델 구조: shared/ → 각 프로젝트 독립 모델
- 워크플로우: shared 동기화 제거
- CURRENT_WORKS.md 위치: mng 추가
2025-11-20 (수) - CSS 브라우저 호환성 문제 해결
주요 작업
- DaisyUI oklch() 색상 함수 브라우저 호환성 문제 해결
- Pure Tailwind CSS로 전환하여 구형 브라우저 지원
문제 상황:
- 증상: mng.sam.kr 로그인 페이지 CSS 스타일이 적용되지 않음
- 원인: DaisyUI 5.5.5가
oklch()색상 함수 사용 → Safari <15.4, Chrome <111 미지원 - 영향: CSS 변수가 계산되지 않아 버튼, 카드 등 모든 컴포넌트 스타일 무효화
해결 과정:
-
DaisyUI 설정 시도 (실패)
- Custom hex 테마 설정 → DaisyUI가 여전히 oklch() 사용
themes: false설정 → base CSS에서 oklch() 사용
-
DaisyUI 완전 제거 (성공)
tailwind.config.js에서 DaisyUI 플러그인 제거- Pure Tailwind CSS + @tailwindcss/forms 사용
- Custom primary/secondary 색상 hex로 정의
-
로그인 페이지 리팩토링
- DaisyUI 클래스 → Tailwind 유틸리티 클래스 변환
btn btn-primary→bg-primary text-white rounded-lgcard→bg-white rounded-lg shadow-xlinput input-bordered→border border-gray-300 rounded-lg
수정된 파일:
tailwind.config.js- DaisyUI 제거, hex 색상 정의resources/css/app.css- CSS 변수 추가 (향후 제거 예정)resources/views/auth/login.blade.php- Tailwind 유틸리티 클래스로 변환.env- DB_HOST를 sam-mysql-1 → 127.0.0.1로 변경 (로컬 접근)
빌드 결과:
- Before: 74.82 KB (DaisyUI 포함, oklch() 사용)
- After: 23.15 KB (Pure Tailwind, hex 색상 사용)
- 파일:
public/build/assets/app-L1Qg3jEH.css
테스트 결과:
- ✅ 로그인 페이지 CSS 정상 적용
- ✅ 모든 브라우저 호환성 확보 (hex 색상 사용)
- ✅ 로그인 기능 정상 작동 (원격 DB 데이터 복원 후)
기술적 결정:
- CSS 프레임워크: DaisyUI → Pure Tailwind CSS
- 색상 시스템: oklch() → hex (#570df8, #f000b8)
- 컴포넌트 스타일: 사전 정의 클래스 → 유틸리티 조합
- 향후 방향: 로그인 페이지 기준으로 일관된 CSS 스타일 유지
Git 커밋:
- ✅
7b3505a"fix: DaisyUI oklch() 브라우저 호환성 문제 해결"
2025-11-20 (수) - Phase 2: 레이아웃 구조화 및 메뉴 시스템 구현
주요 작업
- 좌측 사이드바 + 상단 헤더 레이아웃 구조 설계
- Blade 템플릿 컴포넌트 분리 (@extends/@section 패턴)
- SAM 프로젝트 기반 10개 메뉴 항목 구현
추가된 파일:
resources/views/layouts/app.blade.php- 마스터 레이아웃 (sidebar + header + content)resources/views/partials/sidebar.blade.php- 좌측 사이드바 (256px, 메뉴 10개)resources/views/partials/header.blade.php- 상단 헤더 (64px, 페이지 타이틀 + 사용자 메뉴)
수정된 파일:
resources/views/dashboard/index.blade.php- @extends 패턴으로 리팩토링
레이아웃 구조:
전체 구조 (Flexbox):
┌─────────────────────────────────────┐
│ ┌──────┐ ┌─────────────────────┐ │
│ │ │ │ Header (64px) │ │
│ │ Side │ ├─────────────────────┤ │
│ │ bar │ │ │ │
│ │(256) │ │ Main Content │ │
│ │ │ │ │ │
│ └──────┘ └─────────────────────┘ │
└─────────────────────────────────────┘
사이드바 구조 (Flex Column):
- 상단: 로고/브랜드 (h-16)
- 중단: 메뉴 영역 (flex-1, 스크롤 가능)
- 하단: 사용자 정보 (border-top)
헤더 구조 (Flex Row):
- 좌측: 페이지 제목 (@yield('page-title'))
- 우측: 알림 버튼 + 사용자 드롭다운 메뉴
메뉴 구조 (10개):
조직 관리:
- 대시보드 (활성화됨, route 연결)
- 사용자 관리
- 권한 및 역할
- 부서 관리
제품/자재 관리: 5. 제품 관리 6. 자재 관리 7. BOM 관리 8. 카테고리 관리
시스템 관리: 9. 시스템 설정 10. 감사 로그
메뉴 특징:
- 아이콘: Heroicons (Tailwind 공식 아이콘 라이브러리)
- 활성 상태:
request()->routeIs()체크 → bg-primary + text-white - 호버 효과: hover:bg-gray-100
- 구분선: 영역별 시각적 구분 (border-t border-gray-200)
- 반응형: 메뉴 많아지면 스크롤 가능 (overflow-y-auto)
헤더 기능:
- 알림 버튼: 플레이스홀더 (추후 구현)
- 사용자 드롭다운:
- 사용자 정보 표시 (이름, 이메일)
- 프로필 설정 (링크 미연결)
- 계정 설정 (링크 미연결)
- 로그아웃 (route('logout') 연결)
- JavaScript 외부 클릭 감지로 자동 닫힘
사용자 정보 표시:
- 아바타: 이름 첫 글자 대문자 (bg-primary 원형)
- 이름:
auth()->user()->name ?? 'User' - 이메일:
auth()->user()->email - 위치: 사이드바 하단, 헤더 우측
CSS/디자인:
- 색상: primary (#570df8), gray 팔레트
- 간격: space-y-2 (메뉴), gap-3/4 (아이콘-텍스트)
- 패딩: px-4 py-3 (메뉴), px-6 (헤더/메인)
- 라운드: rounded-lg (버튼/메뉴)
- 그림자: shadow-lg (사이드바), shadow-sm (헤더)
빌드 결과:
- CSS: 25.36 KB (gzip: 5.57 KB)
- JS: 102.67 KB (gzip: 32.86 KB)
- 파일:
public/build/assets/app-BjNnnM4N.css
기술적 결정:
- 레이아웃: 좌측 사이드바 (admin.sam.kr Filament 패널과 일관성)
- 컴포넌트 분리: layouts/ + partials/ 구조
- Blade 패턴: @extends/@section/@include/@yield/@stack
- 반응형: 추후 모바일 대응 예정 (현재 데스크톱 우선)
개발 프로세스:
- Phase 1: 레이아웃 구조 설계 ✅
- Phase 2: 메뉴 리스트업 ✅
- Phase 3: 컨텐츠 구성 (다음 단계)
Git 커밋:
- ✅
9367f61"feat: 좌측 사이드바 레이아웃 및 메뉴 시스템 구현"
2025-11-21 (목) - 테넌트 선택 기능 구현
주요 작업
- admin 패널의 테넌트 전환 기능을 MNG로 이식
- Plain Laravel (Livewire 없이) 방식으로 구현
- ViewServiceProvider를 통한 전역 테넌트 데이터 제공
추가된 파일:
app/Models/Tenant.php- 테넌트 모델 (SoftDeletes, active scope)app/Http/Controllers/TenantController.php- 테넌트 전환 컨트롤러app/Providers/ViewServiceProvider.php- 모든 뷰에 테넌트 목록 자동 제공resources/views/partials/tenant-selector.blade.php- 테넌트 선택 UI 컴포넌트
수정된 파일:
routes/web.php- 테넌트 전환 라우트 추가 (POST /tenant/switch)bootstrap/providers.php- ViewServiceProvider 등록resources/views/dashboard/index.blade.php- 테넌트 선택기 포함
기능 상세:
테넌트 선택기 구조:
┌─────────────────────────────────────────────────┐
│ 좌측 우측 │
│ [아이콘] 테넌트 선택: [드롭다운] [상태 표시] │
└─────────────────────────────────────────────────┘
UI 컴포넌트:
- Welcome Card 위에 배치 (동일한 깊이)
- 좌측: 건물 아이콘 + "테넌트 선택" 라벨 + 셀렉트박스
- 우측: 현재 테넌트 정보 표시
- 특정 테넌트 선택: "○○ 데이터만 표시 중" (primary 색상 뱃지)
- 전체 보기: "전체 테넌트 데이터 표시 중" (회색 텍스트)
동작 방식:
- 드롭다운 변경 시 자동 Form Submit (
onchange) POST /tenant/switch라우트로 전송- Session에
selected_tenant_id저장 - 이전 페이지로 리다이렉트 (
redirect()->back())
ViewServiceProvider 역할:
- 모든 인증된 뷰에서
$tenants변수 자동 사용 가능 - View Composer 패턴 적용 (
View::composer('*', ...)) - 활성 테넌트만 회사명 순 정렬
Tenant 모델:
- SoftDeletes trait 사용
active()scope: 삭제되지 않은 테넌트만 조회tenant_st_code컬럼 사용 (trial, none 등의 상태값)
DB 스키마 분석:
- 테이블:
tenants(29개 컬럼) - 주요 컬럼:
id,company_name,code(회사 기본 정보)tenant_st_code(상태: trial, none 등)deleted_at(SoftDelete)storage_limit,storage_used(용량 관리)
이슈 해결:
- 문제:
is_active컬럼 없음 (SQLSTATE[42S22]) - 원인: admin 패널과 DB 스키마 차이
- 해결:
tenant_st_code사용 → 삭제되지 않은 모든 테넌트 표시
테스트 결과:
- ✅ 테넌트 모델 조회 성공 (7개 활성 테넛트)
- ✅ ViewServiceProvider 등록 완료
- ✅ 테넌트 선택기 UI 렌더링
- ⏳ 브라우저 테스트 대기 중
빌드 결과:
- CSS: 25.58 KB (gzip: 5.61 KB)
- 파일:
public/build/assets/app-CQyaIaRP.css
기술적 결정:
- Livewire 대신 Plain Laravel: 심플함, 페이지 새로고침 방식
- ViewServiceProvider: 전역 데이터 제공 패턴
- Session 기반:
selected_tenant_id세션 저장 - 모든 페이지 공통:
@include('partials.tenant-selector')사용
Git 커밋:
- ✅
661c5ad"feat: 테넌트 선택 기능 구현"
2025-11-24 (일) - 테넌트 관리 페이지네이션 및 공통 컴포넌트화
주요 작업
- 테넌트 목록 페이지에 HTMX 호환 페이지네이션 추가
- 페이지네이션을 공통 컴포넌트로 분리하여 재사용성 향상
추가된 파일:
resources/views/partials/pagination.blade.php- HTMX 호환 공통 페이지네이션 컴포넌트
수정된 파일:
resources/views/tenants/partials/table.blade.php- 페이지네이션 코드 제거, 공통 컴포넌트 include로 대체
작업 배경:
이전 세션 작업 내역 (2025-11-24):
- ✅ 테넌트 수정 폼 HTMX URL 라우팅 문제 해결
- ✅ UpdateTenantRequest 라우트 파라미터 수정 (
route('tenant')→route('id')) - ✅ HTMX 삭제/복원/영구삭제 기능에 CSRF 토큰 헤더 추가
- ✅ TenantService::forceDeleteTenant() 외래키 제약 처리
- ✅
docs/TROUBLESHOOTING.md트러블슈팅 가이드 작성 - ✅ 페이지네이션 추가 (1페이지만 있어도 항상 표시)
- ✅ 페이지네이션을 공통 컴포넌트로 분리
페이지네이션 구현 상세:
구조:
- 모바일: 이전/다음 버튼만 표시 (
sm:hidden) - 데스크톱: 전체 페이지 번호 + 이전/다음 버튼 (
hidden sm:flex)
기능:
- 개별 페이지 번호 버튼 클릭 가능 (1, 2, 3...)
- 현재 페이지 하이라이트 (파란색 배경)
- 비활성화된 버튼 회색 처리
- HTMX 동적 로딩 (페이지 새로고침 없음)
- 검색 필터 유지 (
hx-include) - CSRF 토큰 자동 포함
사용법:
@include('partials.pagination', [
'paginator' => $tenants, // LengthAwarePaginator 객체
'target' => '#tenant-table', // HTMX 타겟 ID
'includeForm' => '#filterForm' // 필터 폼 ID (선택)
])
코드 개선:
- 중복 코드 95줄 → 5줄 (include 문)로 간소화
- 유지보수성 향상 (한 곳만 수정하면 전체 적용)
- 다른 목록 페이지에서도 즉시 재사용 가능
기술적 특징:
HTMX 통합:
hx-get: 페이지 URL 동적 로드hx-target: 교체할 DOM 영역 지정hx-include: 검색 필터 등 폼 데이터 포함hx-headers: CSRF 토큰 자동 전달
Laravel 페이지네이션 메서드:
$paginator->total(): 전체 데이터 개수$paginator->firstItem(): 현재 페이지 첫 번째 항목 번호$paginator->lastItem(): 현재 페이지 마지막 항목 번호$paginator->currentPage(): 현재 페이지 번호$paginator->lastPage(): 마지막 페이지 번호$paginator->getUrlRange(1, $lastPage): 페이지 URL 배열$paginator->previousPageUrl(): 이전 페이지 URL$paginator->nextPageUrl(): 다음 페이지 URL$paginator->onFirstPage(): 첫 페이지 여부$paginator->hasMorePages(): 다음 페이지 존재 여부
반응형 디자인:
- 모바일: 간단한 이전/다음 네비게이션
- 데스크톱: 전체 페이지 번호 + 이전/다음
- Tailwind breakpoint:
sm:(640px)
파일 구조:
resources/views/
├── partials/
│ ├── header.blade.php
│ ├── sidebar.blade.php
│ ├── tenant-selector.blade.php
│ └── pagination.blade.php ← 새로 추가된 공통 컴포넌트
└── tenants/
└── partials/
└── table.blade.php ← 페이지네이션 코드 제거, include로 대체
향후 활용:
이 공통 페이지네이션 컴포넌트는 다음 목록에서도 사용 가능:
- 사용자 목록
- 부서 목록
- 제품 목록
- 자재 목록
- BOM 목록
- 감사 로그 목록
다음 단계:
- 브라우저에서 페이지네이션 동작 확인
- 다른 목록 페이지에 페이지네이션 적용
- 페이지당 표시 개수 선택 기능 추가 고려
Git 커밋:
- ✅
43af1a5"페이지네이션 기능 개선 및 공통화"
2025-11-24 (일) - Phase 4-2: 역할 관리 시스템 구현
주요 작업
- 역할 CRUD 완전 구현 (Spatie Permission 패키지 활용)
- 권한 선택 UI 구현 (체크박스, 전체 선택/해제)
- HTMX + API 패턴 적용
- 페이지네이션 공통 컴포넌트 생성
추가된 파일:
app/Services/RoleService.php- 역할 비즈니스 로직 (Spatie Role 모델 사용)app/Http/Controllers/RoleController.php- Blade 화면 컨트롤러app/Http/Controllers/Api/Admin/RoleController.php- HTMX API 컨트롤러app/Http/Requests/StoreRoleRequest.php- 역할 생성 검증app/Http/Requests/UpdateRoleRequest.php- 역할 수정 검증resources/views/roles/index.blade.php- 역할 목록 (HTMX 로딩)resources/views/roles/create.blade.php- 역할 생성 폼resources/views/roles/edit.blade.php- 역할 수정 폼resources/views/roles/partials/table.blade.php- 역할 테이블resources/views/partials/pagination.blade.php- 공통 페이지네이션 컴포넌트
수정된 파일:
resources/views/partials/sidebar.blade.php- 역할 관리 메뉴 추가routes/web.php- 역할 관리 라우트 추가 (index, create, edit)routes/api.php- 역할 관리 API 라우트 추가 (CRUD)
기능 상세:
역할 관리 CRUD:
- 역할 목록: HTMX 동적 로딩, 검색 필터, 페이지네이션
- 역할 생성: 이름/설명 입력, 권한 선택 (체크박스)
- 역할 수정: 기존 정보 편집, 권한 변경
- 역할 삭제: Soft Delete (복구 가능)
권한 선택 UI:
- 그리드 레이아웃 (3열)
- 체크박스로 권한 선택
- 전체 선택/해제 버튼
- 현재 권한 개수 표시
RoleService 주요 메서드:
getRoles(filters, perPage): 역할 목록 조회 (페이지네이션)getRoleById(id): 특정 역할 조회 (권한 포함)createRole(data): 역할 생성 + 권한 동기화 (syncPermissions())updateRole(id, data): 역할 수정 + 권한 동기화deleteRole(id): 역할 삭제 (권한/사용자 연결 해제)isNameExists(name, excludeId): 역할 이름 중복 체크getActiveRoles(): 활성 역할 목록 (드롭다운용)getRoleStats(): 역할 통계 (전체 수, 권한 있는 역할 수)
Spatie Permission 통합:
Spatie\Permission\Models\Role모델 사용syncPermissions(): 역할-권한 동기화permissions관계: 역할에 할당된 권한 조회- Multi-tenant 지원:
tenant_id필터링
HTMX 패턴:
- 목록 화면:
hx-get="/api/admin/roles"(필터 포함) - 생성/수정:
hx-post,hx-put(JSON 응답 → 리다이렉트) - 삭제:
confirmDelete()JavaScript → HTMX DELETE 요청
페이지네이션 컴포넌트:
- 모바일: 이전/다음 버튼만
- 데스크톱: 전체 페이지 번호 표시
- HTMX 호환:
hx-get,hx-target,hx-include - 재사용 가능:
@include('partials.pagination', [...])
테넌트 필터링:
- 세션에
selected_tenant_id있으면 해당 테넌트만 - 없으면 전체 테넌트 데이터 표시
- 역할/권한 모두 테넌트 필터링 적용
빌드 결과:
- 변경 파일: 17개
- 추가 코드: +1331줄, -106줄
Git 커밋:
- ✅
5f50716"feat: Phase 4-2 역할 관리 시스템 구현 (HTMX + API 패턴)"
2025-11-24 (일) - Phase 4-3: 부서 관리 시스템 구현
주요 작업
- 부서 CRUD 완전 구현 (계층 구조 지원)
- 활성/비활성 상태 관리
- HTMX + API 패턴 적용
추가된 파일:
app/Services/DepartmentService.php- 부서 비즈니스 로직app/Http/Controllers/DepartmentController.php- Blade 화면 컨트롤러app/Http/Controllers/Api/Admin/DepartmentController.php- HTMX API 컨트롤러app/Http/Requests/StoreDepartmentRequest.php- 부서 생성 검증app/Http/Requests/UpdateDepartmentRequest.php- 부서 수정 검증resources/views/departments/index.blade.php- 부서 목록resources/views/departments/create.blade.php- 부서 생성 폼resources/views/departments/edit.blade.php- 부서 수정 폼resources/views/departments/partials/table.blade.php- 부서 테이블
수정된 파일:
resources/views/partials/sidebar.blade.php- 부서 관리 메뉴 추가routes/web.php- 부서 관리 라우트 추가routes/api.php- 부서 관리 API 라우트 추가
기능 상세:
부서 계층 구조:
- Self-referential relationship:
parent_id→departments.id - 상위 부서 선택 가능 (드롭다운)
- 자기 자신을 상위 부서로 선택 방지 (FormRequest 검증)
- 하위 부서 존재 시 삭제 방지
DepartmentService 주요 메서드:
getDepartments(filters, perPage): 부서 목록 조회getDepartmentById(id): 특정 부서 조회createDepartment(data): 부서 생성updateDepartment(id, data): 부서 수정deleteDepartment(id): 부서 삭제 (하위 부서 체크)getActiveDepartments(): 활성 부서 목록 (드롭다운용)getDepartmentTree(): 계층 구조 트리 (향후 구현)
활성 상태 관리:
is_active컬럼: 활성(1) / 비활성(0)- 활성 필터:
activescope 적용 - UI: 활성 상태 뱃지 표시
정렬 순서:
sort_order컬럼: 표시 순서 지정- 기본 정렬:
sort_order ASC,name ASC
검증 규칙:
StoreDepartmentRequest:
name: 필수, 최대 100자parent_id: 선택, 존재하는 부서 IDsort_order: 선택, 정수is_active: 불리언 (기본값: true)
UpdateDepartmentRequest:
- 위와 동일 + 자기 참조 방지
parent_id≠ 현재 부서 ID
Git 커밋:
- ✅
6738505"feat: Phase 4-3 부서 관리 시스템 구현"
2025-11-24 (일) - 사용자 관리 기능 추가
주요 작업
- 사용자 CRUD 완전 구현
- UserService, FormRequest, Blade Views 생성
- MNG_CRITICAL_RULES.md 문서 추가
- 테이블 헤더 스타일 통일
추가된 파일:
app/Http/Controllers/UserController.php- Blade 화면 컨트롤러app/Http/Controllers/Api/Admin/UserController.php- HTMX API 컨트롤러app/Http/Requests/StoreUserRequest.php- 사용자 생성 검증app/Http/Requests/UpdateUserRequest.php- 사용자 수정 검증resources/views/users/index.blade.php- 사용자 목록resources/views/users/create.blade.php- 사용자 생성 폼resources/views/users/edit.blade.php- 사용자 수정 폼resources/views/users/partials/table.blade.php- 사용자 테이블docs/MNG_CRITICAL_RULES.md- MNG 프로젝트 핵심 규칙 문서
수정된 파일:
resources/views/partials/sidebar.blade.php- 사용자 관리 메뉴 이동routes/web.php- 사용자 관리 라우트 추가routes/api.php- 사용자 관리 API 라우트 추가- 테이블 헤더 스타일 통일 (tenants, roles, departments)
기능 상세:
사용자 관리 CRUD:
- 사용자 목록: 검색, 필터링 (역할, 부서, 활성 상태)
- 사용자 생성: 이름, 이메일, 비밀번호, 역할, 부서, 테넌트
- 사용자 수정: 정보 변경, 비밀번호 변경 (선택)
- 사용자 삭제: Soft Delete
MNG_CRITICAL_RULES.md:
- DB 마이그레이션 금지 (API 프로젝트에서만 실행)
- 모델 독립 운영 (admin, api, mng 각각 독립)
- Filament 의존성 제거
- Service-First 패턴 강제
- FormRequest 검증 필수
Git 커밋:
- ✅
0c86b39"feat: 사용자 관리 기능 및 MNG 문서 추가"
2025-11-24 (일) - 사용자 관리 복구 및 영구삭제 기능 추가
주요 작업
- UserService에 복구/영구삭제 메서드 추가
- Audit 컬럼 처리 (created_by, updated_by, deleted_by)
- 삭제된 사용자 UI 표시
수정된 파일:
app/Services/UserService.php- restoreUser(), forceDeleteUser() 추가app/Http/Controllers/Api/Admin/UserController.php- restore, forceDestroy 엔드포인트resources/views/users/index.blade.php- 삭제된 항목 필터 체크박스resources/views/users/partials/table.blade.php- 복원/영구삭제 버튼routes/api.php- restore, forceDestroy 라우트 추가
기능 상세:
복구 기능:
- Soft Delete된 사용자 복원
withTrashed(): 삭제된 사용자 포함 조회- UI: 삭제된 사용자에 "복원" 버튼 표시
영구삭제 기능:
- 물리적 삭제 (복구 불가)
- 권한 체크: 슈퍼관리자만 가능
- UI: 삭제된 사용자에 "영구삭제" 버튼 표시 (빨간색)
Audit 컬럼 처리:
created_by: 생성자 IDupdated_by: 수정자 IDdeleted_by: 삭제자 ID- 자동 기록:
auth()->id()
Git 커밋:
- ✅
8940557"사용자 관리 복구 및 영구삭제 기능 추가"
2025-11-24 (일) - 메뉴 관리 기능 개선
주요 작업
- 메뉴 트리 구조 완전 구현 (무제한 depth)
- 접기/펼치기 기능 (재귀적 처리)
- 활성/숨김 상태 토글 (실시간 업데이트)
- 테넌트 필터링 (마스터 메뉴 지원)
추가된 파일:
app/Services/MenuService.php- 메뉴 비즈니스 로직 (트리 구조)app/Http/Controllers/MenuController.php- Blade 화면 컨트롤러app/Http/Controllers/Api/Admin/MenuController.php- HTMX API 컨트롤러app/Http/Requests/StoreMenuRequest.php- 메뉴 생성 검증app/Http/Requests/UpdateMenuRequest.php- 메뉴 수정 검증resources/views/menus/index.blade.php- 메뉴 목록 (트리 구조)resources/views/menus/create.blade.php- 메뉴 생성 폼resources/views/menus/edit.blade.php- 메뉴 수정 폼resources/views/menus/partials/table.blade.php- 메뉴 트리 테이블
수정된 파일:
routes/web.php- 메뉴 관리 라우트 추가routes/api.php- 메뉴 관리 API 라우트 추가 (tree, toggleActive, toggleHidden)
기능 상세:
트리 구조:
- 무제한 depth 지원
- 재귀적 렌더링 (Blade recursive include)
- 인덴트로 계층 표시
- 접기/펼치기 아이콘
MenuService 주요 메서드:
getMenus(filters): 메뉴 목록 (flat)getMenuTree(filters): 트리 구조 메뉴 (재귀 쿼리)createMenu(data): 메뉴 생성updateMenu(id, data): 메뉴 수정deleteMenu(id): 메뉴 삭제 (하위 메뉴 체크)toggleActive(id): 활성 상태 토글toggleHidden(id): 숨김 상태 토글
토글 기능:
- 활성/비활성:
is_active토글 - 숨김/표시:
is_hidden토글 - HTMX 실시간 업데이트 (페이지 새로고침 없음)
테넌트 필터링:
- 전체 선택: 마스터 메뉴만 표시 (
tenant_id IS NULL) - 특정 테넌트: 해당 테넌트 메뉴만
- 외부 메뉴 표시:
external_link컬럼
Git 커밋:
- ✅
79aebfa"메뉴 관리 기능 개선"
📊 Phase 4 완료 요약 (2025-11-24)
구현된 모든 관리 기능:
✅ Phase 4-1: 테넌트 관리
✅ Phase 4-2: 역할 관리
- CRUD, 권한 할당/해제, Spatie Permission 통합
- 커밋:
5f50716
✅ Phase 4-3: 부서 관리
- CRUD, 계층 구조, 활성 상태 관리
- 커밋:
6738505
✅ Phase 4-4: 사용자 관리
✅ Phase 4-5: 메뉴 관리
- CRUD, 트리 구조, 토글 기능
- 커밋:
79aebfa
공통 컴포넌트:
- ✅
partials/pagination.blade.php- 재사용 가능 페이지네이션 - ✅
partials/tenant-selector.blade.php- 테넌트 선택기 - ✅
partials/sidebar.blade.php- 좌측 메뉴 - ✅
partials/header.blade.php- 상단 헤더
공통 패턴:
- ✅ Service-First 아키텍처
- ✅ FormRequest 검증
- ✅ HTMX + API 패턴
- ✅ Multi-tenant 필터링
- ✅ Soft Delete + 복구/영구삭제
- ✅ Audit 로그 (created_by, updated_by, deleted_by)
문서:
- ✅
docs/MNG_CRITICAL_RULES.md- 핵심 규칙 - ✅
docs/TROUBLESHOOTING.md- 트러블슈팅 가이드 - ✅
docs/INDEX.md- 문서 인덱스
통계:
- 추가 파일: 60개 이상
- 추가 코드: 5,000줄 이상
- 커밋 수: 12개
- 작업 기간: 2025-11-24 하루
📋 다음 단계 (Phase 5 이후)
Phase 5: 제품/자재 관리
- 제품 관리 (Products)
- 자재 관리 (Materials)
- 카테고리 관리 (Categories)
Phase 6: BOM 관리
- BOM 구조 (Bill of Materials)
- BOM 버전 관리
- BOM 트리 뷰
Phase 7: 시스템 관리
- 감사 로그 (Audit Logs)
- 시스템 설정 (Settings)
- 알림 관리 (Notifications)
2025-11-25 (월) - Phase 4-4-2: 역할 권한 관리 기능 구현
주요 작업
- 역할-권한 매핑 관리 기능 완전 구현
- admin 패널의 역할 권한 관리를 MNG로 이식 (Livewire → HTMX)
- 메뉴 기반 권한 체크박스 매트릭스 시스템
추가된 파일:
app/Services/RolePermissionService.php- 역할 권한 비즈니스 로직app/Http/Controllers/RolePermissionController.php- Blade 화면 컨트롤러app/Http/Controllers/Api/Admin/RolePermissionController.php- HTMX API 컨트롤러resources/views/role-permissions/index.blade.php- 메인 페이지resources/views/role-permissions/partials/empty-state.blade.php- 빈 상태 화면resources/views/role-permissions/partials/permission-matrix.blade.php- 권한 매트릭스 테이블
수정된 파일:
resources/views/partials/sidebar.blade.php- 역할 권한 관리 메뉴 활성화routes/web.php- 역할 권한 관리 라우트 추가routes/api.php- 역할 권한 관리 API 라우트 추가
기능 상세:
RolePermissionService 주요 메서드:
getRolePermissionMatrix(roleId, tenantId): 권한 매트릭스 조회togglePermission(roleId, menuId, type, tenantId): 권한 토글propagateToChildren(roleId, menuId, type, value, tenantId): 하위 메뉴 권한 전파allowAllPermissions(roleId, tenantId): 모든 권한 허용denyAllPermissions(roleId, tenantId): 모든 권한 거부getMenuTree(tenantId): 메뉴 트리 조회hasPermission(roleId, menuId, type): 권한 확인
권한 유형 (7가지):
- view (조회)
- create (생성)
- update (수정)
- delete (삭제)
- approve (승인)
- export (내보내기)
- manage (관리)
UI 구조:
-
상단 툴바
- 역할 선택 드롭다운 (HTMX 동적 로딩)
- 전체 허용 (녹색) / 전체 거부 (빨간색) / 초기화 (회색) 버튼
-
권한 매트릭스 테이블
- 행: 메뉴 목록 (계층 구조, "├─" 인덴트)
- 컬럼: 순번, 메뉴명, 상위 메뉴, URL, 순서 + 권한 체크박스 7개
- 체크박스: HTMX로 실시간 토글
-
빈 상태
- 역할 미선택 시 "역할을 선택해주세요" 메시지 표시
HTMX 패턴:
- 역할 변경:
hx-get="/api/admin/role-permissions/matrix" - 권한 토글:
hx-post="/api/admin/role-permissions/toggle" - 전체 허용:
hx-post="/api/admin/role-permissions/allow-all" - 전체 거부:
hx-post="/api/admin/role-permissions/deny-all"
계층적 권한 전파:
- 부모 메뉴 권한 변경 시 하위 메뉴에 자동 전파
- 재귀적 처리로 모든 하위 메뉴에 동일 권한 적용
테넌트 필터링:
- 세션의
selected_tenant_id기준으로 필터링 - 테넌트별 메뉴와 권한만 표시
기술 스택:
- Service-First 패턴
- HTMX (Livewire 대체)
- Plain Blade (Filament 컴포넌트 없음)
- Spatie Permission (role_has_permissions 테이블)
- Tailwind CSS
Admin vs MNG 차이점:
| 항목 | Admin (Filament) | MNG (Plain Laravel) |
|---|---|---|
| 프레임워크 | Livewire | HTMX |
| 컴포넌트 | Filament | Tailwind CSS |
| 메서드 | wire:click | hx-post |
| 모델 바인딩 | wire:model.live | JavaScript change |
Git 커밋:
- ⏳ 작업 완료, 커밋 대기 중
최종 업데이트: 2025-11-25 13:00 현재 Phase: Phase 4-4-2 완료, 브라우저 테스트 대기 중 다음 작업: 브라우저 동작 확인 및 오류 수정
2025-11-25 (월) - 부서 권한 관리 구현 시작
주요 작업
- 역할 권한 관리와 유사한 부서 권한 관리 구현
- admin 패널의 부서 권한 관리를 MNG로 이식 (Livewire → HTMX)
문서 확인 완료:
- ✅ CURRENT_WORKS.md 백업 완료
- ✅ MNG_CRITICAL_RULES.md 확인 (금지사항 숙지)
- ✅ Department 마이그레이션 확인 (parent_id 계층 구조)
- ✅ Permission 통합 마이그레이션 확인
DB 스키마 분석:
중요 발견:
- ❌
department_permissions테이블 드롭됨 (2025_08_21 마이그레이션) - ✅
permission_overrides테이블 신설 (Spatie 표준화) - ✅ Department 모델은 HasRoles trait 사용 (Spatie)
- ✅ permissionOverrides morphMany 관계 사용
권한 관리 구조:
- Spatie 표준:
model_has_permissions(역할/부서 권한) - 개별 오버라이드:
permission_overrides(ALLOW/DENY) - 부서는 model_type='App\Models\Tenants\Department' 사용
다음 작업:
- departments 테이블 전체 스키마 확인
- permission_overrides 테이블 구조 상세 파악
- 부서 권한 관리 UI/UX 설계
- DepartmentPermissionService 설계
- 권한 매트릭스 구현
추가된 파일:
app/Services/DepartmentPermissionService.php- 부서 권한 비즈니스 로직app/Http/Controllers/DepartmentPermissionController.php- Blade 화면 컨트롤러app/Http/Controllers/Api/Admin/DepartmentPermissionController.php- HTMX API 컨트롤러resources/views/department-permissions/index.blade.php- 메인 페이지resources/views/department-permissions/partials/empty-state.blade.php- 빈 상태 화면resources/views/department-permissions/partials/permission-matrix.blade.php- 권한 매트릭스 테이블
수정된 파일:
routes/web.php- 부서 권한 관리 라우트 추가routes/api.php- 부서 권한 관리 API 라우트 추가resources/views/partials/sidebar.blade.php- 부서 권한 관리 메뉴 활성화
기술 구조:
권한 관리 방식:
- Department 모델이 HasRoles trait 사용 (Spatie)
model_has_permissions테이블 사용 (model_type = 'App\Models\Tenants\Department')- 역할 권한 관리와 동일한 패턴 적용
- 하위 부서 권한 자동 전파 (재귀 처리)
주요 메서드 (DepartmentPermissionService):
getDepartmentPermissionMatrix()- 부서별 권한 매트릭스 조회togglePermission()- 특정 메뉴 권한 토글propagateToChildren()- 하위 부서 권한 전파allowAllPermissions()- 모든 권한 허용denyAllPermissions()- 모든 권한 거부getMenuTree()- 메뉴 트리 조회 (depth 계산)
UI 특징:
- 부서 선택: 버튼 방식 (역할 권한 관리와 동일)
- 권한 매트릭스: 체크박스로 권한 토글
- 액션 버튼: 전체 허용/거부/초기화
- HTMX 실시간 업데이트
테넌트 필터링:
- 세션의
selected_tenant_id기준으로 필터링 - 테넌트별 부서와 권한만 표시
다음 작업:
- 브라우저 테스트
- 권한 전파 동작 확인
- CSS 빌드 (필요 시)
- 오류 수정 및 개선