1151 lines
37 KiB
Python
1151 lines
37 KiB
Python
from __future__ import annotations
|
|
|
|
from govoplan_core.core.definition_graphs import (
|
|
DefinitionConfigField,
|
|
DefinitionGraphConstraints,
|
|
DefinitionGraphLibrary,
|
|
DefinitionNodeType,
|
|
DefinitionPort,
|
|
)
|
|
|
|
|
|
CATEGORY_LABELS = {
|
|
"bpmn_event": "Events",
|
|
"bpmn_activity": "Activities",
|
|
"bpmn_gateway": "Gateways",
|
|
"bpmn_data": "Data",
|
|
"bpmn_collaboration": "Collaboration",
|
|
"bpmn_artifact": "Artifacts",
|
|
"trigger": "Start",
|
|
"activity": "Activities",
|
|
"decision": "Decisions",
|
|
"wait": "Wait",
|
|
"integration": "Integrations",
|
|
"outcome": "Outcomes",
|
|
}
|
|
|
|
FOCUSED_VIEW_SURFACES_FIELD = DefinitionConfigField(
|
|
id="view_surface_ids",
|
|
label="Focused View surfaces",
|
|
kind="view_surfaces",
|
|
description=(
|
|
"Optionally narrow the workflow View while this step requires "
|
|
"attention. Administrator limits and protected surfaces still apply."
|
|
),
|
|
)
|
|
|
|
LEGACY_WORKFLOW_NODE_TYPES = (
|
|
DefinitionNodeType(
|
|
type="workflow.start.manual",
|
|
category="trigger",
|
|
label="Manual start",
|
|
description="Start an instance through an explicit user action.",
|
|
icon="circle-play",
|
|
default_config={"input_schema_ref": ""},
|
|
config_fields=(
|
|
DefinitionConfigField(
|
|
id="input_schema_ref",
|
|
label="Input schema",
|
|
kind="text",
|
|
description="Optional schema contract for instance input.",
|
|
),
|
|
),
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.start.api",
|
|
category="trigger",
|
|
label="API start",
|
|
description=(
|
|
"Start through an authenticated API request with an explicit "
|
|
"input contract."
|
|
),
|
|
icon="braces",
|
|
default_config={
|
|
"input_schema_ref": "",
|
|
"authorization_policy_ref": "",
|
|
},
|
|
config_fields=(
|
|
DefinitionConfigField(
|
|
id="input_schema_ref",
|
|
label="Input schema",
|
|
kind="text",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(
|
|
id="authorization_policy_ref",
|
|
label="Authorization policy",
|
|
kind="text",
|
|
required=True,
|
|
),
|
|
),
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.start.workflow",
|
|
category="trigger",
|
|
label="Parent workflow",
|
|
description=(
|
|
"Start as a pinned child or dependency of another Workflow "
|
|
"instance."
|
|
),
|
|
icon="git-branch",
|
|
default_config={
|
|
"parent_definition_ref": "",
|
|
"parent_outcome": "completed",
|
|
"input_mapping": {},
|
|
},
|
|
config_fields=(
|
|
DefinitionConfigField(
|
|
id="parent_definition_ref",
|
|
label="Parent definition",
|
|
kind="text",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(
|
|
id="parent_outcome",
|
|
label="Parent outcome",
|
|
kind="text",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(
|
|
id="input_mapping",
|
|
label="Input mapping",
|
|
kind="mapping",
|
|
),
|
|
),
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.start.event",
|
|
category="trigger",
|
|
label="Event start",
|
|
description="Start when a matching platform event is received.",
|
|
icon="radio",
|
|
config_fields=(
|
|
DefinitionConfigField(
|
|
id="event_type",
|
|
label="Event type",
|
|
kind="text",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(
|
|
id="filter",
|
|
label="Event filter",
|
|
kind="expression",
|
|
description="A constrained expression evaluated against the event envelope.",
|
|
),
|
|
),
|
|
default_config={"event_type": "", "filter": ""},
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.start.schedule",
|
|
category="trigger",
|
|
label="Scheduled start",
|
|
description="Start according to a governed schedule.",
|
|
icon="calendar-clock",
|
|
config_fields=(
|
|
DefinitionConfigField(
|
|
id="schedule",
|
|
label="Schedule",
|
|
kind="schedule",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(
|
|
id="timezone",
|
|
label="Time zone",
|
|
kind="timezone",
|
|
required=True,
|
|
),
|
|
),
|
|
default_config={"schedule": "", "timezone": "Europe/Berlin"},
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.activity",
|
|
category="activity",
|
|
label="Activity",
|
|
description="Record and complete a governed unit of work.",
|
|
icon="square-check-big",
|
|
input_ports=(DefinitionPort(id="input", label="Input"),),
|
|
config_fields=(
|
|
DefinitionConfigField(id="title", label="Title", kind="text", required=True),
|
|
DefinitionConfigField(id="instructions", label="Instructions", kind="textarea"),
|
|
DefinitionConfigField(id="assignee", label="Assignee", kind="subject"),
|
|
DefinitionConfigField(id="due_after", label="Due after", kind="duration"),
|
|
FOCUSED_VIEW_SURFACES_FIELD,
|
|
),
|
|
default_config={
|
|
"title": "",
|
|
"instructions": "",
|
|
"assignee": "",
|
|
"due_after": "",
|
|
"view_surface_ids": [],
|
|
},
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.review",
|
|
category="activity",
|
|
label="Review",
|
|
description="Pause for a human review with explicit outcomes.",
|
|
icon="clipboard-check",
|
|
input_ports=(DefinitionPort(id="input", label="Input"),),
|
|
output_ports=(
|
|
DefinitionPort(id="approved", label="Approved", required=False),
|
|
DefinitionPort(id="changes", label="Changes requested", required=False),
|
|
DefinitionPort(id="rejected", label="Rejected", required=False),
|
|
),
|
|
config_fields=(
|
|
DefinitionConfigField(id="title", label="Title", kind="text", required=True),
|
|
DefinitionConfigField(id="reviewer", label="Reviewer", kind="subject"),
|
|
DefinitionConfigField(
|
|
id="required_evidence",
|
|
label="Required evidence",
|
|
kind="string_list",
|
|
),
|
|
FOCUSED_VIEW_SURFACES_FIELD,
|
|
),
|
|
default_config={
|
|
"title": "",
|
|
"reviewer": "",
|
|
"required_evidence": [],
|
|
"view_surface_ids": [],
|
|
},
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.decision",
|
|
category="decision",
|
|
label="Decision",
|
|
description="Choose a path using a constrained expression.",
|
|
icon="split",
|
|
input_ports=(DefinitionPort(id="input", label="Input"),),
|
|
output_ports=(
|
|
DefinitionPort(id="true", label="Matches", required=False),
|
|
DefinitionPort(id="false", label="Does not match", required=False),
|
|
),
|
|
config_fields=(
|
|
DefinitionConfigField(
|
|
id="expression",
|
|
label="Expression",
|
|
kind="expression",
|
|
required=True,
|
|
),
|
|
),
|
|
default_config={"expression": ""},
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.wait",
|
|
category="wait",
|
|
label="Wait",
|
|
description="Wait for a duration, deadline, event, or explicit resume action.",
|
|
icon="timer",
|
|
input_ports=(DefinitionPort(id="input", label="Input"),),
|
|
output_ports=(
|
|
DefinitionPort(id="resumed", label="Resumed", required=False),
|
|
DefinitionPort(id="timed_out", label="Timed out", required=False),
|
|
),
|
|
config_fields=(
|
|
DefinitionConfigField(
|
|
id="mode",
|
|
label="Wait for",
|
|
kind="select",
|
|
required=True,
|
|
options=(
|
|
("duration", "Duration"),
|
|
("deadline", "Deadline"),
|
|
("event", "Event"),
|
|
("manual", "Manual resume"),
|
|
),
|
|
),
|
|
DefinitionConfigField(id="value", label="Value", kind="text"),
|
|
FOCUSED_VIEW_SURFACES_FIELD,
|
|
),
|
|
default_config={
|
|
"mode": "manual",
|
|
"value": "",
|
|
"view_surface_ids": [],
|
|
},
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.capability",
|
|
category="integration",
|
|
label="Module action",
|
|
description="Invoke a versioned module capability without importing its implementation.",
|
|
icon="plug-zap",
|
|
input_ports=(DefinitionPort(id="input", label="Input"),),
|
|
output_ports=(
|
|
DefinitionPort(id="success", label="Success", required=False),
|
|
DefinitionPort(id="warning", label="Warning", required=False),
|
|
DefinitionPort(
|
|
id="review_required",
|
|
label="Review required",
|
|
required=False,
|
|
),
|
|
DefinitionPort(id="failure", label="Failure", required=False),
|
|
),
|
|
config_fields=(
|
|
DefinitionConfigField(
|
|
id="capability",
|
|
label="Capability",
|
|
kind="capability",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(
|
|
id="operation",
|
|
label="Operation",
|
|
kind="text",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(id="input_mapping", label="Input mapping", kind="mapping"),
|
|
DefinitionConfigField(
|
|
id="idempotency_key",
|
|
label="Idempotency key",
|
|
kind="expression",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(
|
|
id="failure_policy",
|
|
label="On failure",
|
|
kind="select",
|
|
required=True,
|
|
options=(
|
|
("retry", "Retry"),
|
|
("manual", "Require intervention"),
|
|
("continue", "Continue on failure"),
|
|
),
|
|
),
|
|
FOCUSED_VIEW_SURFACES_FIELD,
|
|
),
|
|
default_config={
|
|
"capability": "",
|
|
"operation": "",
|
|
"input_mapping": {},
|
|
"idempotency_key": "workflow-step",
|
|
"failure_policy": "manual",
|
|
"view_surface_ids": [],
|
|
},
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.dataflow",
|
|
category="integration",
|
|
label="Run dataflow",
|
|
description="Run a published Dataflow pipeline and retain its output reference.",
|
|
icon="waypoints",
|
|
input_ports=(DefinitionPort(id="input", label="Input"),),
|
|
output_ports=(
|
|
DefinitionPort(id="success", label="Success", required=False),
|
|
DefinitionPort(id="warning", label="Warning", required=False),
|
|
DefinitionPort(
|
|
id="review_required",
|
|
label="Review required",
|
|
required=False,
|
|
),
|
|
DefinitionPort(id="failure", label="Failure", required=False),
|
|
),
|
|
config_fields=(
|
|
DefinitionConfigField(
|
|
id="pipeline_ref",
|
|
label="Pipeline",
|
|
kind="dataflow",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(
|
|
id="revision",
|
|
label="Pinned revision",
|
|
kind="number",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(
|
|
id="environment",
|
|
label="Environment",
|
|
kind="select",
|
|
required=True,
|
|
options=(
|
|
("development", "Development"),
|
|
("staging", "Staging"),
|
|
("production", "Production"),
|
|
),
|
|
),
|
|
DefinitionConfigField(
|
|
id="row_limit",
|
|
label="Output row limit",
|
|
kind="number",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(
|
|
id="publication_target_ref",
|
|
label="Publication datasource",
|
|
kind="text",
|
|
description=(
|
|
"Optional stable Datasource target for materialized "
|
|
"output."
|
|
),
|
|
),
|
|
DefinitionConfigField(
|
|
id="warning_policy",
|
|
label="Warnings",
|
|
kind="select",
|
|
required=True,
|
|
options=(
|
|
("review", "Require review"),
|
|
("continue", "Continue"),
|
|
),
|
|
),
|
|
DefinitionConfigField(
|
|
id="failure_policy",
|
|
label="Failures",
|
|
kind="select",
|
|
options=(
|
|
("manual", "Require intervention"),
|
|
("fail", "Fail the workflow"),
|
|
("continue", "Follow failure path"),
|
|
),
|
|
),
|
|
DefinitionConfigField(id="input_mapping", label="Input mapping", kind="mapping"),
|
|
FOCUSED_VIEW_SURFACES_FIELD,
|
|
),
|
|
default_config={
|
|
"pipeline_ref": "",
|
|
"revision": 1,
|
|
"environment": "development",
|
|
"row_limit": 500,
|
|
"publication_target_ref": "",
|
|
"warning_policy": "review",
|
|
"failure_policy": "manual",
|
|
"input_mapping": {},
|
|
"view_surface_ids": [],
|
|
},
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.end.completed",
|
|
category="outcome",
|
|
label="Completed",
|
|
description="Complete the workflow successfully.",
|
|
icon="circle-check-big",
|
|
input_ports=(
|
|
DefinitionPort(
|
|
id="input",
|
|
label="Input",
|
|
multiple=True,
|
|
minimum_connections=1,
|
|
),
|
|
),
|
|
output_ports=(),
|
|
config_fields=(
|
|
DefinitionConfigField(id="output_mapping", label="Output mapping", kind="mapping"),
|
|
),
|
|
default_config={"output_mapping": {}},
|
|
),
|
|
DefinitionNodeType(
|
|
type="workflow.end.cancelled",
|
|
category="outcome",
|
|
label="Cancelled",
|
|
description="End the workflow without a successful outcome.",
|
|
icon="circle-x",
|
|
input_ports=(
|
|
DefinitionPort(
|
|
id="input",
|
|
label="Input",
|
|
multiple=True,
|
|
minimum_connections=1,
|
|
),
|
|
),
|
|
output_ports=(),
|
|
config_fields=(
|
|
DefinitionConfigField(id="reason", label="Reason", kind="text"),
|
|
),
|
|
default_config={"reason": ""},
|
|
),
|
|
)
|
|
|
|
_INCOMING = (
|
|
DefinitionPort(
|
|
id="incoming",
|
|
label="Incoming",
|
|
required=False,
|
|
multiple=True,
|
|
minimum_connections=0,
|
|
),
|
|
)
|
|
_OPTIONAL_INCOMING = (
|
|
DefinitionPort(
|
|
id="incoming",
|
|
label="Incoming",
|
|
required=False,
|
|
multiple=True,
|
|
minimum_connections=0,
|
|
),
|
|
)
|
|
_OUTGOING = (
|
|
DefinitionPort(
|
|
id="outgoing",
|
|
label="Outgoing",
|
|
required=False,
|
|
multiple=True,
|
|
minimum_connections=0,
|
|
),
|
|
)
|
|
_DOCUMENTATION_FIELD = DefinitionConfigField(
|
|
id="documentation",
|
|
label="Documentation",
|
|
kind="textarea",
|
|
)
|
|
_EVENT_DEFINITION_FIELD = DefinitionConfigField(
|
|
id="event_definition",
|
|
label="Event definition",
|
|
kind="select",
|
|
options=(
|
|
("none", "None"),
|
|
("message", "Message"),
|
|
("timer", "Timer"),
|
|
("conditional", "Conditional"),
|
|
("signal", "Signal"),
|
|
("error", "Error"),
|
|
("escalation", "Escalation"),
|
|
("compensation", "Compensation"),
|
|
("link", "Link"),
|
|
("cancel", "Cancel"),
|
|
("terminate", "Terminate"),
|
|
("multiple", "Multiple"),
|
|
("parallelMultiple", "Parallel multiple"),
|
|
),
|
|
)
|
|
|
|
|
|
def _bpmn_node(
|
|
*,
|
|
type_id: str,
|
|
category: str,
|
|
label: str,
|
|
description: str,
|
|
icon: str,
|
|
shape: str,
|
|
input_ports: tuple[DefinitionPort, ...] = _INCOMING,
|
|
output_ports: tuple[DefinitionPort, ...] = _OUTGOING,
|
|
config_fields: tuple[DefinitionConfigField, ...] = (),
|
|
default_config: dict[str, object] | None = None,
|
|
runtime_support: str = "model_only",
|
|
) -> DefinitionNodeType:
|
|
return DefinitionNodeType(
|
|
type=type_id,
|
|
category=category,
|
|
label=label,
|
|
description=description,
|
|
icon=icon,
|
|
input_ports=input_ports,
|
|
output_ports=output_ports,
|
|
config_fields=(*config_fields, _DOCUMENTATION_FIELD),
|
|
default_config={
|
|
**(default_config or {}),
|
|
"documentation": "",
|
|
},
|
|
metadata={
|
|
"notation": "bpmn-2.0",
|
|
"shape": shape,
|
|
"runtime_support": runtime_support,
|
|
},
|
|
)
|
|
|
|
|
|
_TASK_FIELDS = (
|
|
DefinitionConfigField(id="title", label="Task title", kind="text"),
|
|
DefinitionConfigField(id="instructions", label="Instructions", kind="textarea"),
|
|
)
|
|
_HUMAN_TASK_FIELDS = (
|
|
*_TASK_FIELDS,
|
|
DefinitionConfigField(id="assignee", label="Assignee", kind="subject"),
|
|
DefinitionConfigField(id="due_after", label="Due after", kind="duration"),
|
|
FOCUSED_VIEW_SURFACES_FIELD,
|
|
)
|
|
_SERVICE_TASK_FIELDS = (
|
|
*_TASK_FIELDS,
|
|
DefinitionConfigField(
|
|
id="implementation",
|
|
label="Implementation",
|
|
kind="select",
|
|
options=(
|
|
("capability", "Module capability"),
|
|
("dataflow", "Dataflow"),
|
|
),
|
|
),
|
|
DefinitionConfigField(id="capability", label="Capability", kind="capability"),
|
|
DefinitionConfigField(id="operation", label="Operation", kind="text"),
|
|
DefinitionConfigField(id="pipeline_ref", label="Dataflow", kind="dataflow"),
|
|
DefinitionConfigField(id="input_mapping", label="Input mapping", kind="mapping"),
|
|
DefinitionConfigField(
|
|
id="idempotency_key",
|
|
label="Idempotency key",
|
|
kind="expression",
|
|
),
|
|
DefinitionConfigField(
|
|
id="failure_policy",
|
|
label="On failure",
|
|
kind="select",
|
|
options=(
|
|
("retry", "Retry"),
|
|
("manual", "Require intervention"),
|
|
("continue", "Continue"),
|
|
("fail", "Fail the workflow"),
|
|
),
|
|
),
|
|
FOCUSED_VIEW_SURFACES_FIELD,
|
|
)
|
|
|
|
BPMN_NODE_TYPES = (
|
|
_bpmn_node(
|
|
type_id="bpmn.startEvent",
|
|
category="bpmn_event",
|
|
label="Start event",
|
|
description="Start a BPMN process from a user, API, schedule, event, or parent flow.",
|
|
icon="circle-play",
|
|
shape="event-start",
|
|
input_ports=(),
|
|
config_fields=(
|
|
_EVENT_DEFINITION_FIELD,
|
|
DefinitionConfigField(
|
|
id="start_kind",
|
|
label="GovOPlaN start",
|
|
kind="select",
|
|
required=True,
|
|
options=(
|
|
("manual", "Manual"),
|
|
("api", "API"),
|
|
("schedule", "Schedule"),
|
|
("event", "Platform event"),
|
|
("parent_workflow", "Parent workflow"),
|
|
),
|
|
),
|
|
DefinitionConfigField(
|
|
id="input_schema_ref",
|
|
label="Input schema",
|
|
kind="text",
|
|
),
|
|
DefinitionConfigField(
|
|
id="authorization_policy_ref",
|
|
label="Authorization policy",
|
|
kind="text",
|
|
),
|
|
DefinitionConfigField(id="schedule", label="Schedule", kind="schedule"),
|
|
DefinitionConfigField(id="timezone", label="Time zone", kind="timezone"),
|
|
DefinitionConfigField(id="event_type", label="Event type", kind="text"),
|
|
DefinitionConfigField(id="filter", label="Event filter", kind="expression"),
|
|
),
|
|
default_config={
|
|
"event_definition": "none",
|
|
"start_kind": "manual",
|
|
"input_schema_ref": "",
|
|
"authorization_policy_ref": "",
|
|
"schedule": "",
|
|
"timezone": "Europe/Berlin",
|
|
"event_type": "",
|
|
"filter": "",
|
|
},
|
|
runtime_support="native",
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.intermediateCatchEvent",
|
|
category="bpmn_event",
|
|
label="Intermediate catch event",
|
|
description="Wait until the configured BPMN event is caught.",
|
|
icon="circle-dot",
|
|
shape="event-intermediate-catch",
|
|
config_fields=(
|
|
_EVENT_DEFINITION_FIELD,
|
|
DefinitionConfigField(
|
|
id="wait_mode",
|
|
label="Wait for",
|
|
kind="select",
|
|
options=(
|
|
("duration", "Duration"),
|
|
("deadline", "Deadline"),
|
|
("event", "Event"),
|
|
("manual", "Manual resume"),
|
|
),
|
|
),
|
|
DefinitionConfigField(id="value", label="Value", kind="text"),
|
|
DefinitionConfigField(id="event_ref", label="Event reference", kind="text"),
|
|
FOCUSED_VIEW_SURFACES_FIELD,
|
|
),
|
|
default_config={
|
|
"event_definition": "none",
|
|
"wait_mode": "manual",
|
|
"value": "",
|
|
"event_ref": "",
|
|
"view_surface_ids": [],
|
|
},
|
|
runtime_support="native",
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.intermediateThrowEvent",
|
|
category="bpmn_event",
|
|
label="Intermediate throw event",
|
|
description="Emit an intermediate BPMN event.",
|
|
icon="circle-dot-dashed",
|
|
shape="event-intermediate-throw",
|
|
config_fields=(
|
|
_EVENT_DEFINITION_FIELD,
|
|
DefinitionConfigField(id="event_ref", label="Event reference", kind="text"),
|
|
),
|
|
default_config={"event_definition": "none", "event_ref": ""},
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.boundaryEvent",
|
|
category="bpmn_event",
|
|
label="Boundary event",
|
|
description="Catch an interrupting or non-interrupting event attached to an activity.",
|
|
icon="circle-dashed",
|
|
shape="event-boundary",
|
|
input_ports=(),
|
|
config_fields=(
|
|
_EVENT_DEFINITION_FIELD,
|
|
DefinitionConfigField(
|
|
id="attached_to_ref",
|
|
label="Attached activity",
|
|
kind="text",
|
|
required=True,
|
|
),
|
|
DefinitionConfigField(
|
|
id="cancel_activity",
|
|
label="Activity behavior",
|
|
kind="select",
|
|
options=(
|
|
("true", "Interrupt activity"),
|
|
("false", "Keep activity running"),
|
|
),
|
|
),
|
|
),
|
|
default_config={
|
|
"event_definition": "none",
|
|
"attached_to_ref": "",
|
|
"cancel_activity": "true",
|
|
},
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.endEvent",
|
|
category="bpmn_event",
|
|
label="End event",
|
|
description="End a BPMN process with an optional result event.",
|
|
icon="circle-stop",
|
|
shape="event-end",
|
|
output_ports=(),
|
|
config_fields=(
|
|
_EVENT_DEFINITION_FIELD,
|
|
DefinitionConfigField(
|
|
id="outcome",
|
|
label="GovOPlaN outcome",
|
|
kind="select",
|
|
options=(
|
|
("completed", "Completed"),
|
|
("cancelled", "Cancelled"),
|
|
),
|
|
),
|
|
DefinitionConfigField(
|
|
id="output_mapping",
|
|
label="Output mapping",
|
|
kind="mapping",
|
|
),
|
|
),
|
|
default_config={
|
|
"event_definition": "none",
|
|
"outcome": "completed",
|
|
"output_mapping": {},
|
|
},
|
|
runtime_support="native",
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.task",
|
|
category="bpmn_activity",
|
|
label="Task",
|
|
description="A generic BPMN task completed as a governed human activity.",
|
|
icon="square",
|
|
shape="activity",
|
|
config_fields=_HUMAN_TASK_FIELDS,
|
|
default_config={
|
|
"title": "",
|
|
"instructions": "",
|
|
"assignee": "",
|
|
"due_after": "",
|
|
"view_surface_ids": [],
|
|
},
|
|
runtime_support="native",
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.userTask",
|
|
category="bpmn_activity",
|
|
label="User task",
|
|
description="A task requiring a user action, review, or evidence.",
|
|
icon="user-round-check",
|
|
shape="activity",
|
|
config_fields=(
|
|
*_HUMAN_TASK_FIELDS,
|
|
DefinitionConfigField(
|
|
id="task_mode",
|
|
label="Task mode",
|
|
kind="select",
|
|
options=(
|
|
("activity", "Activity"),
|
|
("review", "Review"),
|
|
),
|
|
),
|
|
DefinitionConfigField(
|
|
id="required_evidence",
|
|
label="Required evidence",
|
|
kind="string_list",
|
|
),
|
|
),
|
|
default_config={
|
|
"title": "",
|
|
"instructions": "",
|
|
"assignee": "",
|
|
"due_after": "",
|
|
"task_mode": "activity",
|
|
"required_evidence": [],
|
|
"view_surface_ids": [],
|
|
},
|
|
runtime_support="native",
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.manualTask",
|
|
category="bpmn_activity",
|
|
label="Manual task",
|
|
description="A task performed outside the automated runtime.",
|
|
icon="hand",
|
|
shape="activity",
|
|
config_fields=_HUMAN_TASK_FIELDS,
|
|
default_config={
|
|
"title": "",
|
|
"instructions": "",
|
|
"assignee": "",
|
|
"due_after": "",
|
|
"view_surface_ids": [],
|
|
},
|
|
runtime_support="native",
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.serviceTask",
|
|
category="bpmn_activity",
|
|
label="Service task",
|
|
description="Invoke a versioned module capability or published Dataflow.",
|
|
icon="cog",
|
|
shape="activity",
|
|
config_fields=_SERVICE_TASK_FIELDS,
|
|
default_config={
|
|
"title": "",
|
|
"instructions": "",
|
|
"implementation": "capability",
|
|
"capability": "",
|
|
"operation": "",
|
|
"pipeline_ref": "",
|
|
"input_mapping": {},
|
|
"idempotency_key": "workflow-step",
|
|
"failure_policy": "manual",
|
|
"view_surface_ids": [],
|
|
},
|
|
runtime_support="native",
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.sendTask",
|
|
category="bpmn_activity",
|
|
label="Send task",
|
|
description="Send a message through a configured implementation.",
|
|
icon="send",
|
|
shape="activity",
|
|
config_fields=_SERVICE_TASK_FIELDS,
|
|
default_config={
|
|
"title": "",
|
|
"instructions": "",
|
|
"implementation": "capability",
|
|
"capability": "",
|
|
"operation": "",
|
|
"pipeline_ref": "",
|
|
"input_mapping": {},
|
|
"idempotency_key": "workflow-step",
|
|
"failure_policy": "manual",
|
|
"view_surface_ids": [],
|
|
},
|
|
runtime_support="native",
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.receiveTask",
|
|
category="bpmn_activity",
|
|
label="Receive task",
|
|
description="Wait until a matching message is received.",
|
|
icon="inbox",
|
|
shape="activity",
|
|
config_fields=(
|
|
*_TASK_FIELDS,
|
|
DefinitionConfigField(id="message_ref", label="Message reference", kind="text"),
|
|
FOCUSED_VIEW_SURFACES_FIELD,
|
|
),
|
|
default_config={
|
|
"title": "",
|
|
"instructions": "",
|
|
"message_ref": "",
|
|
"view_surface_ids": [],
|
|
},
|
|
runtime_support="native",
|
|
),
|
|
*(
|
|
_bpmn_node(
|
|
type_id=f"bpmn.{type_name}",
|
|
category="bpmn_activity",
|
|
label=label,
|
|
description=description,
|
|
icon=icon,
|
|
shape="activity",
|
|
config_fields=fields,
|
|
default_config=defaults,
|
|
)
|
|
for type_name, label, description, icon, fields, defaults in (
|
|
(
|
|
"scriptTask",
|
|
"Script task",
|
|
"A BPMN script task retained as notation; arbitrary scripts are not executed.",
|
|
"file-code-2",
|
|
(*_TASK_FIELDS, DefinitionConfigField(id="script_format", label="Script format", kind="text"), DefinitionConfigField(id="script", label="Script", kind="textarea")),
|
|
{"title": "", "instructions": "", "script_format": "", "script": ""},
|
|
),
|
|
(
|
|
"businessRuleTask",
|
|
"Business rule task",
|
|
"Evaluate a governed business-rule implementation.",
|
|
"scale",
|
|
(*_TASK_FIELDS, DefinitionConfigField(id="implementation_ref", label="Implementation reference", kind="text")),
|
|
{"title": "", "instructions": "", "implementation_ref": ""},
|
|
),
|
|
(
|
|
"callActivity",
|
|
"Call activity",
|
|
"Call another reusable BPMN process or GovOPlaN workflow.",
|
|
"external-link",
|
|
(*_TASK_FIELDS, DefinitionConfigField(id="called_element", label="Called element", kind="text", required=True)),
|
|
{"title": "", "instructions": "", "called_element": ""},
|
|
),
|
|
(
|
|
"subProcess",
|
|
"Sub-process",
|
|
"Contain a nested BPMN process.",
|
|
"box-select",
|
|
_TASK_FIELDS,
|
|
{"title": "", "instructions": ""},
|
|
),
|
|
(
|
|
"transaction",
|
|
"Transaction",
|
|
"Contain transaction-scoped BPMN activity semantics.",
|
|
"badge-dollar-sign",
|
|
_TASK_FIELDS,
|
|
{"title": "", "instructions": ""},
|
|
),
|
|
(
|
|
"adHocSubProcess",
|
|
"Ad-hoc sub-process",
|
|
"Contain activities whose order is governed at runtime.",
|
|
"shuffle",
|
|
_TASK_FIELDS,
|
|
{"title": "", "instructions": ""},
|
|
),
|
|
)
|
|
),
|
|
*(
|
|
_bpmn_node(
|
|
type_id=f"bpmn.{type_name}",
|
|
category="bpmn_gateway",
|
|
label=label,
|
|
description=description,
|
|
icon=icon,
|
|
shape="gateway",
|
|
config_fields=(),
|
|
default_config={},
|
|
runtime_support=runtime_support,
|
|
)
|
|
for type_name, label, description, icon, runtime_support in (
|
|
("exclusiveGateway", "Exclusive gateway", "Choose exactly one matching sequence flow.", "diamond", "native"),
|
|
("parallelGateway", "Parallel gateway", "Split or join concurrent sequence flows.", "plus", "model_only"),
|
|
("inclusiveGateway", "Inclusive gateway", "Choose one or more matching sequence flows.", "circle-plus", "model_only"),
|
|
("eventBasedGateway", "Event-based gateway", "Choose a path according to the first caught event.", "radio-tower", "model_only"),
|
|
("complexGateway", "Complex gateway", "Apply a complex activation condition.", "asterisk", "model_only"),
|
|
)
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.dataObjectReference",
|
|
category="bpmn_data",
|
|
label="Data object",
|
|
description="Reference data produced or consumed by an activity.",
|
|
icon="file",
|
|
shape="data-object",
|
|
input_ports=_OPTIONAL_INCOMING,
|
|
config_fields=(
|
|
DefinitionConfigField(id="data_object_ref", label="Data object reference", kind="text"),
|
|
DefinitionConfigField(id="item_subject_ref", label="Item definition", kind="text"),
|
|
),
|
|
default_config={"data_object_ref": "", "item_subject_ref": ""},
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.dataStoreReference",
|
|
category="bpmn_data",
|
|
label="Data store",
|
|
description="Reference persistent data used by the process.",
|
|
icon="database",
|
|
shape="data-store",
|
|
input_ports=_OPTIONAL_INCOMING,
|
|
config_fields=(
|
|
DefinitionConfigField(id="data_store_ref", label="Data store reference", kind="text"),
|
|
DefinitionConfigField(id="item_subject_ref", label="Item definition", kind="text"),
|
|
),
|
|
default_config={"data_store_ref": "", "item_subject_ref": ""},
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.participant",
|
|
category="bpmn_collaboration",
|
|
label="Participant / pool",
|
|
description="Represent a BPMN collaboration participant and its process.",
|
|
icon="rectangle-horizontal",
|
|
shape="participant",
|
|
input_ports=_OPTIONAL_INCOMING,
|
|
config_fields=(
|
|
DefinitionConfigField(id="process_ref", label="Process reference", kind="text"),
|
|
),
|
|
default_config={"process_ref": ""},
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.lane",
|
|
category="bpmn_collaboration",
|
|
label="Lane",
|
|
description="Group flow nodes by role or responsibility.",
|
|
icon="rows-3",
|
|
shape="lane",
|
|
input_ports=_OPTIONAL_INCOMING,
|
|
config_fields=(
|
|
DefinitionConfigField(id="flow_node_refs", label="Flow node references", kind="string_list"),
|
|
),
|
|
default_config={"flow_node_refs": []},
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.textAnnotation",
|
|
category="bpmn_artifact",
|
|
label="Text annotation",
|
|
description="Attach explanatory text without changing process execution.",
|
|
icon="text-quote",
|
|
shape="text-annotation",
|
|
input_ports=_OPTIONAL_INCOMING,
|
|
config_fields=(
|
|
DefinitionConfigField(id="text", label="Text", kind="textarea"),
|
|
DefinitionConfigField(id="text_format", label="Text format", kind="text"),
|
|
),
|
|
default_config={"text": "", "text_format": "text/plain"},
|
|
),
|
|
_bpmn_node(
|
|
type_id="bpmn.group",
|
|
category="bpmn_artifact",
|
|
label="Group",
|
|
description="Visually group BPMN elements without changing execution.",
|
|
icon="box-select",
|
|
shape="group",
|
|
input_ports=_OPTIONAL_INCOMING,
|
|
config_fields=(
|
|
DefinitionConfigField(id="category_value_ref", label="Category value", kind="text"),
|
|
),
|
|
default_config={"category_value_ref": ""},
|
|
),
|
|
*(
|
|
_bpmn_node(
|
|
type_id=f"bpmn.{type_name}",
|
|
category="bpmn_collaboration",
|
|
label=label,
|
|
description=description,
|
|
icon=icon,
|
|
shape=shape,
|
|
input_ports=ports,
|
|
config_fields=(
|
|
DefinitionConfigField(
|
|
id="participant_refs",
|
|
label="Participants",
|
|
kind="string_list",
|
|
),
|
|
DefinitionConfigField(
|
|
id="called_element",
|
|
label="Called element",
|
|
kind="text",
|
|
),
|
|
),
|
|
default_config={"participant_refs": [], "called_element": ""},
|
|
)
|
|
for type_name, label, description, icon, shape, ports in (
|
|
(
|
|
"choreographyTask",
|
|
"Choreography task",
|
|
"Model a message exchange between two or more participants.",
|
|
"messages-square",
|
|
"choreography",
|
|
_INCOMING,
|
|
),
|
|
(
|
|
"callChoreography",
|
|
"Call choreography",
|
|
"Call a reusable choreography.",
|
|
"external-link",
|
|
"choreography",
|
|
_INCOMING,
|
|
),
|
|
(
|
|
"subChoreography",
|
|
"Sub-choreography",
|
|
"Contain a nested choreography.",
|
|
"box-select",
|
|
"choreography",
|
|
_INCOMING,
|
|
),
|
|
(
|
|
"conversation",
|
|
"Conversation",
|
|
"Group logically related message exchanges.",
|
|
"messages-square",
|
|
"conversation",
|
|
_OPTIONAL_INCOMING,
|
|
),
|
|
(
|
|
"callConversation",
|
|
"Call conversation",
|
|
"Call a reusable global conversation.",
|
|
"external-link",
|
|
"conversation",
|
|
_OPTIONAL_INCOMING,
|
|
),
|
|
(
|
|
"subConversation",
|
|
"Sub-conversation",
|
|
"Contain a nested conversation.",
|
|
"box-select",
|
|
"conversation",
|
|
_OPTIONAL_INCOMING,
|
|
),
|
|
)
|
|
),
|
|
)
|
|
|
|
WORKFLOW_NODE_TYPES = (*BPMN_NODE_TYPES, *LEGACY_WORKFLOW_NODE_TYPES)
|
|
|
|
WORKFLOW_GRAPH_LIBRARY = DefinitionGraphLibrary(
|
|
id="workflow",
|
|
version="1.0.0",
|
|
category_labels=CATEGORY_LABELS,
|
|
node_types=WORKFLOW_NODE_TYPES,
|
|
constraints=DefinitionGraphConstraints(
|
|
max_nodes=150,
|
|
max_edges=300,
|
|
allow_cycles=True,
|
|
require_connected=False,
|
|
),
|
|
)
|
|
|
|
WORKFLOW_NODE_TYPES_BY_ID = {
|
|
definition.type: definition for definition in WORKFLOW_NODE_TYPES
|
|
}
|
|
|
|
|
|
__all__ = [
|
|
"BPMN_NODE_TYPES",
|
|
"CATEGORY_LABELS",
|
|
"LEGACY_WORKFLOW_NODE_TYPES",
|
|
"WORKFLOW_GRAPH_LIBRARY",
|
|
"WORKFLOW_NODE_TYPES",
|
|
"WORKFLOW_NODE_TYPES_BY_ID",
|
|
]
|