summaryrefslogtreecommitdiff
path: root/app/api/rfq-attachments/revision/route.ts
diff options
context:
space:
mode:
Diffstat (limited to 'app/api/rfq-attachments/revision/route.ts')
-rw-r--r--app/api/rfq-attachments/revision/route.ts122
1 files changed, 122 insertions, 0 deletions
diff --git a/app/api/rfq-attachments/revision/route.ts b/app/api/rfq-attachments/revision/route.ts
new file mode 100644
index 00000000..2592ae78
--- /dev/null
+++ b/app/api/rfq-attachments/revision/route.ts
@@ -0,0 +1,122 @@
+import { NextRequest, NextResponse } from "next/server";
+import { getServerSession } from 'next-auth';
+import { authOptions } from '@/app/api/auth/[...nextauth]/route';
+import db from "@/db/db";
+import { eq } from "drizzle-orm";
+import { rfqLastAttachments, rfqLastAttachmentRevisions } from "@/db/schema";
+import { saveFile, deleteFile } from "@/lib/file-storage";
+
+export async function POST(request: NextRequest) {
+ try {
+ const session = await getServerSession(authOptions);
+ if (!session?.user?.id) {
+ return NextResponse.json(
+ { success: false, message: "인증이 필요합니다" },
+ { status: 401 }
+ );
+ }
+
+ const formData = await request.formData();
+ const attachmentId = parseInt(formData.get("attachmentId") as string);
+ const revisionComment = formData.get("revisionComment") as string;
+ const file = formData.get("file") as File;
+
+ if (!file || file.size === 0) {
+ return NextResponse.json(
+ { success: false, message: "파일이 없습니다" },
+ { status: 400 }
+ );
+ }
+
+ // 파일 크기 검증 (100MB)
+ if (file.size > 100 * 1024 * 1024) {
+ return NextResponse.json(
+ { success: false, message: "파일 크기는 100MB를 초과할 수 없습니다" },
+ { status: 400 }
+ );
+ }
+
+ // 트랜잭션 시작
+ const result = await db.transaction(async (tx) => {
+ // 1. 기존 첨부파일 정보 조회
+ const [existingAttachment] = await tx
+ .select()
+ .from(rfqLastAttachments)
+ .where(eq(rfqLastAttachments.id, attachmentId));
+
+ if (!existingAttachment) {
+ throw new Error("첨부파일을 찾을 수 없습니다");
+ }
+
+ // 2. 현재 리비전 번호 계산
+ const currentRevision = existingAttachment.currentRevision || "A";
+ const nextRevision = String.fromCharCode(currentRevision.charCodeAt(0) + 1);
+
+ // 3. 공용 파일 저장 함수 사용
+ const saveResult = await saveFile({
+ file,
+ directory: `uploads/rfq-attachments/rfq-${existingAttachment.rfqId}`,
+ originalName: file.name,
+ userId: session.user.id,
+ });
+
+ if (!saveResult.success) {
+ throw new Error(saveResult.error || "파일 저장 실패");
+ }
+
+ // 4. 기존 latest 플래그 해제
+ if (existingAttachment.latestRevisionId) {
+ await tx
+ .update(rfqLastAttachmentRevisions)
+ .set({ isLatest: false })
+ .where(eq(rfqLastAttachmentRevisions.id, existingAttachment.latestRevisionId));
+ }
+
+ // 5. 새 리비전 생성
+ const [revision] = await tx
+ .insert(rfqLastAttachmentRevisions)
+ .values({
+ attachmentId,
+ revisionNo: nextRevision,
+ fileName: saveResult.fileName!,
+ originalFileName: saveResult.originalName!,
+ filePath: saveResult.publicPath!,
+ fileSize: saveResult.fileSize!,
+ fileType: file.type || "unknown",
+ isLatest: true,
+ revisionComment,
+ uploadedBy: parseInt(session.user.id),
+ uploadedAt: new Date(),
+ })
+ .returning();
+
+ // 6. 첨부파일 정보 업데이트
+ await tx
+ .update(rfqLastAttachments)
+ .set({
+ currentRevision: nextRevision,
+ latestRevisionId: revision.id,
+ updatedAt: new Date(),
+ })
+ .where(eq(rfqLastAttachments.id, attachmentId));
+
+ return { attachment: existingAttachment, revision };
+ });
+
+ return NextResponse.json({
+ success: true,
+ message: `새 버전이 업로드되었습니다 (Rev. ${result.revision.revisionNo})`,
+ data: result.revision,
+ });
+
+ } catch (error) {
+ console.error("Update revision error:", error);
+ return NextResponse.json(
+ {
+ success: false,
+ message: error instanceof Error ? error.message : "리비전 업데이트 실패"
+ },
+ { status: 500 }
+ );
+ }
+} \ No newline at end of file