summaryrefslogtreecommitdiff
path: root/app/api/vendor-responses/upload
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-06-17 09:02:32 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-06-17 09:02:32 +0000
commit7a1524ba54f43d0f2a19e4bca2c6a2e0b01c5ef1 (patch)
treedaa214d404c7fc78b32419a028724e5671a6c7a4 /app/api/vendor-responses/upload
parentfa6a6093014c5d60188edfc9c4552e81c4b97bd1 (diff)
(대표님) 20250617 18시 작업사항
Diffstat (limited to 'app/api/vendor-responses/upload')
-rw-r--r--app/api/vendor-responses/upload/route.ts105
1 files changed, 105 insertions, 0 deletions
diff --git a/app/api/vendor-responses/upload/route.ts b/app/api/vendor-responses/upload/route.ts
new file mode 100644
index 00000000..111e4bd4
--- /dev/null
+++ b/app/api/vendor-responses/upload/route.ts
@@ -0,0 +1,105 @@
+// app/api/vendor-response-attachments/upload/route.ts
+import { NextRequest, NextResponse } from "next/server";
+import { writeFile, mkdir } from "fs/promises";
+import { existsSync } from "fs";
+import path from "path";
+import db from "@/db/db";
+import { vendorResponseAttachmentsB } from "@/db/schema";
+import { getServerSession } from "next-auth/next"
+import { authOptions } from "@/app/api/auth/[...nextauth]/route"
+
+export async function POST(request: NextRequest) {
+ try {
+ // 인증 확인
+ const session = await getServerSession(authOptions);
+ if (!session?.user?.id) {
+ return NextResponse.json(
+ { message: "인증이 필요합니다." },
+ { status: 401 }
+ );
+ }
+
+ const formData = await request.formData();
+ const responseId = formData.get("responseId") as string;
+ const file = formData.get("file") as File;
+ const description = formData.get("description") as string;
+
+ if (!responseId) {
+ return NextResponse.json(
+ { message: "응답 ID가 필요합니다." },
+ { status: 400 }
+ );
+ }
+
+ if (!file) {
+ return NextResponse.json(
+ { message: "파일이 선택되지 않았습니다." },
+ { status: 400 }
+ );
+ }
+
+ // 파일 크기 검증 (10MB)
+ if (file.size > 10 * 1024 * 1024) {
+ return NextResponse.json(
+ { message: "파일이 너무 큽니다. (최대 10MB)" },
+ { status: 400 }
+ );
+ }
+
+ // 업로드 디렉토리 생성
+ const uploadDir = path.join(
+ process.cwd(),
+ "public",
+ "uploads",
+ "vendor-responses",
+ responseId
+ );
+
+ if (!existsSync(uploadDir)) {
+ await mkdir(uploadDir, { recursive: true });
+ }
+
+ // 고유한 파일명 생성
+ const timestamp = Date.now();
+ const sanitizedName = file.name.replace(/[^a-zA-Z0-9.-]/g, "_");
+ const fileName = `${timestamp}_${sanitizedName}`;
+ const filePath = `/uploads/vendor-responses/${responseId}/${fileName}`;
+ const fullPath = path.join(uploadDir, fileName);
+
+ // 파일 저장
+ const buffer = Buffer.from(await file.arrayBuffer());
+ await writeFile(fullPath, buffer);
+
+ // DB에 파일 정보 저장
+ const [insertedFile] = await db
+ .insert(vendorResponseAttachmentsB)
+ .values({
+ vendorResponseId: parseInt(responseId),
+ fileName,
+ originalFileName: file.name,
+ filePath,
+ fileSize: file.size,
+ fileType: file.type || path.extname(file.name).slice(1),
+ description: description || null,
+ uploadedBy: parseInt(session.user.id),
+ })
+ .returning();
+
+ return NextResponse.json({
+ id: insertedFile.id,
+ fileName,
+ originalFileName: file.name,
+ filePath,
+ fileSize: file.size,
+ fileType: file.type || path.extname(file.name).slice(1),
+ message: "파일이 성공적으로 업로드되었습니다.",
+ });
+
+ } catch (error) {
+ console.error("File upload error:", error);
+ return NextResponse.json(
+ { message: "파일 업로드 중 오류가 발생했습니다." },
+ { status: 500 }
+ );
+ }
+} \ No newline at end of file