diff options
Diffstat (limited to 'app/api/projects/cover-template/upload/route.ts')
| -rw-r--r-- | app/api/projects/cover-template/upload/route.ts | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/app/api/projects/cover-template/upload/route.ts b/app/api/projects/cover-template/upload/route.ts new file mode 100644 index 00000000..9c8df7ca --- /dev/null +++ b/app/api/projects/cover-template/upload/route.ts @@ -0,0 +1,127 @@ +// app/api/projects/cover-template/upload/route.ts +import db from "@/db/db" +import { projectCoverTemplates } from "@/db/schema" +import { saveFile } from "@/lib/file-stroage" +import { eq, and } from "drizzle-orm" +import { NextRequest, NextResponse } from "next/server" +import { revalidateTag } from "next/cache" +import { getServerSession } from 'next-auth'; +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( + { error: '인증이 필요합니다' }, + { status: 401 } + ); + } + + const formData = await request.formData() + const file = formData.get("file") as File + const projectId = formData.get("projectId") as string + + if (!file) { + return NextResponse.json( + { success: false, message: "파일이 없습니다" }, + { status: 400 } + ) + } + + if (!projectId) { + return NextResponse.json( + { success: false, message: "프로젝트 ID가 없습니다" }, + { status: 400 } + ) + } + + // 파일 확장자 확인 + if (!file.name.endsWith('.docx')) { + return NextResponse.json( + { success: false, message: "DOCX 파일만 업로드 가능합니다" }, + { status: 400 } + ) + } + + // 템플릿 디렉토리 + const templateDirectory = `projects/${projectId}/cover-templates` + + // 파일 저장 + const saveResult = await saveFile({ + file, + directory: templateDirectory, + originalName: file.name, + }) + + if (!saveResult.success) { + return NextResponse.json( + { success: false, message: saveResult.error || "파일 저장 실패" }, + { status: 500 } + ) + } + + // 기존 활성 템플릿 비활성화 + await db + .update(projectCoverTemplates) + .set({ + isActive: false, + updatedAt: new Date() + }) + .where( + and( + eq(projectCoverTemplates.projectId, parseInt(projectId)), + eq(projectCoverTemplates.isActive, true) + ) + ) + + // 기본 템플릿 변수 설정 + const defaultVariables = { + docNumber: "{{docNumber}}", + projectNumber: "{{projectNumber}}", + projectName: "{{projectName}}" + } + + // 새 템플릿을 DB에 저장 + const [newTemplate] = await db + .insert(projectCoverTemplates) + .values({ + projectId: parseInt(projectId), + templateName: file.name.replace('.docx', ''), + originalFileName: file.name, + filePath: saveResult.publicPath, + fileSize: saveResult.fileSize, + variables: defaultVariables, + isActive: true, + createdBy: session.user.name, // TODO: 실제 사용자 정보로 변경 + updatedBy: session.user.name, + }) + .returning() + + console.log(`✅ 커버 템플릿 업로드 완료: ${saveResult.fileName}`) + console.log(`✅ DB 저장 완료 - Template ID: ${newTemplate.id}`) + + // 캐시 무효화 + revalidateTag("project-cover-lists") + + return NextResponse.json({ + success: true, + templateId: newTemplate.id, + filePath: saveResult.publicPath, + fileName: saveResult.fileName, + fileSize: saveResult.fileSize, + variables: defaultVariables, + }) + + } catch (error) { + console.error("❌ 템플릿 업로드 오류:", error) + return NextResponse.json( + { + success: false, + message: error instanceof Error ? error.message : "업로드 중 오류 발생" + }, + { status: 500 } + ) + } +}
\ No newline at end of file |
