From 5131bfff98683f4b8842a2ff7431d8691b19d06f Mon Sep 17 00:00:00 2001 From: hskwon Date: Fri, 5 Dec 2025 14:40:09 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20item=5Ffields=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=EC=97=90=20is=5Factive=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 마이그레이션: is_active 컬럼 추가 (기본값 true) - ItemField 모델: fillable, casts에 is_active 추가 - ItemFieldService: store, storeIndependent, clone, update 메서드에 is_active 처리 - FormRequest: is_active 유효성 검사 규칙 추가 - API Flow 테스트 시나리오 추가 (docs/api-flows/) - docs/INDEX.md에 api-flows 섹션 추가 ModelTrait::scopeActive() 메서드 사용을 위한 필수 컬럼 --- .../ItemMaster/ItemFieldStoreRequest.php | 1 + .../ItemMaster/ItemFieldUpdateRequest.php | 1 + app/Models/ItemMaster/ItemField.php | 2 + app/Services/ItemMaster/ItemFieldService.php | 4 + ..._is_active_column_to_item_fields_table.php | 43 +++++ docs/INDEX.md | 9 + .../api-flows/item-fields-is-active-test.json | 172 ++++++++++++++++++ 7 files changed, 232 insertions(+) create mode 100644 database/migrations/2025_12_05_094957_add_is_active_column_to_item_fields_table.php create mode 100644 docs/api-flows/item-fields-is-active-test.json diff --git a/app/Http/Requests/ItemMaster/ItemFieldStoreRequest.php b/app/Http/Requests/ItemMaster/ItemFieldStoreRequest.php index 35cc9c5..9092538 100644 --- a/app/Http/Requests/ItemMaster/ItemFieldStoreRequest.php +++ b/app/Http/Requests/ItemMaster/ItemFieldStoreRequest.php @@ -25,6 +25,7 @@ public function rules(): array 'validation_rules' => 'nullable|array', 'options' => 'nullable|array', 'properties' => 'nullable|array', + 'is_active' => 'nullable|boolean', 'is_locked' => 'nullable|boolean', ]; } diff --git a/app/Http/Requests/ItemMaster/ItemFieldUpdateRequest.php b/app/Http/Requests/ItemMaster/ItemFieldUpdateRequest.php index fc43671..cd91931 100644 --- a/app/Http/Requests/ItemMaster/ItemFieldUpdateRequest.php +++ b/app/Http/Requests/ItemMaster/ItemFieldUpdateRequest.php @@ -24,6 +24,7 @@ public function rules(): array 'validation_rules' => 'nullable|array', 'options' => 'nullable|array', 'properties' => 'nullable|array', + 'is_active' => 'nullable|boolean', 'is_locked' => 'nullable|boolean', ]; } diff --git a/app/Models/ItemMaster/ItemField.php b/app/Models/ItemMaster/ItemField.php index 2b6da14..52ef30c 100644 --- a/app/Models/ItemMaster/ItemField.php +++ b/app/Models/ItemMaster/ItemField.php @@ -28,6 +28,7 @@ class ItemField extends Model 'category', 'description', 'is_common', + 'is_active', 'is_locked', 'locked_by', 'locked_at', @@ -41,6 +42,7 @@ class ItemField extends Model 'order_no' => 'integer', 'is_required' => 'boolean', 'is_common' => 'boolean', + 'is_active' => 'boolean', 'is_locked' => 'boolean', 'display_condition' => 'array', 'validation_rules' => 'array', diff --git a/app/Services/ItemMaster/ItemFieldService.php b/app/Services/ItemMaster/ItemFieldService.php index 0b4b997..df6c651 100644 --- a/app/Services/ItemMaster/ItemFieldService.php +++ b/app/Services/ItemMaster/ItemFieldService.php @@ -54,6 +54,7 @@ public function storeIndependent(array $data): ItemField 'category' => $data['category'] ?? null, 'description' => $data['description'] ?? null, 'is_common' => $data['is_common'] ?? false, + 'is_active' => $data['is_active'] ?? true, 'is_locked' => $data['is_locked'] ?? false, 'locked_by' => ($data['is_locked'] ?? false) ? $userId : null, 'locked_at' => ($data['is_locked'] ?? false) ? now() : null, @@ -103,6 +104,7 @@ public function clone(int $id): ItemField 'category' => $original->category, 'description' => $original->description, 'is_common' => $original->is_common, + 'is_active' => $original->is_active, // 원본의 활성화 상태 복제 'is_locked' => false, // 복제본은 잠금 해제 상태 'created_by' => $userId, ]); @@ -174,6 +176,7 @@ public function store(int $sectionId, array $data): ItemField 'validation_rules' => $data['validation_rules'] ?? null, 'options' => $data['options'] ?? null, 'properties' => $data['properties'] ?? null, + 'is_active' => $data['is_active'] ?? true, 'is_locked' => $data['is_locked'] ?? false, 'locked_by' => ($data['is_locked'] ?? false) ? $userId : null, 'locked_at' => ($data['is_locked'] ?? false) ? now() : null, @@ -230,6 +233,7 @@ public function update(int $id, array $data): ItemField 'category' => $data['category'] ?? $field->category, 'description' => $data['description'] ?? $field->description, 'is_common' => $data['is_common'] ?? $field->is_common, + 'is_active' => $data['is_active'] ?? $field->is_active, 'updated_by' => $userId, ]; diff --git a/database/migrations/2025_12_05_094957_add_is_active_column_to_item_fields_table.php b/database/migrations/2025_12_05_094957_add_is_active_column_to_item_fields_table.php new file mode 100644 index 0000000..58753b7 --- /dev/null +++ b/database/migrations/2025_12_05_094957_add_is_active_column_to_item_fields_table.php @@ -0,0 +1,43 @@ +boolean('is_active') + ->default(true) + ->after('is_common') + ->comment('활성화 여부 (ModelTrait::scopeActive() 사용)'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('item_fields', function (Blueprint $table) { + $table->dropColumn('is_active'); + }); + } +}; diff --git a/docs/INDEX.md b/docs/INDEX.md index dabfa80..2b59058 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -33,8 +33,17 @@ ## 🔗 관련 문서 --- +## 🧪 API Flow 테스트 + +API Flow Tester용 테스트 시나리오입니다. + +- **[ItemField is_active 테스트](api-flows/item-fields-is-active-test.json)** - item_fields is_active 컬럼 검증 + +--- + ## 📝 문서 추가 새로운 API 문서는 다음 디렉토리에 추가: - Swagger 문서 → `swagger/` - 분석 문서 → `analysis/` +- API Flow 테스트 → `api-flows/` diff --git a/docs/api-flows/item-fields-is-active-test.json b/docs/api-flows/item-fields-is-active-test.json new file mode 100644 index 0000000..450ed15 --- /dev/null +++ b/docs/api-flows/item-fields-is-active-test.json @@ -0,0 +1,172 @@ +{ + "name": "ItemField is_active 컬럼 검증 테스트", + "description": "item_fields 테이블에 추가된 is_active 컬럼의 기능을 검증합니다. 필드 생성 시 기본값(true), 수정, 조회 시 is_active 필드 포함 여부를 테스트합니다.", + "version": "1.0", + "config": { + "baseUrl": "https://api.sam.kr/api/v1", + "apiKey": "{{$env.FLOW_TESTER_API_KEY}}", + "timeout": 30000, + "stopOnFailure": true + }, + "variables": { + "user_id": "{{$env.FLOW_TESTER_USER_ID}}", + "user_pwd": "{{$env.FLOW_TESTER_USER_PWD}}" + }, + "steps": [ + { + "id": "login", + "name": "1. 로그인 - 인증 토큰 획득", + "method": "POST", + "endpoint": "/login", + "body": { + "user_id": "{{user_id}}", + "user_pwd": "{{user_pwd}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.message": "로그인 성공", + "$.access_token": "@isString" + } + }, + "extract": { + "token": "$.access_token" + } + }, + { + "id": "get_fields_list", + "name": "2. 필드 목록 조회 - is_active 필드 포함 확인", + "method": "GET", + "endpoint": "/item-master/fields", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data": "@isArray" + } + }, + "extract": { + "existingFieldId": "$.data[0].id", + "fieldCount": "$.data.length" + } + }, + { + "id": "create_field", + "name": "3. 독립 필드 생성 - is_active 기본값 true 확인", + "method": "POST", + "endpoint": "/item-master/fields", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "body": { + "field_name": "[테스트] is_active 검증 필드", + "field_type": "textbox", + "field_key": "test_is_active", + "is_required": false, + "placeholder": "is_active 기본값 테스트", + "description": "API Flow Tester에서 생성한 테스트 필드" + }, + "expect": { + "status": [200, 201], + "jsonPath": { + "$.success": true, + "$.data.id": "@isNumber", + "$.data.field_name": "[테스트] is_active 검증 필드", + "$.data.is_active": true + } + }, + "extract": { + "newFieldId": "$.data.id" + } + }, + { + "id": "verify_field_created", + "name": "4. 생성된 필드 상세 확인 - is_active=true", + "method": "GET", + "endpoint": "/item-master/fields", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true + } + }, + "extract": { + "allFields": "$.data" + } + }, + { + "id": "update_field_inactive", + "name": "5. 필드 비활성화 - is_active=false로 수정", + "method": "PUT", + "endpoint": "/item-master/fields/{{create_field.newFieldId}}", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "body": { + "is_active": false + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data.is_active": false + } + } + }, + { + "id": "verify_field_inactive", + "name": "6. 비활성화 상태 확인", + "method": "GET", + "endpoint": "/item-master/fields", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true + } + } + }, + { + "id": "update_field_active", + "name": "7. 필드 재활성화 - is_active=true로 수정", + "method": "PUT", + "endpoint": "/item-master/fields/{{create_field.newFieldId}}", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "body": { + "is_active": true + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data.is_active": true + } + } + }, + { + "id": "delete_test_field", + "name": "8. 테스트 필드 삭제 (정리)", + "method": "DELETE", + "endpoint": "/item-master/fields/{{create_field.newFieldId}}", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true + } + } + } + ] +}