import { launchRun, listRuns } from "@autoscholar/core"; import { LaunchRunRequest, RunStatus } from "@autoscholar/schemas"; import { z } from "zod"; import { handler, json, parseBody, parseQuery } from "@/lib/server/api"; import { db } from "@/lib/server/db"; import { requireAdmin } from "@/lib/server/session"; export const runtime = "nodejs"; export const GET = handler(async (req) => { await requireAdmin(req); const q = parseQuery( req.url, z.object({ status: z.string().optional(), projectId: z.string().uuid().optional(), limit: z.coerce.number().int().min(1).max(500).default(100), }), ); const status = q.status ? q.status.split(",").map((s) => RunStatus.parse(s)) : undefined; return json({ runs: await listRuns(db(), { status, projectId: q.projectId, limit: q.limit }) }); }); /** Idempotent launch: repeating the same idempotencyKey returns the same run (HTTP 200 instead of 201). */ export const POST = handler(async (req) => { const sess = await requireAdmin(req, { mutation: true }); const body = await parseBody(req, LaunchRunRequest, 32 * 1024); const { run, created } = await launchRun(db(), body, { id: sess.userId, ip: sess.ip }); return json({ run, created }, { status: created ? 201 : 200 }); });