게시판오목 Next.js 웹과 VLM 착수 API 연결하기예제 소스

예제 소스

오목 Next.js 웹과 VLM 착수 API 연결하기 · 파일 59개

route.ts

import { NextRequest, NextResponse } from "next/server";
import { getGameAuthorized, updateGameAuthorized, type GamePatch } from "@/lib/db";
import { PLAY_SIZES } from "@/lib/board";

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.size) {
    return NextResponse.json({ error: "invalid body" }, { status: 400 });
  }
  if (!(PLAY_SIZES as readonly number[]).includes(body.size)) {
    return NextResponse.json({ error: `unsupported size: ${body.size}` }, { status: 400 });
  }
  if (body.board.length !== body.size * body.size) {
    return NextResponse.json(
      { error: `board length must be ${body.size * body.size}` },
      { 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 });
}