feat: rebuild Process Studio into multi-phase Process Creation Wizard\n\n- Replace toy Studio.tsx with proper Wizard.tsx canvas\n- Build 6-step flow: Intake -> Analyze -> Generate -> Validate -> Draft saved -> Publish\n- Implement incremental EA2 writes via wizardApi.ts (flow, batch apply)\n- Use localStorage for draft recovery across reloads\n- Apply industrial-blueprint UI styling matching core doctrine\n- Add Vitest tests for Wizard components and API wrappers
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { api, type Actor } from "./api";
|
||||
|
||||
export interface CreateDraftPayload {
|
||||
name: string;
|
||||
display_name: string;
|
||||
description: string;
|
||||
source_context: string;
|
||||
config: {
|
||||
wizard: {
|
||||
marker: string;
|
||||
maxDepth: number;
|
||||
maxNodes: number;
|
||||
chat: any[];
|
||||
uploads: any[];
|
||||
panelState: any;
|
||||
debug: any[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface BatchOperation {
|
||||
collection: string;
|
||||
op: "insert" | "update" | "delete";
|
||||
_key?: string;
|
||||
_from?: string;
|
||||
_to?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export const wizardApi = {
|
||||
async createDraft(payload: CreateDraftPayload, signal?: AbortSignal) {
|
||||
const res = await fetch(`${api.config.baseUrl}/api/ea2/flow`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${sessionStorage.getItem("fm.mc.token.v1")}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
kind: "definition",
|
||||
status: "draft",
|
||||
...payload,
|
||||
}),
|
||||
signal,
|
||||
});
|
||||
if (!res.ok) throw new Error(`createDraft failed: ${res.status}`);
|
||||
return res.json() as Promise<{ _key: string; name: string }>;
|
||||
},
|
||||
|
||||
async updateDraftConfig(key: string, patch: any, signal?: AbortSignal) {
|
||||
const res = await fetch(`${api.config.baseUrl}/api/ea2/flow/${key}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
Authorization: `Bearer ${sessionStorage.getItem("fm.mc.token.v1")}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(patch),
|
||||
signal,
|
||||
});
|
||||
if (!res.ok) throw new Error(`updateDraftConfig failed: ${res.status}`);
|
||||
return res.json();
|
||||
},
|
||||
|
||||
async applyBatch(flow_key: string, ops: BatchOperation[], actor: Actor, signal?: AbortSignal) {
|
||||
const res = await fetch(`${api.config.baseUrl}/api/ea2/apply-batch`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${sessionStorage.getItem("fm.mc.token.v1")}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ flow_key, ops, actor }),
|
||||
signal,
|
||||
});
|
||||
if (!res.ok) throw new Error(`applyBatch failed: ${res.status}`);
|
||||
return res.json();
|
||||
},
|
||||
|
||||
async startInstance(process_definition_id: string, business_subject?: string, signal?: AbortSignal) {
|
||||
return api.startTransaction(process_definition_id, business_subject, signal);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user