feat: item_fields 테이블에 is_active 컬럼 추가
- 마이그레이션: 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() 메서드 사용을 위한 필수 컬럼
This commit is contained in:
@@ -25,6 +25,7 @@ public function rules(): array
|
|||||||
'validation_rules' => 'nullable|array',
|
'validation_rules' => 'nullable|array',
|
||||||
'options' => 'nullable|array',
|
'options' => 'nullable|array',
|
||||||
'properties' => 'nullable|array',
|
'properties' => 'nullable|array',
|
||||||
|
'is_active' => 'nullable|boolean',
|
||||||
'is_locked' => 'nullable|boolean',
|
'is_locked' => 'nullable|boolean',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public function rules(): array
|
|||||||
'validation_rules' => 'nullable|array',
|
'validation_rules' => 'nullable|array',
|
||||||
'options' => 'nullable|array',
|
'options' => 'nullable|array',
|
||||||
'properties' => 'nullable|array',
|
'properties' => 'nullable|array',
|
||||||
|
'is_active' => 'nullable|boolean',
|
||||||
'is_locked' => 'nullable|boolean',
|
'is_locked' => 'nullable|boolean',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class ItemField extends Model
|
|||||||
'category',
|
'category',
|
||||||
'description',
|
'description',
|
||||||
'is_common',
|
'is_common',
|
||||||
|
'is_active',
|
||||||
'is_locked',
|
'is_locked',
|
||||||
'locked_by',
|
'locked_by',
|
||||||
'locked_at',
|
'locked_at',
|
||||||
@@ -41,6 +42,7 @@ class ItemField extends Model
|
|||||||
'order_no' => 'integer',
|
'order_no' => 'integer',
|
||||||
'is_required' => 'boolean',
|
'is_required' => 'boolean',
|
||||||
'is_common' => 'boolean',
|
'is_common' => 'boolean',
|
||||||
|
'is_active' => 'boolean',
|
||||||
'is_locked' => 'boolean',
|
'is_locked' => 'boolean',
|
||||||
'display_condition' => 'array',
|
'display_condition' => 'array',
|
||||||
'validation_rules' => 'array',
|
'validation_rules' => 'array',
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public function storeIndependent(array $data): ItemField
|
|||||||
'category' => $data['category'] ?? null,
|
'category' => $data['category'] ?? null,
|
||||||
'description' => $data['description'] ?? null,
|
'description' => $data['description'] ?? null,
|
||||||
'is_common' => $data['is_common'] ?? false,
|
'is_common' => $data['is_common'] ?? false,
|
||||||
|
'is_active' => $data['is_active'] ?? true,
|
||||||
'is_locked' => $data['is_locked'] ?? false,
|
'is_locked' => $data['is_locked'] ?? false,
|
||||||
'locked_by' => ($data['is_locked'] ?? false) ? $userId : null,
|
'locked_by' => ($data['is_locked'] ?? false) ? $userId : null,
|
||||||
'locked_at' => ($data['is_locked'] ?? false) ? now() : null,
|
'locked_at' => ($data['is_locked'] ?? false) ? now() : null,
|
||||||
@@ -103,6 +104,7 @@ public function clone(int $id): ItemField
|
|||||||
'category' => $original->category,
|
'category' => $original->category,
|
||||||
'description' => $original->description,
|
'description' => $original->description,
|
||||||
'is_common' => $original->is_common,
|
'is_common' => $original->is_common,
|
||||||
|
'is_active' => $original->is_active, // 원본의 활성화 상태 복제
|
||||||
'is_locked' => false, // 복제본은 잠금 해제 상태
|
'is_locked' => false, // 복제본은 잠금 해제 상태
|
||||||
'created_by' => $userId,
|
'created_by' => $userId,
|
||||||
]);
|
]);
|
||||||
@@ -174,6 +176,7 @@ public function store(int $sectionId, array $data): ItemField
|
|||||||
'validation_rules' => $data['validation_rules'] ?? null,
|
'validation_rules' => $data['validation_rules'] ?? null,
|
||||||
'options' => $data['options'] ?? null,
|
'options' => $data['options'] ?? null,
|
||||||
'properties' => $data['properties'] ?? null,
|
'properties' => $data['properties'] ?? null,
|
||||||
|
'is_active' => $data['is_active'] ?? true,
|
||||||
'is_locked' => $data['is_locked'] ?? false,
|
'is_locked' => $data['is_locked'] ?? false,
|
||||||
'locked_by' => ($data['is_locked'] ?? false) ? $userId : null,
|
'locked_by' => ($data['is_locked'] ?? false) ? $userId : null,
|
||||||
'locked_at' => ($data['is_locked'] ?? false) ? now() : 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,
|
'category' => $data['category'] ?? $field->category,
|
||||||
'description' => $data['description'] ?? $field->description,
|
'description' => $data['description'] ?? $field->description,
|
||||||
'is_common' => $data['is_common'] ?? $field->is_common,
|
'is_common' => $data['is_common'] ?? $field->is_common,
|
||||||
|
'is_active' => $data['is_active'] ?? $field->is_active,
|
||||||
'updated_by' => $userId,
|
'updated_by' => $userId,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* item_fields 테이블에 is_active 컬럼 추가
|
||||||
|
*
|
||||||
|
* 목적: ModelTrait의 scopeActive() 메서드 사용을 위한 활성화 상태 컬럼
|
||||||
|
*
|
||||||
|
* 변경 내용:
|
||||||
|
* - is_active: 필드 활성화 여부 (기본값: true)
|
||||||
|
*
|
||||||
|
* 참고:
|
||||||
|
* - ModelTrait::scopeActive()는 is_active = 1 조건으로 필터링
|
||||||
|
* - 기존 레코드는 모두 활성 상태(1)로 설정
|
||||||
|
*/
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('item_fields', function (Blueprint $table) {
|
||||||
|
$table->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');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -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 문서는 다음 디렉토리에 추가:
|
새로운 API 문서는 다음 디렉토리에 추가:
|
||||||
- Swagger 문서 → `swagger/`
|
- Swagger 문서 → `swagger/`
|
||||||
- 분석 문서 → `analysis/`
|
- 분석 문서 → `analysis/`
|
||||||
|
- API Flow 테스트 → `api-flows/`
|
||||||
|
|||||||
172
docs/api-flows/item-fields-is-active-test.json
Normal file
172
docs/api-flows/item-fields-is-active-test.json
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user