예제 소스
바둑 on-policy 학습: 대국 로그를 KataGo 라벨로 바꾸기 · 파일 169개
route.ts
import { NextRequest, NextResponse } from "next/server";
import { getGameAuthorized, updateGameAuthorized, type GamePatch } from "@/lib/db";
export const runtime = "nodejs";
type Ctx = { params: Promise<{ code: string }> };
function authFrom(req: NextRequest, body?: { guestId?: string; accessKey?: string }) {
return {
guestId: body?.guestId || req.nextUrl.searchParams.get("guestId"),
accessKey: body?.accessKey || req.nextUrl.searchParams.get("key"),
};
}
export async function GET(req: NextRequest, ctx: Ctx) {
const { code } = await ctx.params;
const result = getGameAuthorized(code, authFrom(req));
if ("error" in result) {
const status = result.error === "not_found" ? 404 : 403;
return NextResponse.json(
{
error: result.error,
message:
result.error === "forbidden"
? "본인 대국만 열 수 있습니다. 다른 기기는 이어두기 링크가 필요합니다."
: "대국을 찾을 수 없습니다.",
},
{ status },
);
}
return NextResponse.json({ game: result.game });
}
export async function PUT(req: NextRequest, ctx: Ctx) {
const { code } = await ctx.params;
const body = (await req.json().catch(() => null)) as
| (GamePatch & { guestId?: string; accessKey?: string })
| null;
if (!body || !Array.isArray(body.board) || body.board.length !== 361) {
return NextResponse.json({ error: "invalid body" }, { status: 400 });
}
if (
body.status === "ended" &&
body.winner !== "black" &&
body.winner !== "white" &&
body.winner !== "draw"
) {
return NextResponse.json({ error: "winner required for ended game" }, { status: 400 });
}
const { guestId, accessKey, ...patch } = body;
const result = updateGameAuthorized(code, authFrom(req, { guestId, accessKey }), patch);
if ("error" in result) {
const status = result.error === "not_found" ? 404 : 403;
return NextResponse.json({ error: result.error }, { status });
}
return NextResponse.json({ game: result.game, player: result.player });
}