Your Name d88c28356a
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
feat: add flow board with database drafts
2026-04-11 20:48:46 +08:00

91 lines
2.3 KiB
TypeScript

import { NextResponse } from "next/server";
import { auth } from "@/app/(auth)/auth";
import {
getFlowBoardDraftByUserId,
upsertFlowBoardDraftByUserId,
} from "@/lib/db/queries";
import type { FlowBoardSnapshotData } from "@/lib/db/schema";
export const runtime = "nodejs";
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function normalizeRecord(value: unknown): Record<string, unknown> | null {
return isRecord(value) ? value : null;
}
function normalizeFlowBoardSnapshot(value: unknown): FlowBoardSnapshotData {
const raw = isRecord(value) ? value : {};
const updatedAt =
typeof raw.updatedAt === "string" && raw.updatedAt.trim()
? raw.updatedAt
: new Date().toISOString();
return {
children: Array.isArray(raw.children)
? raw.children.filter(isRecord)
: [],
viewport: normalizeRecord(raw.viewport),
theme: normalizeRecord(raw.theme),
updatedAt,
};
}
export async function GET() {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json(
{ success: false, error: "未登录" },
{ status: 401 }
);
}
const draft = await getFlowBoardDraftByUserId({
userId: session.user.id,
});
return NextResponse.json({
success: true,
data: {
snapshot: draft?.snapshot ?? { children: [] },
updatedAt: draft?.updatedAt?.toISOString() ?? null,
},
});
}
export async function PUT(request: Request) {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json(
{ success: false, error: "未登录" },
{ status: 401 }
);
}
const body = (await request.json().catch(() => ({}))) as {
snapshot?: unknown;
};
const snapshot = normalizeFlowBoardSnapshot(body.snapshot ?? body);
const savedDraft = await upsertFlowBoardDraftByUserId({
userId: session.user.id,
snapshot,
});
if (!savedDraft) {
return NextResponse.json(
{ success: false, error: "保存流程白板失败" },
{ status: 500 }
);
}
return NextResponse.json({
success: true,
data: {
snapshot: savedDraft.snapshot,
updatedAt: savedDraft.updatedAt?.toISOString() ?? snapshot.updatedAt,
},
});
}