From eb42d11f5e9cdf7be4b0b530d48f475bee758b25 Mon Sep 17 00:00:00 2001 From: hskwon Date: Wed, 24 Sep 2025 14:40:51 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20BOM=20=EA=B3=84=EC=82=B0=20API=20Swagge?= =?UTF-8?q?r=20=EB=AC=B8=EC=84=9C=20=EC=99=84=EC=84=B1=20=EB=B0=8F=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - BomCalculationApi.php: 기존 시스템 방식 클래스 형태 Swagger 문서 작성 - BOM Calculation 태그로 5개 API 엔드포인트 완전 문서화 - 요청/응답 스키마, 예시 데이터, 오류 응답 모두 정의 - BomCalculationController.php: ApiResponse 클래스 참조 경로 수정 - App\Http\Resources\ApiResponse → App\Helpers\ApiResponse - 테스트 데이터 생성으로 완전한 API 테스트 환경 구축 Swagger UI에서 "BOM Calculation" 메뉴로 확인 가능 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../V1/Design/BomCalculationController.php | 166 +------- app/Swagger/v1/BomCalculationApi.php | 381 ++++++++++++++++++ 2 files changed, 382 insertions(+), 165 deletions(-) create mode 100644 app/Swagger/v1/BomCalculationApi.php diff --git a/app/Http/Controllers/Api/V1/Design/BomCalculationController.php b/app/Http/Controllers/Api/V1/Design/BomCalculationController.php index 18949eb..a01e94c 100644 --- a/app/Http/Controllers/Api/V1/Design/BomCalculationController.php +++ b/app/Http/Controllers/Api/V1/Design/BomCalculationController.php @@ -7,15 +7,10 @@ use App\Http\Requests\Design\GetEstimateParametersRequest; use App\Http\Requests\Design\CalculateBomRequest; use App\Http\Requests\Design\SaveCompanyFormulaRequest; -use App\Http\Resources\ApiResponse; +use App\Helpers\ApiResponse; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; -/** - * @group Design/BOM Calculation - * - * BOM 기반 동적 산출식 계산 API - */ class BomCalculationController extends Controller { protected BomCalculationService $bomCalculationService; @@ -25,45 +20,6 @@ public function __construct(BomCalculationService $bomCalculationService) $this->bomCalculationService = $bomCalculationService; } - /** - * 견적 파라미터 조회 - * - * 특정 모델의 견적 시 필요한 입력 파라미터 스키마를 조회합니다. - * BOM에 정의된 조건만 동적으로 추출하여 반환합니다. - * - * @urlParam model_id int required 모델 ID Example: 1 - * @queryParam company_name string 업체명 (선택사항) Example: 경동기업 - * - * @response 200 { - * "success": true, - * "message": "견적 파라미터를 성공적으로 조회했습니다.", - * "data": { - * "model_info": { - * "id": 1, - * "name": "스크린셔터 표준형", - * "version": "v1.0", - * "bom_template_id": 1 - * }, - * "company_info": { - * "company_type": "경동기업", - * "formula_version": "v2.0", - * "requested_company": "경동기업" - * }, - * "parameters": { - * "required_parameters": [ - * { - * "key": "W0", - * "label": "오픈사이즈 가로(mm)", - * "type": "integer", - * "required": true, - * "min": 500, - * "max": 15000 - * } - * ] - * } - * } - * } - */ public function getEstimateParameters(GetEstimateParametersRequest $request, int $modelId): JsonResponse { return ApiResponse::handle(function () use ($request, $modelId) { @@ -79,55 +35,6 @@ public function getEstimateParameters(GetEstimateParametersRequest $request, int }); } - /** - * BOM 계산 실행 - * - * 입력된 파라미터를 기반으로 BOM 수량을 동적으로 계산합니다. - * 업체별 산출식을 적용하여 실시간 견적을 생성합니다. - * - * @urlParam bom_template_id int required BOM 템플릿 ID Example: 1 - * - * @bodyParam parameters object required 계산 파라미터 - * @bodyParam parameters.W0 int required 오픈사이즈 가로(mm) Example: 3000 - * @bodyParam parameters.H0 int required 오픈사이즈 세로(mm) Example: 2500 - * @bodyParam parameters.product_type string required 제품타입 Example: screen - * @bodyParam company_name string 업체명 (선택사항) Example: 경동기업 - * - * @response 200 { - * "success": true, - * "message": "BOM 계산이 완료되었습니다.", - * "data": { - * "bom_template": { - * "id": 1, - * "name": "Main", - * "company_type": "경동기업", - * "formula_version": "v2.0" - * }, - * "input_parameters": { - * "W0": 3000, - * "H0": 2500, - * "product_type": "screen" - * }, - * "calculated_values": { - * "W1": 3160, - * "H1": 2850, - * "area": 9.006, - * "weight": 60.42 - * }, - * "bom_items": [ - * { - * "item_id": 1, - * "ref_type": "MATERIAL", - * "ref_id": 101, - * "original_qty": 1, - * "calculated_qty": 2, - * "is_calculated": true, - * "calculation_formula": "bracket_quantity" - * } - * ] - * } - * } - */ public function calculateBom(CalculateBomRequest $request, int $bomTemplateId): JsonResponse { return ApiResponse::handle(function () use ($request, $bomTemplateId) { @@ -155,30 +62,6 @@ public function calculateBom(CalculateBomRequest $request, int $bomTemplateId): }); } - /** - * 업체별 산출식 목록 조회 - * - * 특정 업체의 등록된 산출식 목록을 조회합니다. - * - * @urlParam company_name string required 업체명 Example: 경동기업 - * - * @response 200 { - * "success": true, - * "message": "업체 산출식 목록을 조회했습니다.", - * "data": { - * "company_name": "경동기업", - * "total_formulas": 5, - * "formulas": [ - * { - * "type": "manufacturing_size", - * "version": "v2.0", - * "description": "제작사이즈 계산식", - * "updated_at": "2025-09-22T15:30:00Z" - * } - * ] - * } - * } - */ public function getCompanyFormulas(string $companyName): JsonResponse { return ApiResponse::handle(function () use ($companyName) { @@ -192,34 +75,6 @@ public function getCompanyFormulas(string $companyName): JsonResponse }); } - /** - * 업체별 산출식 등록/수정 - * - * 특정 업체의 산출식을 등록하거나 수정합니다. - * 기존 산출식이 있으면 새 버전으로 업데이트됩니다. - * - * @urlParam company_name string required 업체명 Example: 경동기업 - * @urlParam formula_type string required 산출식 타입 Example: manufacturing_size - * - * @bodyParam formula_expression string required 계산식 표현식 - * @bodyParam parameters array required 필요한 파라미터 정의 - * @bodyParam conditions array 적용 조건 (선택사항) - * @bodyParam validation_rules array 검증 규칙 (선택사항) - * @bodyParam description string 산출식 설명 (선택사항) - * - * @response 201 { - * "success": true, - * "message": "업체 산출식이 등록되었습니다.", - * "data": { - * "id": 1, - * "company_name": "경동기업", - * "formula_type": "manufacturing_size", - * "version": "v1.0", - * "is_active": true, - * "created_at": "2025-09-22T15:30:00Z" - * } - * } - */ public function saveCompanyFormula(SaveCompanyFormulaRequest $request, string $companyName, string $formulaType): JsonResponse { return ApiResponse::handle(function () use ($request, $companyName, $formulaType) { @@ -235,25 +90,6 @@ public function saveCompanyFormula(SaveCompanyFormulaRequest $request, string $c }); } - /** - * 계산식 테스트 실행 - * - * 산출식을 실제 적용하기 전에 테스트해볼 수 있습니다. - * - * @bodyParam formula_expression string required 테스트할 계산식 - * @bodyParam test_parameters object required 테스트 파라미터 - * - * @response 200 { - * "success": true, - * "message": "계산식 테스트가 완료되었습니다.", - * "data": { - * "formula_expression": "bracket_quantity", - * "input_parameters": {"W1": 3000}, - * "result": {"result": 2}, - * "execution_time_ms": 1.5 - * } - * } - */ public function testFormula(Request $request): JsonResponse { return ApiResponse::handle(function () use ($request) { diff --git a/app/Swagger/v1/BomCalculationApi.php b/app/Swagger/v1/BomCalculationApi.php new file mode 100644 index 0000000..97c030d --- /dev/null +++ b/app/Swagger/v1/BomCalculationApi.php @@ -0,0 +1,381 @@ +0", "H1>0"} + * ), + * @OA\Property(property="description", type="string", example="브라켓 수량 계산식") + * ) + * + * @OA\Schema( + * schema="FormulaTestRequest", + * type="object", + * required={"formula_expression","test_parameters"}, + * @OA\Property(property="formula_expression", type="string", example="bracket_quantity"), + * @OA\Property( + * property="test_parameters", + * type="object", + * @OA\Property(property="W1", type="integer", example=3000) + * ) + * ) + * + * @OA\Schema( + * schema="FormulaTestResponse", + * type="object", + * required={"success","message","data"}, + * @OA\Property(property="success", type="boolean", example=true), + * @OA\Property(property="message", type="string", example="계산식 테스트가 완료되었습니다."), + * @OA\Property( + * property="data", + * type="object", + * @OA\Property(property="formula_expression", type="string", example="bracket_quantity"), + * @OA\Property( + * property="input_parameters", + * type="object", + * @OA\Property(property="W1", type="integer", example=3000) + * ), + * @OA\Property( + * property="result", + * type="object", + * @OA\Property(property="result", type="integer", example=2) + * ), + * @OA\Property(property="execution_time_ms", type="number", format="float", example=1.5) + * ) + * ) + */ +class BomCalculationApi +{ + /** + * @OA\Get( + * path="/api/v1/design/models/{model_id}/estimate-parameters", + * summary="견적 파라미터 조회", + * description="특정 모델의 견적 시 필요한 입력 파라미터 스키마를 조회합니다. BOM에 정의된 조건만 동적으로 추출하여 반환합니다.", + * tags={"BOM Calculation"}, + * security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}}, + * @OA\Parameter( + * name="model_id", + * in="path", + * required=true, + * description="모델 ID", + * @OA\Schema(type="integer", example=1) + * ), + * @OA\Parameter( + * name="company_name", + * in="query", + * required=false, + * description="업체명 (선택사항)", + * @OA\Schema(type="string", example="경동기업") + * ), + * @OA\Response( + * response=200, + * description="견적 파라미터 조회 성공", + * @OA\JsonContent(ref="#/components/schemas/EstimateParametersResponse") + * ), + * @OA\Response( + * response=404, + * description="모델을 찾을 수 없음", + * @OA\JsonContent(ref="#/components/schemas/ErrorResponse") + * ) + * ) + */ + public function getEstimateParameters() {} + + /** + * @OA\Post( + * path="/api/v1/design/bom-templates/{bom_template_id}/calculate-bom", + * summary="BOM 계산 실행", + * description="입력된 파라미터를 기반으로 BOM 수량을 동적으로 계산합니다. 업체별 산출식을 적용하여 실시간 견적을 생성합니다.", + * tags={"BOM Calculation"}, + * security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}}, + * @OA\Parameter( + * name="bom_template_id", + * in="path", + * required=true, + * description="BOM 템플릿 ID", + * @OA\Schema(type="integer", example=1) + * ), + * @OA\RequestBody( + * required=true, + * description="계산 파라미터", + * @OA\JsonContent(ref="#/components/schemas/CalculateBomRequest") + * ), + * @OA\Response( + * response=200, + * description="BOM 계산 성공", + * @OA\JsonContent(ref="#/components/schemas/CalculateBomResponse") + * ), + * @OA\Response( + * response=400, + * description="잘못된 파라미터", + * @OA\JsonContent(ref="#/components/schemas/ErrorResponse") + * ) + * ) + */ + public function calculateBom() {} + + /** + * @OA\Get( + * path="/api/v1/design/companies/{company_name}/formulas", + * summary="업체별 산출식 목록 조회", + * description="특정 업체의 등록된 산출식 목록을 조회합니다.", + * tags={"BOM Calculation"}, + * security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}}, + * @OA\Parameter( + * name="company_name", + * in="path", + * required=true, + * description="업체명", + * @OA\Schema(type="string", example="경동기업") + * ), + * @OA\Response( + * response=200, + * description="업체 산출식 목록 조회 성공", + * @OA\JsonContent(ref="#/components/schemas/CompanyFormulasResponse") + * ), + * @OA\Response( + * response=404, + * description="업체를 찾을 수 없음", + * @OA\JsonContent(ref="#/components/schemas/ErrorResponse") + * ) + * ) + */ + public function getCompanyFormulas() {} + + /** + * @OA\Post( + * path="/api/v1/design/companies/{company_name}/formulas/{formula_type}", + * summary="업체별 산출식 등록/수정", + * description="특정 업체의 산출식을 등록하거나 수정합니다. 기존 산출식이 있으면 새 버전으로 업데이트됩니다.", + * tags={"BOM Calculation"}, + * security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}}, + * @OA\Parameter( + * name="company_name", + * in="path", + * required=true, + * description="업체명", + * @OA\Schema(type="string", example="경동기업") + * ), + * @OA\Parameter( + * name="formula_type", + * in="path", + * required=true, + * description="산출식 타입", + * @OA\Schema(type="string", example="manufacturing_size") + * ), + * @OA\RequestBody( + * required=true, + * description="산출식 데이터", + * @OA\JsonContent(ref="#/components/schemas/SaveFormulaRequest") + * ), + * @OA\Response( + * response=201, + * description="업체 산출식 등록 성공", + * @OA\JsonContent( + * allOf={ + * @OA\Schema(ref="#/components/schemas/ApiResponse"), + * @OA\Schema( + * @OA\Property( + * property="data", + * type="object", + * @OA\Property(property="id", type="integer", example=1), + * @OA\Property(property="company_name", type="string", example="경동기업"), + * @OA\Property(property="formula_type", type="string", example="manufacturing_size"), + * @OA\Property(property="version", type="string", example="v1.0"), + * @OA\Property(property="is_active", type="boolean", example=true), + * @OA\Property(property="created_at", type="string", format="date-time", example="2025-09-22T15:30:00Z") + * ) + * ) + * } + * ) + * ), + * @OA\Response( + * response=400, + * description="잘못된 요청", + * @OA\JsonContent(ref="#/components/schemas/ErrorResponse") + * ) + * ) + */ + public function saveCompanyFormula() {} + + /** + * @OA\Post( + * path="/api/v1/design/formulas/test", + * summary="계산식 테스트 실행", + * description="산출식을 실제 적용하기 전에 테스트해볼 수 있습니다.", + * tags={"BOM Calculation"}, + * security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}}, + * @OA\RequestBody( + * required=true, + * description="테스트할 계산식과 파라미터", + * @OA\JsonContent(ref="#/components/schemas/FormulaTestRequest") + * ), + * @OA\Response( + * response=200, + * description="계산식 테스트 성공", + * @OA\JsonContent(ref="#/components/schemas/FormulaTestResponse") + * ), + * @OA\Response( + * response=400, + * description="잘못된 계산식", + * @OA\JsonContent(ref="#/components/schemas/ErrorResponse") + * ) + * ) + */ + public function testFormula() {} +} \ No newline at end of file