# MNG 프로젝트 개발 프로세스 ## 🎯 개발 철학 ``` API 우선 → HTMX 연동 → 단순하고 수정 용이한 코드 ``` ### 핵심 원칙 1. **API First**: 모든 기능은 API로 먼저 개발 2. **Service-First**: 비즈니스 로직은 Service에만 3. **HTMX Driven**: JS 최소화, HTML 속성으로 인터랙션 4. **DaisyUI Only**: 커스텀 CSS 금지, DaisyUI 클래스만 사용 --- ## 📐 표준 개발 프로세스 (6단계) ### Phase 0: 환경 구성 (최초 1회) **참조**: `claudedocs/mng/SETUP_GUIDE.md` ```bash # SETUP_GUIDE.md의 Step 1-10 참조 # 1. Laravel 프로젝트 생성 # 2. Docker 설정 파일 생성 # 3. docker-compose.yml 업데이트 # 4. nginx.conf 업데이트 # 5. Tailwind + DaisyUI + HTMX 설정 # 6. admin/ 모델 복사 # 7. Docker 빌드 및 실행 # 8. 동작 확인 (http://mng.sam.kr) # 스킬 사용: /sc:implement "SETUP_GUIDE.md 따라 MNG 환경 구성" ``` ### Phase 1: 준비 단계 ```bash # 1. 기능 분석 (Sequential Thinking) /sc:analyze --think # 2. 요구사항 정리 - 입력: 어떤 데이터를 받는가? - 처리: 어떤 비즈니스 로직? - 출력: 어떤 데이터를 반환? - 화면: 어떤 UI 필요? # 3. API 명세 작성 - 엔드포인트: GET /api/admin/users - Request: { search: string, role_id?: number } - Response: { success, data, message, meta } ``` ### Phase 1: DB & Model (1단계) ```bash # 1-1. 마이그레이션 확인 # 기존 테이블 사용? → 마이그레이션 불필요 # 신규 테이블? → admin_* or stat_* 접두사 # 1-2. 모델 확인/생성 # admin/app/Models에서 복사했는지 확인 # BelongsToTenant, HasAuditLog 트레잇 적용 # 예시: mng/app/Models/User.php belongsTo(Role::class); } public function department() { return $this->belongsTo(Department::class); } } ``` ### Phase 2: Service Layer (2단계) ```bash # 2-1. Service 생성 (비즈니스 로직) # mng/app/Services/UserService.php where(function ($q) use ($filters) { $q->where('name', 'like', "%{$filters['search']}%") ->orWhere('email', 'like', "%{$filters['search']}%"); }); } // 역할 필터 if (!empty($filters['role_id'])) { $query->where('role_id', $filters['role_id']); } return $query->paginate(20); } /** * 사용자 생성 */ public function createUser(array $data): User { $data['password'] = Hash::make($data['password']); $data['tenant_id'] = auth()->user()->tenant_id; return User::create($data); } /** * 사용자 수정 */ public function updateUser(User $user, array $data): User { if (!empty($data['password'])) { $data['password'] = Hash::make($data['password']); } else { unset($data['password']); } $user->update($data); return $user->fresh(); } /** * 사용자 삭제 (Soft Delete) */ public function deleteUser(User $user): bool { return $user->delete(); } } ``` ### Phase 3: API Controller (3단계) ```bash # 3-1. FormRequest 생성 # mng/app/Http/Requests/StoreUserRequest.php 'required|string|max:255', 'email' => 'required|email|unique:users,email', 'password' => 'required|string|min:8', 'role_id' => 'required|exists:roles,id', 'department_id' => 'required|exists:departments,id', ]; } public function messages(): array { return [ 'name.required' => 'users.validation.name_required', 'email.required' => 'users.validation.email_required', 'email.email' => 'users.validation.email_invalid', 'email.unique' => 'users.validation.email_unique', ]; } } # 3-2. API Controller 생성 # mng/app/Http/Controllers/Api/Admin/UserController.php userService->getUsers($request->all()); return response()->json([ 'success' => true, 'data' => $users->items(), 'message' => 'users.retrieved', 'meta' => [ 'current_page' => $users->currentPage(), 'last_page' => $users->lastPage(), 'per_page' => $users->perPage(), 'total' => $users->total(), ], ]); } /** * 사용자 생성 (API) * POST /api/admin/users */ public function store(StoreUserRequest $request): JsonResponse { $user = $this->userService->createUser($request->validated()); return response()->json([ 'success' => true, 'data' => $user, 'message' => 'users.created', ], 201); } /** * 사용자 수정 (API) * PUT /api/admin/users/{user} */ public function update(UpdateUserRequest $request, User $user): JsonResponse { $user = $this->userService->updateUser($user, $request->validated()); return response()->json([ 'success' => true, 'data' => $user, 'message' => 'users.updated', ]); } /** * 사용자 삭제 (API) * DELETE /api/admin/users/{user} */ public function destroy(User $user): JsonResponse { $this->userService->deleteUser($user); return response()->json([ 'success' => true, 'message' => 'users.deleted', ]); } } # 3-3. 라우트 등록 # mng/routes/api.php Route::middleware(['auth:sanctum', 'admin.permission']) ->prefix('admin') ->group(function () { Route::apiResource('users', UserController::class); }); ``` ### Phase 4: Blade + HTMX (4단계) ```bash # 4-1. HTML 응답용 Controller (선택) # API + Blade 부분 HTML 반환 # mng/app/Http/Controllers/Api/Admin/UserController.php (추가) /** * 사용자 목록 (HTMX용 Blade HTML) * GET /api/admin/users?format=html */ public function index(Request $request) { $users = $this->userService->getUsers($request->all()); // HTMX 요청 시 부분 HTML 반환 if ($request->header('HX-Request')) { return view('users.partials.table', compact('users')); } // 일반 요청 시 JSON 반환 return response()->json([ 'success' => true, 'data' => $users->items(), 'message' => 'users.retrieved', 'meta' => [ 'current_page' => $users->currentPage(), 'last_page' => $users->lastPage(), 'per_page' => $users->perPage(), 'total' => $users->total(), ], ]); } # 4-2. Blade 템플릿 작성 # mng/resources/views/users/index.blade.php @extends('layouts.app') @section('content')
@endsection # 4-3. 부분 템플릿 (HTMX 응답용) # mng/resources/views/users/partials/table.blade.php| ID | 이름 | 이메일 | 역할 | 부서 | 상태 | 작업 |
|---|---|---|---|---|---|---|
| {{ $user->id }} | {{ $user->name }} | {{ $user->email }} | {{ $user->role->name }} | {{ $user->department->name }} | {{ $user->is_active ? '활성' : '비활성' }} |