diff options
Diffstat (limited to 'app/api/vendor-responses/upload/route.ts')
| -rw-r--r-- | app/api/vendor-responses/upload/route.ts | 105 |
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 |
