Files
govoplan-workflow/src/govoplan_workflow/backend/node_library.py
T

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",
]