diff options
| author | joonhoekim <26rote@gmail.com> | 2025-11-03 18:46:35 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-11-03 18:46:35 +0900 |
| commit | 1393acc4b6675fd5eac65c6f1a9e399edfb2d44f (patch) | |
| tree | 6610385198545277ed51c4616d315aa0800c07bc /app/api | |
| parent | a9c038e51f1cf508165e9d196ffe332f6ac54d74 (diff) | |
(김준회) SWP: 커버페이지 생성 API 오류 수정
Diffstat (limited to 'app/api')
| -rw-r--r-- | app/api/projects/[projectId]/cover/route.ts | 78 | ||||
| -rw-r--r-- | app/api/projects/code-to-id/route.ts | 47 |
2 files changed, 88 insertions, 37 deletions
diff --git a/app/api/projects/[projectId]/cover/route.ts b/app/api/projects/[projectId]/cover/route.ts index b88f06ee..802e2ab6 100644 --- a/app/api/projects/[projectId]/cover/route.ts +++ b/app/api/projects/[projectId]/cover/route.ts @@ -1,15 +1,22 @@ // app/api/projects/[projectId]/cover/route.ts import { NextRequest, NextResponse } from "next/server" -import db from "@/db/db" -import { projectCoverTemplates, generatedCoverPages } from "@/db/schema" -import { eq, and, desc } from "drizzle-orm" +import { generateCoverPage } from "@/lib/cover/cover-service" +/** + * 커버페이지 생성 및 다운로드 + * + * GET /api/projects/[projectId]/cover?docNumber=DOC-001 + * + * @param projectId - 프로젝트 ID + * @param docNumber - 문서 번호 (쿼리 파라미터) + */ export async function GET( request: NextRequest, - { params }: { params: { projectId: string } } + { params }: { params: Promise<{ projectId: string }> } ) { try { - const projectId = parseInt(params.projectId) + const { projectId: projectIdParam } = await params + const projectId = parseInt(projectIdParam) if (isNaN(projectId)) { return NextResponse.json( @@ -18,54 +25,51 @@ export async function GET( ) } - // 1. 해당 프로젝트의 활성 템플릿 찾기 - const [activeTemplate] = await db - .select() - .from(projectCoverTemplates) - .where( - and( - eq(projectCoverTemplates.projectId, projectId), - eq(projectCoverTemplates.isActive, true) - ) - ) - .limit(1) + // docNumber 쿼리 파라미터 가져오기 + const { searchParams } = new URL(request.url) + const docNumber = searchParams.get("docNumber") - if (!activeTemplate) { + if (!docNumber) { return NextResponse.json( - { success: false, message: "활성 템플릿을 찾을 수 없습니다" }, - { status: 404 } + { success: false, message: "문서 번호(docNumber)가 필요합니다" }, + { status: 400 } ) } - // 2. 해당 템플릿의 최신 생성된 커버 페이지 찾기 - const [latestCover] = await db - .select() - .from(generatedCoverPages) - .where(eq(generatedCoverPages.templateId, activeTemplate.id)) - .orderBy(desc(generatedCoverPages.generatedAt)) - .limit(1) + console.log(`📄 커버페이지 요청 - ProjectID: ${projectId}, DocNumber: ${docNumber}`) - if (!latestCover) { + // 커버페이지 생성 + const result = await generateCoverPage(projectId, docNumber) + + if (!result.success || !result.buffer) { return NextResponse.json( - { success: false, message: "생성된 커버 페이지를 찾을 수 없습니다" }, - { status: 404 } + { + success: false, + message: result.error || "커버페이지 생성 실패" + }, + { status: 500 } ) } - // 3. 파일 경로와 정보 반환 - return NextResponse.json({ - success: true, - fileUrl: latestCover.filePath, - fileName: latestCover.fileName, - generatedAt: latestCover.generatedAt, + // DOCX 파일로 응답 + // Buffer를 Uint8Array로 변환 + const uint8Array = new Uint8Array(result.buffer) + + return new NextResponse(uint8Array, { + status: 200, + headers: { + "Content-Type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "Content-Disposition": `attachment; filename="${encodeURIComponent(result.fileName || "cover.docx")}"`, + "Content-Length": result.buffer.length.toString(), + }, }) } catch (error) { - console.error("❌ 커버 페이지 조회 오류:", error) + console.error("❌ 커버 페이지 생성 오류:", error) return NextResponse.json( { success: false, - message: error instanceof Error ? error.message : "조회 중 오류 발생" + message: error instanceof Error ? error.message : "생성 중 오류 발생" }, { status: 500 } ) diff --git a/app/api/projects/code-to-id/route.ts b/app/api/projects/code-to-id/route.ts new file mode 100644 index 00000000..f2fdb3c5 --- /dev/null +++ b/app/api/projects/code-to-id/route.ts @@ -0,0 +1,47 @@ +// app/api/projects/code-to-id/route.ts +import { NextRequest, NextResponse } from "next/server" +import { getProjectIdByCode } from "@/lib/swp/project-utils" + +/** + * 프로젝트 코드로 프로젝트 ID 조회 + * + * GET /api/projects/code-to-id?code=PROJ_CODE + */ +export async function GET(request: NextRequest) { + try { + const { searchParams } = new URL(request.url) + const code = searchParams.get("code") + + if (!code) { + return NextResponse.json( + { success: false, message: "프로젝트 코드(code)가 필요합니다" }, + { status: 400 } + ) + } + + const projectId = await getProjectIdByCode(code) + + if (!projectId) { + return NextResponse.json( + { success: false, message: "프로젝트를 찾을 수 없습니다" }, + { status: 404 } + ) + } + + return NextResponse.json({ + success: true, + projectId, + }) + + } catch (error) { + console.error("❌ 프로젝트 ID 조회 오류:", error) + return NextResponse.json( + { + success: false, + message: error instanceof Error ? error.message : "조회 중 오류 발생" + }, + { status: 500 } + ) + } +} + |
