313 lines
12 KiB
Markdown
313 lines
12 KiB
Markdown
# 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: 테넌트 선택 기능 구현" |