spb/autoscholar
Public
1import { launchRun, listRuns } from "@autoscholar/core";2import { LaunchRunRequest, RunStatus } from "@autoscholar/schemas";3import { z } from "zod";4import { handler, json, parseBody, parseQuery } from "@/lib/server/api";5import { db } from "@/lib/server/db";6import { requireAdmin } from "@/lib/server/session";78export const runtime = "nodejs";910export const GET = handler(async (req) => {11 await requireAdmin(req);12 const q = parseQuery(13 req.url,14 z.object({15 status: z.string().optional(),16 projectId: z.string().uuid().optional(),17 limit: z.coerce.number().int().min(1).max(500).default(100),18 }),19 );20 const status = q.status ? q.status.split(",").map((s) => RunStatus.parse(s)) : undefined;21 return json({ runs: await listRuns(db(), { status, projectId: q.projectId, limit: q.limit }) });22});2324/** Idempotent launch: repeating the same idempotencyKey returns the same run (HTTP 200 instead of 201). */25export const POST = handler(async (req) => {26 const sess = await requireAdmin(req, { mutation: true });27 const body = await parseBody(req, LaunchRunRequest, 32 * 1024);28 const { run, created } = await launchRun(db(), body, { id: sess.userId, ip: sess.ip });29 return json({ run, created }, { status: created ? 201 : 200 });30});31