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; waypoints: Array<{ x: number; y: number }>; }; export type WorkflowGraph = Omit & { schema_version: 1; nodes: WorkflowGraphNode[]; edges: WorkflowGraphEdge[]; metadata: Record; }; 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; support_counts: Record; 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; contribution_origin_module_version?: string | null; contribution_schema_version?: string | null; contribution_hash?: string | null; contribution_metadata: Record; created_by?: string | null; created_at: string; }; export type WorkflowStandardProvenance = { kind: "baseline" | "override"; origin_module_id: string; origin_module_version?: string | null; definition_key: string; contribution_schema_version?: string | null; contribution_hash?: string | null; baseline_definition_id: string; latest_baseline_revision: number; active_baseline_revision?: number | null; pinned_baseline_revision?: number | null; pinned_baseline_hash?: string | null; update_available: boolean; reset_available: boolean; }; export type WorkflowStandardDiffItem = { resource_type: "graph" | "node" | "edge"; resource_id: string; state: "unchanged" | "local_only" | "upstream_only" | "same_change" | "conflict"; recommended_action: "none" | "keep_local" | "adopt_upstream" | "either" | "manual_resolution"; changed_fields: string[]; baseline?: Record | null; local?: Record | null; latest?: Record | null; }; export type WorkflowStandardDiff = { override_definition_id: string; baseline_definition_id: string; pinned_baseline_revision: number; local_revision: number; latest_baseline_revision: number; counts: Record; conflict_count: number; auto_mergeable: boolean; items: WorkflowStandardDiffItem[]; }; 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; created_by?: string | null; updated_by?: string | null; created_at: string; updated_at: string; revision: WorkflowRevision; governance: WorkflowGovernance; standard?: WorkflowStandardProvenance | null; }; export type WorkflowActionDecision = { allowed: boolean; reason?: string | null; source_path: Array>; requirements: string[]; details: Record; }; 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; actions: Record; 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; output: Record; handoff: Record; 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; 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; context: Record; output: Record; 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; 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 { 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 { const response = await apiFetch<{ definitions: WorkflowDefinition[] }>( settings, "/api/v1/workflow/definitions" ); return response.definitions; } export function createWorkflowDefinition( settings: ApiSettings, payload: WorkflowDefinitionPayload ): Promise { 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 { 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; 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 { return apiFetch( settings, `/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/derive`, { method: "POST", body: JSON.stringify(payload) } ); } export function reconcileWorkflowStandards( settings: ApiSettings ): Promise<{ discovered: number; created: number; updated: number; unchanged: number; blocked: number; pending_tenant_scope: number; items: Array>; }> { return apiFetch(settings, "/api/v1/workflow/standards/reconcile", { method: "POST" }); } export function resetWorkflowDefinitionToStandard( settings: ApiSettings, definitionId: string ): Promise { return apiFetch( settings, `/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/reset-standard`, { method: "POST" } ); } export function compareWorkflowDefinitionToStandard( settings: ApiSettings, definitionId: string ): Promise { return apiFetch( settings, `/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/standard-diff` ); } export async function listWorkflowRevisions( settings: ApiSettings, definitionId: string ): Promise { const response = await apiFetch<{ revisions: WorkflowRevision[] }>( settings, `/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/revisions` ); return response.revisions; } export function getWorkflowRevision( settings: ApiSettings, definitionId: string, revision: number ): Promise { return apiFetch( settings, `/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/revisions/${revision}` ); } export function getWorkflowRevisionBpmn( settings: ApiSettings, definitionId: string, revision: number ): Promise { return apiFetch( settings, `/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/revisions/${revision}/bpmn` ); } export function activateWorkflowDefinition( settings: ApiSettings, definitionId: string, revision?: number ): Promise { return apiFetch( settings, `/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/activate`, { method: "POST", body: JSON.stringify({ revision }) } ); } export function archiveWorkflowDefinition( settings: ApiSettings, definitionId: string ): Promise { 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 { 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; correlation_id?: string | null; } ): Promise { return apiFetch( settings, `/api/v1/workflow/definitions/${encodeURIComponent(definitionId)}/instances`, { method: "POST", body: JSON.stringify(payload) } ); } export function getWorkflowInstance( settings: ApiSettings, instanceId: string ): Promise { return apiFetch( settings, `/api/v1/workflow/instances/${encodeURIComponent(instanceId)}` ); } export function reconcileWorkflowInstance( settings: ApiSettings, instanceId: string ): Promise { 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" | "confirm_effect" | "confirm_absent" | "cancel"; output?: Record; evidence?: string[]; comment?: string | null; } ): Promise { 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 { return apiFetch( settings, `/api/v1/workflow/instances/${encodeURIComponent(instanceId)}/cancel`, { method: "POST" } ); }