feat: [bending] 절곡품 전용 테이블 분리 API

- bending_items 전용 테이블 생성 (items.options → 정규 컬럼 승격)
- bending_models 전용 테이블 생성 (가이드레일/케이스/하단마감재 통합)
- bending_data JSON 통합 (별도 테이블 → bending_items.bending_data 컬럼)
- bending_item_mappings 테이블 DROP (bending_items.code에 흡수)
- BendingItemService/BendingCodeService → BendingItem 모델 전환
- GuiderailModelService component 이미지 자동 복사
- ItemsFileController bending_items/bending_models 폴백 지원
- Swagger 스키마 업데이트
This commit is contained in:
강영보
2026-03-19 19:54:23 +09:00
parent 623298dd82
commit c29090a0b8
32 changed files with 3114 additions and 490 deletions

View File

@@ -6,6 +6,8 @@
use App\Http\Controllers\Controller;
use App\Http\Requests\Item\ItemFileUploadRequest;
use App\Models\Commons\File;
use App\Models\BendingItem;
use App\Models\BendingModel;
use App\Models\Items\Item;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
@@ -53,12 +55,13 @@ public function index(int $id, Request $request)
$fieldKey = $request->input('field_key');
// 품목 존재 확인
$this->getItemById($id, $tenantId);
$owner = $this->getItemById($id, $tenantId);
$docType = $this->getDocumentType($owner);
// 파일 조회
$query = File::query()
->where('tenant_id', $tenantId)
->where('document_type', self::ITEM_GROUP_ID)
->where('document_type', $docType)
->where('document_id', $id);
// 특정 field_key만 조회
@@ -94,7 +97,8 @@ public function upload(int $id, ItemFileUploadRequest $request)
$existingFileId = $validated['file_id'] ?? null;
// 품목 존재 확인
$this->getItemById($id, $tenantId);
$owner = $this->getItemById($id, $tenantId);
$docType = $this->getDocumentType($owner);
$replaced = false;
@@ -102,7 +106,7 @@ public function upload(int $id, ItemFileUploadRequest $request)
if ($existingFileId) {
$existingFile = File::query()
->where('tenant_id', $tenantId)
->where('document_type', self::ITEM_GROUP_ID)
->where('document_type', $docType)
->where('document_id', $id)
->where('id', $existingFileId)
->first();
@@ -142,7 +146,7 @@ public function upload(int $id, ItemFileUploadRequest $request)
'file_type' => $fileType, // 파일 형식 (image, document, excel, archive)
'field_key' => $fieldKey, // 비즈니스 용도 (drawing, certificate 등)
'document_id' => $id,
'document_type' => self::ITEM_GROUP_ID, // group_id
'document_type' => $docType,
'is_temp' => false,
'uploaded_by' => $userId,
'created_by' => $userId,
@@ -175,12 +179,13 @@ public function delete(int $id, mixed $fileId, Request $request)
$tenantId = app('tenant_id');
// 품목 존재 확인
$this->getItemById($id, $tenantId);
$owner = $this->getItemById($id, $tenantId);
$docType = $this->getDocumentType($owner);
// 파일 조회
$file = File::query()
->where('tenant_id', $tenantId)
->where('document_type', self::ITEM_GROUP_ID)
->where('document_type', $docType)
->where('document_id', $id)
->where('id', $fileId)
->first();
@@ -200,19 +205,51 @@ public function delete(int $id, mixed $fileId, Request $request)
}
/**
* ID로 품목 조회 (통합 items 테이블)
* ID로 품목 조회 (items → bending_items 폴백)
*/
private function getItemById(int $id, int $tenantId): Item
private function getItemById(int $id, int $tenantId): Item|BendingItem|BendingModel
{
$item = Item::query()
->where('tenant_id', $tenantId)
->find($id);
if (! $item) {
throw new NotFoundHttpException(__('error.not_found'));
if ($item) {
return $item;
}
return $item;
// bending_items 폴백
$bendingItem = BendingItem::query()
->where('tenant_id', $tenantId)
->find($id);
if ($bendingItem) {
return $bendingItem;
}
// bending_models 폴백
$bendingModel = BendingModel::query()
->where('tenant_id', $tenantId)
->find($id);
if ($bendingModel) {
return $bendingModel;
}
throw new NotFoundHttpException(__('error.not_found'));
}
/**
* 품목 유형에 따른 document_type 반환
*/
private function getDocumentType(Item|BendingItem|BendingModel $item): string
{
if ($item instanceof BendingItem) {
return 'bending_item';
}
if ($item instanceof BendingModel) {
return 'bending_model';
}
return self::ITEM_GROUP_ID;
}
/**