2025-11-20 16:24:40 +09:00
|
|
|
|
# SAM MNG 작업 현황
|
|
|
|
|
|
|
2025-12-17 22:06:28 +09:00
|
|
|
|
## 2025-12-17 (화) - API Explorer Phase 1 개발
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 작업
|
|
|
|
|
|
|
|
|
|
|
|
**API Explorer (Swagger UI 대체 개발 도구)**
|
|
|
|
|
|
- OpenAPI 3.0 JSON 파싱 및 엔드포인트 표시
|
|
|
|
|
|
- 3-Panel 레이아웃 (사이드바, 요청, 응답)
|
|
|
|
|
|
- HTMX 기반 SPA 경험
|
|
|
|
|
|
- 즐겨찾기, 템플릿, 히스토리 관리
|
|
|
|
|
|
- 환경 설정 (API Key 암호화 저장)
|
|
|
|
|
|
|
|
|
|
|
|
### 생성된 파일
|
|
|
|
|
|
|
|
|
|
|
|
**Config**
|
|
|
|
|
|
- `config/api-explorer.php` - 설정 파일
|
|
|
|
|
|
|
|
|
|
|
|
**Migration (4개)**
|
|
|
|
|
|
- `2025_12_17_000001_create_api_bookmarks_table.php`
|
|
|
|
|
|
- `2025_12_17_000002_create_api_templates_table.php`
|
|
|
|
|
|
- `2025_12_17_000003_create_api_histories_table.php`
|
|
|
|
|
|
- `2025_12_17_000004_create_api_environments_table.php`
|
|
|
|
|
|
|
|
|
|
|
|
**Model (4개)**
|
|
|
|
|
|
- `app/Models/DevTools/ApiBookmark.php`
|
|
|
|
|
|
- `app/Models/DevTools/ApiTemplate.php`
|
|
|
|
|
|
- `app/Models/DevTools/ApiHistory.php`
|
|
|
|
|
|
- `app/Models/DevTools/ApiEnvironment.php`
|
|
|
|
|
|
|
|
|
|
|
|
**Service (3개)**
|
|
|
|
|
|
- `app/Services/ApiExplorer/OpenApiParserService.php` - OpenAPI 파싱
|
|
|
|
|
|
- `app/Services/ApiExplorer/ApiRequestService.php` - API 프록시 실행
|
|
|
|
|
|
- `app/Services/ApiExplorer/ApiExplorerService.php` - CRUD 로직
|
|
|
|
|
|
|
|
|
|
|
|
**Controller**
|
|
|
|
|
|
- `app/Http/Controllers/DevTools/ApiExplorerController.php`
|
|
|
|
|
|
|
|
|
|
|
|
**View (5개)**
|
|
|
|
|
|
- `resources/views/dev-tools/api-explorer/index.blade.php`
|
|
|
|
|
|
- `resources/views/dev-tools/api-explorer/partials/sidebar.blade.php`
|
|
|
|
|
|
- `resources/views/dev-tools/api-explorer/partials/request-panel.blade.php`
|
|
|
|
|
|
- `resources/views/dev-tools/api-explorer/partials/response-panel.blade.php`
|
|
|
|
|
|
- `resources/views/dev-tools/api-explorer/partials/history-drawer.blade.php`
|
|
|
|
|
|
|
|
|
|
|
|
**Route**
|
|
|
|
|
|
- `routes/web.php` - 23개 라우트 등록
|
|
|
|
|
|
|
|
|
|
|
|
### 접근 경로
|
|
|
|
|
|
```
|
|
|
|
|
|
/mng/dev-tools/api-explorer
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 다음 단계 (Phase 2-5)
|
|
|
|
|
|
- Phase 2: API 실행 기능 완성
|
|
|
|
|
|
- Phase 3: 즐겨찾기/템플릿 UI
|
|
|
|
|
|
- Phase 4: 히스토리/환경 관리
|
|
|
|
|
|
- Phase 5: UX 개선
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-12-02 09:35:42 +09:00
|
|
|
|
## 2025-12-02 (월) - 메뉴/게시판/사용자 기능 확장
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 작업
|
|
|
|
|
|
|
|
|
|
|
|
**1. 메뉴 관리 드래그 앤 드롭 기능**
|
|
|
|
|
|
- SortableJS 기반 같은 레벨 내 순서 변경
|
|
|
|
|
|
- Notion 스타일 좌우 드래그로 계층 이동
|
|
|
|
|
|
- → 오른쪽 드래그: 하위로 이동 (인덴트)
|
|
|
|
|
|
- ← 왼쪽 드래그: 상위로 이동 (아웃덴트)
|
|
|
|
|
|
- 시각적 피드백: 펄스 애니메이션, 색상 구분 (파란색/주황색)
|
|
|
|
|
|
- 드래그 인디케이터 툴팁
|
|
|
|
|
|
|
|
|
|
|
|
**2. 프로필 설정 페이지**
|
|
|
|
|
|
- `/profile` - 프로필 설정 페이지 추가
|
|
|
|
|
|
- 기본 정보 수정 (이름, 이메일)
|
|
|
|
|
|
- 비밀번호 변경 기능
|
|
|
|
|
|
- ProfileController, ProfileService 추가
|
|
|
|
|
|
|
|
|
|
|
|
**3. 최초 로그인 비밀번호 변경 강제**
|
|
|
|
|
|
- EnsurePasswordChanged 미들웨어
|
|
|
|
|
|
- must_change_password 필드 활용
|
|
|
|
|
|
- 최초 로그인 시 프로필 페이지로 리다이렉트
|
|
|
|
|
|
|
|
|
|
|
|
**4. 게시판 관리 기능 확장**
|
|
|
|
|
|
- 템플릿 기반 게시판 생성 (공지사항, FAQ, 자료실, 갤러리 등)
|
|
|
|
|
|
- config/board_templates.php 설정 파일
|
|
|
|
|
|
- SVG 아이콘 적용
|
|
|
|
|
|
|
|
|
|
|
|
**5. 게시글 파일 첨부 기능**
|
|
|
|
|
|
- 파일 업로드/다운로드/삭제
|
|
|
|
|
|
- 다중 파일 첨부 지원
|
|
|
|
|
|
- boards/{board_id}/posts/{post_id} 디렉토리 구조
|
|
|
|
|
|
|
|
|
|
|
|
**6. 일일 스크럼(Daily Logs) 기능**
|
|
|
|
|
|
- 스크럼 목록/상세/작성
|
|
|
|
|
|
- 날짜별 엔트리 관리
|
|
|
|
|
|
- DailyLogController, DailyLogService
|
|
|
|
|
|
- AdminPmDailyLog, AdminPmDailyLogEntry 모델
|
|
|
|
|
|
|
|
|
|
|
|
**7. 테넌트 관리 UI 개선**
|
|
|
|
|
|
- 목록/모달 UI 개선
|
|
|
|
|
|
- 모달 하단 버튼 플로팅 고정
|
|
|
|
|
|
|
|
|
|
|
|
### 수정된 파일
|
|
|
|
|
|
- `app/Http/Controllers/Api/Admin/MenuController.php` - move, reorder 메서드 추가
|
|
|
|
|
|
- `app/Services/MenuService.php` - moveMenu, reorderMenus 메서드 추가
|
|
|
|
|
|
- `resources/views/menus/index.blade.php` - 드래그 앤 드롭 JS/CSS
|
|
|
|
|
|
- `app/Http/Controllers/ProfileController.php` - 신규
|
|
|
|
|
|
- `app/Services/ProfileService.php` - 신규
|
|
|
|
|
|
- `app/Http/Middleware/EnsurePasswordChanged.php` - 신규
|
|
|
|
|
|
- `app/Services/BoardService.php` - 템플릿 생성 메서드 추가
|
|
|
|
|
|
- `app/Services/PostService.php` - 파일 첨부 로직 추가
|
|
|
|
|
|
- `resources/views/posts/*.blade.php` - 파일 첨부 UI
|
|
|
|
|
|
|
|
|
|
|
|
### API 엔드포인트 추가
|
|
|
|
|
|
- POST `/api/admin/menus/reorder` - 메뉴 순서 변경
|
|
|
|
|
|
- POST `/api/admin/menus/move` - 메뉴 계층 이동
|
|
|
|
|
|
- POST `/api/admin/boards/from-template` - 템플릿 기반 게시판 생성
|
|
|
|
|
|
- POST `/api/admin/posts/{id}/files` - 파일 업로드
|
|
|
|
|
|
- DELETE `/api/admin/posts/{id}/files/{fileId}` - 파일 삭제
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-11-30 21:05:18 +09:00
|
|
|
|
## 2025-11-27 (수) - 시스템 게시판 관리 화면 개발
|
|
|
|
|
|
|
|
|
|
|
|
### 작업 목표
|
|
|
|
|
|
- mng에서 시스템 게시판 (is_system=true) 생성/수정/삭제 관리
|
|
|
|
|
|
- 게시판 커스텀 필드 관리 기능
|
|
|
|
|
|
|
|
|
|
|
|
### 추가된 파일
|
|
|
|
|
|
|
|
|
|
|
|
**Model**:
|
|
|
|
|
|
- `app/Models/Boards/Board.php` - 게시판 모델 (SoftDeletes, 스코프)
|
|
|
|
|
|
- `app/Models/Boards/BoardSetting.php` - 게시판 필드 설정 모델
|
|
|
|
|
|
|
|
|
|
|
|
**Service**:
|
|
|
|
|
|
- `app/Services/BoardService.php` - 게시판 비즈니스 로직
|
|
|
|
|
|
|
|
|
|
|
|
**Controller**:
|
|
|
|
|
|
- `app/Http/Controllers/BoardController.php` - Blade 뷰 컨트롤러
|
|
|
|
|
|
- `app/Http/Controllers/Api/Admin/BoardController.php` - API 컨트롤러 (HTMX)
|
|
|
|
|
|
|
|
|
|
|
|
**Views**:
|
|
|
|
|
|
- `resources/views/boards/index.blade.php` - 게시판 목록
|
|
|
|
|
|
- `resources/views/boards/create.blade.php` - 게시판 생성
|
|
|
|
|
|
- `resources/views/boards/edit.blade.php` - 게시판 수정 + 필드 관리
|
|
|
|
|
|
- `resources/views/boards/partials/table.blade.php` - 테이블 파셜
|
|
|
|
|
|
|
|
|
|
|
|
### 수정된 파일
|
|
|
|
|
|
- `routes/web.php` - boards.* 라우트 추가
|
|
|
|
|
|
- `routes/api.php` - api.admin.boards.* API 라우트 추가
|
|
|
|
|
|
|
|
|
|
|
|
### API 엔드포인트 (17개)
|
|
|
|
|
|
|
|
|
|
|
|
**게시판 관리**:
|
|
|
|
|
|
- GET `/api/admin/boards` - 목록 (HTMX)
|
|
|
|
|
|
- GET `/api/admin/boards/stats` - 통계
|
|
|
|
|
|
- POST `/api/admin/boards` - 생성
|
|
|
|
|
|
- GET `/api/admin/boards/{id}` - 조회
|
|
|
|
|
|
- PUT `/api/admin/boards/{id}` - 수정
|
|
|
|
|
|
- DELETE `/api/admin/boards/{id}` - 삭제 (Soft)
|
|
|
|
|
|
- POST `/api/admin/boards/{id}/restore` - 복원
|
|
|
|
|
|
- DELETE `/api/admin/boards/{id}/force` - 영구삭제
|
|
|
|
|
|
- POST `/api/admin/boards/{id}/toggle-active` - 활성/비활성 토글
|
|
|
|
|
|
|
|
|
|
|
|
**필드 관리**:
|
|
|
|
|
|
- GET `/api/admin/boards/{id}/fields` - 필드 목록
|
|
|
|
|
|
- POST `/api/admin/boards/{id}/fields` - 필드 추가
|
|
|
|
|
|
- PUT `/api/admin/boards/{id}/fields/{fieldId}` - 필드 수정
|
|
|
|
|
|
- DELETE `/api/admin/boards/{id}/fields/{fieldId}` - 필드 삭제
|
|
|
|
|
|
- POST `/api/admin/boards/{id}/fields/reorder` - 필드 순서 변경
|
|
|
|
|
|
|
|
|
|
|
|
**웹 라우트**:
|
|
|
|
|
|
- GET `/boards` - 목록 화면
|
|
|
|
|
|
- GET `/boards/create` - 생성 화면
|
|
|
|
|
|
- GET `/boards/{id}/edit` - 수정 화면
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 기능
|
|
|
|
|
|
1. 시스템 게시판 CRUD (is_system=true 자동 설정)
|
|
|
|
|
|
2. 게시판 유형 자유 입력 (board_type)
|
|
|
|
|
|
3. 커스텀 필드 관리 (EAV 패턴)
|
|
|
|
|
|
4. SoftDeletes 지원 (복원/영구삭제)
|
|
|
|
|
|
5. HTMX 기반 테이블 로딩
|
|
|
|
|
|
|
|
|
|
|
|
### 다음 작업
|
|
|
|
|
|
- sam API 개발 (테넌트용 게시판 + 게시글 API)
|
|
|
|
|
|
- Swagger 문서화
|
|
|
|
|
|
- 테스트
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-11-20 16:24:40 +09:00
|
|
|
|
## 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` - 로그인 검증 FormRequest
|
|
|
|
|
|
- `app/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)
|
|
|
|
|
|
|
|
|
|
|
|
### 작업 내용:
|
|
|
|
|
|
1. **DB 스키마 분석**
|
|
|
|
|
|
- API 프로젝트의 공유 DB 구조 확인 (users, personal_access_tokens, sessions)
|
|
|
|
|
|
- Multi-tenant 구조 파악 (tenant_id, user_tenants)
|
|
|
|
|
|
|
|
|
|
|
|
2. **인증 시스템 설계**
|
|
|
|
|
|
- Service-First 패턴 적용
|
|
|
|
|
|
- FormRequest를 통한 검증 분리
|
|
|
|
|
|
- 세션 기반 웹 인증 (향후 API 토큰 인증 준비)
|
|
|
|
|
|
|
|
|
|
|
|
3. **구현 완료**
|
|
|
|
|
|
- AuthService: 비즈니스 로직 캡슐화
|
|
|
|
|
|
- LoginRequest: 이메일/비밀번호 검증 및 한글 메시지
|
|
|
|
|
|
- LoginController: 로그인/로그아웃 처리
|
|
|
|
|
|
- Blade 템플릿: DaisyUI 단순 디자인
|
|
|
|
|
|
|
|
|
|
|
|
4. **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: 대시보드 구현 (메뉴, 사이드바)
|
2025-11-25 20:53:53 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2025-11-25 (월) - 권한 관리 시스템 Guard 선택 기능 추가
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 작업
|
|
|
|
|
|
- 부서 권한 관리에 Guard 선택 기능 추가 (API/Web 분리)
|
|
|
|
|
|
- 역할 권한 관리에 Guard 선택 기능 추가 (API/Web 분리)
|
|
|
|
|
|
- 부서 권한 아키텍처 재설계 (Role 기반 → Department 직접 할당)
|
|
|
|
|
|
|
|
|
|
|
|
### 수정된 파일:
|
|
|
|
|
|
|
|
|
|
|
|
#### 부서 권한 관리
|
|
|
|
|
|
- `app/Models/Tenants/Department.php` - HasPermissions trait 추가
|
|
|
|
|
|
- `app/Services/DepartmentPermissionService.php` - 완전 재작성 (직접 할당 패턴)
|
|
|
|
|
|
- getDepartmentPermissionMatrix() - guard_name 필터링
|
|
|
|
|
|
- togglePermission() - guard_name으로 권한 생성
|
|
|
|
|
|
- propagateToChildren() - guard_name 전파
|
|
|
|
|
|
- allowAllPermissions() - guard_name 적용
|
|
|
|
|
|
- denyAllPermissions() - guard_name 필터링
|
|
|
|
|
|
- resetToDefaultPermissions() - guard_name 기본 권한 설정
|
|
|
|
|
|
- `app/Http/Controllers/Api/Admin/DepartmentPermissionController.php` - guard_name 처리
|
|
|
|
|
|
- getMatrix() - guard_name 파라미터 추가
|
|
|
|
|
|
- toggle() - guard_name 전달
|
|
|
|
|
|
- allowAll() - guard_name 전달
|
|
|
|
|
|
- denyAll() - guard_name 전달
|
|
|
|
|
|
- reset() - guard_name 전달
|
|
|
|
|
|
- `resources/views/department-permissions/index.blade.php` - Guard 선택기 UI
|
|
|
|
|
|
- Guard 선택 드롭다운 (API/Web)
|
|
|
|
|
|
- 모든 HTMX 요청에 guard_name 포함
|
|
|
|
|
|
- reloadPermissions() 함수 추가
|
|
|
|
|
|
- `resources/views/department-permissions/partials/permission-matrix.blade.php`
|
|
|
|
|
|
- 체크박스 hx-include에 guard_name 추가
|
|
|
|
|
|
|
|
|
|
|
|
#### 역할 권한 관리
|
|
|
|
|
|
- `app/Services/RolePermissionService.php` - guard_name 파라미터 추가
|
|
|
|
|
|
- getRolePermissionMatrix() - guard_name 필터링
|
|
|
|
|
|
- togglePermission() - guard_name으로 권한 생성
|
|
|
|
|
|
- propagateToChildren() - guard_name 전파
|
|
|
|
|
|
- allowAllPermissions() - guard_name 적용
|
|
|
|
|
|
- denyAllPermissions() - guard_name 필터링
|
|
|
|
|
|
- resetToDefaultPermissions() - guard_name 기본 권한 설정
|
|
|
|
|
|
- `app/Http/Controllers/Api/Admin/RolePermissionController.php` - guard_name 처리
|
|
|
|
|
|
- getMatrix() - guard_name 파라미터 추가
|
|
|
|
|
|
- toggle() - guard_name 전달
|
|
|
|
|
|
- allowAll() - guard_name 전달
|
|
|
|
|
|
- denyAll() - guard_name 전달
|
|
|
|
|
|
- reset() - guard_name 전달
|
|
|
|
|
|
- `resources/views/role-permissions/index.blade.php` - Guard 선택기 UI
|
|
|
|
|
|
- Guard 선택 드롭다운 (Web/API)
|
|
|
|
|
|
- 모든 HTMX 요청에 guard_name 포함
|
|
|
|
|
|
- reloadPermissions() 함수 추가
|
|
|
|
|
|
- `resources/views/role-permissions/partials/permission-matrix.blade.php`
|
|
|
|
|
|
- 체크박스 hx-include에 guard_name 추가
|
|
|
|
|
|
|
|
|
|
|
|
#### 라우트 및 기타
|
|
|
|
|
|
- `routes/api.php` - reset 엔드포인트 추가
|
|
|
|
|
|
- department-permissions/reset
|
|
|
|
|
|
- role-permissions/reset
|
|
|
|
|
|
- `docs/INDEX.md` - 문서 업데이트
|
|
|
|
|
|
|
|
|
|
|
|
### 작업 내용:
|
|
|
|
|
|
|
|
|
|
|
|
1. **부서 권한 아키텍처 재설계**
|
|
|
|
|
|
- 기존: Department → Role → Permission (잘못된 설계)
|
|
|
|
|
|
- 변경: Department → Permission (직접 할당)
|
|
|
|
|
|
- model_has_permissions 테이블 직접 사용
|
|
|
|
|
|
- HasPermissions trait 추가로 Spatie 기능 활용
|
|
|
|
|
|
|
|
|
|
|
|
2. **Guard 선택 기능 구현**
|
|
|
|
|
|
- API Guard: API 토큰 인증용 권한
|
|
|
|
|
|
- Web Guard: 웹 세션 인증용 권한
|
|
|
|
|
|
- Guard별 독립적인 권한 매트릭스 관리
|
|
|
|
|
|
|
|
|
|
|
|
3. **초기화(Reset) 기능 추가**
|
|
|
|
|
|
- 전체 허용: 모든 권한 부여
|
|
|
|
|
|
- 전체 거부: 모든 권한 제거
|
|
|
|
|
|
- 초기화: 조회(view) 권한만 부여 (기본 권한)
|
|
|
|
|
|
|
|
|
|
|
|
4. **UI/UX 개선**
|
|
|
|
|
|
- Guard 선택기를 "전체 허용" 버튼 앞으로 배치
|
|
|
|
|
|
- 시각적 구분선(Divider) 추가
|
|
|
|
|
|
- Guard 변경 시 자동 새로고침
|
|
|
|
|
|
|
|
|
|
|
|
### 코드 품질:
|
|
|
|
|
|
- ✅ Pint 포맷팅 통과
|
|
|
|
|
|
- ✅ Service-First 아키텍처 유지
|
|
|
|
|
|
- ✅ BelongsToTenant 스코프 적용
|
|
|
|
|
|
- ✅ FormRequest 검증 패턴 유지
|
|
|
|
|
|
|
|
|
|
|
|
### Git 커밋:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
feat: 권한 관리 시스템에 Guard 선택 기능 추가
|
|
|
|
|
|
|
|
|
|
|
|
- 부서 권한 아키텍처 재설계 (Role → Department 직접 할당)
|
|
|
|
|
|
- Guard 선택 기능 구현 (API/Web 분리)
|
|
|
|
|
|
- 초기화(Reset) 기능 추가 (view 권한만 허용)
|
|
|
|
|
|
- UI 개선 (Guard 선택기 + 구분선)
|
|
|
|
|
|
```
|
2025-11-20 16:24:40 +09:00
|
|
|
|
- [ ] Phase 3: 사용자 관리 기능
|
|
|
|
|
|
|
|
|
|
|
|
### Git 커밋:
|
2025-11-20 16:34:43 +09:00
|
|
|
|
- ✅ `ece1f28` "feat: MNG 인증 시스템 구현"
|
|
|
|
|
|
- ✅ `b71e85a` "fix: Tailwind 3.x 다운그레이드 및 DaisyUI 적용"
|
|
|
|
|
|
|
|
|
|
|
|
### 이슈 해결:
|
|
|
|
|
|
- **문제**: Tailwind CSS 4.x에서 DaisyUI 플러그인 미적용
|
|
|
|
|
|
- **원인**: DaisyUI가 Tailwind 4.x를 완전히 지원하지 않음
|
|
|
|
|
|
- **해결**: Tailwind 3.4.17로 다운그레이드, PostCSS 설정 수정
|
2025-11-20 21:09:14 +09:00
|
|
|
|
- **결과**: 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 변수가 계산되지 않아 버튼, 카드 등 모든 컴포넌트 스타일 무효화
|
|
|
|
|
|
|
|
|
|
|
|
### 해결 과정:
|
|
|
|
|
|
1. **DaisyUI 설정 시도** (실패)
|
|
|
|
|
|
- Custom hex 테마 설정 → DaisyUI가 여전히 oklch() 사용
|
|
|
|
|
|
- `themes: false` 설정 → base CSS에서 oklch() 사용
|
|
|
|
|
|
|
|
|
|
|
|
2. **DaisyUI 완전 제거** (성공)
|
|
|
|
|
|
- `tailwind.config.js`에서 DaisyUI 플러그인 제거
|
|
|
|
|
|
- Pure Tailwind CSS + @tailwindcss/forms 사용
|
|
|
|
|
|
- Custom primary/secondary 색상 hex로 정의
|
|
|
|
|
|
|
|
|
|
|
|
3. **로그인 페이지 리팩토링**
|
|
|
|
|
|
- DaisyUI 클래스 → Tailwind 유틸리티 클래스 변환
|
|
|
|
|
|
- `btn btn-primary` → `bg-primary text-white rounded-lg`
|
|
|
|
|
|
- `card` → `bg-white rounded-lg shadow-xl`
|
|
|
|
|
|
- `input 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 커밋:
|
feat: 좌측 사이드바 레이아웃 및 메뉴 시스템 구현
- layouts/app.blade.php 마스터 레이아웃 생성
- partials/sidebar.blade.php 좌측 사이드바 컴포넌트 (256px, 10개 메뉴)
- partials/header.blade.php 상단 헤더 컴포넌트 (64px, 페이지 타이틀 + 사용자 메뉴)
- dashboard/index.blade.php @extends 패턴으로 리팩토링
메뉴 구조:
- 조직 관리: 대시보드, 사용자, 권한/역할, 부서
- 제품/자재: 제품, 자재, BOM, 카테고리
- 시스템: 시스템 설정, 감사 로그
레이아웃:
- Flexbox 구조 (사이드바 + 메인 영역)
- Blade 컴포넌트 분리 (@extends/@section/@include)
- Heroicons 아이콘, 활성 상태 하이라이트
- 사용자 드롭다운 메뉴 (JavaScript 토글)
2025-11-20 21:28:58 +09:00
|
|
|
|
- ✅ `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개):
|
|
|
|
|
|
**조직 관리:**
|
|
|
|
|
|
1. 대시보드 (활성화됨, route 연결)
|
|
|
|
|
|
2. 사용자 관리
|
|
|
|
|
|
3. 권한 및 역할
|
|
|
|
|
|
4. 부서 관리
|
|
|
|
|
|
|
|
|
|
|
|
**제품/자재 관리:**
|
|
|
|
|
|
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
|
|
|
|
|
|
- **반응형**: 추후 모바일 대응 예정 (현재 데스크톱 우선)
|
|
|
|
|
|
|
|
|
|
|
|
### 개발 프로세스:
|
|
|
|
|
|
1. Phase 1: 레이아웃 구조 설계 ✅
|
|
|
|
|
|
2. Phase 2: 메뉴 리스트업 ✅
|
|
|
|
|
|
3. Phase 3: 컨텐츠 구성 (다음 단계)
|
|
|
|
|
|
|
|
|
|
|
|
### Git 커밋:
|
2025-11-21 09:18:19 +09:00
|
|
|
|
- ✅ `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 색상 뱃지)
|
|
|
|
|
|
- 전체 보기: "전체 테넌트 데이터 표시 중" (회색 텍스트)
|
|
|
|
|
|
|
|
|
|
|
|
**동작 방식:**
|
|
|
|
|
|
1. 드롭다운 변경 시 자동 Form Submit (`onchange`)
|
|
|
|
|
|
2. `POST /tenant/switch` 라우트로 전송
|
|
|
|
|
|
3. Session에 `selected_tenant_id` 저장
|
|
|
|
|
|
4. 이전 페이지로 리다이렉트 (`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 커밋:
|
2025-11-24 16:36:02 +09:00
|
|
|
|
- ✅ `661c5ad` "feat: 테넌트 선택 기능 구현"
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2025-11-24 (일) - 테넌트 관리 페이지네이션 및 공통 컴포넌트화
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 작업
|
|
|
|
|
|
- 테넌트 목록 페이지에 HTMX 호환 페이지네이션 추가
|
|
|
|
|
|
- 페이지네이션을 공통 컴포넌트로 분리하여 재사용성 향상
|
|
|
|
|
|
|
|
|
|
|
|
### 추가된 파일:
|
|
|
|
|
|
- `resources/views/partials/pagination.blade.php` - HTMX 호환 공통 페이지네이션 컴포넌트
|
|
|
|
|
|
|
|
|
|
|
|
### 수정된 파일:
|
|
|
|
|
|
- `resources/views/tenants/partials/table.blade.php` - 페이지네이션 코드 제거, 공통 컴포넌트 include로 대체
|
|
|
|
|
|
|
|
|
|
|
|
### 작업 배경:
|
|
|
|
|
|
**이전 세션 작업 내역 (2025-11-24):**
|
|
|
|
|
|
1. ✅ 테넌트 수정 폼 HTMX URL 라우팅 문제 해결
|
|
|
|
|
|
2. ✅ UpdateTenantRequest 라우트 파라미터 수정 (`route('tenant')` → `route('id')`)
|
|
|
|
|
|
3. ✅ HTMX 삭제/복원/영구삭제 기능에 CSRF 토큰 헤더 추가
|
|
|
|
|
|
4. ✅ TenantService::forceDeleteTenant() 외래키 제약 처리
|
|
|
|
|
|
5. ✅ `docs/TROUBLESHOOTING.md` 트러블슈팅 가이드 작성
|
|
|
|
|
|
6. ✅ 페이지네이션 추가 (1페이지만 있어도 항상 표시)
|
|
|
|
|
|
7. ✅ 페이지네이션을 공통 컴포넌트로 분리
|
|
|
|
|
|
|
|
|
|
|
|
### 페이지네이션 구현 상세:
|
|
|
|
|
|
|
|
|
|
|
|
**구조:**
|
|
|
|
|
|
- **모바일**: 이전/다음 버튼만 표시 (`sm:hidden`)
|
|
|
|
|
|
- **데스크톱**: 전체 페이지 번호 + 이전/다음 버튼 (`hidden sm:flex`)
|
|
|
|
|
|
|
|
|
|
|
|
**기능:**
|
|
|
|
|
|
- 개별 페이지 번호 버튼 클릭 가능 (1, 2, 3...)
|
|
|
|
|
|
- 현재 페이지 하이라이트 (파란색 배경)
|
|
|
|
|
|
- 비활성화된 버튼 회색 처리
|
|
|
|
|
|
- HTMX 동적 로딩 (페이지 새로고침 없음)
|
|
|
|
|
|
- 검색 필터 유지 (`hx-include`)
|
|
|
|
|
|
- CSRF 토큰 자동 포함
|
|
|
|
|
|
|
|
|
|
|
|
**사용법:**
|
|
|
|
|
|
```blade
|
|
|
|
|
|
@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 목록
|
|
|
|
|
|
- 감사 로그 목록
|
|
|
|
|
|
|
|
|
|
|
|
### 다음 단계:
|
|
|
|
|
|
- [ ] 브라우저에서 페이지네이션 동작 확인
|
|
|
|
|
|
- [ ] 다른 목록 페이지에 페이지네이션 적용
|
|
|
|
|
|
- [ ] 페이지당 표시 개수 선택 기능 추가 고려
|
|
|
|
|
|
|
2025-11-24 23:07:09 +09:00
|
|
|
|
### 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)
|
|
|
|
|
|
- 활성 필터: `active` scope 적용
|
|
|
|
|
|
- UI: 활성 상태 뱃지 표시
|
|
|
|
|
|
|
|
|
|
|
|
**정렬 순서:**
|
|
|
|
|
|
- `sort_order` 컬럼: 표시 순서 지정
|
|
|
|
|
|
- 기본 정렬: `sort_order ASC`, `name ASC`
|
|
|
|
|
|
|
|
|
|
|
|
### 검증 규칙:
|
|
|
|
|
|
|
|
|
|
|
|
**StoreDepartmentRequest:**
|
|
|
|
|
|
- `name`: 필수, 최대 100자
|
|
|
|
|
|
- `parent_id`: 선택, 존재하는 부서 ID
|
|
|
|
|
|
- `sort_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`: 생성자 ID
|
|
|
|
|
|
- `updated_by`: 수정자 ID
|
|
|
|
|
|
- `deleted_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: 테넌트 관리**
|
|
|
|
|
|
- CRUD, 복구/영구삭제, 페이지네이션
|
|
|
|
|
|
- 커밋: 575e9df, 0f21445, bc3777a
|
|
|
|
|
|
|
|
|
|
|
|
**✅ Phase 4-2: 역할 관리**
|
|
|
|
|
|
- CRUD, 권한 할당/해제, Spatie Permission 통합
|
|
|
|
|
|
- 커밋: 5f50716
|
|
|
|
|
|
|
|
|
|
|
|
**✅ Phase 4-3: 부서 관리**
|
|
|
|
|
|
- CRUD, 계층 구조, 활성 상태 관리
|
|
|
|
|
|
- 커밋: 6738505
|
|
|
|
|
|
|
|
|
|
|
|
**✅ Phase 4-4: 사용자 관리**
|
|
|
|
|
|
- CRUD, 복구/영구삭제, 역할/부서 연결
|
|
|
|
|
|
- 커밋: 0c86b39, 8940557
|
|
|
|
|
|
|
|
|
|
|
|
**✅ 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 15:21:48 +09:00
|
|
|
|
## 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 구조:**
|
|
|
|
|
|
1. **상단 툴바**
|
|
|
|
|
|
- 역할 선택 드롭다운 (HTMX 동적 로딩)
|
|
|
|
|
|
- 전체 허용 (녹색) / 전체 거부 (빨간색) / 초기화 (회색) 버튼
|
|
|
|
|
|
|
|
|
|
|
|
2. **권한 매트릭스 테이블**
|
|
|
|
|
|
- 행: 메뉴 목록 (계층 구조, "├─" 인덴트)
|
|
|
|
|
|
- 컬럼: 순번, 메뉴명, 상위 메뉴, URL, 순서 + 권한 체크박스 7개
|
|
|
|
|
|
- 체크박스: HTMX로 실시간 토글
|
|
|
|
|
|
|
|
|
|
|
|
3. **빈 상태**
|
|
|
|
|
|
- 역할 미선택 시 "역할을 선택해주세요" 메시지 표시
|
|
|
|
|
|
|
|
|
|
|
|
**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 15:32:58 +09:00
|
|
|
|
**다음 작업**: 브라우저 동작 확인 및 오류 수정
|
|
|
|
|
|
## 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 빌드 (필요 시)
|
|
|
|
|
|
- [ ] 오류 수정 및 개선
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2025-11-25 20:53:53 +09:00
|
|
|
|
|
|
|
|
|
|
## 2025-11-25 (월) - 부서 권한 체크박스 문제 해결
|
|
|
|
|
|
|
|
|
|
|
|
### 문제 상황:
|
|
|
|
|
|
- **증상**: 부서 권한 매트릭스의 체크박스 클릭 시 권한이 저장되지 않음
|
|
|
|
|
|
- **발견**: 역할 권한은 정상 작동, 부서 권한만 문제
|
|
|
|
|
|
- **사용자 피드백**:
|
|
|
|
|
|
1. 체크 후 저장 안 됨
|
|
|
|
|
|
2. 나갔다 들어오면 체크 해제됨
|
|
|
|
|
|
3. 첫 번째 부서가 자동 선택되지 않음
|
|
|
|
|
|
4. 클릭 기능이 작동하지 않음
|
|
|
|
|
|
|
|
|
|
|
|
### 근본 원인 발견 (code-workflow 스킬 사용):
|
|
|
|
|
|
**admin 패널 분석 결과:**
|
|
|
|
|
|
- Admin은 **부서별 전용 역할(Role)** 생성 방식 사용
|
|
|
|
|
|
- 부서 → 역할 매핑: `model_has_roles` 테이블
|
|
|
|
|
|
- 권한 저장: `role_has_permissions` 테이블 (Spatie)
|
|
|
|
|
|
- 역할명 패턴: "부서_{name}_권한"
|
|
|
|
|
|
|
|
|
|
|
|
**MNG 구현의 잘못된 접근:**
|
|
|
|
|
|
- ❌ `model_has_permissions` 테이블 직접 사용
|
|
|
|
|
|
- ❌ Department 모델에 permissions() 관계 추가
|
|
|
|
|
|
- ✅ 올바른 방법: admin과 동일하게 부서별 Role 생성
|
|
|
|
|
|
|
|
|
|
|
|
### 해결 방안:
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. DepartmentPermissionService.php 완전 재작성
|
|
|
|
|
|
**새로운 메서드 추가:**
|
|
|
|
|
|
- `getDepartmentRole(departmentId)`: 부서 전용 역할 찾기/생성
|
|
|
|
|
|
- `model_has_roles` 테이블에서 부서-역할 매핑 조회
|
|
|
|
|
|
- 없으면 "부서_{name}_권한" 역할 자동 생성
|
|
|
|
|
|
- Department 모델에 역할 할당
|
|
|
|
|
|
|
|
|
|
|
|
**수정된 메서드:**
|
|
|
|
|
|
- `getDepartmentPermissionMatrix()`: role_has_permissions 테이블 조회로 변경
|
|
|
|
|
|
- `togglePermission()`: Spatie의 givePermissionTo/revokePermissionTo 사용
|
|
|
|
|
|
- `allowAllPermissions()`: 역할에 권한 부여
|
|
|
|
|
|
- `denyAllPermissions()`: 역할에서 권한 제거
|
|
|
|
|
|
- `propagateToChildren()`: 하위 부서의 역할에 권한 전파
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. Department.php 모델 정리
|
|
|
|
|
|
- ❌ 제거: permissions() MorphToMany 관계
|
|
|
|
|
|
- ✅ 유지: HasRoles trait (Spatie)
|
|
|
|
|
|
- ✅ 유지: guard_name = 'web'
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. View 파일 수정
|
|
|
|
|
|
**permission-matrix.blade.php:**
|
|
|
|
|
|
- 추가: `hx-trigger="click"` 속성
|
|
|
|
|
|
- 이유: 체크박스 클릭 시 즉시 HTMX 요청 발생
|
|
|
|
|
|
|
|
|
|
|
|
**index.blade.php:**
|
|
|
|
|
|
- 개선: 자동 선택 로직 수정
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
// Before: firstButton.click() (HTMX 이벤트 미발생)
|
|
|
|
|
|
// After: selectDepartment(firstButton) + htmx.trigger(firstButton, 'click')
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 변경된 파일:
|
|
|
|
|
|
- `app/Services/DepartmentPermissionService.php` - 전면 재작성 (330줄)
|
|
|
|
|
|
- `app/Services/RolePermissionService.php` - Pint 자동 수정
|
|
|
|
|
|
- `app/Models/Tenants/Department.php` - permissions() 관계 제거
|
|
|
|
|
|
- `resources/views/department-permissions/index.blade.php` - 자동 선택 개선
|
|
|
|
|
|
- `resources/views/department-permissions/partials/permission-matrix.blade.php` - hx-trigger 추가
|
|
|
|
|
|
|
|
|
|
|
|
### 코드 품질:
|
|
|
|
|
|
- ✅ Laravel Pint 통과 (1개 스타일 이슈 자동 수정)
|
|
|
|
|
|
|
|
|
|
|
|
### 다음 단계:
|
|
|
|
|
|
- [ ] 브라우저 테스트 (체크박스 클릭, 권한 저장 확인)
|
|
|
|
|
|
- [ ] 자동 선택 동작 확인
|
|
|
|
|
|
- [ ] 하위 부서 권한 전파 동작 확인
|
|
|
|
|
|
- [ ] Git 커밋 (테스트 완료 후)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2025-11-25 (월) - guard_name 불일치 문제 해결 (code-workflow 스킬 사용)
|
|
|
|
|
|
|
|
|
|
|
|
### 🔍 근본 원인 재발견:
|
|
|
|
|
|
**Admin 패널 vs MNG 구현 차이:**
|
|
|
|
|
|
- **Admin**: guard_name = 'api', tenant_id 포함 (model_has_roles), Permission tenant_id = null
|
|
|
|
|
|
- **MNG (잘못된 구현)**: guard_name = 'web', tenant_id 누락, Permission tenant_id = $tenantId
|
|
|
|
|
|
|
|
|
|
|
|
**영향:**
|
|
|
|
|
|
- Spatie Permission은 guard_name이 일치해야 작동
|
|
|
|
|
|
- guard_name 불일치로 인해 hasPermissionTo(), givePermissionTo(), revokePermissionTo() 모두 실패
|
|
|
|
|
|
- 체크박스 클릭해도 권한이 저장되지 않는 근본 원인
|
|
|
|
|
|
|
|
|
|
|
|
### ✅ 해결 방안 (code-workflow 5단계):
|
|
|
|
|
|
|
|
|
|
|
|
#### 1단계: 분석 ✅
|
|
|
|
|
|
- MNG_CRITICAL_RULES.md, admin 구현 분석
|
|
|
|
|
|
- guard_name 불일치, tenant_id 누락 발견
|
|
|
|
|
|
|
|
|
|
|
|
#### 2단계: 수정 ✅
|
|
|
|
|
|
**DepartmentPermissionService.php:**
|
|
|
|
|
|
- line 44: guard_name 'web' → 'api'
|
|
|
|
|
|
- line 50-54: model_has_roles에 tenant_id 추가
|
|
|
|
|
|
- line 124: Permission guard_name 'web' → 'api', tenant_id null
|
|
|
|
|
|
- line 166: Permission guard_name 'web' → 'api', tenant_id null
|
|
|
|
|
|
- line 210: Permission guard_name 'web' → 'api', tenant_id null
|
|
|
|
|
|
|
|
|
|
|
|
**Department.php:**
|
|
|
|
|
|
- line 34: guard_name 'web' → 'api'
|
|
|
|
|
|
|
|
|
|
|
|
#### 3단계: 검증 ✅
|
|
|
|
|
|
- ✅ Laravel Pint: 2개 파일 통과
|
|
|
|
|
|
- ✅ 라우트 확인: API 라우트 정상
|
|
|
|
|
|
|
|
|
|
|
|
#### 4단계: 정리 ✅
|
|
|
|
|
|
- 임시 파일 없음
|
|
|
|
|
|
|
|
|
|
|
|
#### 5단계: 커밋 ⏳
|
|
|
|
|
|
- 대기 중 (브라우저 테스트 후)
|
|
|
|
|
|
|
|
|
|
|
|
### 변경된 파일:
|
|
|
|
|
|
- `app/Services/DepartmentPermissionService.php` - guard_name 통일, tenant_id 수정
|
|
|
|
|
|
- `app/Models/Tenants/Department.php` - guard_name 'api'로 변경
|
|
|
|
|
|
|
|
|
|
|
|
### 다음 단계:
|
|
|
|
|
|
- [ ] 브라우저 테스트 (권한 저장/조회 확인)
|
|
|
|
|
|
- [ ] 커밋 및 문서화
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2025-11-26 20:40:54 +09:00
|
|
|
|
|
|
|
|
|
|
## 2025-11-26 (화) - 개인 권한 관리 구현 및 permission_overrides 테이블 통일
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 작업
|
|
|
|
|
|
- 개인 권한 관리 (UserPermission) 기능 완전 구현
|
|
|
|
|
|
- 기존 model_has_permissions 테이블 → permission_overrides 테이블로 통일
|
|
|
|
|
|
- API AccessService와 동일한 테이블 구조 사용
|
|
|
|
|
|
|
|
|
|
|
|
### 추가된 파일:
|
|
|
|
|
|
- `app/Http/Controllers/UserPermissionController.php` - Blade 화면 컨트롤러
|
|
|
|
|
|
- `app/Http/Controllers/Api/Admin/UserPermissionController.php` - HTMX API 컨트롤러
|
|
|
|
|
|
- `resources/views/user-permissions/index.blade.php` - 메인 페이지
|
|
|
|
|
|
- `resources/views/user-permissions/partials/permission-matrix.blade.php` - 권한 매트릭스
|
|
|
|
|
|
- `resources/views/user-permissions/partials/empty-state.blade.php` - 빈 상태 화면
|
|
|
|
|
|
|
|
|
|
|
|
### 수정된 파일:
|
|
|
|
|
|
- `app/Services/UserPermissionService.php` - model_has_permissions → permission_overrides 테이블 사용
|
|
|
|
|
|
- `app/Services/DepartmentPermissionService.php` - model_has_permissions → permission_overrides 테이블 사용
|
|
|
|
|
|
- `routes/web.php` - 개인 권한 관리 라우트 추가
|
|
|
|
|
|
- `routes/api.php` - 개인 권한 관리 API 라우트 추가
|
|
|
|
|
|
- `resources/views/partials/sidebar.blade.php` - 개인 권한 관리 메뉴 링크 연결
|
|
|
|
|
|
|
|
|
|
|
|
### 기술 상세:
|
|
|
|
|
|
**permission_overrides 테이블 통일:**
|
|
|
|
|
|
- `model_type`: 폴리모픽 타입 (User, Department)
|
|
|
|
|
|
- `model_id`: 대상 ID
|
|
|
|
|
|
- `permission_id`: 권한 ID
|
|
|
|
|
|
- `effect`: 0=DENY, 1=ALLOW (현재 ALLOW만 관리)
|
|
|
|
|
|
- `effective_from`, `effective_to`: 유효 기간 지원
|
|
|
|
|
|
- Soft delete 지원 (deleted_at, deleted_by)
|
|
|
|
|
|
|
|
|
|
|
|
**권한 체크 우선순위 (API AccessService):**
|
|
|
|
|
|
1. 개인 DENY → 거부
|
|
|
|
|
|
2. Role 권한 (Spatie can) → 허용
|
|
|
|
|
|
3. 부서 ALLOW → 허용
|
|
|
|
|
|
4. 개인 ALLOW → 허용
|
|
|
|
|
|
5. 기본 → 거부
|
|
|
|
|
|
|
|
|
|
|
|
### 코드 품질:
|
|
|
|
|
|
- ✅ PHP 문법 검사 통과
|
|
|
|
|
|
- ✅ Pint 포맷팅 통과
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2025-11-26 (화) - 역할/부서 권한 관리 테넌트별 그룹핑
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 작업
|
|
|
|
|
|
- "전체" 테넌트 선택 시 역할/부서가 혼합 표시되는 문제 해결
|
|
|
|
|
|
- 테넌트별로 그룹핑하여 가독성 향상
|
|
|
|
|
|
|
|
|
|
|
|
### 수정된 파일:
|
|
|
|
|
|
- `app/Http/Controllers/RolePermissionController.php` - 테넌트별 역할 그룹핑 로직 추가
|
|
|
|
|
|
- `app/Http/Controllers/DepartmentPermissionController.php` - 테넌트별 부서 그룹핑 로직 추가
|
|
|
|
|
|
- `resources/views/role-permissions/index.blade.php` - 테넌트별 섹션 헤더 및 그룹핑 UI
|
|
|
|
|
|
- `resources/views/department-permissions/index.blade.php` - 테넌트별 섹션 헤더 및 그룹핑 UI
|
|
|
|
|
|
|
|
|
|
|
|
### 기술 구현:
|
|
|
|
|
|
**Controller 로직:**
|
|
|
|
|
|
```php
|
|
|
|
|
|
if ($tenantId && $tenantId !== 'all') {
|
|
|
|
|
|
// 특정 테넌트 선택 시 기존 방식
|
|
|
|
|
|
$roles = $rolesQuery->where('tenant_id', $tenantId)->get();
|
|
|
|
|
|
$rolesByTenant = null;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 전체 선택 시 테넌트별 그룹핑
|
|
|
|
|
|
$roles = $rolesQuery->get();
|
|
|
|
|
|
$rolesByTenant = $roles->groupBy('tenant_id');
|
|
|
|
|
|
$tenantIds = $rolesByTenant->keys()->filter()->toArray();
|
|
|
|
|
|
$tenants = Tenant::whereIn('id', $tenantIds)->pluck('company_name', 'id');
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**View UI:**
|
|
|
|
|
|
- 전체 테넌트 선택 시: 테넌트별 섹션으로 구분 (회색 라벨)
|
|
|
|
|
|
- 선택된 역할/부서 표시: `[테넌트명] 역할명 역할` 형식
|
|
|
|
|
|
- 기존 단일 테넌트 선택 시: 기존 UI 유지
|
|
|
|
|
|
|
|
|
|
|
|
### 이슈 해결:
|
|
|
|
|
|
- **문제**: `tenants` 테이블에 `name` 컬럼 없음 (SQL 에러)
|
|
|
|
|
|
- **원인**: 테넌트 테이블은 `company_name` 컬럼 사용
|
|
|
|
|
|
- **해결**: `pluck('name', 'id')` → `pluck('company_name', 'id')` 변경
|
|
|
|
|
|
|
|
|
|
|
|
### Git 커밋:
|
|
|
|
|
|
- ✅ `f029d78` "역할/부서 권한 관리 페이지 테넌트별 그룹핑 기능 추가"
|
|
|
|
|
|
|
|
|
|
|
|
### 문서화:
|
|
|
|
|
|
- ✅ `docs/[MNG-2025-11-26] role-department-permission-tenant-grouping.md` 작성
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2025-11-26 (화) - 개인 권한 관리 3-state 토글 UI 구현
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 작업
|
|
|
|
|
|
- 개인 권한 관리에서 허용/거부/미설정 3단계 상태 지원
|
|
|
|
|
|
- 체크박스 → 토글 버튼 UI로 변경
|
|
|
|
|
|
- 권한 상태 순환: 미설정 → 허용 → 거부 → 미설정
|
|
|
|
|
|
|
|
|
|
|
|
### 수정된 파일:
|
|
|
|
|
|
- `app/Services/UserPermissionService.php`
|
|
|
|
|
|
- `getUserPermissionMatrix()`: 3-state 지원 (null/'allow'/'deny' 반환)
|
|
|
|
|
|
- `togglePermission()`: 3단계 순환 로직 (null→allow→deny→null)
|
|
|
|
|
|
- `allowAllPermissions()`: DENY 레코드도 ALLOW로 변경
|
|
|
|
|
|
- `denyAllPermissions()`: ALLOW/DENY 모두 soft delete (미설정으로 초기화)
|
|
|
|
|
|
- `resources/views/user-permissions/partials/permission-matrix.blade.php`
|
|
|
|
|
|
- 체크박스 → 토글 버튼으로 변경
|
|
|
|
|
|
- 3가지 상태별 아이콘 및 색상:
|
|
|
|
|
|
- 미설정: ➖ (회색)
|
|
|
|
|
|
- 허용: ✓ (녹색)
|
|
|
|
|
|
- 거부: ✕ (빨간색)
|
|
|
|
|
|
- 범례 추가 (하단)
|
|
|
|
|
|
|
|
|
|
|
|
### UI/UX 변경사항:
|
|
|
|
|
|
**토글 버튼 디자인:**
|
|
|
|
|
|
```
|
|
|
|
|
|
미설정: bg-gray-100 text-gray-400 (➖)
|
|
|
|
|
|
허용: bg-green-100 text-green-600 (✓)
|
|
|
|
|
|
거부: bg-red-100 text-red-600 (✕)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**토글 순환:**
|
|
|
|
|
|
```
|
|
|
|
|
|
클릭 시: 미설정 → 허용 → 거부 → 미설정 (무한 순환)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**DB 상태:**
|
|
|
|
|
|
- 미설정: 레코드 없음 또는 soft delete (deleted_at)
|
|
|
|
|
|
- 허용: effect=1, deleted_at=null
|
|
|
|
|
|
- 거부: effect=0, deleted_at=null
|
|
|
|
|
|
|
|
|
|
|
|
### API AccessService 권한 체크 우선순위:
|
|
|
|
|
|
1. 개인 DENY → 즉시 거부
|
|
|
|
|
|
2. Role 권한 (Spatie can) → 허용
|
|
|
|
|
|
3. 부서 ALLOW → 허용
|
|
|
|
|
|
4. 개인 ALLOW → 허용
|
|
|
|
|
|
5. 기본 → 거부
|
|
|
|
|
|
|
|
|
|
|
|
### 코드 품질:
|
|
|
|
|
|
- ✅ PHP 문법 검사 통과
|
|
|
|
|
|
- ✅ Pint 포맷팅 통과
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2025-11-26 (화) - 개인 권한 관리 통합 매트릭스 구현
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 작업
|
|
|
|
|
|
- 역할/부서/개인 권한을 통합하여 최종 유효 권한 표시
|
|
|
|
|
|
- 권한 소스별 색상 구분 (역할=보라, 부서=파랑, 개인허용=녹색, 개인거부=빨강)
|
|
|
|
|
|
- 스마트 토글 로직 구현 (상속된 권한 오버라이드 지원)
|
|
|
|
|
|
|
|
|
|
|
|
### 수정된 파일:
|
|
|
|
|
|
- `app/Services/UserPermissionService.php` - 역할/부서/개인 권한 통합 조회
|
|
|
|
|
|
- `getRolePermissions()`: Spatie `model_has_roles` + `role_has_permissions` 조회
|
|
|
|
|
|
- `getDepartmentPermissions()`: `permission_overrides` 테이블 (Department 모델타입) 조회
|
|
|
|
|
|
- `getPersonalOverrides()`: `permission_overrides` 테이블 (User 모델타입) 조회
|
|
|
|
|
|
- `getUserPermissionMatrix()`: 모든 권한 소스 통합, 소스 정보 반환
|
|
|
|
|
|
- `togglePermission()`: 스마트 토글 로직
|
|
|
|
|
|
- `resources/views/user-permissions/index.blade.php` - 사용자 ID 뱃지 스타일 개선
|
|
|
|
|
|
- `resources/views/user-permissions/partials/permission-matrix.blade.php` - 5가지 상태 UI
|
|
|
|
|
|
|
|
|
|
|
|
### 기술 구현:
|
|
|
|
|
|
|
|
|
|
|
|
**권한 소스 우선순위 (표시용):**
|
|
|
|
|
|
1. 개인 DENY → 최우선 (빨간색)
|
|
|
|
|
|
2. 개인 ALLOW → 녹색
|
|
|
|
|
|
3. 역할 권한 (Spatie) → 보라색
|
|
|
|
|
|
4. 부서 권한 → 파란색
|
|
|
|
|
|
5. 미설정 → 회색
|
|
|
|
|
|
|
|
|
|
|
|
**스마트 토글 로직:**
|
|
|
|
|
|
```
|
|
|
|
|
|
- 역할/부서 권한 (개인 설정 없음) → 클릭 시 개인 DENY 추가 (오버라이드)
|
|
|
|
|
|
- 개인 DENY → 클릭 시 삭제 (상속된 권한 복원)
|
|
|
|
|
|
- 권한 없음 → 클릭 시 개인 ALLOW 추가
|
|
|
|
|
|
- 개인 ALLOW → 클릭 시 개인 DENY로 변경
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**색상 코드:**
|
|
|
|
|
|
```
|
|
|
|
|
|
보라색 (bg-purple-100): 역할에서 상속된 권한
|
|
|
|
|
|
파란색 (bg-blue-100): 부서에서 상속된 권한
|
|
|
|
|
|
녹색 (bg-green-100): 개인 허용 설정
|
|
|
|
|
|
빨간색 (bg-red-100): 개인 거부 설정
|
|
|
|
|
|
회색 (bg-gray-100): 미설정
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**UI 개선:**
|
|
|
|
|
|
- 사용자 선택 버튼: 이름 + 아이디 뱃지 (` ` 패딩)
|
|
|
|
|
|
- 선택된 사용자 표시: 테두리 스타일 (`border border-blue-400`)
|
|
|
|
|
|
- 범례 업데이트: 5가지 상태 모두 표시
|
|
|
|
|
|
|
|
|
|
|
|
### 코드 품질:
|
|
|
|
|
|
- ✅ PHP 문법 검사 통과
|
|
|
|
|
|
- ✅ Pint 포맷팅 통과
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2025-11-27 20:05:27 +09:00
|
|
|
|
|
|
|
|
|
|
## 2025-11-27 (수) - 테넌트 정보 모달 팝업 기능 구현
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 작업
|
|
|
|
|
|
- 테넌트 행 클릭 시 모달 팝업 오픈 기능 구현
|
|
|
|
|
|
- 모달 내 JS 함수 window 객체 등록 (동적 HTML 접근 문제 해결)
|
|
|
|
|
|
- 삭제된 테넌트 경고 배너 추가 (삭제일, 삭제자 표시)
|
|
|
|
|
|
- 복원 후 모달 내용 자동 새로고침
|
|
|
|
|
|
|
|
|
|
|
|
### 수정된 파일:
|
|
|
|
|
|
|
|
|
|
|
|
#### JavaScript
|
|
|
|
|
|
- `public/js/tenant-modal.js`
|
|
|
|
|
|
- `toggleModalMenuChildren`, `hideModalMenuDescendants` → `window` 객체에 등록
|
|
|
|
|
|
- 모달 오픈 시 구독정보 탭 자동 로드 (`switchTab('subscription')`)
|
|
|
|
|
|
- `isOpen()` 메서드 추가 (모달 상태 확인용)
|
|
|
|
|
|
|
|
|
|
|
|
#### Blade Views
|
|
|
|
|
|
- `resources/views/tenants/partials/table.blade.php`
|
|
|
|
|
|
- 행 클릭 시 모달 오픈: `onclick="TenantModal.open({{ $tenant->id }})"`
|
|
|
|
|
|
- 액션 버튼 우선권: `onclick="event.stopPropagation()"`
|
|
|
|
|
|
|
|
|
|
|
|
- `resources/views/tenants/partials/modal-info.blade.php`
|
|
|
|
|
|
- 삭제된 테넌트 경고 배너 추가 (빨간색 bg-red-50)
|
|
|
|
|
|
- 삭제일/삭제자 정보 표시
|
|
|
|
|
|
- 배너 내 복원 버튼 추가
|
|
|
|
|
|
|
|
|
|
|
|
- `resources/views/tenants/index.blade.php`
|
|
|
|
|
|
- `confirmRestore()`: 복원 후 모달 내용 새로고침 로직 추가
|
|
|
|
|
|
|
|
|
|
|
|
#### Models & Services
|
|
|
|
|
|
- `app/Models/Tenants/Tenant.php`
|
|
|
|
|
|
- `deleted_by` 컬럼 fillable 추가
|
|
|
|
|
|
- `deletedByUser()` 관계 추가 (삭제자 정보 조회)
|
|
|
|
|
|
|
|
|
|
|
|
- `app/Services/TenantService.php`
|
|
|
|
|
|
- `deleteTenant()`: deleted_by 기록
|
|
|
|
|
|
- `restoreTenant()`: deleted_by null 초기화
|
|
|
|
|
|
- `getTenantForModal()`: deletedByUser 관계 eager loading 추가
|
|
|
|
|
|
|
|
|
|
|
|
### 기술 상세:
|
|
|
|
|
|
|
|
|
|
|
|
**JS 함수 window 등록 (동적 HTML 문제 해결):**
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
// Before: function toggleModalMenuChildren() {}
|
|
|
|
|
|
// After: window.toggleModalMenuChildren = function() {}
|
|
|
|
|
|
```
|
|
|
|
|
|
- 동적으로 로드된 HTML에서 함수 접근 가능
|
|
|
|
|
|
|
|
|
|
|
|
**행 클릭 + 액션 버튼 우선권:**
|
|
|
|
|
|
```html
|
|
|
|
|
|
<tr onclick="TenantModal.open({{ $tenant->id }})">
|
|
|
|
|
|
<td onclick="event.stopPropagation()">
|
|
|
|
|
|
<!-- 액션 버튼들 -->
|
|
|
|
|
|
</td>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
```
|
|
|
|
|
|
- `event.stopPropagation()`으로 버블링 방지
|
|
|
|
|
|
|
|
|
|
|
|
**삭제된 테넌트 경고 배너:**
|
|
|
|
|
|
- 빨간색 배경 (bg-red-50)
|
|
|
|
|
|
- 삭제일 + 삭제자 정보 표시
|
|
|
|
|
|
- 복원 버튼 포함
|
|
|
|
|
|
|
|
|
|
|
|
**복원 후 모달 새로고침:**
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
if (TenantModal.isOpen() && TenantModal.currentTenantId === id) {
|
|
|
|
|
|
TenantModal.loadTenantInfo();
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 이슈 해결:
|
|
|
|
|
|
- **toggleModalMenuChildren not defined**: window 객체에 함수 등록으로 해결
|
|
|
|
|
|
- **복원 후 배너 미갱신**: `loadTenantInfo()` 호출 추가
|
|
|
|
|
|
|
|
|
|
|
|
### Git 커밋:
|
|
|
|
|
|
- ✅ `b32f6cf` "feat: 테넌트 정보 모달 팝업 기능 추가"
|
|
|
|
|
|
- 17 files changed, 1476 insertions(+), 4 deletions(-)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2025-12-01 11:07:58 +09:00
|
|
|
|
|
|
|
|
|
|
## 2025-12-01 (일) - 사용자 비밀번호 자동 생성 및 이메일 발송 기능
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 작업
|
|
|
|
|
|
- 사용자 등록 시 비밀번호 입력 필드 제거 → 임의 비밀번호 자동 생성 후 이메일 발송
|
|
|
|
|
|
- 사용자 수정 페이지에 비밀번호 초기화 버튼 추가
|
|
|
|
|
|
- 사용자 모달에 비밀번호 초기화 버튼 추가
|
|
|
|
|
|
- 사용자 모달 프로필 이미지 없을 때 이름 첫글자 표시 (한글 지원: `mb_strtoupper`)
|
|
|
|
|
|
|
|
|
|
|
|
### 추가된 파일:
|
|
|
|
|
|
|
|
|
|
|
|
#### Mail
|
|
|
|
|
|
- `app/Mail/UserPasswordMail.php` - 비밀번호 알림 Mailable 클래스
|
|
|
|
|
|
- 신규 사용자 / 비밀번호 초기화 구분 (`$isNewUser`)
|
|
|
|
|
|
- 제목: `[SAM] 계정이 생성되었습니다` / `[SAM] 비밀번호가 초기화되었습니다`
|
|
|
|
|
|
|
|
|
|
|
|
- `resources/views/emails/user-password.blade.php` - 이메일 템플릿
|
|
|
|
|
|
- 스타일링된 HTML 이메일
|
|
|
|
|
|
- 사용자 이름, 이메일, 임시 비밀번호 표시
|
|
|
|
|
|
- 첫 로그인 후 비밀번호 변경 안내
|
|
|
|
|
|
|
|
|
|
|
|
### 수정된 파일:
|
|
|
|
|
|
|
|
|
|
|
|
#### Service
|
|
|
|
|
|
- `app/Services/UserService.php`
|
|
|
|
|
|
- `createUser()`: 비밀번호 자동 생성 + 이메일 발송
|
|
|
|
|
|
- `resetPassword()`: 비밀번호 초기화 + 이메일 발송 (신규 메서드)
|
|
|
|
|
|
- `generateRandomPassword()`: 8자리 임의 비밀번호 생성 (혼동 문자 제외: 0, O, l, 1, I)
|
|
|
|
|
|
- `sendPasswordMail()`: 이메일 발송 헬퍼 메서드
|
|
|
|
|
|
|
|
|
|
|
|
#### Controller
|
|
|
|
|
|
- `app/Http/Controllers/Api/Admin/UserController.php`
|
|
|
|
|
|
- `resetPassword()`: 비밀번호 초기화 엔드포인트 추가
|
|
|
|
|
|
- 슈퍼관리자 보호: 일반 관리자가 슈퍼관리자 비밀번호 초기화 불가
|
|
|
|
|
|
|
|
|
|
|
|
#### Request
|
|
|
|
|
|
- `app/Http/Requests/StoreUserRequest.php`
|
|
|
|
|
|
- password 필드 검증 주석 처리 (자동 생성으로 변경)
|
|
|
|
|
|
|
|
|
|
|
|
#### Routes
|
|
|
|
|
|
- `routes/api.php`
|
|
|
|
|
|
- `POST /api/admin/users/{id}/reset-password` 라우트 추가
|
|
|
|
|
|
|
|
|
|
|
|
#### Views
|
|
|
|
|
|
- `resources/views/users/create.blade.php`
|
|
|
|
|
|
- 비밀번호 입력 필드 제거 → 안내 메시지 표시
|
|
|
|
|
|
- "임시 비밀번호가 생성되어 사용자 이메일로 발송됩니다"
|
|
|
|
|
|
|
|
|
|
|
|
- `resources/views/users/edit.blade.php`
|
|
|
|
|
|
- 비밀번호 입력 필드 제거 → 초기화 버튼으로 변경
|
|
|
|
|
|
- HTMX 대신 Fetch API 사용 (버튼 상태 관리)
|
|
|
|
|
|
|
|
|
|
|
|
- `resources/views/users/partials/modal-info.blade.php`
|
|
|
|
|
|
- 프로필 이미지 없을 때: `strtoupper(substr())` → `mb_strtoupper(mb_substr())` (한글 지원)
|
|
|
|
|
|
- 비밀번호 초기화 버튼 추가 (삭제된 사용자 제외)
|
|
|
|
|
|
|
|
|
|
|
|
#### JavaScript
|
|
|
|
|
|
- `public/js/user-modal.js`
|
|
|
|
|
|
- `resetPassword()`: 비밀번호 초기화 메서드 추가
|
|
|
|
|
|
- confirm 다이얼로그 후 API 호출
|
|
|
|
|
|
|
|
|
|
|
|
### API 엔드포인트:
|
|
|
|
|
|
- `POST /api/admin/users/{id}/reset-password`
|
|
|
|
|
|
- 성공: `{ success: true, message: "비밀번호가 초기화되어 이메일로 발송되었습니다." }`
|
|
|
|
|
|
- 실패 (슈퍼관리자 보호): `{ success: false, message: "슈퍼관리자의 비밀번호는 초기화할 수 없습니다." }`
|
|
|
|
|
|
|
|
|
|
|
|
### 이메일 설정:
|
|
|
|
|
|
- Gmail SMTP 사용 (`smtp.gmail.com:587`)
|
|
|
|
|
|
- Google Groups 이메일 발신자 지원 (Gmail "다른 주소에서 메일 보내기" 설정 필요)
|
|
|
|
|
|
- 설정 가이드: `docs/SETUP_GUIDE.md` 참조
|
|
|
|
|
|
|
|
|
|
|
|
### 코드 품질:
|
|
|
|
|
|
- ✅ Laravel Pint 통과
|
|
|
|
|
|
- ✅ PHP 문법 검사 통과
|
|
|
|
|
|
|
|
|
|
|
|
### Git 커밋:
|
|
|
|
|
|
- ✅ `85cbe23` "feat: [users] 사용자 등록 시 비밀번호 자동 생성 및 이메일 발송"
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2025-12-22 22:48:03 +09:00
|
|
|
|
|
|
|
|
|
|
## 2025-12-22 (일) - 견적 자동산출 시더 및 Price 모델 수정
|
|
|
|
|
|
|
|
|
|
|
|
### 주요 작업
|
|
|
|
|
|
|
|
|
|
|
|
**1. Price 모델 수정 (products → items 테이블)**
|
|
|
|
|
|
- `getSalesPriceByItemCode()` 메서드가 삭제된 `products`, `materials` 테이블 대신 통합된 `items` 테이블 조회하도록 수정
|
|
|
|
|
|
- 원인: products/materials 테이블이 items로 통합되었으나 MNG의 Price 모델은 미반영
|
|
|
|
|
|
|
|
|
|
|
|
**2. 견적수식 시더 입력 필드 추가**
|
|
|
|
|
|
- Design 사이트 견적 입력 폼과 동기화
|
|
|
|
|
|
- INPUT 카테고리 추가 (sort_order: 0)
|
|
|
|
|
|
- 새 입력 필드 6개 추가:
|
|
|
|
|
|
|
|
|
|
|
|
| 변수명 | 필드명 | 타입 | 옵션 |
|
|
|
|
|
|
|------------|-------------|--------|------|
|
|
|
|
|
|
| PC | 제품카테고리 | select | 스크린/철재 |
|
|
|
|
|
|
| PRODUCT_ID | 제품명 | select | PC에 따라 변경 |
|
|
|
|
|
|
| GT | 설치유형 | select | 벽면/천장/바닥 |
|
|
|
|
|
|
| MP | 모터전원 | select | 220V/380V |
|
|
|
|
|
|
| CT | 제어기 | select | 단독제어/연동제어 |
|
|
|
|
|
|
| QTY | 수량 | number | min: 1 |
|
|
|
|
|
|
|
|
|
|
|
|
- 기존 W0, H0 필드 metadata 보강
|
|
|
|
|
|
|
|
|
|
|
|
### 수정된 파일
|
|
|
|
|
|
|
|
|
|
|
|
**Models**
|
|
|
|
|
|
- `app/Models/Price.php` - getSalesPriceByItemCode() items 테이블 사용
|
|
|
|
|
|
|
|
|
|
|
|
**Console Commands**
|
|
|
|
|
|
- `app/Console/Commands/SeedQuoteFormulasCommand.php`
|
|
|
|
|
|
- INPUT 카테고리 추가
|
|
|
|
|
|
- Design 사이트 입력 필드 6개 추가 (PC, PRODUCT_ID, GT, MP, CT, QTY)
|
|
|
|
|
|
- metadata에 field_type, options 정보 추가
|
|
|
|
|
|
|
|
|
|
|
|
### 시더 실행 결과 (tenant: 287)
|
|
|
|
|
|
```
|
|
|
|
|
|
카테고리: 12개 (INPUT 추가)
|
|
|
|
|
|
수식: 24개 (이전 18개 + 새 input 6개)
|
|
|
|
|
|
범위: 18개
|
|
|
|
|
|
품목: 4개
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 시뮬레이터 접근
|
|
|
|
|
|
- URL: https://mng.sam.kr/quote-formulas/simulator
|
|
|
|
|
|
- 새 입력 필드 표시 (UI가 metadata 지원 시)
|
|
|
|
|
|
|
|
|
|
|
|
---
|