리팩터링
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { verifyAccessToken } from "@/features/auth/authCrypto";
|
||||
import type { Block } from "@/features/editor/state/editorStore";
|
||||
import { cachePublicProject } from "@/features/projects/publicCache";
|
||||
import { cachePublicProject, parseProjectContentJson } from "@/features/projects/publicCache";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
@@ -62,7 +61,80 @@ export async function GET(request: Request) {
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json(projects, { status: 200 });
|
||||
if (projects.length === 0) {
|
||||
return NextResponse.json(
|
||||
projects.map((p) => ({
|
||||
...p,
|
||||
todaySubmissions: 0,
|
||||
totalSubmissions: 0,
|
||||
})),
|
||||
{ status: 200 },
|
||||
);
|
||||
}
|
||||
|
||||
const projectIds = projects.map((p) => p.id);
|
||||
|
||||
const submissions = await prisma.formSubmission.findMany({
|
||||
where: {
|
||||
userId: authUser.id,
|
||||
projectId: { in: projectIds },
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
projectId: true,
|
||||
createdAt: true,
|
||||
},
|
||||
});
|
||||
|
||||
const now = new Date();
|
||||
const startOfToday = new Date(now);
|
||||
startOfToday.setHours(0, 0, 0, 0);
|
||||
|
||||
const statsByProjectId = new Map<
|
||||
string,
|
||||
{
|
||||
todaySubmissions: number;
|
||||
totalSubmissions: number;
|
||||
}
|
||||
>();
|
||||
|
||||
for (const project of projects) {
|
||||
statsByProjectId.set(project.id, { todaySubmissions: 0, totalSubmissions: 0 });
|
||||
}
|
||||
|
||||
for (const submission of submissions) {
|
||||
const projectId = submission.projectId;
|
||||
if (!projectId) continue;
|
||||
|
||||
const stat = statsByProjectId.get(projectId);
|
||||
if (!stat) continue;
|
||||
|
||||
stat.totalSubmissions += 1;
|
||||
|
||||
const createdAt =
|
||||
submission.createdAt instanceof Date
|
||||
? submission.createdAt
|
||||
: new Date((submission.createdAt as unknown as string) ?? "");
|
||||
|
||||
if (createdAt >= startOfToday) {
|
||||
stat.todaySubmissions += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const result = projects.map((project) => {
|
||||
const stat = statsByProjectId.get(project.id) ?? {
|
||||
todaySubmissions: 0,
|
||||
totalSubmissions: 0,
|
||||
};
|
||||
|
||||
return {
|
||||
...project,
|
||||
todaySubmissions: stat.todaySubmissions,
|
||||
totalSubmissions: stat.totalSubmissions,
|
||||
};
|
||||
});
|
||||
|
||||
return NextResponse.json(result, { status: 200 });
|
||||
} catch (error: any) {
|
||||
return NextResponse.json(
|
||||
{ message: "프로젝트 목록을 가져오는 중 오류가 발생했습니다.", error: error?.message },
|
||||
@@ -112,17 +184,15 @@ export async function POST(request: Request) {
|
||||
|
||||
// 퍼블릭 슬러그 페이지(/p/[slug])가 DB 조회 없이도 최신 스냅샷을 바로 렌더링할 수 있도록
|
||||
// 메모리 기반 캐시에 프로젝트 스냅샷을 저장해 둔다.
|
||||
const rawContent = project.contentJson;
|
||||
let contentBlocks: Block[] = [];
|
||||
if (Array.isArray(rawContent)) {
|
||||
contentBlocks = rawContent as unknown as Block[];
|
||||
}
|
||||
const { blocks, projectConfig } = parseProjectContentJson((project as any).contentJson);
|
||||
|
||||
try {
|
||||
cachePublicProject({
|
||||
slug: project.slug,
|
||||
title: project.title,
|
||||
contentJson: contentBlocks,
|
||||
status: (project as any).status ?? "DRAFT",
|
||||
blocks,
|
||||
projectConfig,
|
||||
});
|
||||
} catch {
|
||||
// 캐시 저장 실패는 퍼블릭 렌더링에만 영향을 주므로, API 응답 자체는 정상적으로 계속 진행한다.
|
||||
|
||||
Reference in New Issue
Block a user