[taskboard] add dispatch control plane
This commit is contained in:
26
app/api/tasks/[id]/ack/route.ts
Normal file
26
app/api/tasks/[id]/ack/route.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
import { updateTask } from "@/lib/tasks";
|
||||
|
||||
export async function POST(
|
||||
_request: Request,
|
||||
{ params }: { params: Promise<{ id: string }> },
|
||||
) {
|
||||
const { id } = await params;
|
||||
const numericId = Number(id);
|
||||
if (!Number.isInteger(numericId) || numericId <= 0) {
|
||||
return NextResponse.json({ error: "invalid_task_id" }, { status: 400 });
|
||||
}
|
||||
|
||||
const task = await updateTask(numericId, {
|
||||
dispatch_state: "acknowledged",
|
||||
acknowledged_at: new Date().toISOString(),
|
||||
status: "In Progress",
|
||||
});
|
||||
|
||||
if (!task) {
|
||||
return NextResponse.json({ error: "task_not_found" }, { status: 404 });
|
||||
}
|
||||
|
||||
return NextResponse.json(task);
|
||||
}
|
||||
21
app/api/tasks/[id]/dispatch/route.ts
Normal file
21
app/api/tasks/[id]/dispatch/route.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
import { dispatchTask } from "@/lib/dispatch";
|
||||
|
||||
export async function POST(
|
||||
_request: Request,
|
||||
{ params }: { params: Promise<{ id: string }> },
|
||||
) {
|
||||
const { id } = await params;
|
||||
const numericId = Number(id);
|
||||
if (!Number.isInteger(numericId) || numericId <= 0) {
|
||||
return NextResponse.json({ error: "invalid_task_id" }, { status: 400 });
|
||||
}
|
||||
|
||||
try {
|
||||
return NextResponse.json(await dispatchTask(numericId));
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
return NextResponse.json({ error: "dispatch_failed", detail: message }, { status: 500 });
|
||||
}
|
||||
}
|
||||
16
app/api/tasks/[id]/events/route.ts
Normal file
16
app/api/tasks/[id]/events/route.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
import { listTaskEvents } from "@/lib/tasks";
|
||||
|
||||
export async function GET(
|
||||
_request: Request,
|
||||
{ params }: { params: Promise<{ id: string }> },
|
||||
) {
|
||||
const { id } = await params;
|
||||
const numericId = Number(id);
|
||||
if (!Number.isInteger(numericId) || numericId <= 0) {
|
||||
return NextResponse.json({ error: "invalid_task_id" }, { status: 400 });
|
||||
}
|
||||
|
||||
return NextResponse.json(await listTaskEvents(numericId, 50));
|
||||
}
|
||||
@@ -22,8 +22,34 @@ export async function PATCH(
|
||||
title: typeof payload.title === "string" ? payload.title : undefined,
|
||||
description: typeof payload.description === "string" ? payload.description : undefined,
|
||||
assignee: typeof payload.assignee === "string" ? payload.assignee : undefined,
|
||||
family:
|
||||
payload.family === null || typeof payload.family === "string"
|
||||
? (payload.family as never)
|
||||
: undefined,
|
||||
target_host: typeof payload.target_host === "string" ? payload.target_host : undefined,
|
||||
target_channel: typeof payload.target_channel === "string" ? payload.target_channel : undefined,
|
||||
dispatch_method: payload.dispatch_method as never,
|
||||
dispatch_state: payload.dispatch_state as never,
|
||||
template_key: typeof payload.template_key === "string" ? payload.template_key : undefined,
|
||||
repo_slug: typeof payload.repo_slug === "string" ? payload.repo_slug : undefined,
|
||||
base_branch: typeof payload.base_branch === "string" ? payload.base_branch : undefined,
|
||||
preferred_agent:
|
||||
typeof payload.preferred_agent === "string" ? payload.preferred_agent : undefined,
|
||||
reasoning_effort:
|
||||
typeof payload.reasoning_effort === "string" ? payload.reasoning_effort : undefined,
|
||||
model_hint: typeof payload.model_hint === "string" ? payload.model_hint : undefined,
|
||||
priority: payload.priority as never,
|
||||
status: payload.status as never,
|
||||
last_dispatch_at:
|
||||
typeof payload.last_dispatch_at === "string" ? payload.last_dispatch_at : undefined,
|
||||
acknowledged_at:
|
||||
payload.acknowledged_at === null || typeof payload.acknowledged_at === "string"
|
||||
? (payload.acknowledged_at as never)
|
||||
: undefined,
|
||||
last_error:
|
||||
payload.last_error === null || typeof payload.last_error === "string"
|
||||
? (payload.last_error as never)
|
||||
: undefined,
|
||||
tags: Array.isArray(payload.tags) ? payload.tags.filter((tag) => typeof tag === "string") : undefined,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user