fix : 카테고리, 제품등록, BOM등록 API (일부 개발 - BOM 추가 작업 필요)
This commit is contained in:
564
app/Swagger/v1/CategoryExtras.php
Normal file
564
app/Swagger/v1/CategoryExtras.php
Normal file
@@ -0,0 +1,564 @@
|
||||
<?php
|
||||
|
||||
namespace App\Swagger\v1;
|
||||
|
||||
/**
|
||||
* @OA\Tag(name="Category-Fields", description="카테고리별 동적 필드 관리")
|
||||
* @OA\Tag(name="Category-Templates", description="카테고리 템플릿 버전 관리")
|
||||
* @OA\Tag(name="Category-Logs", description="카테고리 변경 이력 조회")
|
||||
*/
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* ===== Schemas ========
|
||||
* =========================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @OA\Schema(
|
||||
* schema="CategoryField",
|
||||
* type="object",
|
||||
* required={"id","tenant_id","category_id","field_key","field_name","field_type"},
|
||||
* @OA\Property(property="id", type="integer", example=11),
|
||||
* @OA\Property(property="tenant_id", type="integer", example=1),
|
||||
* @OA\Property(property="category_id", type="integer", example=7),
|
||||
* @OA\Property(property="field_key", type="string", example="width"),
|
||||
* @OA\Property(property="field_name", type="string", example="폭(mm)"),
|
||||
* @OA\Property(property="field_type", type="string", example="number"),
|
||||
* @OA\Property(property="is_required", type="string", enum={"Y","N"}, example="N"),
|
||||
* @OA\Property(property="sort_order", type="integer", example=1),
|
||||
* @OA\Property(property="default_value", type="string", nullable=true, example=null),
|
||||
* @OA\Property(
|
||||
* property="options",
|
||||
* type="object",
|
||||
* nullable=true,
|
||||
* description="선택지(콤보박스 등)",
|
||||
* example={"units": {"mm","cm","m"}}
|
||||
* ),
|
||||
* @OA\Property(property="description", type="string", nullable=true, example=null),
|
||||
* @OA\Property(property="created_at", type="string", format="date-time", example="2025-08-25 10:00:00"),
|
||||
* @OA\Property(property="updated_at", type="string", format="date-time", example="2025-08-25 10:20:00")
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="CategoryFieldPagination",
|
||||
* type="object",
|
||||
* @OA\Property(property="current_page", type="integer", example=1),
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* type="array",
|
||||
* @OA\Items(ref="#/components/schemas/CategoryField")
|
||||
* ),
|
||||
* @OA\Property(property="per_page", type="integer", example=20),
|
||||
* @OA\Property(property="total", type="integer", example=3)
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="CategoryFieldCreateRequest",
|
||||
* type="object",
|
||||
* required={"field_key","field_name","field_type"},
|
||||
* @OA\Property(property="field_key", type="string", example="height"),
|
||||
* @OA\Property(property="field_name", type="string", example="높이(mm)"),
|
||||
* @OA\Property(property="field_type", type="string", example="number"),
|
||||
* @OA\Property(property="is_required", type="string", enum={"Y","N"}, example="N"),
|
||||
* @OA\Property(property="sort_order", type="integer", example=2),
|
||||
* @OA\Property(property="default_value", type="string", nullable=true, example=null),
|
||||
* @OA\Property(
|
||||
* property="options",
|
||||
* type="object",
|
||||
* nullable=true,
|
||||
* example={"min": 0, "max": 9999, "step": 1}
|
||||
* ),
|
||||
* @OA\Property(property="description", type="string", nullable=true, example="선택 입력")
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="CategoryFieldUpdateRequest",
|
||||
* type="object",
|
||||
* @OA\Property(property="field_key", type="string", example="height"),
|
||||
* @OA\Property(property="field_name", type="string", example="높이(mm)"),
|
||||
* @OA\Property(property="field_type", type="string", example="number"),
|
||||
* @OA\Property(property="is_required", type="string", enum={"Y","N"}, example="Y"),
|
||||
* @OA\Property(property="sort_order", type="integer", example=1),
|
||||
* @OA\Property(property="default_value", type="string", nullable=true, example=null),
|
||||
* @OA\Property(
|
||||
* property="options",
|
||||
* type="object",
|
||||
* nullable=true,
|
||||
* example={"min": 0, "max": 9999, "step": 1}
|
||||
* ),
|
||||
* @OA\Property(property="description", type="string", nullable=true, example=null)
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="CategoryFieldReorderRequest",
|
||||
* type="array",
|
||||
* @OA\Items(
|
||||
* type="object",
|
||||
* required={"id","sort_order"},
|
||||
* @OA\Property(property="id", type="integer", example=11),
|
||||
* @OA\Property(property="sort_order", type="integer", example=1)
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="CategoryFieldBulkUpsertRequest",
|
||||
* type="object",
|
||||
* required={"items"},
|
||||
* @OA\Property(
|
||||
* property="items",
|
||||
* type="array",
|
||||
* @OA\Items(
|
||||
* type="object",
|
||||
* @OA\Property(property="id", type="integer", nullable=true, example=null),
|
||||
* @OA\Property(property="field_key", type="string", example="thickness"),
|
||||
* @OA\Property(property="field_name", type="string", example="두께(mm)"),
|
||||
* @OA\Property(property="field_type", type="string", example="number"),
|
||||
* @OA\Property(property="is_required", type="string", enum={"Y","N"}, example="N"),
|
||||
* @OA\Property(property="sort_order", type="integer", example=3),
|
||||
* @OA\Property(property="default_value", type="string", nullable=true, example=null),
|
||||
* @OA\Property(property="options", type="object", nullable=true, example={"unit":"mm"}),
|
||||
* @OA\Property(property="description", type="string", nullable=true, example=null)
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="CategoryTemplate",
|
||||
* type="object",
|
||||
* required={"id","tenant_id","category_id","version_no","template_json","applied_at"},
|
||||
* @OA\Property(property="id", type="integer", example=1001),
|
||||
* @OA\Property(property="tenant_id", type="integer", example=1),
|
||||
* @OA\Property(property="category_id", type="integer", example=7),
|
||||
* @OA\Property(property="version_no", type="integer", example=3),
|
||||
* @OA\Property(
|
||||
* property="template_json",
|
||||
* type="object",
|
||||
* description="템플릿 스냅샷",
|
||||
* example={"fields": {{"key":"width","type":"number","required":true}}}
|
||||
* ),
|
||||
* @OA\Property(property="applied_at", type="string", format="date-time", example="2025-08-25 11:00:00"),
|
||||
* @OA\Property(property="remarks", type="string", nullable=true, example="높이 필드 추가"),
|
||||
* @OA\Property(property="created_at", type="string", format="date-time", example="2025-08-25 10:50:00"),
|
||||
* @OA\Property(property="updated_at", type="string", format="date-time", example="2025-08-25 11:05:00")
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="CategoryTemplateCreateRequest",
|
||||
* type="object",
|
||||
* required={"version_no","template_json","applied_at"},
|
||||
* @OA\Property(property="version_no", type="integer", example=4),
|
||||
* @OA\Property(
|
||||
* property="template_json",
|
||||
* type="object",
|
||||
* example={
|
||||
* "fields": {
|
||||
* {"key":"width","type":"number","required":true},
|
||||
* {"key":"height","type":"number","required":false}
|
||||
* }
|
||||
* }
|
||||
* ),
|
||||
* @OA\Property(property="applied_at", type="string", format="date-time", example="2025-08-25 13:00:00"),
|
||||
* @OA\Property(property="remarks", type="string", nullable=true, example="높이 추가 버전")
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="CategoryTemplateUpdateRequest",
|
||||
* type="object",
|
||||
* @OA\Property(
|
||||
* property="template_json",
|
||||
* type="object",
|
||||
* example={"fields": {{"key":"width","type":"number"}}}
|
||||
* ),
|
||||
* @OA\Property(property="applied_at", type="string", format="date-time", example="2025-08-26 09:00:00"),
|
||||
* @OA\Property(property="remarks", type="string", nullable=true, example="비고 수정")
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="CategoryLog",
|
||||
* type="object",
|
||||
* required={"id","tenant_id","category_id","action","changed_at"},
|
||||
* @OA\Property(property="id", type="integer", example=501),
|
||||
* @OA\Property(property="tenant_id", type="integer", example=1),
|
||||
* @OA\Property(property="category_id", type="integer", example=7),
|
||||
* @OA\Property(property="action", type="string", example="update"),
|
||||
* @OA\Property(property="changed_by", type="integer", nullable=true, example=1),
|
||||
* @OA\Property(property="changed_at", type="string", format="date-time", example="2025-08-25 14:00:00"),
|
||||
* @OA\Property(property="before_json", type="object", nullable=true, example={"name":"old"}),
|
||||
* @OA\Property(property="after_json", type="object", nullable=true, example={"name":"new"}),
|
||||
* @OA\Property(property="remarks", type="string", nullable=true, example=null)
|
||||
* )
|
||||
*/
|
||||
class CategoryExtras
|
||||
{
|
||||
/**
|
||||
* ===============================
|
||||
* ==== Category Field APIs ======
|
||||
* ===============================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/categories/{id}/fields",
|
||||
* tags={"Category-Fields"},
|
||||
* summary="카테고리별 필드 목록",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer"), description="카테고리 ID"),
|
||||
* @OA\Parameter(ref="#/components/parameters/Page"),
|
||||
* @OA\Parameter(ref="#/components/parameters/Size"),
|
||||
* @OA\Parameter(name="sort", in="query", @OA\Schema(type="string", example="sort_order")),
|
||||
* @OA\Parameter(name="order", in="query", @OA\Schema(type="string", enum={"asc","desc"}, example="asc")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="목록 조회 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/CategoryFieldPagination"))
|
||||
* })
|
||||
* ),
|
||||
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||
* )
|
||||
*/
|
||||
public function fieldsIndex() {}
|
||||
|
||||
/**
|
||||
* @OA\Post(
|
||||
* path="/api/v1/categories/{id}/fields",
|
||||
* tags={"Category-Fields"},
|
||||
* summary="카테고리 필드 생성",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/CategoryFieldCreateRequest")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="생성 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/CategoryField"))
|
||||
* })
|
||||
* ),
|
||||
* @OA\Response(response=400, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||
* )
|
||||
*/
|
||||
public function fieldsStore() {}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/categories/fields/{field}",
|
||||
* tags={"Category-Fields"},
|
||||
* summary="카테고리 필드 단건 조회",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="field", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="조회 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/CategoryField"))
|
||||
* })
|
||||
* ),
|
||||
* @OA\Response(response=404, description="없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||
* )
|
||||
*/
|
||||
public function fieldsShow() {}
|
||||
|
||||
/**
|
||||
* @OA\Patch(
|
||||
* path="/api/v1/categories/fields/{field}",
|
||||
* tags={"Category-Fields"},
|
||||
* summary="카테고리 필드 수정",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="field", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/CategoryFieldUpdateRequest")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="수정 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/CategoryField"))
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function fieldsUpdate() {}
|
||||
|
||||
/**
|
||||
* @OA\Delete(
|
||||
* path="/api/v1/categories/fields/{field}",
|
||||
* tags={"Category-Fields"},
|
||||
* summary="카테고리 필드 삭제",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="field", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="삭제 성공",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ApiResponse")
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function fieldsDestroy() {}
|
||||
|
||||
/**
|
||||
* @OA\Post(
|
||||
* path="/api/v1/categories/{id}/fields/reorder",
|
||||
* tags={"Category-Fields"},
|
||||
* summary="카테고리 필드 정렬 저장",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/CategoryFieldReorderRequest")),
|
||||
* @OA\Response(response=200, description="저장 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse"))
|
||||
* )
|
||||
*/
|
||||
public function fieldsReorder() {}
|
||||
|
||||
/**
|
||||
* @OA\Put(
|
||||
* path="/api/v1/categories/{id}/fields/bulk-upsert",
|
||||
* tags={"Category-Fields"},
|
||||
* summary="카테고리 필드 일괄 업서트",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/CategoryFieldBulkUpsertRequest")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="업서트 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(property="data", type="object",
|
||||
* @OA\Property(property="created", type="integer", example=2),
|
||||
* @OA\Property(property="updated", type="integer", example=3)
|
||||
* )
|
||||
* )
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function fieldsBulkUpsert() {}
|
||||
|
||||
/**
|
||||
* ==================================
|
||||
* ==== Category Template APIs =====
|
||||
* ==================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/categories/{id}/templates",
|
||||
* tags={"Category-Templates"},
|
||||
* summary="카테고리 템플릿 버전 목록",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Parameter(ref="#/components/parameters/Page"),
|
||||
* @OA\Parameter(ref="#/components/parameters/Size"),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="목록 조회 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* type="object",
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* type="array",
|
||||
* @OA\Items(ref="#/components/schemas/CategoryTemplate")
|
||||
* ),
|
||||
* @OA\Property(property="total", type="integer", example=3)
|
||||
* )
|
||||
* )
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function templatesIndex() {}
|
||||
|
||||
/**
|
||||
* @OA\Post(
|
||||
* path="/api/v1/categories/{id}/templates",
|
||||
* tags={"Category-Templates"},
|
||||
* summary="카테고리 템플릿 생성(새 버전)",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/CategoryTemplateCreateRequest")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="생성 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/CategoryTemplate"))
|
||||
* })
|
||||
* ),
|
||||
* @OA\Response(response=409, description="버전 중복", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||
* )
|
||||
*/
|
||||
public function templatesStore() {}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/categories/templates/{tpl}",
|
||||
* tags={"Category-Templates"},
|
||||
* summary="카테고리 템플릿 단건 조회",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="tpl", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="조회 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/CategoryTemplate"))
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function templatesShow() {}
|
||||
|
||||
/**
|
||||
* @OA\Patch(
|
||||
* path="/api/v1/categories/templates/{tpl}",
|
||||
* tags={"Category-Templates"},
|
||||
* summary="카테고리 템플릿 수정",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="tpl", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/CategoryTemplateUpdateRequest")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="수정 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/CategoryTemplate"))
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function templatesUpdate() {}
|
||||
|
||||
/**
|
||||
* @OA\Delete(
|
||||
* path="/api/v1/categories/templates/{tpl}",
|
||||
* tags={"Category-Templates"},
|
||||
* summary="카테고리 템플릿 삭제",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="tpl", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse"))
|
||||
* )
|
||||
*/
|
||||
public function templatesDestroy() {}
|
||||
|
||||
/**
|
||||
* @OA\Post(
|
||||
* path="/api/v1/categories/{id}/templates/{tpl}/apply",
|
||||
* tags={"Category-Templates"},
|
||||
* summary="카테고리 템플릿 적용(활성화)",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Parameter(name="tpl", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(response=200, description="적용 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse"))
|
||||
* )
|
||||
*/
|
||||
public function templatesApply() {}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/categories/{id}/templates/{tpl}/preview",
|
||||
* tags={"Category-Templates"},
|
||||
* summary="카테고리 템플릿 미리보기",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Parameter(name="tpl", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="미리보기 성공",
|
||||
* @OA\JsonContent(allOf={@OA\Schema(ref="#/components/schemas/ApiResponse")})
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function templatesPreview() {}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/categories/{id}/templates/diff",
|
||||
* tags={"Category-Templates"},
|
||||
* summary="두 버전 비교(diff)",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Parameter(name="a", in="query", required=true, @OA\Schema(type="integer"), description="비교 기준 버전"),
|
||||
* @OA\Parameter(name="b", in="query", required=true, @OA\Schema(type="integer"), description="비교 대상 버전"),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="비교 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(property="data", type="object",
|
||||
* @OA\Property(property="added", type="array", @OA\Items(type="string")),
|
||||
* @OA\Property(property="removed", type="array", @OA\Items(type="string"))
|
||||
* )
|
||||
* )
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function templatesDiff() {}
|
||||
|
||||
/**
|
||||
* ==============================
|
||||
* ===== Category Log APIs =====
|
||||
* ==============================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/categories/{id}/logs",
|
||||
* tags={"Category-Logs"},
|
||||
* summary="카테고리 변경 이력 목록",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Parameter(name="action", in="query", @OA\Schema(type="string", enum={"insert","update","delete"})),
|
||||
* @OA\Parameter(name="from", in="query", @OA\Schema(type="string", format="date")),
|
||||
* @OA\Parameter(name="to", in="query", @OA\Schema(type="string", format="date")),
|
||||
* @OA\Parameter(ref="#/components/parameters/Page"),
|
||||
* @OA\Parameter(ref="#/components/parameters/Size"),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="목록 조회 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* type="object",
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* type="array",
|
||||
* @OA\Items(ref="#/components/schemas/CategoryLog")
|
||||
* ),
|
||||
* @OA\Property(property="total", type="integer", example=12)
|
||||
* )
|
||||
* )
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function logsIndex() {}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/categories/logs/{log}",
|
||||
* tags={"Category-Logs"},
|
||||
* summary="카테고리 변경 이력 단건 조회",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="log", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="조회 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/CategoryLog"))
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function logsShow() {}
|
||||
}
|
||||
@@ -3,37 +3,19 @@
|
||||
namespace App\Swagger\v1;
|
||||
|
||||
/**
|
||||
* 제품 카테고리 스키마
|
||||
* @OA\Schema(
|
||||
* schema="ProductCategory",
|
||||
* type="object",
|
||||
* description="제품 카테고리",
|
||||
* required={"id","code_group","code","name","is_active","sort_order"},
|
||||
* @OA\Property(property="id", type="integer", example=4),
|
||||
* @OA\Property(property="code_group", type="string", example="category"),
|
||||
* @OA\Property(property="code", type="string", example="BP"),
|
||||
* @OA\Property(property="name", type="string", example="절곡판"),
|
||||
* @OA\Property(property="parent_id", type="integer", nullable=true, example=null),
|
||||
* @OA\Property(
|
||||
* property="attributes",
|
||||
* type="object",
|
||||
* nullable=true,
|
||||
* description="카테고리 속성(자유형식 JSON)",
|
||||
* example={"color":"blue","flags":{"screen":true}}
|
||||
* ),
|
||||
* @OA\Property(property="description", type="string", nullable=true, example="절곡판"),
|
||||
* @OA\Property(property="is_active", type="integer", example=1),
|
||||
* @OA\Property(property="sort_order", type="integer", example=10),
|
||||
* @OA\Property(property="created_at", type="string", format="date-time", example="2025-07-23T09:00:00+09:00"),
|
||||
* @OA\Property(property="updated_at", type="string", format="date-time", example="2025-07-23T09:00:00+09:00")
|
||||
* )
|
||||
*
|
||||
* 카테고리 목록 조회
|
||||
* @OA\Tag(name="Product", description="제품 카테고리/검색(간단)")
|
||||
* @OA\Tag(name="Products", description="제품/부품/서브어셈블리 CRUD")
|
||||
* @OA\Tag(name="Products-BOM", description="제품 BOM (제품/자재 혼합) 관리")
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 카테고리 목록 조회 (기존)
|
||||
* @OA\Get(
|
||||
* path="/api/v1/product/category",
|
||||
* summary="제품 카테고리 목록 조회",
|
||||
* description="제품 카테고리(최상위: parent_id = null) 리스트를 반환합니다.",
|
||||
* tags={"Product"},
|
||||
* tags={"Products"},
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
@@ -51,12 +33,326 @@
|
||||
* }
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(response=400, description="필수 파라미터 누락", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||||
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||||
* @OA\Response(response=403, description="권한 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||||
* @OA\Response(response=404, description="존재하지 않는 URI 또는 데이터", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||||
* @OA\Response(response=405, description="허용되지 않는 메서드", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||||
* @OA\Response(response=500, description="서버 에러", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||
* @OA\Response(response=403, description="권한 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||
* )
|
||||
*/
|
||||
class ProductApi {}
|
||||
class ProductApi
|
||||
{
|
||||
/**
|
||||
* 제품 목록/검색
|
||||
* @OA\Get(
|
||||
* path="/api/v1/products",
|
||||
* tags={"Products"},
|
||||
* summary="제품 목록/검색",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(ref="#/components/parameters/Page"),
|
||||
* @OA\Parameter(ref="#/components/parameters/Size"),
|
||||
* @OA\Parameter(name="q", in="query", @OA\Schema(type="string"), description="코드/이름/설명 검색"),
|
||||
* @OA\Parameter(name="category_id", in="query", @OA\Schema(type="integer")),
|
||||
* @OA\Parameter(name="product_type", in="query", @OA\Schema(type="string", example="PRODUCT")),
|
||||
* @OA\Parameter(name="active", in="query", @OA\Schema(type="integer", enum={0,1})),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="조회 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ProductPagination"))
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function productsIndex() {}
|
||||
|
||||
|
||||
/**
|
||||
* 제품 생성
|
||||
* @OA\Post(
|
||||
* path="/api/v1/products",
|
||||
* tags={"Products"},
|
||||
* summary="제품 생성",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ProductCreateRequest")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="생성 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/Product"))
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function productsStore() {}
|
||||
|
||||
|
||||
/**
|
||||
* 제품 단건
|
||||
* @OA\Get(
|
||||
* path="/api/v1/products/{id}",
|
||||
* tags={"Products"},
|
||||
* summary="제품 단건 조회",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="조회 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/Product"))
|
||||
* })
|
||||
* ),
|
||||
* @OA\Response(response=404, description="없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||
* )
|
||||
*/
|
||||
public function productsShow() {}
|
||||
|
||||
/**
|
||||
* 제품 수정
|
||||
* @OA\Patch(
|
||||
* path="/api/v1/products/{id}",
|
||||
* tags={"Products"},
|
||||
* summary="제품 수정",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ProductUpdateRequest")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="수정 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/Product"))
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function productsUpdate() {}
|
||||
|
||||
/**
|
||||
* 제품 삭제(soft)
|
||||
* @OA\Delete(
|
||||
* path="/api/v1/products/{id}",
|
||||
* tags={"Products"},
|
||||
* summary="제품 삭제(soft)",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse"))
|
||||
* )
|
||||
*/
|
||||
public function productsDestroy() {}
|
||||
|
||||
/**
|
||||
* 제품 간편 검색(모달/드롭다운)
|
||||
* @OA\Get(
|
||||
* path="/api/v1/products/search",
|
||||
* tags={"Products"},
|
||||
* summary="제품 간편 검색",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="q", in="query", @OA\Schema(type="string")),
|
||||
* @OA\Parameter(name="limit", in="query", @OA\Schema(type="integer"), description="기본 20"),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="검색 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* type="array",
|
||||
* @OA\Items(type="object",
|
||||
* @OA\Property(property="id", type="integer", example=101),
|
||||
* @OA\Property(property="code", type="string", example="PRD-001"),
|
||||
* @OA\Property(property="name", type="string", example="스크린 모듈 KS001"),
|
||||
* @OA\Property(property="product_type", type="string", example="PRODUCT"),
|
||||
* @OA\Property(property="category_id", type="integer", example=7),
|
||||
* @OA\Property(property="is_active", type="integer", example=1)
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function productsSearch() {}
|
||||
|
||||
/**
|
||||
* 제품 활성/비활성 토글
|
||||
* @OA\Post(
|
||||
* path="/api/v1/products/{id}/toggle",
|
||||
* tags={"Products"},
|
||||
* summary="제품 활성/비활성 토글",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* 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=101),
|
||||
* @OA\Property(property="is_active", type="integer", example=0)
|
||||
* )
|
||||
* )
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function productsToggle() {}
|
||||
|
||||
/**
|
||||
* BOM 항목 목록
|
||||
* @OA\Get(
|
||||
* path="/api/v1/products/{id}/bom/items",
|
||||
* tags={"Products-BOM"},
|
||||
* summary="BOM 항목 목록(제품+자재 병합)",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="조회 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/BomItem"))
|
||||
* )
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function bomItemsIndex() {}
|
||||
|
||||
/**
|
||||
* BOM 대량 업서트
|
||||
* @OA\Post(
|
||||
* path="/api/v1/products/{id}/bom/items/bulk",
|
||||
* tags={"Products-BOM"},
|
||||
* summary="BOM 항목 대량 업서트",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/BomItemBulkUpsertRequest")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="업서트 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(property="data", type="object",
|
||||
* @OA\Property(property="created", type="integer", example=2),
|
||||
* @OA\Property(property="updated", type="integer", example=3)
|
||||
* )
|
||||
* )
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function bomItemsBulk() {}
|
||||
|
||||
/**
|
||||
* BOM 단건 수정
|
||||
* @OA\Patch(
|
||||
* path="/api/v1/products/{id}/bom/items/{item}",
|
||||
* tags={"Products-BOM"},
|
||||
* summary="BOM 항목 단건 수정",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Parameter(name="item", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/BomItemUpdateRequest")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="수정 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/BomItem"))
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function bomItemsUpdate() {}
|
||||
|
||||
/**
|
||||
* BOM 단건 삭제
|
||||
* @OA\Delete(
|
||||
* path="/api/v1/products/{id}/bom/items/{item}",
|
||||
* tags={"Products-BOM"},
|
||||
* summary="BOM 항목 단건 삭제",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Parameter(name="item", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse"))
|
||||
* )
|
||||
*/
|
||||
public function bomItemsDestroy() {}
|
||||
|
||||
/**
|
||||
* BOM 정렬 변경
|
||||
* @OA\Post(
|
||||
* path="/api/v1/products/{id}/bom/items/reorder",
|
||||
* tags={"Products-BOM"},
|
||||
* summary="BOM 정렬 변경",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/BomReorderRequest")),
|
||||
* @OA\Response(response=200, description="저장 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse"))
|
||||
* )
|
||||
*/
|
||||
public function bomItemsReorder() {}
|
||||
|
||||
/**
|
||||
* BOM 요약(건수/합계 등)
|
||||
* @OA\Get(
|
||||
* path="/api/v1/products/{id}/bom/summary",
|
||||
* tags={"Products-BOM"},
|
||||
* summary="BOM 요약",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="요약 성공",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(property="data", type="object",
|
||||
* @OA\Property(property="count", type="integer", example=5),
|
||||
* @OA\Property(property="count_product", type="integer", example=2),
|
||||
* @OA\Property(property="count_material", type="integer", example=3),
|
||||
* @OA\Property(property="quantity_sum", type="string", example="7.0000")
|
||||
* )
|
||||
* )
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function bomSummary() {}
|
||||
|
||||
/**
|
||||
* BOM 유효성 검사
|
||||
* @OA\Get(
|
||||
* path="/api/v1/products/{id}/bom/validate",
|
||||
* tags={"Products-BOM"},
|
||||
* summary="BOM 유효성 검사",
|
||||
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="검증 결과",
|
||||
* @OA\JsonContent(allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(property="data", type="object",
|
||||
* @OA\Property(property="valid", type="boolean", example=false),
|
||||
* @OA\Property(property="errors", type="array",
|
||||
* @OA\Items(type="object",
|
||||
* @OA\Property(property="id", type="integer", example=11),
|
||||
* @OA\Property(property="error", type="string", example="DUPLICATE_ITEM")
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* })
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function bomValidate() {}
|
||||
}
|
||||
|
||||
161
app/Swagger/v1/ProductExtraSchemas.php
Normal file
161
app/Swagger/v1/ProductExtraSchemas.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
namespace App\Swagger\v1;
|
||||
|
||||
/**
|
||||
* 스키마 컨테이너(어노테이션 스캔 용)
|
||||
*/
|
||||
class ProductExtraSchemas
|
||||
{
|
||||
/**
|
||||
* 제품 카테고리 스키마
|
||||
* @OA\Schema(
|
||||
* schema="ProductCategory",
|
||||
* type="object",
|
||||
* required={"id","code_group","code","name","is_active","sort_order"},
|
||||
* @OA\Property(property="id", type="integer", example=4),
|
||||
* @OA\Property(property="code_group", type="string", example="category"),
|
||||
* @OA\Property(property="code", type="string", example="BP"),
|
||||
* @OA\Property(property="name", type="string", example="절곡판"),
|
||||
* @OA\Property(property="parent_id", type="integer", nullable=true, example=null),
|
||||
* @OA\Property(
|
||||
* property="attributes", type="object", nullable=true,
|
||||
* example={"color":"blue","flags":{"screen":true}}
|
||||
* ),
|
||||
* @OA\Property(property="description", type="string", nullable=true, example="절곡판"),
|
||||
* @OA\Property(property="is_active", type="integer", example=1),
|
||||
* @OA\Property(property="sort_order", type="integer", example=10),
|
||||
* @OA\Property(property="created_at", type="string", format="date-time", example="2025-07-23T09:00:00+09:00"),
|
||||
* @OA\Property(property="updated_at", type="string", format="date-time", example="2025-07-23T09:00:00+09:00")
|
||||
* )
|
||||
*/
|
||||
public function _category() {}
|
||||
|
||||
/**
|
||||
* 제품 관련 스키마들
|
||||
* @OA\Schema(
|
||||
* schema="Product",
|
||||
* type="object",
|
||||
* required={"id","tenant_id","code","name","category_id","product_type","is_active"},
|
||||
* @OA\Property(property="id", type="integer", example=101),
|
||||
* @OA\Property(property="tenant_id", type="integer", example=1),
|
||||
* @OA\Property(property="code", type="string", example="PRD-001"),
|
||||
* @OA\Property(property="name", type="string", example="스크린 모듈 KS001"),
|
||||
* @OA\Property(property="category_id", type="integer", example=7),
|
||||
* @OA\Property(property="product_type", type="string", example="PRODUCT"),
|
||||
* @OA\Property(property="attributes", type="object", nullable=true, example={"color":"black","size":"L"}),
|
||||
* @OA\Property(property="description", type="string", nullable=true, example="고객사 스펙"),
|
||||
* @OA\Property(property="is_sellable", type="integer", example=1),
|
||||
* @OA\Property(property="is_purchasable", type="integer", example=0),
|
||||
* @OA\Property(property="is_producible", type="integer", example=1),
|
||||
* @OA\Property(property="is_active", type="integer", example=1),
|
||||
* @OA\Property(property="created_at", type="string", format="date-time", example="2025-08-25 10:00:00"),
|
||||
* @OA\Property(property="updated_at", type="string", format="date-time", example="2025-08-25 11:00:00")
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="ProductPagination",
|
||||
* type="object",
|
||||
* description="라라벨 LengthAwarePaginator 구조",
|
||||
* @OA\Property(property="current_page", type="integer", example=1),
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* type="array",
|
||||
* @OA\Items(ref="#/components/schemas/Product")
|
||||
* ),
|
||||
* @OA\Property(property="per_page", type="integer", example=20),
|
||||
* @OA\Property(property="total", type="integer", example=123)
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="ProductCreateRequest",
|
||||
* type="object",
|
||||
* required={"code","name","category_id","product_type"},
|
||||
* @OA\Property(property="code", type="string", example="PRD-001"),
|
||||
* @OA\Property(property="name", type="string", example="스크린 모듈 KS001"),
|
||||
* @OA\Property(property="category_id", type="integer", example=7),
|
||||
* @OA\Property(property="product_type", type="string", example="PRODUCT"),
|
||||
* @OA\Property(property="attributes", type="object", nullable=true, example={"color":"black"}),
|
||||
* @OA\Property(property="description", type="string", nullable=true, example=null),
|
||||
* @OA\Property(property="is_sellable", type="integer", example=1),
|
||||
* @OA\Property(property="is_purchasable", type="integer", example=0),
|
||||
* @OA\Property(property="is_producible", type="integer", example=1),
|
||||
* @OA\Property(property="is_active", type="integer", example=1)
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="ProductUpdateRequest",
|
||||
* type="object",
|
||||
* @OA\Property(property="code", type="string", example="PRD-001"),
|
||||
* @OA\Property(property="name", type="string", example="스크린 모듈 KS001"),
|
||||
* @OA\Property(property="category_id", type="integer", example=7),
|
||||
* @OA\Property(property="product_type", type="string", example="PART"),
|
||||
* @OA\Property(property="attributes", type="object", nullable=true, example={"size":"XL"}),
|
||||
* @OA\Property(property="description", type="string", nullable=true, example="사양 변경"),
|
||||
* @OA\Property(property="is_sellable", type="integer", example=1),
|
||||
* @OA\Property(property="is_purchasable", type="integer", example=0),
|
||||
* @OA\Property(property="is_producible", type="integer", example=1),
|
||||
* @OA\Property(property="is_active", type="integer", example=1)
|
||||
* )
|
||||
*/
|
||||
public function _product() {}
|
||||
|
||||
/**
|
||||
* BOM 스키마들
|
||||
* @OA\Schema(
|
||||
* schema="BomItem",
|
||||
* type="object",
|
||||
* required={"id","ref_type","ref_id","quantity","sort_order"},
|
||||
* @OA\Property(property="id", type="integer", example=11),
|
||||
* @OA\Property(property="ref_type", type="string", enum={"PRODUCT","MATERIAL"}, example="PRODUCT"),
|
||||
* @OA\Property(property="ref_id", type="integer", example=3),
|
||||
* @OA\Property(property="code", type="string", nullable=true, example="PRD-003"),
|
||||
* @OA\Property(property="name", type="string", nullable=true, example="모듈A"),
|
||||
* @OA\Property(property="unit", type="string", nullable=true, example="EA"),
|
||||
* @OA\Property(property="quantity", type="number", format="float", example=2.0000),
|
||||
* @OA\Property(property="sort_order", type="integer", example=1),
|
||||
* @OA\Property(property="is_default", type="integer", example=1)
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="BomItemBulkUpsertRequest",
|
||||
* type="object",
|
||||
* required={"items"},
|
||||
* @OA\Property(
|
||||
* property="items",
|
||||
* type="array",
|
||||
* @OA\Items(
|
||||
* type="object",
|
||||
* @OA\Property(property="id", type="integer", nullable=true, example=null),
|
||||
* @OA\Property(property="ref_type", type="string", enum={"PRODUCT","MATERIAL"}, example="MATERIAL"),
|
||||
* @OA\Property(property="ref_id", type="integer", example=5),
|
||||
* @OA\Property(property="quantity", type="number", format="float", example=4.0000),
|
||||
* @OA\Property(property="sort_order", type="integer", example=2),
|
||||
* @OA\Property(property="is_default", type="integer", example=0)
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="BomItemUpdateRequest",
|
||||
* type="object",
|
||||
* @OA\Property(property="ref_type", type="string", enum={"PRODUCT","MATERIAL"}, example="PRODUCT"),
|
||||
* @OA\Property(property="ref_id", type="integer", example=9),
|
||||
* @OA\Property(property="quantity", type="number", format="float", example=1.5000),
|
||||
* @OA\Property(property="sort_order", type="integer", example=3),
|
||||
* @OA\Property(property="is_default", type="integer", example=1)
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="BomReorderRequest",
|
||||
* type="array",
|
||||
* @OA\Items(
|
||||
* type="object",
|
||||
* required={"id","sort_order"},
|
||||
* @OA\Property(property="id", type="integer", example=11),
|
||||
* @OA\Property(property="sort_order", type="integer", example=1)
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function _bom() {}
|
||||
}
|
||||
Reference in New Issue
Block a user