# 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` - 로그인 검증 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: 대시보드 구현 (메뉴, 사이드바) - [ ] 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 변수가 계산되지 않아 버튼, 카드 등 모든 컴포넌트 스타일 무효화 ### 해결 과정: 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 커밋: - ✅ `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 커밋: - ✅ `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 커밋: - ✅ `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 목록 - 감사 로그 목록 ### 다음 단계: - [ ] 브라우저에서 페이지네이션 동작 확인 - [ ] 다른 목록 페이지에 페이지네이션 적용 - [ ] 페이지당 표시 개수 선택 기능 추가 고려 ### Git 상태: - 🔄 수정됨: `resources/views/tenants/partials/table.blade.php` - ➕ 추가됨: `resources/views/partials/pagination.blade.php` - ⏳ 커밋 대기 중 (사용자 확인 후 커밋 예정)