feat: 품목 파일 업로드를 files 테이블 기반으로 변경
- ItemsFileController: files 테이블에 메타데이터 저장, products는 file_id 참조
- 저장 경로: storage/app/tenants/{tenant_id}/items/{year}/{month}/{stored_name}
- 파일명: 64bit 난수로 보안 강화 (bin2hex(random_bytes(8)))
- Swagger 문서: file_id 반환 및 저장 구조 설명 추가
- file-storage-guide.md 규격 준수
This commit is contained in:
@@ -5,18 +5,21 @@
|
||||
/**
|
||||
* @OA\Tag(
|
||||
* name="Items Files",
|
||||
* description="품목 파일 관리 API (절곡도, 시방서, 인정서)"
|
||||
* description="품목 파일 관리 API (절곡도, 시방서, 인정서) - files 테이블 기반"
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="ItemFileUploadResponse",
|
||||
* type="object",
|
||||
* required={"file_type", "file_url", "file_path", "file_name"},
|
||||
* required={"file_id", "file_type", "file_url", "file_path", "file_name"},
|
||||
*
|
||||
* @OA\Property(property="file_id", type="integer", example=123, description="files 테이블 ID"),
|
||||
* @OA\Property(property="file_type", type="string", enum={"bending_diagram", "specification", "certification"}, example="bending_diagram", description="파일 타입"),
|
||||
* @OA\Property(property="file_url", type="string", format="uri", example="http://api.sam.kr/storage/items/P-001/bending_diagram/abc123.jpg", description="파일 URL"),
|
||||
* @OA\Property(property="file_path", type="string", example="items/P-001/bending_diagram/abc123.jpg", description="파일 경로"),
|
||||
* @OA\Property(property="file_url", type="string", format="uri", example="https://api.sam.kr/api/v1/files/download/MjE3L2l0ZW1zLzIwMjUvMTIvYTFiMmMzZDRlNWY2ZzdoOC5wbmc=", description="파일 다운로드 URL"),
|
||||
* @OA\Property(property="file_path", type="string", example="287/items/2025/12/a1b2c3d4e5f6g7h8.png", description="파일 저장 경로"),
|
||||
* @OA\Property(property="file_name", type="string", example="절곡도_V1.jpg", description="원본 파일명"),
|
||||
* @OA\Property(property="file_size", type="integer", example=102400, description="파일 크기 (bytes)"),
|
||||
* @OA\Property(property="mime_type", type="string", example="image/png", description="MIME 타입"),
|
||||
* @OA\Property(property="product", ref="#/components/schemas/Product", description="업데이트된 품목 정보")
|
||||
* )
|
||||
*
|
||||
@@ -26,7 +29,7 @@
|
||||
* required={"file_type", "deleted"},
|
||||
*
|
||||
* @OA\Property(property="file_type", type="string", enum={"bending_diagram", "specification", "certification"}, example="bending_diagram", description="파일 타입"),
|
||||
* @OA\Property(property="deleted", type="boolean", example=true, description="파일 삭제 여부"),
|
||||
* @OA\Property(property="deleted", type="boolean", example=true, description="파일 삭제 여부 (soft delete)"),
|
||||
* @OA\Property(property="product", ref="#/components/schemas/Product", description="업데이트된 품목 정보")
|
||||
* )
|
||||
*/
|
||||
@@ -36,20 +39,26 @@ class ItemsFileApi
|
||||
* 파일 업로드
|
||||
*
|
||||
* @OA\Post(
|
||||
* path="/api/v1/items/{code}/files",
|
||||
* path="/api/v1/items/{id}/files",
|
||||
* summary="품목 파일 업로드",
|
||||
* description="품목에 파일을 업로드합니다 (절곡도/시방서/인정서)",
|
||||
* description="품목에 파일을 업로드합니다 (절곡도/시방서/인정서). 파일은 files 테이블에 저장되고, Product에는 file_id가 참조됩니다.
|
||||
*
|
||||
* **저장 경로**: `storage/app/tenants/{tenant_id}/items/{year}/{month}/{stored_name}`
|
||||
*
|
||||
* **저장 구조**:
|
||||
* - files 테이블: 파일 메타데이터 저장 (display_name, stored_name, file_path, file_size, mime_type 등)
|
||||
* - products 테이블: file_id 참조 (bending_diagram, specification_file, certification_file 컬럼)",
|
||||
* operationId="uploadItemFile",
|
||||
* tags={"Items Files"},
|
||||
* security={{"ApiKeyAuth": {}, "BearerAuth": {}}},
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="code",
|
||||
* name="id",
|
||||
* in="path",
|
||||
* required=true,
|
||||
* description="품목 코드",
|
||||
* description="품목 ID",
|
||||
*
|
||||
* @OA\Schema(type="string", example="P-001")
|
||||
* @OA\Schema(type="integer", example=795)
|
||||
* ),
|
||||
*
|
||||
* @OA\RequestBody(
|
||||
@@ -72,7 +81,7 @@ class ItemsFileApi
|
||||
* property="file",
|
||||
* type="string",
|
||||
* format="binary",
|
||||
* description="업로드할 파일 (절곡도: jpg,png,gif,svg / 문서: pdf,doc,docx,xls,xlsx,hwp)"
|
||||
* description="업로드할 파일 (이미지: jpg,png,gif,svg / 문서: pdf,doc,docx,xls,xlsx,hwp). 최대 20MB"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="bending_details",
|
||||
@@ -135,20 +144,20 @@ public function upload() {}
|
||||
* 파일 삭제
|
||||
*
|
||||
* @OA\Delete(
|
||||
* path="/api/v1/items/{code}/files/{type}",
|
||||
* path="/api/v1/items/{id}/files/{type}",
|
||||
* summary="품목 파일 삭제",
|
||||
* description="품목의 파일을 삭제합니다",
|
||||
* description="품목의 파일을 삭제합니다 (Soft Delete). files 테이블의 deleted_at이 설정되고, products 테이블의 file_id 참조가 null로 변경됩니다.",
|
||||
* operationId="deleteItemFile",
|
||||
* tags={"Items Files"},
|
||||
* security={{"ApiKeyAuth": {}, "BearerAuth": {}}},
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="code",
|
||||
* name="id",
|
||||
* in="path",
|
||||
* required=true,
|
||||
* description="품목 코드",
|
||||
* description="품목 ID",
|
||||
*
|
||||
* @OA\Schema(type="string", example="P-001")
|
||||
* @OA\Schema(type="integer", example=795)
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
@@ -177,4 +186,4 @@ public function upload() {}
|
||||
* )
|
||||
*/
|
||||
public function delete() {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user