import { NextResponse } from "next/server"; import { PrismaClient } from "@prisma/client"; import { verifyAccessToken, decryptJson } from "@/features/auth/authCrypto"; const prisma = new PrismaClient(); interface AuthUser { id: string; email: string; tokenVersion: number; } function extractTokenFromCookieHeader(cookieHeader: string | null): string | null { if (!cookieHeader) return null; const parts = cookieHeader.split(";"); for (const part of parts) { const trimmed = part.trim(); if (trimmed.startsWith("pb_access=")) { const value = trimmed.substring("pb_access=".length); return decodeURIComponent(value); } } return null; } async function getAuthUserFromRequest(request: Request): Promise { const cookieHeader = request.headers.get("cookie"); const token = extractTokenFromCookieHeader(cookieHeader); if (!token) return null; const payload = await verifyAccessToken(token); if (!payload) return null; return { id: payload.sub, email: payload.email, tokenVersion: payload.tokenVersion, }; } export async function GET( request: Request, context: { params: { slug: string } | Promise<{ slug: string }> }, ) { const authUser = await getAuthUserFromRequest(request); if (!authUser) { return NextResponse.json({ message: "폼 제출 내역을 조회하려면 로그인이 필요합니다." }, { status: 401 }); } const { slug } = await context.params; const project = await prisma.project.findUnique({ where: { slug }, }); if (!project || (project.userId && project.userId !== authUser.id)) { return NextResponse.json({ message: "프로젝트를 찾을 수 없습니다." }, { status: 404 }); } const submissions = await prisma.formSubmission.findMany({ where: { projectId: project.id }, orderBy: { createdAt: "desc" }, take: 100, }); const items = await Promise.all( submissions.map(async (s: any) => { const basePayload = (s.payloadJson ?? {}) as Record; let sensitive: Record = {}; if (s.sensitiveEnc) { try { sensitive = (await decryptJson>(s.sensitiveEnc)) ?? {}; } catch { sensitive = {}; } } const payload = { ...basePayload, ...sensitive }; return { id: s.id, createdAt: s.createdAt, projectSlug: s.projectSlug, payload, }; }), ); return NextResponse.json(items, { status: 200 }); }