feat: 품목 마스터 소스 매핑 기능 추가

- ItemField 모델: 소스 매핑 컬럼 추가 (source_table, source_column 등)
- ItemPage 모델: source_table 컬럼 추가
- ItemDataService: 동적 데이터 조회 서비스
- ItemMasterApi Swagger 업데이트
- ItemTypeSeeder: 품목 유형 시더
- 스펙 문서: ITEM_MASTER_FIELD_INTEGRATION_PLAN.md
This commit is contained in:
2025-12-09 09:39:16 +09:00
parent 46d4c30880
commit bf92b37ff6
8 changed files with 1950 additions and 370 deletions

View File

@@ -32,7 +32,7 @@
* @OA\Schema(
* schema="ItemSection",
* type="object",
* description="독립 엔티티 - 관계는 entity_relationships로 관리",
* description="엔티티 - 관계는 entity_relationships로 관리",
*
* @OA\Property(property="id", type="integer", example=1),
* @OA\Property(property="tenant_id", type="integer", example=1),
@@ -64,7 +64,7 @@
* @OA\Schema(
* schema="ItemField",
* type="object",
* description="독립 엔티티 - 관계는 entity_relationships로 관리",
* description="엔티티 - 관계는 entity_relationships로 관리",
*
* @OA\Property(property="id", type="integer", example=1),
* @OA\Property(property="tenant_id", type="integer", example=1),
@@ -93,7 +93,7 @@
* @OA\Schema(
* schema="ItemBomItem",
* type="object",
* description="독립 엔티티 - 관계는 entity_relationships로 관리",
* description="엔티티 - 관계는 entity_relationships로 관리",
*
* @OA\Property(property="id", type="integer", example=1),
* @OA\Property(property="tenant_id", type="integer", example=1),
@@ -190,7 +190,7 @@
* required={"title","type"},
*
* @OA\Property(property="group_id", type="integer", nullable=true, example=1, description="계층번호"),
* @OA\Property(property="title", type="string", maxLength=255, example="독립 섹션"),
* @OA\Property(property="title", type="string", maxLength=255, example="섹션"),
* @OA\Property(property="type", type="string", enum={"fields","bom"}, example="fields"),
* @OA\Property(property="is_template", type="boolean", example=false),
* @OA\Property(property="is_default", type="boolean", example=false),
@@ -415,7 +415,7 @@
* @OA\Property(
* property="sections",
* type="array",
* description="모든 독립 섹션 목록 (재사용 가능)",
* description="모든 섹션 목록 (재사용 가능)",
*
* @OA\Items(ref="#/components/schemas/ItemSection")
* ),
@@ -423,7 +423,7 @@
* @OA\Property(
* property="fields",
* type="array",
* description="모든 독립 필드 목록 (재사용 가능)",
* description="모든 필드 목록 (재사용 가능)",
*
* @OA\Items(ref="#/components/schemas/ItemField")
* ),
@@ -445,6 +445,10 @@
*/
class ItemMasterApi
{
// ════════════════════════════════════════════════════════════════════════
// 초기화
// ════════════════════════════════════════════════════════════════════════
/**
* @OA\Get(
* path="/api/v1/item-master/init",
@@ -466,6 +470,253 @@ class ItemMasterApi
*/
public function init() {}
// ════════════════════════════════════════════════════════════════════════
// 필드 (Fields)
// ════════════════════════════════════════════════════════════════════════
/**
* @OA\Get(
* path="/api/v1/item-master/fields",
* tags={"ItemMaster"},
* summary="필드 목록 조회",
* description="섹션과 연결되지 않은 필드 목록을 조회합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @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/ItemField")))
* })
* ),
*
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function indexFields() {}
/**
* @OA\Post(
* path="/api/v1/item-master/fields",
* tags={"ItemMaster"},
* summary="필드 생성",
* description="섹션과 연결되지 않은 필드를 생성합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/IndependentFieldStoreRequest")),
*
* @OA\Response(response=200, description="생성 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
* })
* ),
*
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function storeIndependentField() {}
/**
* @OA\Post(
* path="/api/v1/item-master/sections/{sectionId}/fields",
* tags={"ItemMaster"},
* summary="필드 생성 (섹션 연결)",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemFieldStoreRequest")),
*
* @OA\Response(response=200, description="생성 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
* })
* ),
*
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function storeFields() {}
/**
* @OA\Put(
* path="/api/v1/item-master/fields/{id}",
* tags={"ItemMaster"},
* 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/ItemFieldUpdateRequest")),
*
* @OA\Response(response=200, description="수정 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
* })
* ),
*
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function updateFields() {}
/**
* @OA\Delete(
* path="/api/v1/item-master/fields/{id}",
* tags={"ItemMaster"},
* summary="필드 삭제",
* 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")),
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function destroyFields() {}
/**
* @OA\Put(
* path="/api/v1/item-master/sections/{sectionId}/fields/reorder",
* tags={"ItemMaster"},
* summary="필드 순서 변경",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ReorderRequest")),
*
* @OA\Response(response=200, description="순서 변경 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function reorderFields() {}
/**
* @OA\Post(
* path="/api/v1/item-master/fields/{id}/clone",
* tags={"ItemMaster"},
* summary="필드 복제",
* description="기존 필드를 복제하여 새 필드를 생성합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="id", in="path", required=true, description="복제할 필드 ID", @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/ItemField"))
* })
* ),
*
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function cloneField() {}
/**
* @OA\Get(
* path="/api/v1/item-master/fields/{id}/usage",
* tags={"ItemMaster"},
* summary="필드 사용처 조회",
* description="필드가 어떤 섹션/페이지에 연결되어 있는지 조회합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="id", in="path", required=true, description="필드 ID", @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/FieldUsageResponse"))
* })
* ),
*
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function getFieldUsage() {}
// ════════════════════════════════════════════════════════════════════════
// 단위 (Unit Options)
// ════════════════════════════════════════════════════════════════════════
/**
* @OA\Get(
* path="/api/v1/item-master/unit-options",
* tags={"ItemMaster"},
* summary="단위 옵션 목록",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @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/UnitOption")))
* })
* ),
*
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function indexUnitOptions() {}
/**
* @OA\Post(
* path="/api/v1/item-master/unit-options",
* tags={"ItemMaster"},
* summary="단위 옵션 생성",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/UnitOptionStoreRequest")),
*
* @OA\Response(response=200, description="생성 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/UnitOption"))
* })
* ),
*
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function storeUnitOptions() {}
/**
* @OA\Delete(
* path="/api/v1/item-master/unit-options/{id}",
* tags={"ItemMaster"},
* summary="단위 옵션 삭제",
* 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")),
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function destroyUnitOptions() {}
// ════════════════════════════════════════════════════════════════════════
// 페이지 (Pages)
// ════════════════════════════════════════════════════════════════════════
/**
* @OA\Get(
* path="/api/v1/item-master/pages",
@@ -553,12 +804,16 @@ public function updatePages() {}
*/
public function destroyPages() {}
// ════════════════════════════════════════════════════════════════════════
// 섹션 (Sections)
// ════════════════════════════════════════════════════════════════════════
/**
* @OA\Get(
* path="/api/v1/item-master/sections",
* tags={"ItemMaster"},
* summary="독립 섹션 목록 조회",
* description="페이지와 연결되지 않은 독립 섹션 목록을 조회합니다. is_template 파라미터로 템플릿 필터링이 가능합니다.",
* summary="섹션 목록 조회",
* description="페이지와 연결되지 않은 섹션 목록을 조회합니다. is_template 파라미터로 템플릿 필터링이 가능합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="is_template", in="query", description="템플릿 여부 필터", @OA\Schema(type="boolean")),
@@ -581,8 +836,8 @@ public function indexSections() {}
* @OA\Post(
* path="/api/v1/item-master/sections",
* tags={"ItemMaster"},
* summary="독립 섹션 생성",
* description="페이지와 연결되지 않은 독립 섹션을 생성합니다.",
* summary="섹션 생성",
* description="페이지와 연결되지 않은 섹션을 생성합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/IndependentSectionStoreRequest")),
@@ -601,194 +856,6 @@ public function indexSections() {}
*/
public function storeIndependentSection() {}
/**
* @OA\Post(
* path="/api/v1/item-master/sections/{id}/clone",
* tags={"ItemMaster"},
* summary="섹션 복제",
* description="기존 섹션을 복제하여 새 독립 섹션을 생성합니다. 하위 필드와 BOM 항목도 함께 복제됩니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="id", in="path", required=true, description="복제할 섹션 ID", @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/ItemSection"))
* })
* ),
*
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function cloneSection() {}
/**
* @OA\Get(
* path="/api/v1/item-master/sections/{id}/usage",
* tags={"ItemMaster"},
* summary="섹션 사용처 조회",
* description="섹션이 어떤 페이지에 연결되어 있는지 조회합니다 (entity_relationships 기반).",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="id", in="path", required=true, description="섹션 ID", @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/SectionUsageResponse"))
* })
* ),
*
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function getSectionUsage() {}
/**
* @OA\Get(
* path="/api/v1/item-master/fields",
* tags={"ItemMaster"},
* summary="독립 필드 목록 조회",
* description="섹션과 연결되지 않은 독립 필드 목록을 조회합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @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/ItemField")))
* })
* ),
*
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function indexFields() {}
/**
* @OA\Post(
* path="/api/v1/item-master/fields",
* tags={"ItemMaster"},
* summary="독립 필드 생성",
* description="섹션과 연결되지 않은 독립 필드를 생성합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/IndependentFieldStoreRequest")),
*
* @OA\Response(response=200, description="생성 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
* })
* ),
*
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function storeIndependentField() {}
/**
* @OA\Post(
* path="/api/v1/item-master/fields/{id}/clone",
* tags={"ItemMaster"},
* summary="필드 복제",
* description="기존 필드를 복제하여 새 독립 필드를 생성합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="id", in="path", required=true, description="복제할 필드 ID", @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/ItemField"))
* })
* ),
*
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function cloneField() {}
/**
* @OA\Get(
* path="/api/v1/item-master/fields/{id}/usage",
* tags={"ItemMaster"},
* summary="필드 사용처 조회",
* description="필드가 어떤 섹션/페이지에 연결되어 있는지 조회합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="id", in="path", required=true, description="필드 ID", @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/FieldUsageResponse"))
* })
* ),
*
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function getFieldUsage() {}
/**
* @OA\Get(
* path="/api/v1/item-master/bom-items",
* tags={"ItemMaster"},
* summary="독립 BOM 목록 조회",
* description="섹션과 연결되지 않은 독립 BOM 항목 목록을 조회합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @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/ItemBomItem")))
* })
* ),
*
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function indexBomItems() {}
/**
* @OA\Post(
* path="/api/v1/item-master/bom-items",
* tags={"ItemMaster"},
* summary="독립 BOM 생성",
* description="섹션과 연결되지 않은 독립 BOM 항목을 생성합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/IndependentBomItemStoreRequest")),
*
* @OA\Response(response=200, description="생성 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
* })
* ),
*
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function storeIndependentBomItem() {}
/**
* @OA\Post(
* path="/api/v1/item-master/pages/{pageId}/sections",
@@ -874,150 +941,55 @@ public function reorderSections() {}
/**
* @OA\Post(
* path="/api/v1/item-master/sections/{sectionId}/fields",
* path="/api/v1/item-master/sections/{id}/clone",
* tags={"ItemMaster"},
* summary="필드 생성",
* summary="섹션 복제",
* description="기존 섹션을 복제하여 새 섹션을 생성합니다. 하위 필드와 BOM 항목도 함께 복제됩니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
* @OA\Parameter(name="id", in="path", required=true, description="복제할 섹션 ID", @OA\Schema(type="integer")),
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemFieldStoreRequest")),
*
* @OA\Response(response=200, description="생성 성공",
* @OA\Response(response=200, description="복제 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
* })
* ),
*
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function storeFields() {}
/**
* @OA\Put(
* path="/api/v1/item-master/fields/{id}",
* tags={"ItemMaster"},
* 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/ItemFieldUpdateRequest")),
*
* @OA\Response(response=200, description="수정 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemSection"))
* })
* ),
*
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function updateFields() {}
public function cloneSection() {}
/**
* @OA\Delete(
* path="/api/v1/item-master/fields/{id}",
* @OA\Get(
* path="/api/v1/item-master/sections/{id}/usage",
* tags={"ItemMaster"},
* summary="필드 삭제",
* summary="섹션 사용처 조회",
* description="섹션이 어떤 페이지에 연결되어 있는지 조회합니다 (entity_relationships 기반).",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
* @OA\Parameter(name="id", in="path", required=true, description="섹션 ID", @OA\Schema(type="integer")),
*
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function destroyFields() {}
/**
* @OA\Put(
* path="/api/v1/item-master/sections/{sectionId}/fields/reorder",
* tags={"ItemMaster"},
* summary="필드 순서 변경",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ReorderRequest")),
*
* @OA\Response(response=200, description="순서 변경 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function reorderFields() {}
/**
* @OA\Post(
* path="/api/v1/item-master/sections/{sectionId}/bom-items",
* tags={"ItemMaster"},
* summary="BOM 항목 생성",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemBomItemStoreRequest")),
*
* @OA\Response(response=200, description="생성 성공",
* @OA\Response(response=200, description="조회 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
* })
* ),
*
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function storeBomItems() {}
/**
* @OA\Put(
* path="/api/v1/item-master/bom-items/{id}",
* tags={"ItemMaster"},
* 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/ItemBomItemUpdateRequest")),
*
* @OA\Response(response=200, description="수정 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/SectionUsageResponse"))
* })
* ),
*
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function updateBomItems() {}
public function getSectionUsage() {}
/**
* @OA\Delete(
* path="/api/v1/item-master/bom-items/{id}",
* tags={"ItemMaster"},
* summary="BOM 항목 삭제",
* 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")),
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function destroyBomItems() {}
// ────────────────────────────────────────────────────────────────────────
// 섹션 템플릿 (Section Templates)
// ────────────────────────────────────────────────────────────────────────
/**
* @OA\Get(
@@ -1103,6 +1075,125 @@ public function updateSectionTemplates() {}
*/
public function destroySectionTemplates() {}
// ════════════════════════════════════════════════════════════════════════
// BOM
// ════════════════════════════════════════════════════════════════════════
/**
* @OA\Get(
* path="/api/v1/item-master/bom-items",
* tags={"ItemMaster"},
* summary="BOM 목록 조회",
* description="섹션과 연결되지 않은 BOM 항목 목록을 조회합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @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/ItemBomItem")))
* })
* ),
*
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function indexBomItems() {}
/**
* @OA\Post(
* path="/api/v1/item-master/bom-items",
* tags={"ItemMaster"},
* summary="BOM 생성",
* description="섹션과 연결되지 않은 BOM 항목을 생성합니다.",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/IndependentBomItemStoreRequest")),
*
* @OA\Response(response=200, description="생성 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
* })
* ),
*
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function storeIndependentBomItem() {}
/**
* @OA\Post(
* path="/api/v1/item-master/sections/{sectionId}/bom-items",
* tags={"ItemMaster"},
* summary="BOM 항목 생성 (섹션 연결)",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemBomItemStoreRequest")),
*
* @OA\Response(response=200, description="생성 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
* })
* ),
*
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function storeBomItems() {}
/**
* @OA\Put(
* path="/api/v1/item-master/bom-items/{id}",
* tags={"ItemMaster"},
* 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/ItemBomItemUpdateRequest")),
*
* @OA\Response(response=200, description="수정 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
* })
* ),
*
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function updateBomItems() {}
/**
* @OA\Delete(
* path="/api/v1/item-master/bom-items/{id}",
* tags={"ItemMaster"},
* summary="BOM 항목 삭제",
* 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")),
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function destroyBomItems() {}
// ════════════════════════════════════════════════════════════════════════
// 커스텀 탭 (Custom Tabs)
// ════════════════════════════════════════════════════════════════════════
/**
* @OA\Get(
* path="/api/v1/item-master/custom-tabs",
@@ -1201,63 +1292,4 @@ public function destroyCustomTabs() {}
* )
*/
public function reorderCustomTabs() {}
/**
* @OA\Get(
* path="/api/v1/item-master/unit-options",
* tags={"ItemMaster"},
* summary="단위 옵션 목록",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @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/UnitOption")))
* })
* ),
*
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function indexUnitOptions() {}
/**
* @OA\Post(
* path="/api/v1/item-master/unit-options",
* tags={"ItemMaster"},
* summary="단위 옵션 생성",
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
*
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/UnitOptionStoreRequest")),
*
* @OA\Response(response=200, description="생성 성공",
*
* @OA\JsonContent(allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/UnitOption"))
* })
* ),
*
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function storeUnitOptions() {}
/**
* @OA\Delete(
* path="/api/v1/item-master/unit-options/{id}",
* tags={"ItemMaster"},
* summary="단위 옵션 삭제",
* 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")),
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function destroyUnitOptions() {}
}