feat: persist and edit versioned workflow definitions
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
import { apiFetch, type ApiSettings } from "@govoplan/core-webui";
|
||||
import type {
|
||||
DefinitionGraph,
|
||||
DefinitionGraphNode,
|
||||
DefinitionGraphNodeType
|
||||
} from "@govoplan/core-webui/definition-graph";
|
||||
|
||||
export type WorkflowStatus = "draft" | "active" | "archived";
|
||||
export type WorkflowGraphNode = DefinitionGraphNode;
|
||||
export type WorkflowGraph = DefinitionGraph & {
|
||||
schema_version: 1;
|
||||
nodes: WorkflowGraphNode[];
|
||||
};
|
||||
|
||||
export type WorkflowDiagnostic = {
|
||||
severity: "error" | "warning";
|
||||
code: string;
|
||||
message: string;
|
||||
node_id?: string | null;
|
||||
field?: string | null;
|
||||
};
|
||||
|
||||
export type WorkflowNodeType = DefinitionGraphNodeType;
|
||||
|
||||
export type WorkflowRevision = {
|
||||
id: string;
|
||||
revision: number;
|
||||
schema_version: number;
|
||||
graph: WorkflowGraph;
|
||||
content_hash: string;
|
||||
library_id: string;
|
||||
library_version: string;
|
||||
created_by?: string | null;
|
||||
created_at: string;
|
||||
};
|
||||
|
||||
export type WorkflowDefinition = {
|
||||
id: string;
|
||||
tenant_id: string;
|
||||
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;
|
||||
};
|
||||
|
||||
export type WorkflowDefinitionPayload = {
|
||||
name: string;
|
||||
description?: string | null;
|
||||
graph: WorkflowGraph;
|
||||
metadata: Record<string, unknown>;
|
||||
};
|
||||
|
||||
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 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 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 })
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user