577 lines
14 KiB
TypeScript
577 lines
14 KiB
TypeScript
import {
|
|
apiFetch,
|
|
apiReferenceOptionProvider,
|
|
type ApiSettings,
|
|
type ReferenceOptionProvider
|
|
} from "@govoplan/core-webui";
|
|
import type {
|
|
DefinitionGraph,
|
|
DefinitionGraphEdge,
|
|
DefinitionGraphNode,
|
|
DefinitionGraphNodeType
|
|
} from "@govoplan/core-webui/definition-graph";
|
|
|
|
export type WorkflowStatus = "draft" | "active" | "archived";
|
|
export type DefinitionScopeType = "system" | "tenant" | "group" | "user";
|
|
export type DefinitionKind = "flow" | "template";
|
|
export type WorkflowExecutionMode = "guided" | "automated" | "hybrid";
|
|
export type WorkflowStartOrigin =
|
|
| "user"
|
|
| "api"
|
|
| "schedule"
|
|
| "event"
|
|
| "parent_workflow"
|
|
| "dependency"
|
|
| "retry"
|
|
| "replay"
|
|
| "backfill";
|
|
export type WorkflowGraphNode = DefinitionGraphNode & {
|
|
size?: { width: number; height: number } | null;
|
|
parent_id?: string | null;
|
|
process_id?: string | null;
|
|
};
|
|
export type WorkflowGraphEdge = DefinitionGraphEdge & {
|
|
type:
|
|
| "bpmn.sequenceFlow"
|
|
| "bpmn.messageFlow"
|
|
| "bpmn.association"
|
|
| "bpmn.dataInputAssociation"
|
|
| "bpmn.dataOutputAssociation"
|
|
| "bpmn.conversationLink";
|
|
label: string;
|
|
config: Record<string, unknown>;
|
|
waypoints: Array<{ x: number; y: number }>;
|
|
};
|
|
export type WorkflowGraph = Omit<DefinitionGraph, "nodes" | "edges"> & {
|
|
schema_version: 1;
|
|
nodes: WorkflowGraphNode[];
|
|
edges: WorkflowGraphEdge[];
|
|
metadata: Record<string, unknown>;
|
|
};
|
|
|
|
export type WorkflowDiagnostic = {
|
|
severity: "error" | "warning";
|
|
code: string;
|
|
message: string;
|
|
node_id?: string | null;
|
|
field?: string | null;
|
|
};
|
|
|
|
export type WorkflowNodeType = DefinitionGraphNodeType;
|
|
|
|
export type BpmnRuntimeKind = "model_only" | "native_graph" | "external";
|
|
|
|
export type BpmnDiagnostic = {
|
|
severity: "error" | "warning" | "info";
|
|
code: string;
|
|
message: string;
|
|
element_id?: string | null;
|
|
};
|
|
|
|
export type BpmnAdapterProfile = {
|
|
id: string;
|
|
version: string;
|
|
label: string;
|
|
description: string;
|
|
conformance: string;
|
|
runtime_kind: BpmnRuntimeKind;
|
|
executable: boolean;
|
|
supported_elements: string[];
|
|
supported_event_definitions: string[];
|
|
requirements: string[];
|
|
};
|
|
|
|
export type BpmnInspection = {
|
|
valid_xml: boolean;
|
|
definitions_id?: string | null;
|
|
target_namespace?: string | null;
|
|
process_count: number;
|
|
executable_process_count: number;
|
|
collaboration_count: number;
|
|
choreography_count: number;
|
|
element_counts: Record<string, number>;
|
|
support_counts: Record<string, number>;
|
|
elements: Array<{
|
|
element_type: string;
|
|
element_id?: string | null;
|
|
name?: string | null;
|
|
parent_type?: string | null;
|
|
parent_id?: string | null;
|
|
support_level: "interchange_only" | "native_mapping" | "native_execution";
|
|
}>;
|
|
diagnostics: BpmnDiagnostic[];
|
|
adapter_id?: string | null;
|
|
adapter_version?: string | null;
|
|
runtime_kind?: BpmnRuntimeKind | null;
|
|
executable: boolean;
|
|
activatable: boolean;
|
|
};
|
|
|
|
export type BpmnRevisionSummary = {
|
|
format: "bpmn-2.0";
|
|
content_hash: string;
|
|
adapter_id: string;
|
|
adapter_version: string;
|
|
runtime_kind: BpmnRuntimeKind;
|
|
executable: boolean;
|
|
adapter_available: boolean;
|
|
};
|
|
|
|
export type BpmnRevisionDocument = BpmnRevisionSummary & {
|
|
definition_id: string;
|
|
revision: number;
|
|
xml: string;
|
|
inspection: BpmnInspection;
|
|
};
|
|
|
|
export type WorkflowRevision = {
|
|
id: string;
|
|
revision: number;
|
|
schema_version: number;
|
|
graph: WorkflowGraph;
|
|
content_hash: string;
|
|
library_id: string;
|
|
library_version: string;
|
|
execution_mode: WorkflowExecutionMode;
|
|
view_id?: string | null;
|
|
view_revision_id?: string | null;
|
|
bpmn?: BpmnRevisionSummary | null;
|
|
created_by?: string | null;
|
|
created_at: string;
|
|
};
|
|
|
|
export type WorkflowDefinition = {
|
|
id: string;
|
|
tenant_id: string | null;
|
|
key: string;
|
|
name: string;
|
|
description?: string | null;
|
|
status: WorkflowStatus;
|
|
current_revision: number;
|
|
active_revision?: number | null;
|
|
metadata: Record<string, unknown>;
|
|
created_by?: string | null;
|
|
updated_by?: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
revision: WorkflowRevision;
|
|
governance: WorkflowGovernance;
|
|
};
|
|
|
|
export type WorkflowActionDecision = {
|
|
allowed: boolean;
|
|
reason?: string | null;
|
|
source_path: Array<Record<string, unknown>>;
|
|
requirements: string[];
|
|
details: Record<string, unknown>;
|
|
};
|
|
|
|
export type WorkflowGovernance = {
|
|
scope_type: DefinitionScopeType;
|
|
scope_id?: string | null;
|
|
definition_kind: DefinitionKind;
|
|
inherit_to_lower_scopes: boolean;
|
|
allow_start: boolean;
|
|
allow_reuse: boolean;
|
|
allow_automation: boolean;
|
|
derived_from_definition_id?: string | null;
|
|
derived_from_revision?: number | null;
|
|
derived_from_hash?: string | null;
|
|
derivation_provenance: Record<string, unknown>;
|
|
actions: Record<string, WorkflowActionDecision>;
|
|
automation_runtime_available: boolean;
|
|
automation_runtime_reason?: string | null;
|
|
};
|
|
|
|
export type WorkflowInstanceStatus =
|
|
| "running"
|
|
| "waiting"
|
|
| "completed"
|
|
| "failed"
|
|
| "cancelled";
|
|
|
|
export type WorkflowStepStatus =
|
|
| "running"
|
|
| "waiting"
|
|
| "completed"
|
|
| "failed"
|
|
| "cancelled"
|
|
| "superseded";
|
|
|
|
export type WorkflowInstanceStep = {
|
|
id: string;
|
|
sequence: number;
|
|
node_id: string;
|
|
node_type: string;
|
|
status: WorkflowStepStatus;
|
|
attempt: number;
|
|
input: Record<string, unknown>;
|
|
output: Record<string, unknown>;
|
|
handoff: Record<string, unknown>;
|
|
external_ref?: string | null;
|
|
started_at?: string | null;
|
|
finished_at?: string | null;
|
|
error?: string | null;
|
|
completed_by?: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
};
|
|
|
|
export type WorkflowInstanceEvent = {
|
|
id: string;
|
|
sequence: number;
|
|
step_id?: string | null;
|
|
kind: string;
|
|
actor_id?: string | null;
|
|
payload: Record<string, unknown>;
|
|
created_at: string;
|
|
};
|
|
|
|
export type WorkflowInstance = {
|
|
id: string;
|
|
definition_id: string;
|
|
definition_name: string;
|
|
definition_revision: number;
|
|
definition_hash: string;
|
|
execution_mode: WorkflowExecutionMode;
|
|
start_origin: WorkflowStartOrigin;
|
|
view_context?: {
|
|
view_id: string;
|
|
revision_id?: string | null;
|
|
visible_surface_ids: string[];
|
|
step_id?: string | null;
|
|
node_id?: string | null;
|
|
} | null;
|
|
status: WorkflowInstanceStatus;
|
|
idempotency_key: string;
|
|
correlation_id?: string | null;
|
|
current_step_id?: string | null;
|
|
input: Record<string, unknown>;
|
|
context: Record<string, unknown>;
|
|
output: Record<string, unknown>;
|
|
started_at: string;
|
|
finished_at?: string | null;
|
|
cancellation_requested_at?: string | null;
|
|
error?: string | null;
|
|
created_by?: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
steps: WorkflowInstanceStep[];
|
|
events: WorkflowInstanceEvent[];
|
|
replayed: boolean;
|
|
};
|
|
|
|
export type WorkflowDefinitionPayload = {
|
|
name: string;
|
|
description?: string | null;
|
|
graph: WorkflowGraph;
|
|
bpmn?: {
|
|
xml: string;
|
|
adapter_id: string;
|
|
adapter_version?: string | null;
|
|
} | null;
|
|
metadata: Record<string, unknown>;
|
|
scope_type: DefinitionScopeType;
|
|
scope_id?: string | null;
|
|
definition_kind: DefinitionKind;
|
|
inherit_to_lower_scopes: boolean;
|
|
allow_start: boolean;
|
|
allow_reuse: boolean;
|
|
allow_automation: boolean;
|
|
execution_mode: WorkflowExecutionMode;
|
|
view_id?: string | null;
|
|
view_revision_id?: string | null;
|
|
};
|
|
|
|
export async function getBpmnSupportProfile(
|
|
settings: ApiSettings
|
|
): Promise<{
|
|
specification: string;
|
|
model_namespace: string;
|
|
interchange: string;
|
|
native_runtime: string;
|
|
native_execution_elements: string[];
|
|
native_mapping_elements: string[];
|
|
adapters: BpmnAdapterProfile[];
|
|
}> {
|
|
return apiFetch(settings, "/api/v1/workflow/bpmn/profile");
|
|
}
|
|
|
|
export function inspectWorkflowBpmn(
|
|
settings: ApiSettings,
|
|
payload: {
|
|
xml: string;
|
|
adapter_id: string;
|
|
adapter_version?: string | null;
|
|
activation?: boolean;
|
|
}
|
|
): Promise<BpmnInspection> {
|
|
return apiFetch(settings, "/api/v1/workflow/bpmn/inspect", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export function compileWorkflowBpmn(
|
|
settings: ApiSettings,
|
|
payload: {
|
|
xml: string;
|
|
adapter_id: string;
|
|
adapter_version?: string | null;
|
|
}
|
|
): Promise<{
|
|
adapter: BpmnAdapterProfile;
|
|
graph: WorkflowGraph;
|
|
inspection: BpmnInspection;
|
|
}> {
|
|
return apiFetch(settings, "/api/v1/workflow/bpmn/compile", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export function renderWorkflowBpmn(
|
|
settings: ApiSettings,
|
|
payload: { graph: WorkflowGraph; name?: string }
|
|
): Promise<{ xml: string; inspection: BpmnInspection }> {
|
|
return apiFetch(settings, "/api/v1/workflow/bpmn/render", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export async function listWorkflowNodeTypes(
|
|
settings: ApiSettings
|
|
): Promise<{ id: string; version: string; allows_cycles: boolean; nodes: WorkflowNodeType[] }> {
|
|
return apiFetch(settings, "/api/v1/workflow/node-types");
|
|
}
|
|
|
|
export async function listWorkflowDefinitions(
|
|
settings: ApiSettings
|
|
): Promise<WorkflowDefinition[]> {
|
|
const response = await apiFetch<{ definitions: WorkflowDefinition[] }>(
|
|
settings,
|
|
"/api/v1/workflow/definitions"
|
|
);
|
|
return response.definitions;
|
|
}
|
|
|
|
export function createWorkflowDefinition(
|
|
settings: ApiSettings,
|
|
payload: WorkflowDefinitionPayload
|
|
): Promise<WorkflowDefinition> {
|
|
return apiFetch(settings, "/api/v1/workflow/definitions", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export function updateWorkflowDefinition(
|
|
settings: ApiSettings,
|
|
definitionId: string,
|
|
payload: WorkflowDefinitionPayload & { expected_revision: number }
|
|
): Promise<WorkflowDefinition> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}`,
|
|
{
|
|
method: "PUT",
|
|
body: JSON.stringify(payload)
|
|
}
|
|
);
|
|
}
|
|
|
|
export function deriveWorkflowDefinition(
|
|
settings: ApiSettings,
|
|
definitionId: string,
|
|
payload: {
|
|
key?: string | null;
|
|
name: string;
|
|
description?: string | null;
|
|
source_revision?: number | null;
|
|
metadata: Record<string, unknown>;
|
|
scope_type: DefinitionScopeType;
|
|
scope_id?: string | null;
|
|
definition_kind: DefinitionKind;
|
|
inherit_to_lower_scopes: boolean;
|
|
allow_start: boolean;
|
|
allow_reuse: boolean;
|
|
allow_automation: boolean;
|
|
execution_mode?: WorkflowExecutionMode | null;
|
|
view_id?: string | null;
|
|
view_revision_id?: string | null;
|
|
}
|
|
): Promise<WorkflowDefinition> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/derive`,
|
|
{ method: "POST", body: JSON.stringify(payload) }
|
|
);
|
|
}
|
|
|
|
export async function listWorkflowRevisions(
|
|
settings: ApiSettings,
|
|
definitionId: string
|
|
): Promise<WorkflowRevision[]> {
|
|
const response = await apiFetch<{ revisions: WorkflowRevision[] }>(
|
|
settings,
|
|
`/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/revisions`
|
|
);
|
|
return response.revisions;
|
|
}
|
|
|
|
export function getWorkflowRevisionBpmn(
|
|
settings: ApiSettings,
|
|
definitionId: string,
|
|
revision: number
|
|
): Promise<BpmnRevisionDocument> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/revisions/${revision}/bpmn`
|
|
);
|
|
}
|
|
|
|
export function activateWorkflowDefinition(
|
|
settings: ApiSettings,
|
|
definitionId: string,
|
|
revision?: number
|
|
): Promise<WorkflowDefinition> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/activate`,
|
|
{
|
|
method: "POST",
|
|
body: JSON.stringify({ revision })
|
|
}
|
|
);
|
|
}
|
|
|
|
export function archiveWorkflowDefinition(
|
|
settings: ApiSettings,
|
|
definitionId: string
|
|
): Promise<WorkflowDefinition> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/archive`,
|
|
{ method: "POST" }
|
|
);
|
|
}
|
|
|
|
export function deleteWorkflowDefinition(
|
|
settings: ApiSettings,
|
|
definitionId: string
|
|
): Promise<{ deleted: boolean; definition_id: string }> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}`,
|
|
{ method: "DELETE" }
|
|
);
|
|
}
|
|
|
|
export function validateWorkflowDefinition(
|
|
settings: ApiSettings,
|
|
graph: WorkflowGraph
|
|
): Promise<{ valid: boolean; diagnostics: WorkflowDiagnostic[] }> {
|
|
return apiFetch(settings, "/api/v1/workflow/definitions/validate", {
|
|
method: "POST",
|
|
body: JSON.stringify({ graph })
|
|
});
|
|
}
|
|
|
|
export function workflowScopeReferenceProvider(
|
|
settings: ApiSettings,
|
|
scopeType: "user" | "group"
|
|
): ReferenceOptionProvider {
|
|
return apiReferenceOptionProvider(
|
|
settings,
|
|
"/api/v1/workflow/scope-targets",
|
|
{ scope_type: scopeType }
|
|
);
|
|
}
|
|
|
|
export async function listWorkflowInstances(
|
|
settings: ApiSettings,
|
|
definitionId?: string | null
|
|
): Promise<WorkflowInstance[]> {
|
|
const params = new URLSearchParams();
|
|
if (definitionId) params.set("definition_id", definitionId);
|
|
const query = params.size ? `?${params.toString()}` : "";
|
|
const response = await apiFetch<{ instances: WorkflowInstance[] }>(
|
|
settings,
|
|
`/api/v1/workflow/instances${query}`
|
|
);
|
|
return response.instances;
|
|
}
|
|
|
|
export function startWorkflowInstance(
|
|
settings: ApiSettings,
|
|
definitionId: string,
|
|
payload: {
|
|
idempotency_key: string;
|
|
input?: Record<string, unknown>;
|
|
correlation_id?: string | null;
|
|
}
|
|
): Promise<WorkflowInstance> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/instances`,
|
|
{
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
}
|
|
);
|
|
}
|
|
|
|
export function getWorkflowInstance(
|
|
settings: ApiSettings,
|
|
instanceId: string
|
|
): Promise<WorkflowInstance> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/workflow/instances/${encodeURIComponent(instanceId)}`
|
|
);
|
|
}
|
|
|
|
export function reconcileWorkflowInstance(
|
|
settings: ApiSettings,
|
|
instanceId: string
|
|
): Promise<WorkflowInstance> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/workflow/instances/${encodeURIComponent(instanceId)}/reconcile`,
|
|
{ method: "POST" }
|
|
);
|
|
}
|
|
|
|
export function resolveWorkflowStep(
|
|
settings: ApiSettings,
|
|
instanceId: string,
|
|
stepId: string,
|
|
payload: {
|
|
action: "complete" | "approve" | "changes" | "reject" | "resume" | "retry" | "cancel";
|
|
output?: Record<string, unknown>;
|
|
evidence?: string[];
|
|
comment?: string | null;
|
|
}
|
|
): Promise<WorkflowInstance> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/workflow/instances/${encodeURIComponent(instanceId)}/steps/${encodeURIComponent(stepId)}/actions`,
|
|
{
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
}
|
|
);
|
|
}
|
|
|
|
export function cancelWorkflowInstance(
|
|
settings: ApiSettings,
|
|
instanceId: string
|
|
): Promise<WorkflowInstance> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/workflow/instances/${encodeURIComponent(instanceId)}/cancel`,
|
|
{ method: "POST" }
|
|
);
|
|
}
|