feat(wizard): produce fully startable EA2 flows
Reverse-engineered the EA2 runtime startability contract by diffing
pr_to_po_def (startable) against wizard-created drafts (500). Minimum
shape required:
Parent flow (kind=definition, status=published)
+ Step flow (kind=definition, status=published, dispatch_kind=human)
+ View doc (kind=definition, status=active, layout={fields,layout:form})
+ Version doc (kind=definition, status=active)
+ defines edge: parent -> step (role=child)
+ defines edge: step -> step (role=dispatch self-edge)
+ defines edge: step -> view (role=presentation)
+ governs edge collection 'governs': version -> parent (role=governs)
wizardApi.ops gains: createView, createVersion, childEdge, dispatchEdge,
presentationEdge, governsEdge. createStepEdge renamed to childEdge to
reflect the actual EA2 role. Steps now create with status=published
(was draft) so they're visible to the runtime.
Wizard.handleStructureSave emits all of the above in two apply-batches
(creates then wires). Verified live: posted a probe flow with this
contract, /api/runtime/transactions returned 200 + a running
transaction with step_run_id.
This commit is contained in:
+69
-3
@@ -130,7 +130,7 @@ export const wizardApi = {
|
||||
kind: "definition",
|
||||
name,
|
||||
display_name: node.display_name,
|
||||
status: "draft",
|
||||
status: "published",
|
||||
description: node.description || node.display_name,
|
||||
source_context: "EA2_WIZARD_STEP",
|
||||
dispatch_kind: node.dispatch_kind,
|
||||
@@ -138,13 +138,79 @@ export const wizardApi = {
|
||||
},
|
||||
};
|
||||
},
|
||||
createStepEdge(parentFlowKey: string, childFlowKey: string): CreateEdgeOp {
|
||||
createView(node: { display_name: string }): CreateOp {
|
||||
const name = `${node.display_name.toLowerCase().replace(/[^a-z0-9]+/g, "_").slice(0, 40) || "view"}_view`;
|
||||
return {
|
||||
op: "create",
|
||||
coll: "view",
|
||||
data: {
|
||||
kind: "definition",
|
||||
name,
|
||||
label: `${node.display_name} · form`,
|
||||
status: "active",
|
||||
description: null,
|
||||
source_context: null,
|
||||
channel: "web",
|
||||
layout: {
|
||||
layout: "form",
|
||||
fields: [
|
||||
{ name: "notes", label: "Notes", type: "textarea", required: false, description: "Notes" },
|
||||
],
|
||||
},
|
||||
actions: [{ label: "Submit", action: "submit" }],
|
||||
},
|
||||
};
|
||||
},
|
||||
createVersion(parentDisplayName: string): CreateOp {
|
||||
const name = `${parentDisplayName.toLowerCase().replace(/[^a-z0-9]+/g, "_").slice(0, 40) || "process"}_v1`;
|
||||
return {
|
||||
op: "create",
|
||||
coll: "version",
|
||||
data: {
|
||||
kind: "definition",
|
||||
name,
|
||||
label: "v1",
|
||||
status: "active",
|
||||
change_description: `Initial publish of ${parentDisplayName}`,
|
||||
legal_entity: "canvas",
|
||||
source_context: "EA2_WIZARD_VERSION",
|
||||
},
|
||||
};
|
||||
},
|
||||
childEdge(parentFlowKey: string, childFlowKey: string): CreateEdgeOp {
|
||||
return {
|
||||
op: "create_edge",
|
||||
edge_coll: "defines",
|
||||
from: `flow/${parentFlowKey}`,
|
||||
to: `flow/${childFlowKey}`,
|
||||
role: "next",
|
||||
role: "child",
|
||||
};
|
||||
},
|
||||
dispatchEdge(stepFlowKey: string): CreateEdgeOp {
|
||||
return {
|
||||
op: "create_edge",
|
||||
edge_coll: "defines",
|
||||
from: `flow/${stepFlowKey}`,
|
||||
to: `flow/${stepFlowKey}`,
|
||||
role: "dispatch",
|
||||
};
|
||||
},
|
||||
presentationEdge(stepFlowKey: string, viewKey: string): CreateEdgeOp {
|
||||
return {
|
||||
op: "create_edge",
|
||||
edge_coll: "defines",
|
||||
from: `flow/${stepFlowKey}`,
|
||||
to: `view/${viewKey}`,
|
||||
role: "presentation",
|
||||
};
|
||||
},
|
||||
governsEdge(versionKey: string, parentFlowKey: string): CreateEdgeOp {
|
||||
return {
|
||||
op: "create_edge",
|
||||
edge_coll: "governs",
|
||||
from: `version/${versionKey}`,
|
||||
to: `flow/${parentFlowKey}`,
|
||||
role: "governs",
|
||||
};
|
||||
},
|
||||
publishFlow(flowKey: string): UpdateOp {
|
||||
|
||||
Reference in New Issue
Block a user