Add "Start Workflow" button to trigger CEO agent from web UI
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 49s
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 49s
New endpoint POST /api/cases/{case_number}/start-workflow creates a
Paperclip issue, wakes the CEO agent via wakeup API, and transitions
case status to "processing". Button appears on case page only when
status is "new" or "documents_ready".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,9 @@ import { DocumentsPanel } from "@/components/cases/documents-panel";
|
||||
import { DraftsPanel } from "@/components/cases/drafts-panel";
|
||||
import { UploadSheet } from "@/components/documents/upload-sheet";
|
||||
import { expectedOutcomes } from "@/lib/schemas/case";
|
||||
import { useCase } from "@/lib/api/cases";
|
||||
import { useCase, useStartWorkflow } from "@/lib/api/cases";
|
||||
import { toast } from "sonner";
|
||||
import { Play, Loader2 } from "lucide-react";
|
||||
|
||||
const EXPECTED_OUTCOME_LABELS: Record<string, string> = Object.fromEntries(
|
||||
expectedOutcomes.map((o) => [o.value, o.label]),
|
||||
@@ -33,6 +35,8 @@ export default function CaseDetailPage({
|
||||
}) {
|
||||
const { caseNumber } = use(params);
|
||||
const { data, isPending, error } = useCase(caseNumber);
|
||||
const startWorkflow = useStartWorkflow(caseNumber);
|
||||
const canStartWorkflow = data?.status === "new" || data?.status === "documents_ready";
|
||||
const expectedOutcomeLabel = data?.expected_outcome
|
||||
? EXPECTED_OUTCOME_LABELS[data.expected_outcome] ?? data.expected_outcome
|
||||
: null;
|
||||
@@ -107,6 +111,29 @@ export default function CaseDetailPage({
|
||||
</dl>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 flex-wrap pt-2 border-t border-rule">
|
||||
{canStartWorkflow && (
|
||||
<Button
|
||||
className="bg-gold-deep hover:bg-gold-deep/90 text-parchment"
|
||||
disabled={startWorkflow.isPending}
|
||||
onClick={() =>
|
||||
startWorkflow.mutate(undefined, {
|
||||
onSuccess: (res) =>
|
||||
toast.success(
|
||||
`תהליך הופעל — ${res.issue_identifier}`,
|
||||
),
|
||||
onError: (err) =>
|
||||
toast.error(`שגיאה: ${err.message}`),
|
||||
})
|
||||
}
|
||||
>
|
||||
{startWorkflow.isPending ? (
|
||||
<Loader2 className="w-4 h-4 animate-spin me-1.5" />
|
||||
) : (
|
||||
<Play className="w-4 h-4 me-1.5" />
|
||||
)}
|
||||
התחל תהליך
|
||||
</Button>
|
||||
)}
|
||||
<Button asChild className="bg-navy hover:bg-navy-soft text-parchment">
|
||||
<Link href={`/cases/${caseNumber}/compose`}>
|
||||
פתח בעורך ההחלטה
|
||||
|
||||
@@ -167,6 +167,32 @@ export function useGitStatus(caseNumber: string | undefined) {
|
||||
});
|
||||
}
|
||||
|
||||
export type StartWorkflowResult = {
|
||||
case_number: string;
|
||||
status: string;
|
||||
issue_id: string;
|
||||
issue_identifier: string;
|
||||
project_url: string;
|
||||
wakeup: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export function useStartWorkflow(caseNumber: string | undefined) {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: () =>
|
||||
apiRequest<StartWorkflowResult>(
|
||||
`/api/cases/${caseNumber}/start-workflow`,
|
||||
{ method: "POST" },
|
||||
),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: casesKeys.all });
|
||||
if (caseNumber) {
|
||||
qc.invalidateQueries({ queryKey: casesKeys.detail(caseNumber) });
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useWorkflowStatus(caseNumber: string | undefined) {
|
||||
return useQuery({
|
||||
queryKey: [...casesKeys.all, "workflow", caseNumber ?? ""] as const,
|
||||
|
||||
Reference in New Issue
Block a user