diff options
Diffstat (limited to 'app/api/projects/cover-template/save/route.ts')
| -rw-r--r-- | app/api/projects/cover-template/save/route.ts | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/app/api/projects/cover-template/save/route.ts b/app/api/projects/cover-template/save/route.ts new file mode 100644 index 00000000..e681512d --- /dev/null +++ b/app/api/projects/cover-template/save/route.ts @@ -0,0 +1,125 @@ +// app/api/projects/cover-template/save/route.ts +import { saveFile } from "@/lib/file-stroage" +import db from "@/db/db" +import { projectCoverTemplates, generatedCoverPages } from "@/db/schema" +import { eq, and, desc } 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 + const templateName = formData.get("templateName") as string | null + + if (!file) { + return NextResponse.json( + { success: false, message: "파일이 없습니다" }, + { status: 400 } + ) + } + + if (!projectId) { + return NextResponse.json( + { success: false, message: "프로젝트 ID가 없습니다" }, + { status: 400 } + ) + } + + // 해당 프로젝트의 활성 템플릿 찾기 + const [activeTemplate] = await db + .select() + .from(projectCoverTemplates) + .where( + and( + eq(projectCoverTemplates.projectId, parseInt(projectId)), + eq(projectCoverTemplates.isActive, true) + ) + ) + .limit(1) + + if (!activeTemplate) { + return NextResponse.json( + { success: false, message: "활성 템플릿을 찾을 수 없습니다" }, + { status: 404 } + ) + } + + // 생성된 커버 페이지 저장 디렉토리 + const coverPagesDirectory = `projects/${projectId}/generated-covers` + + // 파일명 생성 (타임스탬프 포함) + const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5) + const fileName = templateName + ? `${templateName}_${timestamp}.docx` + : `cover_${timestamp}.docx` + + // 파일 저장 + const saveResult = await saveFile({ + file, + directory: coverPagesDirectory, + originalName: fileName, + }) + + if (!saveResult.success) { + return NextResponse.json( + { success: false, message: saveResult.error || "파일 저장 실패" }, + { status: 500 } + ) + } + + // TODO: 실제로는 문서에서 변수 값을 추출하거나 별도로 전달받아야 함 + // 현재는 빈 객체로 저장 (추후 확장 가능) + const variableValues = {} + + // generatedCoverPages 테이블에 저장 + const [generatedCover] = await db + .insert(generatedCoverPages) + .values({ + templateId: activeTemplate.id, + variableValues: variableValues, + fileName: saveResult.fileName, + filePath: saveResult.publicPath, + fileSize: saveResult.fileSize, + generatedBy: session.user.name, + }) + .returning() + + console.log(`✅ 커버 페이지 생성 완료: ${saveResult.fileName}`) + console.log(`✅ DB 저장 완료 - Generated Cover ID: ${generatedCover.id}`) + + // 캐시 무효화 + revalidateTag("project-cover-lists") + + return NextResponse.json({ + success: true, + generatedCoverId: generatedCover.id, + templateId: activeTemplate.id, + filePath: saveResult.publicPath, + fileName: saveResult.fileName, + fileSize: saveResult.fileSize, + message: "커버 페이지가 저장되었습니다" + }) + + } catch (error) { + console.error("❌ 커버 페이지 저장 오류:", error) + return NextResponse.json( + { + success: false, + message: error instanceof Error ? error.message : "저장 중 오류 발생" + }, + { status: 500 } + ) + } +}
\ No newline at end of file |
