From cb0bc1a545c7729482d786cc9c5544275d36797b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Fri, 27 Feb 2026 09:24:04 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[attendance]=20attendance=5Frequests=20?= =?UTF-8?q?=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98=20MNG?= =?UTF-8?q?=EC=97=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - API 운영 배포 중지 기간 동안 MNG에서 마이그레이션 관리 - Schema::hasTable() 가드로 중복 실행 방지 - CLAUDE.md DB 아키텍처 정책 업데이트 --- CLAUDE.md | 58 +++++++++++-------- ...00000_create_attendance_requests_table.php | 43 ++++++++++++++ 2 files changed, 77 insertions(+), 24 deletions(-) create mode 100644 database/migrations/2026_02_26_100000_create_attendance_requests_table.php diff --git a/CLAUDE.md b/CLAUDE.md index a61bd1b4..d7538421 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -128,42 +128,52 @@ ### Tailwind 기본 클래스는 그대로 사용 ## 데이터베이스 아키텍처 (필수 규칙) -> **경고: MNG 프로젝트에서는 마이그레이션 파일을 생성하지 않습니다!** +> **2026-02-27 정책 변경**: API/React 운영 배포 중지 기간 동안 MNG에서 마이그레이션 생성 및 실행을 허용한다. ### 핵심 원칙 -| 작업 | 올바른 위치 | MNG에서 | -|------|------------|---------| -| 마이그레이션 생성 | `/home/aweso/sam/api/database/migrations/` | ❌ 금지 | -| 마이그레이션 실행 | `docker exec sam-api-1 php artisan migrate` | ❌ 금지 | -| 테이블 생성/수정 | API 프로젝트에서만 | ❌ 금지 | +| 작업 | MNG에서 | 비고 | +|------|---------|------| +| 마이그레이션 생성 | ✅ 허용 | 운영 배포에 필요한 테이블 | +| 마이그레이션 실행 | ✅ 허용 | `php artisan migrate` | +| 모델 작성 | ✅ 허용 | | +| 시더 | ⚠️ MNG 전용만 | MngMenuSeeder 등 | +| 팩토리 | ❌ 금지 | | -### MNG database 폴더 상태 +### MNG 마이그레이션 작성 규칙 -``` -/home/aweso/sam/mng/database/ -├── migrations/ ← 비어있음 (파일 생성 금지!) -├── seeders/ ← MNG 전용 시더만 허용 (예: MngMenuSeeder) -└── factories/ ← 사용 안 함 +1. API develop에 동일 마이그레이션이 있으면 **파일명을 동일하게** 유지 +2. `Schema::hasTable()` 가드 **필수** — 중복 실행 방지 + +```php +public function up(): void +{ + if (Schema::hasTable('table_name')) { + return; + } + Schema::create('table_name', function (Blueprint $table) { + // ... + }); +} ``` -### MNG에서 허용되는 것 +### 마이그레이션 실행 -- ✅ 컨트롤러, 뷰, 라우트 작성 -- ✅ 모델 작성 (API의 테이블 사용) -- ✅ MNG 전용 시더 (MngMenuSeeder 등) +```bash +# 로컬 (Docker) +docker exec sam-mng-1 php artisan migrate -### MNG에서 금지되는 것 +# 개발 서버 +cd /home/webservice/mng && php artisan migrate -- ❌ `database/migrations/` 에 파일 생성 -- ❌ `docker exec sam-mng-1 php artisan migrate` 실행 -- ❌ 테이블 구조 변경 관련 작업 +# 운영 서버 (--force 필수) +cd /home/webservice/mng && php artisan migrate --force +``` -### 새 테이블이 필요할 때 +### 향후 정리 -1. API 프로젝트에서 마이그레이션 생성 -2. `docker exec sam-api-1 php artisan migrate` 실행 -3. MNG에서 해당 테이블의 모델만 작성 +- API 운영 배포 재개 시 MNG 마이그레이션을 API로 통합 정리 +- 동일 파일명 + `Schema::hasTable()` 가드로 충돌 없음 --- diff --git a/database/migrations/2026_02_26_100000_create_attendance_requests_table.php b/database/migrations/2026_02_26_100000_create_attendance_requests_table.php new file mode 100644 index 00000000..1500a9f6 --- /dev/null +++ b/database/migrations/2026_02_26_100000_create_attendance_requests_table.php @@ -0,0 +1,43 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->unsignedBigInteger('user_id')->comment('신청자'); + $table->enum('request_type', ['vacation', 'businessTrip', 'remote', 'fieldWork'])->comment('신청 유형'); + $table->date('start_date'); + $table->date('end_date'); + $table->text('reason')->nullable()->comment('사유'); + $table->enum('status', ['pending', 'approved', 'rejected'])->default('pending'); + $table->unsignedBigInteger('approved_by')->nullable()->comment('승인자'); + $table->timestamp('approved_at')->nullable(); + $table->text('reject_reason')->nullable()->comment('반려 사유'); + $table->json('json_details')->nullable()->comment('반차 구분 등 추가 정보'); + $table->timestamps(); + $table->softDeletes(); + + $table->foreign('tenant_id')->references('id')->on('tenants')->cascadeOnDelete(); + $table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete(); + + $table->index(['tenant_id', 'status']); + $table->index(['tenant_id', 'user_id']); + }); + } + + public function down(): void + { + Schema::dropIfExists('attendance_requests'); + } +};