- 개발 단계별 문서 추가 (00_OVERVIEW ~ 06_PHASE) - 기술 표준 문서 추가 (99_TECHNICAL_STANDARDS) - 개발 프로세스 및 패턴 문서 추가 - API_FLOW_TESTER_DESIGN, DEV_PROCESS - HTMX_API_PATTERN, LAYOUT_PATTERN - SETUP_GUIDE, MNG_PROJECT_PLAN - 프로젝트 관리 문서 추가 (project-management/) - INDEX.md, MNG_CRITICAL_RULES.md 업데이트
8.0 KiB
8.0 KiB
MNG 프로젝트 Critical Rules
🚨 절대 위반하지 말아야 할 규칙들
작성일: 2025-11-24 목적: 반복되는 실수 방지 및 프로젝트 정책 명확화
🚫 절대 금지 사항
1. DB 마이그레이션 금지
규칙:
- ❌ mng/에서는 절대로 마이그레이션 파일 생성 금지
- ❌ 기존 테이블 구조 변경 금지
- ✅ 모델 관계 정의만 가능
- ✅ 필요 시 api/에 마이그레이션 요청
이유:
- mng/는 api/의 DB를 읽기 전용으로 사용
- DB 스키마는 api/에서만 관리
- 여러 저장소(api, admin, mng)가 동일 DB 공유
mng 전용 테이블 생성 시:
- ✅ mng에서만 사용하는 테이블은
admin_*접두사 사용 - ✅ 마이그레이션은 무조건 api/에서 생성 (mng에서 생성 금지!)
- 예:
admin_pm_projects,admin_pm_tasks등
실수 사례:
// ❌ 잘못된 예: mng/에서 users 테이블 수정 시도
Schema::table('users', function (Blueprint $table) {
$table->foreignId('tenant_id')->comment('테넌트 ID');
});
// ✅ 올바른 예: User 모델에 관계만 정의
public function tenants(): BelongsToMany
{
return $this->belongsToMany(Tenant::class, 'user_tenants');
}
2. 기존 테이블은 재사용만
재사용 테이블:
users- 사용자 계정tenants- 테넌트 (회사)user_tenants- 사용자-테넌트 관계 (pivot)roles- 역할departments- 부서permissions- 권한products,materials,categories등 모든 비즈니스 테이블
작업 방법:
- 모델 복사: admin/app/Models → mng/app/Models
- Filament 코드 제거: form(), table() 등 제거
- 관계만 유지: belongsTo, hasMany, belongsToMany
- Traits 적용: BelongsToTenant (필요 시), SoftDeletes
3. Multi-tenant 아키텍처 이해
user_tenants pivot 테이블 구조:
user_tenants:
├── user_id (FK → users)
├── tenant_id (FK → tenants)
├── is_active (활성 여부)
├── is_default (기본 테넌트)
├── joined_at (가입일)
└── left_at (탈퇴일)
관계 정의:
// User 모델
public function tenants(): BelongsToMany
{
return $this->belongsToMany(Tenant::class, 'user_tenants')
->withTimestamps()
->withPivot(['is_active', 'is_default', 'joined_at', 'left_at']);
}
// Tenant 모델
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class, 'user_tenants');
}
세션 기반 테넌트 선택:
session('selected_tenant_id')- 현재 선택된 테넌트currentTenant()헬퍼 메서드 사용 권장
4. BelongsToTenant Trait 사용 주의
언제 사용하지 말아야 하나:
- ❌
users테이블 - user_tenants pivot 사용 - ❌
tenants테이블 - 테넌트 자체 - ❌ 다대다 관계 테이블
언제 사용해야 하나:
- ✅
roles- tenant_id 컬럼 있음 - ✅
departments- tenant_id 컬럼 있음 - ✅
products- tenant_id 컬럼 있음
판단 기준:
- 테이블에 직접
tenant_id컬럼이 있으면 → BelongsToTenant 사용 - pivot 테이블로 관계가 맺어지면 → belongsToMany 관계만 정의
5. Service-First 패턴 엄수
규칙:
- ✅ 비즈니스 로직은 Service 클래스에만
- ✅ Controller는 FormRequest + Service 호출만
- ✅ Model은 관계와 accessor만
잘못된 예:
// ❌ Controller에 로직
public function store(Request $request)
{
$user = User::create($request->all());
$user->tenant_id = session('selected_tenant_id');
$user->save();
}
올바른 예:
// ✅ Service에 로직
class UserService
{
public function createUser(array $data): User
{
// 비즈니스 로직
return User::create($data);
}
}
// Controller는 호출만
public function store(StoreUserRequest $request, UserService $service)
{
$user = $service->createUser($request->validated());
return response()->json(['success' => true]);
}
6. FormRequest 필수 사용
규칙:
- ❌ Controller에서
$request->validate()금지 - ✅ 모든 검증은 FormRequest 클래스로
예:
// ✅ StoreUserRequest.php
class StoreUserRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
];
}
}
// ✅ Controller
public function store(StoreUserRequest $request)
{
// $request->validated() 만 Service에 전달
}
7. MNG 데이터 접근 아키텍처
MNG는 자체 내부 API 사용 (외부 api/ 프로젝트 호출 안 함)
┌─────────────────────────────────────────────────────────────┐
│ routes/web.php (Blade 화면만) │
│ └─ Controller → view('xxx.index') (데이터 없이 화면만) │
│ │
│ routes/api.php (HTMX 호출 + CRUD) │
│ └─ Api/Admin/Controller → Service → Model → DB │
│ │
│ Blade에서 HTMX로 /api/admin/* 호출 │
│ └─ hx-get="/api/admin/tenants" │
│ └─ hx-post="/api/admin/tenants" │
└─────────────────────────────────────────────────────────────┘
규칙:
- ❌ 외부 api/ 프로젝트의 API 호출 금지
- ✅ mng 내부 API (
/api/admin/*) 사용 - ✅ Service → Model → DB (직접 접근)
Controller 구분:
app/Http/Controllers/XxxController.php→ Blade 화면만 (GET)app/Http/Controllers/Api/Admin/XxxController.php→ CRUD 처리 (HTMX)
예시:
// ✅ Web Controller: 화면만 반환
class TenantController extends Controller
{
public function index(): View
{
return view('tenants.index'); // 데이터 없이 화면만
}
}
// ✅ API Controller: CRUD 처리
class Api\Admin\TenantController extends Controller
{
public function index(Request $request)
{
$tenants = $this->tenantService->getTenants($request->all());
return view('tenants.partials.list', compact('tenants')); // HTML partial
}
}
📋 작업 전 체크리스트
DB 작업 시:
□ mng/에서 작업 중인가? → 마이그레이션 금지!
□ 기존 테이블 수정인가? → api/에 요청!
□ mng 전용 새 테이블인가? → admin_* 접두사 + api/에 마이그레이션!
□ 관계만 추가인가? → OK, 모델만 수정
모델 작업 시:
□ tenant_id 컬럼 있는가? → BelongsToTenant trait
□ pivot 테이블 사용하는가? → belongsToMany 관계만
□ 비즈니스 로직 있는가? → Service로 이동!
Controller 작업 시:
□ FormRequest 생성했는가?
□ Service 클래스 생성했는가?
□ Controller는 호출만 하는가?
🔗 관련 문서
- INDEX.md - MNG 프로젝트 개요
- MIGRATION_PLAN.md - Admin → MNG 마이그레이션
- DEV_PROCESS.md - 개발 프로세스
- database-schema.md - DB 스키마
- api-rules.md - API 개발 규칙
📝 실수 사례 로그
2025-11-24: users 테이블 마이그레이션 시도
- 문제: mng/에서 users 테이블에 tenant_id 추가 시도
- 원인: user_tenants pivot 테이블 존재를 간과
- 교훈: 다대다 관계는 belongsToMany로, 마이그레이션 금지
- 해결: User 모델에 tenants() 관계만 추가
최종 업데이트: 2025-11-27 다음 리뷰: 반복 실수 발생 시 업데이트