mirror of
https://github.com/multica-ai/multica.git
synced 2026-08-03 19:20:07 +02:00
Wires the frontend onto the PR1 webhook delivery layer. Adds a Deliveries section to the autopilot detail page that lists recent deliveries (queued / dispatched / rejected / ignored / failed) with provider, event, attempt count, and timestamp. Clicking a row opens a detail dialog with raw body, headers subset, response body, signature status, and a Replay button. Replay is disabled client-side for signature-invalid / rejected / still-queued deliveries to mirror the server's 400. Backend contract is locked behind a lenient zod schema via parseWithFallback — unknown future status / signature_status values degrade to a generic row instead of dropping the whole list. Co-authored-by: multica-agent <github@multica.ai>
90 lines
3.1 KiB
TypeScript
90 lines
3.1 KiB
TypeScript
import { queryOptions } from "@tanstack/react-query";
|
|
import { api } from "../api";
|
|
|
|
export const autopilotKeys = {
|
|
all: (wsId: string) => ["autopilots", wsId] as const,
|
|
list: (wsId: string) => [...autopilotKeys.all(wsId), "list"] as const,
|
|
detail: (wsId: string, id: string) =>
|
|
[...autopilotKeys.all(wsId), "detail", id] as const,
|
|
runs: (wsId: string, id: string) =>
|
|
[...autopilotKeys.all(wsId), "runs", id] as const,
|
|
run: (wsId: string, autopilotId: string, runId: string) =>
|
|
[...autopilotKeys.all(wsId), "runs", autopilotId, runId] as const,
|
|
deliveries: (wsId: string, id: string) =>
|
|
[...autopilotKeys.all(wsId), "deliveries", id] as const,
|
|
delivery: (wsId: string, autopilotId: string, deliveryId: string) =>
|
|
[...autopilotKeys.all(wsId), "deliveries", autopilotId, deliveryId] as const,
|
|
};
|
|
|
|
export function autopilotListOptions(wsId: string) {
|
|
return queryOptions({
|
|
queryKey: autopilotKeys.list(wsId),
|
|
queryFn: () => api.listAutopilots(),
|
|
select: (data) => data.autopilots,
|
|
});
|
|
}
|
|
|
|
export function autopilotDetailOptions(wsId: string, id: string) {
|
|
return queryOptions({
|
|
queryKey: autopilotKeys.detail(wsId, id),
|
|
queryFn: () => api.getAutopilot(id),
|
|
});
|
|
}
|
|
|
|
export function autopilotRunsOptions(wsId: string, id: string) {
|
|
return queryOptions({
|
|
queryKey: autopilotKeys.runs(wsId, id),
|
|
queryFn: () => api.listAutopilotRuns(id),
|
|
select: (data) => data.runs,
|
|
});
|
|
}
|
|
|
|
// autopilotRunOptions fetches a single run with its full trigger_payload.
|
|
// The list endpoint (autopilotRunsOptions) omits trigger_payload to keep
|
|
// list responses small; callers (e.g. the run-detail dialog) use this
|
|
// query on demand when the user opens a run.
|
|
export function autopilotRunOptions(
|
|
wsId: string,
|
|
autopilotId: string,
|
|
runId: string,
|
|
options?: { enabled?: boolean },
|
|
) {
|
|
return queryOptions({
|
|
queryKey: autopilotKeys.run(wsId, autopilotId, runId),
|
|
queryFn: () => api.getAutopilotRun(autopilotId, runId),
|
|
enabled: options?.enabled ?? true,
|
|
});
|
|
}
|
|
|
|
// autopilotDeliveriesOptions powers the Deliveries section in the autopilot
|
|
// detail page. The list is slim — raw_body / selected_headers / response_body
|
|
// are omitted server-side. Detail rows are fetched on-demand when the user
|
|
// expands a row (see autopilotDeliveryOptions).
|
|
export function autopilotDeliveriesOptions(
|
|
wsId: string,
|
|
autopilotId: string,
|
|
options?: { enabled?: boolean },
|
|
) {
|
|
return queryOptions({
|
|
queryKey: autopilotKeys.deliveries(wsId, autopilotId),
|
|
queryFn: () => api.listAutopilotDeliveries(autopilotId),
|
|
select: (data) => data.deliveries,
|
|
enabled: options?.enabled ?? true,
|
|
});
|
|
}
|
|
|
|
// autopilotDeliveryOptions fetches the full delivery row including raw_body
|
|
// and headers subset. Used by the detail dialog opened from a list row.
|
|
export function autopilotDeliveryOptions(
|
|
wsId: string,
|
|
autopilotId: string,
|
|
deliveryId: string,
|
|
options?: { enabled?: boolean },
|
|
) {
|
|
return queryOptions({
|
|
queryKey: autopilotKeys.delivery(wsId, autopilotId, deliveryId),
|
|
queryFn: () => api.getAutopilotDelivery(autopilotId, deliveryId),
|
|
enabled: options?.enabled ?? true,
|
|
});
|
|
}
|