feat: [client] Client API 사업자 정보 필드 및 toggle 버그 수정
- business_no, business_type, business_item 필드 추가 - toggle 로직 수정: boolean 캐스팅 호환 (is_active === 'Y' → !is_active)
This commit is contained in:
@@ -21,6 +21,9 @@ public function rules(): array
|
||||
'phone' => 'nullable|string|max:20',
|
||||
'email' => 'nullable|email|max:100',
|
||||
'address' => 'nullable|string|max:255',
|
||||
'business_no' => 'nullable|string|max:20',
|
||||
'business_type' => 'nullable|string|max:50',
|
||||
'business_item' => 'nullable|string|max:100',
|
||||
'is_active' => 'nullable|in:Y,N',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@ public function rules(): array
|
||||
'contact_person' => 'nullable|string|max:100',
|
||||
'phone' => 'nullable|string|max:20',
|
||||
'email' => 'nullable|email|max:100',
|
||||
'address' => 'nullable|string|max:255',
|
||||
'address' => 'nullable|string|max:255', 'business_no' => 'nullable|string|max:20',
|
||||
'business_type' => 'nullable|string|max:50',
|
||||
'business_item' => 'nullable|string|max:100',
|
||||
'is_active' => 'nullable|in:Y,N',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ class Client extends Model
|
||||
'phone',
|
||||
'email',
|
||||
'address',
|
||||
'business_no',
|
||||
'business_type',
|
||||
'business_item',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
|
||||
@@ -63,6 +63,9 @@ public function store(array $params)
|
||||
'phone' => 'nullable|string|max:30',
|
||||
'email' => 'nullable|email|max:80',
|
||||
'address' => 'nullable|string|max:255',
|
||||
'business_no' => 'nullable|string|max:20',
|
||||
'business_type' => 'nullable|string|max:50',
|
||||
'business_item' => 'nullable|string|max:100',
|
||||
'is_active' => 'nullable|in:Y,N',
|
||||
]);
|
||||
|
||||
@@ -104,6 +107,9 @@ public function update(int $id, array $params)
|
||||
'phone' => 'nullable|string|max:30',
|
||||
'email' => 'nullable|email|max:80',
|
||||
'address' => 'nullable|string|max:255',
|
||||
'business_no' => 'nullable|string|max:20',
|
||||
'business_type' => 'nullable|string|max:50',
|
||||
'business_item' => 'nullable|string|max:100',
|
||||
'is_active' => 'nullable|in:Y,N',
|
||||
]);
|
||||
|
||||
@@ -157,7 +163,8 @@ public function toggle(int $id)
|
||||
throw new NotFoundHttpException(__('error.not_found'));
|
||||
}
|
||||
|
||||
$client->is_active = $client->is_active === 'Y' ? 'N' : 'Y';
|
||||
// Model에서 is_active가 boolean으로 캐스팅되므로 boolean으로 토글
|
||||
$client->is_active = ! $client->is_active;
|
||||
$client->save();
|
||||
|
||||
return $client->refresh();
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
* @OA\Property(property="phone", type="string", nullable=true, example="010-1234-5678"),
|
||||
* @OA\Property(property="email", type="string", nullable=true, example="client@example.com"),
|
||||
* @OA\Property(property="address", type="string", nullable=true, example="서울시 강남구"),
|
||||
* @OA\Property(property="business_no", type="string", nullable=true, maxLength=20, example="123-45-67890", description="사업자등록번호"),
|
||||
* @OA\Property(property="business_type", type="string", nullable=true, maxLength=50, example="제조업", description="업태"),
|
||||
* @OA\Property(property="business_item", type="string", nullable=true, maxLength=100, example="전자부품", description="업종"),
|
||||
* @OA\Property(property="is_active", type="string", enum={"Y", "N"}, example="Y"),
|
||||
* @OA\Property(property="created_at", type="string", example="2025-10-01 12:00:00"),
|
||||
* @OA\Property(property="updated_at", type="string", example="2025-10-01 12:00:00")
|
||||
@@ -71,6 +74,9 @@
|
||||
* @OA\Property(property="phone", type="string", nullable=true, maxLength=20, example="010-1234-5678"),
|
||||
* @OA\Property(property="email", type="string", nullable=true, maxLength=100, example="client@example.com"),
|
||||
* @OA\Property(property="address", type="string", nullable=true, maxLength=255, example="서울시 강남구"),
|
||||
* @OA\Property(property="business_no", type="string", nullable=true, maxLength=20, example="123-45-67890", description="사업자등록번호"),
|
||||
* @OA\Property(property="business_type", type="string", nullable=true, maxLength=50, example="제조업", description="업태"),
|
||||
* @OA\Property(property="business_item", type="string", nullable=true, maxLength=100, example="전자부품", description="업종"),
|
||||
* @OA\Property(property="is_active", type="string", enum={"Y", "N"}, example="Y")
|
||||
* )
|
||||
*
|
||||
@@ -85,6 +91,9 @@
|
||||
* @OA\Property(property="phone", type="string", nullable=true, maxLength=20),
|
||||
* @OA\Property(property="email", type="string", nullable=true, maxLength=100),
|
||||
* @OA\Property(property="address", type="string", nullable=true, maxLength=255),
|
||||
* @OA\Property(property="business_no", type="string", nullable=true, maxLength=20, description="사업자등록번호"),
|
||||
* @OA\Property(property="business_type", type="string", nullable=true, maxLength=50, description="업태"),
|
||||
* @OA\Property(property="business_item", type="string", nullable=true, maxLength=100, description="업종"),
|
||||
* @OA\Property(property="is_active", type="string", enum={"Y", "N"})
|
||||
* )
|
||||
*/
|
||||
|
||||
223
claudedocs/flow-tester-client.json
Normal file
223
claudedocs/flow-tester-client.json
Normal file
@@ -0,0 +1,223 @@
|
||||
{
|
||||
"name": "Client API CRUD 테스트",
|
||||
"description": "거래처(Client) API 전체 CRUD 테스트 - 생성, 조회, 수정, 토글, 삭제 포함. business_no, business_type, business_item 신규 필드 검증 포함.",
|
||||
"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}}",
|
||||
"test_client_code": "TEST_CLIENT_{{$timestamp}}"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": "login",
|
||||
"name": "1. 로그인 - 토큰 획득",
|
||||
"method": "POST",
|
||||
"endpoint": "/login",
|
||||
"body": {
|
||||
"user_id": "{{variables.user_id}}",
|
||||
"user_pwd": "{{variables.user_pwd}}"
|
||||
},
|
||||
"expect": {
|
||||
"status": [200],
|
||||
"jsonPath": {
|
||||
"$.access_token": "@isString"
|
||||
}
|
||||
},
|
||||
"extract": {
|
||||
"token": "$.access_token"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "create_client",
|
||||
"name": "2. 거래처 생성 (신규 필드 포함)",
|
||||
"method": "POST",
|
||||
"endpoint": "/clients",
|
||||
"headers": {
|
||||
"Authorization": "Bearer {{login.token}}"
|
||||
},
|
||||
"body": {
|
||||
"client_code": "{{test_client_code}}",
|
||||
"name": "테스트 거래처",
|
||||
"contact_person": "홍길동",
|
||||
"phone": "02-1234-5678",
|
||||
"email": "test@example.com",
|
||||
"address": "서울시 강남구 테헤란로 123",
|
||||
"business_no": "123-45-67890",
|
||||
"business_type": "제조업",
|
||||
"business_item": "전자부품",
|
||||
"is_active": "Y"
|
||||
},
|
||||
"expect": {
|
||||
"status": [200],
|
||||
"jsonPath": {
|
||||
"$.success": true,
|
||||
"$.data.id": "@isNumber",
|
||||
"$.data.client_code": "{{test_client_code}}",
|
||||
"$.data.name": "테스트 거래처",
|
||||
"$.data.business_no": "123-45-67890",
|
||||
"$.data.business_type": "제조업",
|
||||
"$.data.business_item": "전자부품"
|
||||
}
|
||||
},
|
||||
"extract": {
|
||||
"client_id": "$.data.id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "list_clients",
|
||||
"name": "3. 거래처 목록 조회",
|
||||
"method": "GET",
|
||||
"endpoint": "/clients",
|
||||
"headers": {
|
||||
"Authorization": "Bearer {{login.token}}"
|
||||
},
|
||||
"params": {
|
||||
"page": 1,
|
||||
"size": 20,
|
||||
"q": "테스트"
|
||||
},
|
||||
"expect": {
|
||||
"status": [200],
|
||||
"jsonPath": {
|
||||
"$.success": true,
|
||||
"$.data.data": "@isArray",
|
||||
"$.data.current_page": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "show_client",
|
||||
"name": "4. 거래처 단건 조회",
|
||||
"method": "GET",
|
||||
"endpoint": "/clients/{{create_client.client_id}}",
|
||||
"headers": {
|
||||
"Authorization": "Bearer {{login.token}}"
|
||||
},
|
||||
"expect": {
|
||||
"status": [200],
|
||||
"jsonPath": {
|
||||
"$.success": true,
|
||||
"$.data.id": "{{create_client.client_id}}",
|
||||
"$.data.client_code": "{{test_client_code}}",
|
||||
"$.data.business_no": "123-45-67890",
|
||||
"$.data.business_type": "제조업",
|
||||
"$.data.business_item": "전자부품"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "update_client",
|
||||
"name": "5. 거래처 수정 (신규 필드 변경)",
|
||||
"method": "PUT",
|
||||
"endpoint": "/clients/{{create_client.client_id}}",
|
||||
"headers": {
|
||||
"Authorization": "Bearer {{login.token}}"
|
||||
},
|
||||
"body": {
|
||||
"name": "테스트 거래처 (수정됨)",
|
||||
"contact_person": "김철수",
|
||||
"business_no": "987-65-43210",
|
||||
"business_type": "도소매업",
|
||||
"business_item": "IT솔루션"
|
||||
},
|
||||
"expect": {
|
||||
"status": [200],
|
||||
"jsonPath": {
|
||||
"$.success": true,
|
||||
"$.data.name": "테스트 거래처 (수정됨)",
|
||||
"$.data.contact_person": "김철수",
|
||||
"$.data.business_no": "987-65-43210",
|
||||
"$.data.business_type": "도소매업",
|
||||
"$.data.business_item": "IT솔루션"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "toggle_client",
|
||||
"name": "6. 거래처 활성/비활성 토글",
|
||||
"method": "PATCH",
|
||||
"endpoint": "/clients/{{create_client.client_id}}/toggle",
|
||||
"headers": {
|
||||
"Authorization": "Bearer {{login.token}}"
|
||||
},
|
||||
"expect": {
|
||||
"status": [200],
|
||||
"jsonPath": {
|
||||
"$.success": true,
|
||||
"$.data.is_active": "N"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "toggle_client_back",
|
||||
"name": "7. 거래처 토글 복원 (Y로)",
|
||||
"method": "PATCH",
|
||||
"endpoint": "/clients/{{create_client.client_id}}/toggle",
|
||||
"headers": {
|
||||
"Authorization": "Bearer {{login.token}}"
|
||||
},
|
||||
"expect": {
|
||||
"status": [200],
|
||||
"jsonPath": {
|
||||
"$.success": true,
|
||||
"$.data.is_active": "Y"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "list_active_only",
|
||||
"name": "8. 활성 거래처만 조회",
|
||||
"method": "GET",
|
||||
"endpoint": "/clients",
|
||||
"headers": {
|
||||
"Authorization": "Bearer {{login.token}}"
|
||||
},
|
||||
"params": {
|
||||
"only_active": true
|
||||
},
|
||||
"expect": {
|
||||
"status": [200],
|
||||
"jsonPath": {
|
||||
"$.success": true,
|
||||
"$.data.data": "@isArray"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "delete_client",
|
||||
"name": "9. 거래처 삭제",
|
||||
"method": "DELETE",
|
||||
"endpoint": "/clients/{{create_client.client_id}}",
|
||||
"headers": {
|
||||
"Authorization": "Bearer {{login.token}}"
|
||||
},
|
||||
"expect": {
|
||||
"status": [200],
|
||||
"jsonPath": {
|
||||
"$.success": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "verify_deleted",
|
||||
"name": "10. 삭제 확인 (404 예상)",
|
||||
"method": "GET",
|
||||
"endpoint": "/clients/{{create_client.client_id}}",
|
||||
"headers": {
|
||||
"Authorization": "Bearer {{login.token}}"
|
||||
},
|
||||
"expect": {
|
||||
"status": [404],
|
||||
"jsonPath": {
|
||||
"$.success": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('clients', function (Blueprint $table) {
|
||||
$table->string('business_no', 20)->nullable()->after('address')->comment('사업자등록번호');
|
||||
$table->string('business_type', 50)->nullable()->after('business_no')->comment('업태');
|
||||
$table->string('business_item', 100)->nullable()->after('business_type')->comment('업종');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('clients', function (Blueprint $table) {
|
||||
$table->dropColumn(['business_no', 'business_type', 'business_item']);
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user