diff --git a/core/Extensions/subflow-test/grandchild-data-extension.json b/core/Extensions/subflow-test/grandchild-data-extension.json
new file mode 100644
index 0000000..a7a9bf1
--- /dev/null
+++ b/core/Extensions/subflow-test/grandchild-data-extension.json
@@ -0,0 +1,31 @@
+{
+ "key": "grandchild-data-extension",
+ "version": "1.0.0",
+ "domain": "core",
+ "flow": "sys-extensions",
+ "flowVersion": "1.0.0",
+ "tags": [
+ "subflow-test",
+ "grandchild-extension",
+ "data-extension",
+ "longpolling-test",
+ "deep-nested-test"
+ ],
+ "attributes": {
+ "type": 2,
+ "scope": 1,
+ "task": {
+ "order": 1,
+ "task": {
+ "key": "test-http-task",
+ "domain": "core",
+ "version": "1.0.0",
+ "flow": "sys-tasks"
+ },
+ "mapping": {
+ "location": "./src/GrandchildDataExtensionMapping.csx",
+ "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuU2NyaXB0aW5nOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CgovLy8gPHN1bW1hcnk+Ci8vLyBHcmFuZGNoaWxkIERhdGEgRXh0ZW5zaW9uIE1hcHBpbmcgLSBQcm92aWRlcyBhZGRpdGlvbmFsIGRhdGEgZm9yIGdyYW5kY2hpbGQgd29ya2Zsb3cgdmlldwovLy8gVGhpcyBleHRlbnNpb24gaXMgdXNlZCB0byB0ZXN0IGxvbmdwb2xsaW5nIGZ1bmN0aW9uYWxpdHkgZm9yIGRlZXBseSBuZXN0ZWQgd29ya2Zsb3cgdmlld3MuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBHcmFuZGNoaWxkRGF0YUV4dGVuc2lvbk1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgaHR0cFRhc2sgPSB0YXNrIGFzIEh0dHBUYXNrOwogICAgICAgICAgICBpZiAoaHR0cFRhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhbiBIdHRwVGFzayIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBQcmVwYXJlIHJlcXVlc3QgYm9keSBmb3IgZXh0ZW5zaW9uIGRhdGEKICAgICAgICAgICAgdmFyIHJlcXVlc3RCb2R5ID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGV4dGVuc2lvblR5cGUgPSAiZ3JhbmRjaGlsZC1kYXRhLWV4dGVuc2lvbiIsCiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICB3b3JrZmxvd0tleSA9IGNvbnRleHQuV29ya2Zsb3c/LktleSwKICAgICAgICAgICAgICAgIHBhcmVudEluc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5wYXJlbnRJbnN0YW5jZUlkLAogICAgICAgICAgICAgICAgY2hpbGRJbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uY2hpbGRJbnN0YW5jZUlkLAogICAgICAgICAgICAgICAgbmVzdGluZ0xldmVsID0gMywKICAgICAgICAgICAgICAgIHJlcXVlc3RlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgIH07CgogICAgICAgICAgICBodHRwVGFzay5TZXRCb2R5KHJlcXVlc3RCb2R5KTsKCiAgICAgICAgICAgIC8vIFNldCBoZWFkZXJzCiAgICAgICAgICAgIHZhciBoZWFkZXJzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc/PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbIkNvbnRlbnQtVHlwZSJdID0gImFwcGxpY2F0aW9uL2pzb24iLAogICAgICAgICAgICAgICAgWyJYLUV4dGVuc2lvbi1UeXBlIl0gPSAiZ3JhbmRjaGlsZC1kYXRhIiwKICAgICAgICAgICAgICAgIFsiWC1OZXN0aW5nLUxldmVsIl0gPSAiMyIsCiAgICAgICAgICAgICAgICBbIlgtUmVxdWVzdC1JZCJdID0gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKQogICAgICAgICAgICB9OwogICAgICAgICAgICBodHRwVGFzay5TZXRIZWFkZXJzKGhlYWRlcnMpOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZ3JhbmRjaGlsZC1leHRlbnNpb24taW5wdXQtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJncmFuZGNoaWxkLWV4dGVuc2lvbi1zdWNjZXNzIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBncmFuZGNoaWxkRXh0ZW5zaW9uID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25OYW1lID0gImdyYW5kY2hpbGQtZGF0YS1leHRlbnNpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UgPSAiZ3JhbmRjaGlsZC13b3JrZmxvdyIsCiAgICAgICAgICAgICAgICAgICAgICAgIG5lc3RpbmdMZXZlbCA9IDMsCiAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyYW5kY2hpbGRDb25maWcgPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1N1YmZsb3cgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRGVlcE5lc3RlZCA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tzUGFyZW50ID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uUmVxdWlyZWQgPSB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JhbmRjaGlsZE1ldGFkYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ya2Zsb3dUeXBlID0gImRlZXAtc3ViZmxvdyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50V29ya2Zsb3cgPSAic3ViZmxvdy12aWV3LXRlc3QtY2hpbGQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyYW5kcGFyZW50V29ya2Zsb3cgPSAic3ViZmxvdy12aWV3LXRlc3QtcGFyZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25WZXJzaW9uID0gIjEuMC4wIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeVBhdGggPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbDEgPSAic3ViZmxvdy12aWV3LXRlc3QtcGFyZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbDIgPSAic3ViZmxvdy12aWV3LXRlc3QtY2hpbGQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsMyA9ICJzdWJmbG93LXZpZXctdGVzdC1ncmFuZGNoaWxkIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJzdWJmbG93LXRlc3QiLCAiZ3JhbmRjaGlsZC1leHRlbnNpb24iLCAibG9uZ3BvbGxpbmciLCAiZGVlcC1uZXN0ZWQiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImdyYW5kY2hpbGQtZXh0ZW5zaW9uLWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQo="
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/Extensions/subflow-test/src/GrandchildDataExtensionMapping.csx b/core/Extensions/subflow-test/src/GrandchildDataExtensionMapping.csx
new file mode 100644
index 0000000..7639345
--- /dev/null
+++ b/core/Extensions/subflow-test/src/GrandchildDataExtensionMapping.csx
@@ -0,0 +1,110 @@
+using System;
+using System.Threading.Tasks;
+using BBT.Workflow.Scripting;
+using BBT.Workflow.Definitions;
+
+///
+/// Grandchild Data Extension Mapping - Provides additional data for grandchild workflow view
+/// This extension is used to test longpolling functionality for deeply nested workflow views.
+///
+public class GrandchildDataExtensionMapping : IMapping
+{
+ public Task InputHandler(WorkflowTask task, ScriptContext context)
+ {
+ try
+ {
+ var httpTask = task as HttpTask;
+ if (httpTask == null)
+ {
+ throw new InvalidOperationException("Task must be an HttpTask");
+ }
+
+ // Prepare request body for extension data
+ var requestBody = new
+ {
+ extensionType = "grandchild-data-extension",
+ instanceId = context.Instance?.Id,
+ workflowKey = context.Workflow?.Key,
+ parentInstanceId = context.Instance?.Data?.parentInstanceId,
+ childInstanceId = context.Instance?.Data?.childInstanceId,
+ nestingLevel = 3,
+ requestedAt = DateTime.UtcNow
+ };
+
+ httpTask.SetBody(requestBody);
+
+ // Set headers
+ var headers = new Dictionary
+ {
+ ["Content-Type"] = "application/json",
+ ["X-Extension-Type"] = "grandchild-data",
+ ["X-Nesting-Level"] = "3",
+ ["X-Request-Id"] = Guid.NewGuid().ToString()
+ };
+ httpTask.SetHeaders(headers);
+
+ return Task.FromResult(new ScriptResponse());
+ }
+ catch (Exception ex)
+ {
+ return Task.FromResult(new ScriptResponse
+ {
+ Key = "grandchild-extension-input-error",
+ Data = new { error = ex.Message }
+ });
+ }
+ }
+
+ public async Task OutputHandler(ScriptContext context)
+ {
+ try
+ {
+ return new ScriptResponse
+ {
+ Key = "grandchild-extension-success",
+ Data = new
+ {
+ grandchildExtension = new
+ {
+ extensionName = "grandchild-data-extension",
+ source = "grandchild-workflow",
+ nestingLevel = 3,
+ loadedAt = DateTime.UtcNow,
+ data = new
+ {
+ grandchildConfig = new
+ {
+ isSubflow = true,
+ isDeepNested = true,
+ blocksParent = true,
+ completionRequired = true
+ },
+ grandchildMetadata = new
+ {
+ workflowType = "deep-subflow",
+ parentWorkflow = "subflow-view-test-child",
+ grandparentWorkflow = "subflow-view-test-parent",
+ extensionVersion = "1.0.0"
+ },
+ hierarchyPath = new
+ {
+ level1 = "subflow-view-test-parent",
+ level2 = "subflow-view-test-child",
+ level3 = "subflow-view-test-grandchild"
+ }
+ }
+ }
+ },
+ Tags = new[] { "subflow-test", "grandchild-extension", "longpolling", "deep-nested" }
+ };
+ }
+ catch (Exception ex)
+ {
+ return new ScriptResponse
+ {
+ Key = "grandchild-extension-error",
+ Data = new { error = ex.Message }
+ };
+ }
+ }
+}
diff --git a/core/Tasks/subflow-test/start-busy-subprocess-task.json b/core/Tasks/subflow-test/start-busy-subprocess-task.json
new file mode 100644
index 0000000..2f75752
--- /dev/null
+++ b/core/Tasks/subflow-test/start-busy-subprocess-task.json
@@ -0,0 +1,22 @@
+{
+ "key": "start-busy-subprocess-task",
+ "flow": "sys-tasks",
+ "domain": "core",
+ "version": "1.0.0",
+ "flowVersion": "1.0.0",
+ "tags": [
+ "subflow-test",
+ "subprocess",
+ "busy-state",
+ "trigger-task"
+ ],
+ "attributes": {
+ "type": "11",
+ "config": {
+ "domain": "core",
+ "flow": "sys-flows",
+ "key": "busy-subprocess-workflow",
+ "version": "1.0.0"
+ }
+ }
+}
diff --git a/core/Tasks/subflow-test/trigger-busy-completion-task.json b/core/Tasks/subflow-test/trigger-busy-completion-task.json
new file mode 100644
index 0000000..f5c8a5d
--- /dev/null
+++ b/core/Tasks/subflow-test/trigger-busy-completion-task.json
@@ -0,0 +1,22 @@
+{
+ "key": "trigger-busy-completion-task",
+ "flow": "sys-tasks",
+ "domain": "core",
+ "version": "1.0.0",
+ "flowVersion": "1.0.0",
+ "tags": [
+ "subflow-test",
+ "direct-trigger",
+ "busy-state",
+ "trigger-task"
+ ],
+ "attributes": {
+ "type": "12",
+ "config": {
+ "domain": "core",
+ "flow": "sys-flows",
+ "transitionName": "complete-busy-state",
+ "body": {}
+ }
+ }
+}
diff --git a/core/Views/subflow-test/grandchild-workflow-view.json b/core/Views/subflow-test/grandchild-workflow-view.json
new file mode 100644
index 0000000..62bd4d3
--- /dev/null
+++ b/core/Views/subflow-test/grandchild-workflow-view.json
@@ -0,0 +1,29 @@
+{
+ "key": "grandchild-workflow-view",
+ "version": "1.0.0",
+ "domain": "core",
+ "flow": "sys-views",
+ "flowVersion": "1.0.0",
+ "tags": [
+ "subflow-test",
+ "grandchild-workflow",
+ "view",
+ "longpolling-test",
+ "deep-nested-test"
+ ],
+ "attributes": {
+ "type": 1,
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Grandchild Workflow View"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Torun Akış Görünümü"
+ }
+ ],
+ "display": "full-page",
+ "content": "{\"type\":\"form\",\"title\":{\"en-US\":\"Grandchild Workflow - Active (Level 3)\",\"tr-TR\":\"Torun Akış - Aktif (Seviye 3)\"},\"description\":{\"en-US\":\"This is the grandchild (nested subflow) workflow view. This is the deepest level of the subflow hierarchy. Complete this workflow to continue the child.\",\"tr-TR\":\"Bu torun (iç içe alt akış) görünümüdür. Bu alt akış hiyerarşisinin en derin seviyesidir. Alt akışın devam etmesi için bu akışı tamamlayın.\"},\"fields\":[{\"key\":\"grandchildStatus\",\"type\":\"text\",\"label\":{\"en-US\":\"Grandchild Status\",\"tr-TR\":\"Torun Akış Durumu\"},\"readonly\":true,\"defaultValue\":\"active\"},{\"key\":\"nestingLevel\",\"type\":\"text\",\"label\":{\"en-US\":\"Nesting Level\",\"tr-TR\":\"İç İçe Seviye\"},\"readonly\":true,\"defaultValue\":\"3 (Parent > Child > Grandchild)\"},{\"key\":\"grandchildInfo\",\"type\":\"info\",\"label\":{\"en-US\":\"Grandchild Info\",\"tr-TR\":\"Torun Akış Bilgisi\"},\"content\":{\"en-US\":\"This view includes grandchild extension data for deep nested longpolling test.\",\"tr-TR\":\"Bu görünüm derin iç içe longpolling testi için torun akış extension verisini içerir.\"}}],\"buttons\":[{\"key\":\"complete\",\"label\":{\"en-US\":\"Complete Grandchild Workflow\",\"tr-TR\":\"Torun Akışı Tamamla\"},\"style\":\"success\",\"action\":\"submit\",\"transition\":\"complete-grandchild\"}]}"
+ }
+}
diff --git a/core/Workflows/subflow-test/.meta/busy-subprocess-workflow.diagram.json b/core/Workflows/subflow-test/.meta/busy-subprocess-workflow.diagram.json
new file mode 100644
index 0000000..bd62b40
--- /dev/null
+++ b/core/Workflows/subflow-test/.meta/busy-subprocess-workflow.diagram.json
@@ -0,0 +1,74 @@
+{
+ "workflow": "busy-subprocess-workflow",
+ "version": "1.0.0",
+ "diagram": {
+ "nodes": [
+ {
+ "id": "start",
+ "type": "start",
+ "label": "Start SubProcess",
+ "position": { "x": 100, "y": 100 }
+ },
+ {
+ "id": "processing",
+ "type": "state",
+ "label": "Processing",
+ "stateType": "initial",
+ "subType": "normal",
+ "position": { "x": 300, "y": 100 }
+ },
+ {
+ "id": "trigger-parent",
+ "type": "state",
+ "label": "Trigger Parent",
+ "stateType": "intermediate",
+ "subType": "normal",
+ "description": "Uses DirectTriggerTask to trigger parent workflow",
+ "position": { "x": 500, "y": 100 }
+ },
+ {
+ "id": "completed",
+ "type": "state",
+ "label": "Completed",
+ "stateType": "final",
+ "subType": "success",
+ "position": { "x": 700, "y": 100 }
+ }
+ ],
+ "edges": [
+ {
+ "id": "start-to-processing",
+ "source": "start",
+ "target": "processing",
+ "label": "start-subprocess",
+ "type": "start-transition"
+ },
+ {
+ "id": "processing-to-trigger",
+ "source": "processing",
+ "target": "trigger-parent",
+ "label": "complete-processing (auto)",
+ "type": "auto-transition",
+ "description": "Always true rule"
+ },
+ {
+ "id": "trigger-to-completed",
+ "source": "trigger-parent",
+ "target": "completed",
+ "label": "finish-subprocess (auto)",
+ "type": "auto-transition",
+ "description": "Always true rule"
+ }
+ ]
+ },
+ "metadata": {
+ "description": "Busy state subprocess workflow - runs independently and triggers parent when complete",
+ "purpose": "Test busy state (subType: 5) behavior with subprocess trigger pattern",
+ "features": [
+ "Independent subprocess execution",
+ "DirectTriggerTask to trigger parent workflow",
+ "Automatic state transitions",
+ "Fire-and-forget pattern"
+ ]
+ }
+}
diff --git a/core/Workflows/subflow-test/.meta/subflow-view-test-child.diagram.json b/core/Workflows/subflow-test/.meta/subflow-view-test-child.diagram.json
index bc2239a..ab02bcf 100644
--- a/core/Workflows/subflow-test/.meta/subflow-view-test-child.diagram.json
+++ b/core/Workflows/subflow-test/.meta/subflow-view-test-child.diagram.json
@@ -5,8 +5,8 @@
"y": 100
},
"child-completed": {
- "x": 496,
- "y": 100
+ "x": 551.6088888888888,
+ "y": 96.37333333333333
},
"__start__": {
"x": -296,
diff --git a/core/Workflows/subflow-test/.meta/subflow-view-test-grandchild.diagram.json b/core/Workflows/subflow-test/.meta/subflow-view-test-grandchild.diagram.json
new file mode 100644
index 0000000..dc7fa73
--- /dev/null
+++ b/core/Workflows/subflow-test/.meta/subflow-view-test-grandchild.diagram.json
@@ -0,0 +1,20 @@
+{
+ "nodePos": {
+ "grandchild-active": {
+ "x": 100,
+ "y": 100
+ },
+ "grandchild-completed": {
+ "x": 670,
+ "y": 36
+ },
+ "__start__": {
+ "x": -296,
+ "y": 100
+ },
+ "grandchild-after-busy": {
+ "x": 126,
+ "y": -162
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/Workflows/subflow-test/.meta/subflow-view-test-parent.diagram.json b/core/Workflows/subflow-test/.meta/subflow-view-test-parent.diagram.json
new file mode 100644
index 0000000..aee3fb7
--- /dev/null
+++ b/core/Workflows/subflow-test/.meta/subflow-view-test-parent.diagram.json
@@ -0,0 +1,24 @@
+{
+ "nodePos": {
+ "parent-initial": {
+ "x": 100,
+ "y": 100
+ },
+ "waiting-for-subflow": {
+ "x": 496,
+ "y": 100
+ },
+ "parent-after-subflow": {
+ "x": 892,
+ "y": 100
+ },
+ "parent-completed": {
+ "x": 1288,
+ "y": 100
+ },
+ "__start__": {
+ "x": -296,
+ "y": 100
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/Workflows/subflow-test/BUSY-STATE-TEST-README.md b/core/Workflows/subflow-test/BUSY-STATE-TEST-README.md
new file mode 100644
index 0000000..a637b4f
--- /dev/null
+++ b/core/Workflows/subflow-test/BUSY-STATE-TEST-README.md
@@ -0,0 +1,226 @@
+# Busy State Test Implementation
+
+## Overview
+
+This document describes the implementation of the Busy state test feature in the grandchild workflow. The test demonstrates the new `subType: 5` (Busy) state functionality.
+
+## New State subType Values
+
+- **Busy: 5** - State is busy processing, waiting for external trigger
+- **Human: 6** - State is waiting for human interaction
+
+## Test Objective
+
+Test the Busy state behavior where:
+1. A workflow enters a Busy state (`subType: 5`)
+2. The state launches a subprocess that runs independently
+3. The workflow waits in Busy state for the subprocess to complete
+4. The subprocess triggers a transition on the parent workflow when complete
+5. The parent workflow exits Busy state and continues normal flow
+
+## Expected Behavior
+
+```
+State enters → Status: BUSY → Waits → SubProcess completes → SubProcess pings parent → Transition occurs → State changes
+```
+
+## Components Created
+
+### 1. Tasks
+
+#### `start-busy-subprocess-task.json`
+- **Type**: 11 (SubProcessTask)
+- **Purpose**: Launches the busy subprocess workflow
+- **Location**: `core/Tasks/subflow-test/start-busy-subprocess-task.json`
+
+#### `trigger-busy-completion-task.json`
+- **Type**: 12 (DirectTriggerTask)
+- **Purpose**: Triggers transition on parent workflow from subprocess
+- **Location**: `core/Tasks/subflow-test/trigger-busy-completion-task.json`
+
+### 2. Workflows
+
+#### `busy-subprocess-workflow.json`
+- **Purpose**: Independent subprocess that runs while parent is in Busy state
+- **States**:
+ - `processing` (Initial) - Subprocess starts and processes
+ - `trigger-parent` (Intermediate) - Triggers parent workflow transition
+ - `completed` (Final) - Subprocess completes
+- **Location**: `core/Workflows/subflow-test/busy-subprocess-workflow.json`
+
+### 3. Mappings
+
+#### `StartBusySubprocessMapping.csx`
+- **Purpose**: Configures and launches the subprocess
+- **Task**: SubProcessTask (Type 11)
+- **Actions**:
+ - Sets subprocess domain, flow, and key
+ - Passes parent instance ID to subprocess
+ - Prepares subprocess initialization data
+
+#### `BusySubprocessStartMapping.csx`
+- **Purpose**: Initializes subprocess instance
+- **Actions**:
+ - Stores parent instance information
+ - Prepares subprocess data
+
+#### `TriggerParentBusyCompletionMapping.csx`
+- **Purpose**: Triggers parent workflow transition from subprocess
+- **Task**: DirectTriggerTask (Type 12)
+- **Actions**:
+ - Sets target instance (parent workflow)
+ - Sets transition name (`complete-busy-state`)
+ - Prepares transition payload with completion data
+
+### 4. Workflow States
+
+#### Modified `subflow-view-test-grandchild.json`
+
+Added new states:
+
+**State: `grandchild-busy`**
+- **Type**: Intermediate (2)
+- **SubType**: Busy (5) ⚠️ NEW FEATURE
+- **OnEntry**: Launches subprocess via `start-busy-subprocess-task`
+- **Transition**: `complete-busy-state` - Manual transition triggered by subprocess
+
+**State: `grandchild-after-busy`**
+- **Type**: Intermediate (2)
+- **SubType**: Normal (0)
+- **Purpose**: Continues workflow after busy state completes
+
+## Workflow Flow
+
+```mermaid
+graph TD
+ A[grandchild-active] -->|enter-busy-state| B[grandchild-busy
subType: 5 - BUSY]
+ B -->|onEntry: Launch SubProcess| C[busy-subprocess-workflow]
+ C -->|processing| D[trigger-parent state]
+ D -->|DirectTriggerTask| E[Trigger: complete-busy-state]
+ E -->|Transition| F[grandchild-after-busy]
+ F -->|complete-grandchild| G[grandchild-completed]
+```
+
+## Testing Steps
+
+See `subflow-view-test.http` for complete test sequence. Key steps:
+
+1. **Step 17**: Trigger `enter-busy-state` transition
+2. **Step 18**: Verify state is `grandchild-busy` with `subType: 5`
+3. **Step 19**: Check data shows subprocess launched
+4. **Step 20**: Wait ~5-10 seconds for subprocess to complete
+5. **Step 21**: Verify state automatically changed to `grandchild-after-busy`
+6. **Step 22**: Check data shows subprocess completion and trigger info
+7. **Step 23**: Complete grandchild workflow normally
+
+## API Endpoints Used
+
+### Start Busy State
+```http
+PATCH http://localhost:4201/api/v1/core/workflows/subflow-view-test-grandchild/instances/{instanceId}/transitions/enter-busy-state
+```
+
+### Check State (Should show BUSY status)
+```http
+GET http://localhost:4201/api/v1/core/workflows/subflow-view-test-grandchild/instances/{instanceId}/functions/state
+```
+
+### Get Instance Data
+```http
+GET http://localhost:4201/api/v1/core/workflows/subflow-view-test-grandchild/instances/{instanceId}/functions/data
+```
+
+## Task Types Reference
+
+### SubProcessTask (Type 11)
+- Fire-and-forget subprocess launch
+- Subprocess runs independently
+- Parent doesn't wait for subprocess completion
+- Used in: `start-busy-subprocess-task`
+
+### DirectTriggerTask (Type 12)
+- Triggers specific transition on existing workflow instance
+- Requires target instance ID and transition name
+- Used in: `trigger-busy-completion-task`
+
+## Expected Data Flow
+
+### When Entering Busy State
+
+```json
+{
+ "subprocessLaunched": true,
+ "subprocessInstanceId": "uuid",
+ "launchedAt": "timestamp",
+ "status": "BUSY"
+}
+```
+
+### When SubProcess Triggers Parent
+
+```json
+{
+ "transitionTriggered": true,
+ "triggeredAt": "timestamp",
+ "parentNewState": "grandchild-after-busy",
+ "status": "PARENT_TRANSITION_SUCCESS",
+ "result": {
+ "subprocessCompleted": true,
+ "busyStateTestPassed": true
+ }
+}
+```
+
+## Known Issues
+
+### Schema Validation
+
+The `subType: 5` value currently fails schema validation because it's a new feature under development:
+
+```
+Schema validation failed for workflow:
+/attributes/states/1/subType: must be equal to one of the allowed values (line 74) ({"allowedValues":[0,1,2,3,4]})
+```
+
+**Resolution**: The `@burgan-tech/vnext-schema` package needs to be updated to include:
+- `Busy: 5`
+- `Human: 6`
+
+Once the schema is updated, validation will pass.
+
+## Files Modified/Created
+
+### Created Files
+- `core/Tasks/subflow-test/start-busy-subprocess-task.json`
+- `core/Tasks/subflow-test/trigger-busy-completion-task.json`
+- `core/Workflows/subflow-test/busy-subprocess-workflow.json`
+- `core/Workflows/subflow-test/src/StartBusySubprocessMapping.csx`
+- `core/Workflows/subflow-test/src/BusySubprocessStartMapping.csx`
+- `core/Workflows/subflow-test/src/TriggerParentBusyCompletionMapping.csx`
+
+### Modified Files
+- `core/Workflows/subflow-test/subflow-view-test-grandchild.json` - Added busy state and transitions
+- `core/Workflows/subflow-test/subflow-view-test.http` - Added busy state test steps
+
+## Architecture Benefits
+
+1. **State Awareness**: Runtime knows the state is busy (subType: 5)
+2. **Status Tracking**: Can monitor busy states across all workflows
+3. **Independent Processing**: Subprocess runs without blocking
+4. **Automatic Transition**: Subprocess triggers parent when ready
+5. **Flexible Pattern**: Can be used for any long-running operation
+
+## Use Cases
+
+This pattern is useful for:
+- Long-running background processes
+- External API calls with callbacks
+- Async processing workflows
+- Human approval processes (with subType: 6)
+- Queue-based processing
+
+## Related Documentation
+
+- vNext Runtime Docs: TriggerTask types (SubProcess, DirectTrigger)
+- State lifecycle and subTypes
+- Transition trigger types
diff --git a/core/Workflows/subflow-test/busy-subprocess-workflow.json b/core/Workflows/subflow-test/busy-subprocess-workflow.json
new file mode 100644
index 0000000..794a2f5
--- /dev/null
+++ b/core/Workflows/subflow-test/busy-subprocess-workflow.json
@@ -0,0 +1,191 @@
+{
+ "key": "busy-subprocess-workflow",
+ "flow": "sys-flows",
+ "domain": "core",
+ "version": "1.0.0",
+ "flowVersion": "1.0.0",
+ "tags": [
+ "subflow-test",
+ "subprocess",
+ "busy-state-test",
+ "background-process"
+ ],
+ "attributes": {
+ "type": "S",
+ "timeout": null,
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Busy State SubProcess Workflow"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Meşgul Durumu Alt İşlem Akışı"
+ }
+ ],
+ "functions": [],
+ "features": [],
+ "extensions": [],
+ "sharedTransitions": [],
+ "startTransition": {
+ "key": "start-subprocess",
+ "target": "processing",
+ "triggerType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Start SubProcess"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Alt İşlemi Başlat"
+ }
+ ],
+ "onExecutionTasks": [
+ {
+ "order": 1,
+ "task": {
+ "key": "script-task",
+ "domain": "core",
+ "version": "1.0.0",
+ "flow": "sys-tasks"
+ },
+ "mapping": {
+ "location": "./src/BusySubprocessStartMapping.csx",
+ "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gQnVzeSBTdWJQcm9jZXNzIFN0YXJ0IE1hcHBpbmcgLSBJbml0aWFsaXplcyB0aGUgc3VicHJvY2VzcyB0aGF0IHdpbGwgcnVuIHdoaWxlIHBhcmVudCBpcyBidXN5Ci8vLyBUaGlzIHN1YnByb2Nlc3Mgd2lsbCBjb21wbGV0ZSBpdHMgd29yayBhbmQgdHJpZ2dlciB0aGUgcGFyZW50IHRvIGV4aXQgYnVzeSBzdGF0ZQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgQnVzeVN1YnByb2Nlc3NTdGFydE1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkJ1c3lTdWJwcm9jZXNzU3RhcnRNYXBwaW5nIC0gU3RhcnRpbmcgYnVzeSBzdGF0ZSBzdWJwcm9jZXNzIik7CiAgICAgICAgICAgIAogICAgICAgICAgICB2YXIgaW5wdXREYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImJ1c3ktc3VicHJvY2Vzcy1zdGFydGVkIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzV29ya2Zsb3dJZCA9IGNvbnRleHQuV29ya2Zsb3c/LktleSwKICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzSW5zdGFuY2VJZCA9IGNvbnRleHQuSW5zdGFuY2U/LklkLAogICAgICAgICAgICAgICAgICAgIHBhcmVudEluc3RhbmNlSWQgPSBpbnB1dERhdGE/LmdyYW5kY2hpbGRJbnN0YW5jZUlkLAogICAgICAgICAgICAgICAgICAgIHBhcmVudFdvcmtmbG93SWQgPSBpbnB1dERhdGE/LmdyYW5kY2hpbGRXb3JrZmxvd0lkLAogICAgICAgICAgICAgICAgICAgIHN0YXJ0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSAicHJvY2Vzc2luZyIsCiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9ICJCdXN5IHN0YXRlIHN1YnByb2Nlc3Mgc3RhcnRlZCAtIHdpbGwgdHJpZ2dlciBwYXJlbnQgd2hlbiBjb21wbGV0ZSIsCiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2luZ1Rhc2sgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tUeXBlID0gImJhY2tncm91bmQtcHJvY2Vzc2luZyIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkRHVyYXRpb24gPSAiNS0xMCBzZWNvbmRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgd2lsbFRyaWdnZXJQYXJlbnQgPSB0cnVlCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJidXN5LXN1YnByb2Nlc3MiLCAic3RhcnRlZCIsICJiYWNrZ3JvdW5kLXRhc2siIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0Vycm9yKCJCdXN5U3VicHJvY2Vzc1N0YXJ0TWFwcGluZyAtIEVycm9yOiB7MH0iLCBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiYnVzeS1zdWJwcm9jZXNzLXN0YXJ0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQo="
+ }
+ }
+ ]
+ },
+ "states": [
+ {
+ "key": "processing",
+ "stateType": 1,
+ "subType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Processing"
+ },
+ {
+ "language": "tr-TR",
+ "label": "İşleniyor"
+ }
+ ],
+ "view": null,
+ "subFlow": null,
+ "onEntries": [],
+ "onExits": [],
+ "transitions": [
+ {
+ "key": "complete-processing",
+ "target": "trigger-parent",
+ "triggerType": 1,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Complete Processing (Auto)"
+ },
+ {
+ "language": "tr-TR",
+ "label": "İşlemi Tamamla (Otomatik)"
+ }
+ ],
+ "schema": null,
+ "rule": {
+ "location": "./src/AlwaysTrueRule.csx",
+ "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo="
+ },
+ "timer": null,
+ "view": null,
+ "onExecutionTasks": []
+ }
+ ]
+ },
+ {
+ "key": "trigger-parent",
+ "stateType": 2,
+ "subType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Trigger Parent Workflow"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Üst Akışı Tetikle"
+ }
+ ],
+ "view": null,
+ "subFlow": null,
+ "onEntries": [
+ {
+ "order": 1,
+ "task": {
+ "key": "trigger-busy-completion-task",
+ "domain": "core",
+ "version": "1.0.0",
+ "flow": "sys-tasks"
+ },
+ "mapping": {
+ "location": "./src/TriggerParentBusyCompletionMapping.csx",
+ "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVHJpZ2dlciBQYXJlbnQgQnVzeSBDb21wbGV0aW9uIE1hcHBpbmcgLSBUcmlnZ2VycyB0aGUgcGFyZW50IHdvcmtmbG93IHRvIGV4aXQgYnVzeSBzdGF0ZQovLy8gVGhpcyBtYXBwaW5nIHVzZXMgRGlyZWN0VHJpZ2dlclRhc2sgdG8gdHJpZ2dlciB0aGUgJ2NvbXBsZXRlLWJ1c3ktc3RhdGUnIHRyYW5zaXRpb24gb24gdGhlIHBhcmVudAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgVHJpZ2dlclBhcmVudEJ1c3lDb21wbGV0aW9uTWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBkaXJlY3RUcmlnZ2VyVGFzayA9IHRhc2sgYXMgRGlyZWN0VHJpZ2dlclRhc2s7CiAgICAgICAgICAgIAogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiVHJpZ2dlclBhcmVudEJ1c3lDb21wbGV0aW9uTWFwcGluZyAtIFByZXBhcmluZyB0byB0cmlnZ2VyIHBhcmVudCB3b3JrZmxvdyBidXN5IGNvbXBsZXRpb24iKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIEdldCBwYXJlbnQgaW5zdGFuY2UgSUQgZnJvbSBzdWJwcm9jZXNzIGlucHV0IGRhdGEKICAgICAgICAgICAgdmFyIHBhcmVudEluc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5wYXJlbnRJbnN0YW5jZUlkOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KHBhcmVudEluc3RhbmNlSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMb2dFcnJvcigiVHJpZ2dlclBhcmVudEJ1c3lDb21wbGV0aW9uTWFwcGluZyAtIFBhcmVudCBpbnN0YW5jZSBJRCBub3QgZm91bmQiKTsKICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gInRyaWdnZXItZXJyb3IiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9ICJQYXJlbnQgaW5zdGFuY2UgSUQgbm90IGZvdW5kIiB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLy8gU2V0IHRoZSB0YXJnZXQgaW5zdGFuY2UgYW5kIHRyYW5zaXRpb24KICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0RG9tYWluKCJjb3JlIik7CiAgICAgICAgICAgIGRpcmVjdFRyaWdnZXJUYXNrLlNldEZsb3coInN5cy1mbG93cyIpOwogICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXRJbnN0YW5jZShwYXJlbnRJbnN0YW5jZUlkKTsKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0VHJhbnNpdGlvbk5hbWUoImNvbXBsZXRlLWJ1c3ktc3RhdGUiKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFByZXBhcmUgdHJhbnNpdGlvbiBwYXlsb2FkCiAgICAgICAgICAgIGRpcmVjdFRyaWdnZXJUYXNrLlNldEJvZHkobmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN1YnByb2Nlc3NDb21wbGV0ZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgc3VicHJvY2Vzc0luc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZCwKICAgICAgICAgICAgICAgIGNvbXBsZXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9ICJTdWJwcm9jZXNzIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHksIHRyaWdnZXJpbmcgcGFyZW50IGJ1c3kgc3RhdGUgY29tcGxldGlvbiIsCiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2luZ1RpbWUgPSAiNSBzZWNvbmRzIiwKICAgICAgICAgICAgICAgICAgICBkYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBidXN5U3RhdGVUZXN0UGFzc2VkID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgc3VicHJvY2Vzc0V4ZWN1dGVkID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50VHJpZ2dlcmVkID0gdHJ1ZQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiVHJpZ2dlclBhcmVudEJ1c3lDb21wbGV0aW9uTWFwcGluZyAtIFRyaWdnZXJpbmcgdHJhbnNpdGlvbiAnY29tcGxldGUtYnVzeS1zdGF0ZScgb24gcGFyZW50IGluc3RhbmNlIHswfSIsIGFyZ3M6IG5ldyBvYmplY3Q/W10geyBwYXJlbnRJbnN0YW5jZUlkIH0pOwogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRGF0YSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGEKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiVHJpZ2dlclBhcmVudEJ1c3lDb21wbGV0aW9uTWFwcGluZyAtIEVycm9yOiB7MH0iLCBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInRyaWdnZXItZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgcmVzcG9uc2UgPSBuZXcgU2NyaXB0UmVzcG9uc2UoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChjb250ZXh0LkJvZHk/LmlzU3VjY2VzcyA9PSB0cnVlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiVHJpZ2dlclBhcmVudEJ1c3lDb21wbGV0aW9uTWFwcGluZyAtIFBhcmVudCB0cmFuc2l0aW9uIHRyaWdnZXJlZCBzdWNjZXNzZnVsbHkiKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgcmVzcG9uc2UuRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRyYW5zaXRpb25UcmlnZ2VyZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgIHRyaWdnZXJlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgIHBhcmVudE5ld1N0YXRlID0gY29udGV4dC5Cb2R5LmRhdGE/LmN1cnJlbnRTdGF0ZSwKICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSAiUEFSRU5UX1RSQU5TSVRJT05fU1VDQ0VTUyIsCiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9ICJQYXJlbnQgd29ya2Zsb3cgc3VjY2Vzc2Z1bGx5IHRyYW5zaXRpb25lZCBmcm9tIGJ1c3kgc3RhdGUiCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTG9nRXJyb3IoIlRyaWdnZXJQYXJlbnRCdXN5Q29tcGxldGlvbk1hcHBpbmcgLSBQYXJlbnQgdHJhbnNpdGlvbiBmYWlsZWQ6IHswfSIsIGFyZ3M6IG5ldyBvYmplY3Q/W10geyBjb250ZXh0LkJvZHk/LmVycm9yTWVzc2FnZSB9KTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgcmVzcG9uc2UuRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRyYW5zaXRpb25UcmlnZ2VyZWQgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGNvbnRleHQuQm9keT8uZXJyb3JNZXNzYWdlLAogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9ICJQQVJFTlRfVFJBTlNJVElPTl9GQUlMRUQiCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiVHJpZ2dlclBhcmVudEJ1c3lDb21wbGV0aW9uTWFwcGluZyAtIE91dHB1dCBoYW5kbGVyIGVycm9yOiB7MH0iLCBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAib3V0cHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQo="
+ }
+ }
+ ],
+ "onExits": [],
+ "transitions": [
+ {
+ "key": "finish-subprocess",
+ "target": "completed",
+ "triggerType": 1,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Finish SubProcess (Auto)"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Alt İşlemi Bitir (Otomatik)"
+ }
+ ],
+ "schema": null,
+ "rule": {
+ "location": "./src/AlwaysTrueRule.csx",
+ "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo="
+ },
+ "timer": null,
+ "view": null,
+ "onExecutionTasks": []
+ }
+ ]
+ },
+ {
+ "key": "completed",
+ "stateType": 3,
+ "subType": 1,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "SubProcess Completed"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Alt İşlem Tamamlandı"
+ }
+ ],
+ "view": null,
+ "subFlow": null,
+ "onEntries": [],
+ "onExits": [],
+ "transitions": []
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/core/Workflows/subflow-test/src/BusySubprocessStartMapping.csx b/core/Workflows/subflow-test/src/BusySubprocessStartMapping.csx
new file mode 100644
index 0000000..649ab8f
--- /dev/null
+++ b/core/Workflows/subflow-test/src/BusySubprocessStartMapping.csx
@@ -0,0 +1,58 @@
+using System;
+using System.Threading.Tasks;
+using BBT.Workflow.Definitions;
+using BBT.Workflow.Scripting;
+using BBT.Workflow.Scripting.Functions;
+
+///
+/// Busy SubProcess Start Mapping - Initializes the subprocess that will run while parent is busy
+/// This subprocess will complete its work and trigger the parent to exit busy state
+///
+public class BusySubprocessStartMapping : ScriptBase, IMapping
+{
+ public Task InputHandler(WorkflowTask task, ScriptContext context)
+ {
+ return Task.FromResult(new ScriptResponse());
+ }
+
+ public async Task OutputHandler(ScriptContext context)
+ {
+ try
+ {
+ LogInformation("BusySubprocessStartMapping - Starting busy state subprocess");
+
+ var inputData = context.Instance?.Data;
+
+ return new ScriptResponse
+ {
+ Key = "busy-subprocess-started",
+ Data = new
+ {
+ subprocessWorkflowId = context.Workflow?.Key,
+ subprocessInstanceId = context.Instance?.Id,
+ parentInstanceId = inputData?.grandchildInstanceId,
+ parentWorkflowId = inputData?.grandchildWorkflowId,
+ startedAt = DateTime.UtcNow,
+ status = "processing",
+ message = "Busy state subprocess started - will trigger parent when complete",
+ processingTask = new
+ {
+ taskType = "background-processing",
+ expectedDuration = "5-10 seconds",
+ willTriggerParent = true
+ }
+ },
+ Tags = new[] { "busy-subprocess", "started", "background-task" }
+ };
+ }
+ catch (Exception ex)
+ {
+ LogError("BusySubprocessStartMapping - Error: {0}", args: new object?[] { ex.Message });
+ return new ScriptResponse
+ {
+ Key = "busy-subprocess-start-error",
+ Data = new { error = ex.Message }
+ };
+ }
+ }
+}
diff --git a/core/Workflows/subflow-test/src/ChildToGrandchildSubFlowMapping.csx b/core/Workflows/subflow-test/src/ChildToGrandchildSubFlowMapping.csx
new file mode 100644
index 0000000..dae94b2
--- /dev/null
+++ b/core/Workflows/subflow-test/src/ChildToGrandchildSubFlowMapping.csx
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Threading.Tasks;
+using BBT.Workflow.Definitions;
+using BBT.Workflow.Scripting;
+using BBT.Workflow.Scripting.Functions;
+
+///
+/// Child to Grandchild SubFlow Mapping - Handles input/output for grandchild subflow state
+/// This mapping prepares data for grandchild subflow and processes its result.
+/// Manages the Level 2 to Level 3 transition in the subflow hierarchy.
+///
+public class ChildToGrandchildSubFlowMapping : ScriptBase, ISubFlowMapping
+{
+ ///
+ /// Prepares input data for the grandchild subflow
+ ///
+ public async Task InputHandler(ScriptContext context)
+ {
+ try
+ {
+ LogInformation("ChildToGrandchildSubFlowMapping - Preparing grandchild subflow input data");
+
+ // Prepare data to pass to grandchild workflow using Dictionary
+ var testContext = new Dictionary
+ {
+ ["testType"] = "deep-nested-view-extension-longpolling",
+ ["expectViewData"] = true,
+ ["expectExtensionData"] = true,
+ ["nestingLevel"] = 3
+ };
+
+ var inputData = new Dictionary
+ {
+ ["childInstanceId"] = context.Instance?.Id,
+ ["childWorkflowId"] = context.Workflow?.Key ?? string.Empty,
+ ["parentInstanceId"] = context.Instance?.Data?.parentInstanceId,
+ ["parentWorkflowId"] = context.Instance?.Data?.parentWorkflowId,
+ ["initiatedAt"] = DateTime.UtcNow,
+ ["initiatedBy"] = "child-workflow",
+ ["nestingLevel"] = 3,
+ ["testContext"] = testContext
+ };
+
+ return new ScriptResponse
+ {
+ Key = context.Instance?.Key,
+ Data = inputData,
+ Tags = new[] { "subflow-test", "grandchild-subflow-input", "level-3" }
+ };
+ }
+ catch (Exception ex)
+ {
+ LogError("ChildToGrandchildSubFlowMapping InputHandler - Error: {0}", args: new object?[] { ex.Message });
+ return new ScriptResponse
+ {
+ Key = "grandchild-subflow-input-error",
+ Data = new Dictionary { ["error"] = ex.Message }
+ };
+ }
+ }
+
+ ///
+ /// Processes the result from the completed grandchild subflow
+ ///
+ public async Task OutputHandler(ScriptContext context)
+ {
+ try
+ {
+ LogInformation("ChildToGrandchildSubFlowMapping - Processing grandchild subflow output data");
+
+ // Get grandchild subflow result data
+ var grandchildResult = context.Body;
+
+ var grandchildResultData = new Dictionary
+ {
+ ["grandchildInstanceData"] = grandchildResult,
+ ["processed"] = true,
+ ["viewTestResult"] = "success",
+ ["extensionTestResult"] = "success",
+ ["deepNestedTestResult"] = "success"
+ };
+
+ var childContinuation = new Dictionary
+ {
+ ["canProceed"] = true,
+ ["nextState"] = "child-after-grandchild"
+ };
+
+ var outputData = new Dictionary
+ {
+ ["grandchildSubflowCompleted"] = true,
+ ["completedAt"] = DateTime.UtcNow,
+ ["grandchildResult"] = grandchildResultData,
+ ["childContinuation"] = childContinuation,
+ ["nestingLevel"] = 3
+ };
+
+ return new ScriptResponse
+ {
+ Key = "grandchild-subflow-output-processed",
+ Data = outputData,
+ Tags = new[] { "subflow-test", "grandchild-subflow-output", "completed", "level-3" }
+ };
+ }
+ catch (Exception ex)
+ {
+ LogError("ChildToGrandchildSubFlowMapping OutputHandler - Error: {0}", args: new object?[] { ex.Message });
+ return new ScriptResponse
+ {
+ Key = "grandchild-subflow-output-error",
+ Data = new Dictionary { ["error"] = ex.Message }
+ };
+ }
+ }
+}
diff --git a/core/Workflows/subflow-test/src/GrandchildCompleteMapping.csx b/core/Workflows/subflow-test/src/GrandchildCompleteMapping.csx
new file mode 100644
index 0000000..b65ae9c
--- /dev/null
+++ b/core/Workflows/subflow-test/src/GrandchildCompleteMapping.csx
@@ -0,0 +1,63 @@
+using System;
+using System.Threading.Tasks;
+using BBT.Workflow.Definitions;
+using BBT.Workflow.Scripting;
+using BBT.Workflow.Scripting.Functions;
+
+///
+/// Grandchild Complete Mapping - Marks the grandchild workflow as completed
+/// This data will be returned to the child workflow (Level 2)
+///
+public class GrandchildCompleteMapping : ScriptBase, IMapping
+{
+ public Task InputHandler(WorkflowTask task, ScriptContext context)
+ {
+ return Task.FromResult(new ScriptResponse());
+ }
+
+ public async Task OutputHandler(ScriptContext context)
+ {
+ try
+ {
+ LogInformation("GrandchildCompleteMapping - Completing grandchild workflow (Level 3)");
+
+ var inputData = context.Instance?.Data;
+
+ return new ScriptResponse
+ {
+ Key = "grandchild-complete-success",
+ Data = new
+ {
+ completedAt = DateTime.UtcNow,
+ status = "completed",
+ nestingLevel = 3,
+ result = new
+ {
+ grandchildWorkflowId = context.Workflow?.Key,
+ grandchildInstanceId = context.Instance?.Id,
+ success = true,
+ message = "Grandchild workflow completed successfully (Level 3)",
+ dataForChild = new
+ {
+ grandchildResult = "processed",
+ processingTime = 100,
+ viewTestPassed = true,
+ extensionTestPassed = true,
+ deepNestedTestPassed = true
+ }
+ }
+ },
+ Tags = new[] { "subflow-test", "grandchild-workflow", "completed", "level-3" }
+ };
+ }
+ catch (Exception ex)
+ {
+ LogError("GrandchildCompleteMapping - Error: {0}", args: new object?[] { ex.Message });
+ return new ScriptResponse
+ {
+ Key = "grandchild-complete-error",
+ Data = new { error = ex.Message }
+ };
+ }
+ }
+}
diff --git a/core/Workflows/subflow-test/src/GrandchildStartMapping.csx b/core/Workflows/subflow-test/src/GrandchildStartMapping.csx
new file mode 100644
index 0000000..2f97b62
--- /dev/null
+++ b/core/Workflows/subflow-test/src/GrandchildStartMapping.csx
@@ -0,0 +1,64 @@
+using System;
+using System.Threading.Tasks;
+using BBT.Workflow.Definitions;
+using BBT.Workflow.Scripting;
+using BBT.Workflow.Scripting.Functions;
+
+///
+/// Grandchild Start Mapping - Initializes the grandchild workflow with data from child
+/// This is the deepest level (level 3) in the subflow hierarchy.
+///
+public class GrandchildStartMapping : ScriptBase, IMapping
+{
+ public Task InputHandler(WorkflowTask task, ScriptContext context)
+ {
+ return Task.FromResult(new ScriptResponse());
+ }
+
+ public async Task OutputHandler(ScriptContext context)
+ {
+ try
+ {
+ LogInformation("GrandchildStartMapping - Initializing grandchild workflow (Level 3)");
+
+ var inputData = context.Instance?.Data;
+
+ return new ScriptResponse
+ {
+ Key = "grandchild-start-success",
+ Data = new
+ {
+ grandchildWorkflowId = context.Workflow?.Key,
+ grandchildInstanceId = context.Instance?.Id,
+ childInstanceId = inputData?.childInstanceId,
+ childWorkflowId = inputData?.childWorkflowId,
+ parentInstanceId = inputData?.parentInstanceId,
+ parentWorkflowId = inputData?.parentWorkflowId,
+ nestingLevel = 3,
+ startedAt = DateTime.UtcNow,
+ status = "active",
+ message = "Grandchild workflow started successfully (Level 3)",
+ grandchildContext = new
+ {
+ isSubflow = true,
+ isDeepNested = true,
+ blocksParent = true,
+ viewTestEnabled = true,
+ extensionTestEnabled = true,
+ hierarchyPath = "Parent > Child > Grandchild"
+ }
+ },
+ Tags = new[] { "subflow-test", "grandchild-workflow", "started", "level-3" }
+ };
+ }
+ catch (Exception ex)
+ {
+ LogError("GrandchildStartMapping - Error: {0}", args: new object?[] { ex.Message });
+ return new ScriptResponse
+ {
+ Key = "grandchild-start-error",
+ Data = new { error = ex.Message }
+ };
+ }
+ }
+}
diff --git a/core/Workflows/subflow-test/src/StartBusySubprocessMapping.csx b/core/Workflows/subflow-test/src/StartBusySubprocessMapping.csx
new file mode 100644
index 0000000..0ec35c7
--- /dev/null
+++ b/core/Workflows/subflow-test/src/StartBusySubprocessMapping.csx
@@ -0,0 +1,89 @@
+using System;
+using System.Threading.Tasks;
+using BBT.Workflow.Definitions;
+using BBT.Workflow.Scripting;
+using BBT.Workflow.Scripting.Functions;
+
+///
+/// Start Busy SubProcess Mapping - Starts the subprocess when grandchild enters busy state
+/// This mapping configures the SubProcessTask to launch an independent subprocess
+///
+public class StartBusySubprocessMapping : ScriptBase, IMapping
+{
+ public Task InputHandler(WorkflowTask task, ScriptContext context)
+ {
+ try
+ {
+ var subProcessTask = task as SubProcessTask;
+
+ LogInformation("StartBusySubprocessMapping - Preparing to start busy subprocess");
+
+ // Configure subprocess
+ subProcessTask.SetDomain("core");
+ subProcessTask.SetFlow("sys-flows");
+ subProcessTask.SetKey("busy-subprocess-workflow");
+
+ // Prepare subprocess data - include parent instance ID so subprocess can trigger back
+ subProcessTask.SetBody(new
+ {
+ grandchildInstanceId = context.Instance?.Id,
+ grandchildWorkflowId = context.Workflow?.Key,
+ parentInstanceId = context.Instance?.Data?.childInstanceId,
+ startedAt = DateTime.UtcNow,
+ taskType = "busy-state-processing",
+ context = new
+ {
+ nestingLevel = 3,
+ testType = "busy-state-test",
+ expectedBehavior = "subprocess-will-trigger-parent"
+ }
+ });
+
+ LogInformation("StartBusySubprocessMapping - Subprocess configured and ready to launch");
+
+ return Task.FromResult(new ScriptResponse
+ {
+ Data = context.Instance?.Data
+ });
+ }
+ catch (Exception ex)
+ {
+ LogError("StartBusySubprocessMapping - Error: {0}", args: new object?[] { ex.Message });
+ return Task.FromResult(new ScriptResponse
+ {
+ Key = "subprocess-start-error",
+ Data = new { error = ex.Message }
+ });
+ }
+ }
+
+ public async Task OutputHandler(ScriptContext context)
+ {
+ try
+ {
+ LogInformation("StartBusySubprocessMapping - Subprocess launched successfully");
+
+ // SubProcess is fire-and-forget, just track that it was initiated
+ return new ScriptResponse
+ {
+ Data = new
+ {
+ subprocessLaunched = true,
+ subprocessInstanceId = context.Body?.data?.instanceId,
+ launchedAt = DateTime.UtcNow,
+ status = "BUSY",
+ message = "Subprocess launched - grandchild now in busy state waiting for subprocess to complete"
+ }
+ };
+ }
+ catch (Exception ex)
+ {
+ LogError("StartBusySubprocessMapping - Output handler error: {0}", args: new object?[] { ex.Message });
+ return new ScriptResponse
+ {
+ Key = "output-error",
+ Data = new { error = ex.Message }
+ };
+ }
+ }
+}
diff --git a/core/Workflows/subflow-test/src/TriggerParentBusyCompletionMapping.csx b/core/Workflows/subflow-test/src/TriggerParentBusyCompletionMapping.csx
new file mode 100644
index 0000000..0dfb3f1
--- /dev/null
+++ b/core/Workflows/subflow-test/src/TriggerParentBusyCompletionMapping.csx
@@ -0,0 +1,121 @@
+using System;
+using System.Threading.Tasks;
+using BBT.Workflow.Definitions;
+using BBT.Workflow.Scripting;
+using BBT.Workflow.Scripting.Functions;
+
+///
+/// Trigger Parent Busy Completion Mapping - Triggers the parent workflow to exit busy state
+/// This mapping uses DirectTriggerTask to trigger the 'complete-busy-state' transition on the parent
+///
+public class TriggerParentBusyCompletionMapping : ScriptBase, IMapping
+{
+ public Task InputHandler(WorkflowTask task, ScriptContext context)
+ {
+ try
+ {
+ var directTriggerTask = task as DirectTriggerTask;
+
+ LogInformation("TriggerParentBusyCompletionMapping - Preparing to trigger parent workflow busy completion");
+
+ // Get parent instance ID from subprocess input data
+ var parentInstanceId = context.Instance?.Data?.parentInstanceId;
+
+ if (string.IsNullOrEmpty(parentInstanceId))
+ {
+ LogError("TriggerParentBusyCompletionMapping - Parent instance ID not found");
+ return Task.FromResult(new ScriptResponse
+ {
+ Key = "trigger-error",
+ Data = new { error = "Parent instance ID not found" }
+ });
+ }
+
+ // Set the target instance and transition
+ directTriggerTask.SetDomain("core");
+ directTriggerTask.SetFlow("sys-flows");
+ directTriggerTask.SetInstance(parentInstanceId);
+ directTriggerTask.SetTransitionName("complete-busy-state");
+
+ // Prepare transition payload
+ directTriggerTask.SetBody(new
+ {
+ subprocessCompleted = true,
+ subprocessInstanceId = context.Instance?.Id,
+ completedAt = DateTime.UtcNow,
+ result = new
+ {
+ success = true,
+ message = "Subprocess completed successfully, triggering parent busy state completion",
+ processingTime = "5 seconds",
+ data = new
+ {
+ busyStateTestPassed = true,
+ subprocessExecuted = true,
+ parentTriggered = true
+ }
+ }
+ });
+
+ LogInformation("TriggerParentBusyCompletionMapping - Triggering transition 'complete-busy-state' on parent instance {0}", args: new object?[] { parentInstanceId });
+
+ return Task.FromResult(new ScriptResponse
+ {
+ Data = context.Instance?.Data
+ });
+ }
+ catch (Exception ex)
+ {
+ LogError("TriggerParentBusyCompletionMapping - Error: {0}", args: new object?[] { ex.Message });
+ return Task.FromResult(new ScriptResponse
+ {
+ Key = "trigger-error",
+ Data = new { error = ex.Message }
+ });
+ }
+ }
+
+ public async Task OutputHandler(ScriptContext context)
+ {
+ try
+ {
+ var response = new ScriptResponse();
+
+ if (context.Body?.isSuccess == true)
+ {
+ LogInformation("TriggerParentBusyCompletionMapping - Parent transition triggered successfully");
+
+ response.Data = new
+ {
+ transitionTriggered = true,
+ triggeredAt = DateTime.UtcNow,
+ parentNewState = context.Body.data?.currentState,
+ status = "PARENT_TRANSITION_SUCCESS",
+ message = "Parent workflow successfully transitioned from busy state"
+ };
+ }
+ else
+ {
+ LogError("TriggerParentBusyCompletionMapping - Parent transition failed: {0}", args: new object?[] { context.Body?.errorMessage });
+
+ response.Data = new
+ {
+ transitionTriggered = false,
+ error = context.Body?.errorMessage,
+ status = "PARENT_TRANSITION_FAILED"
+ };
+ }
+
+ return response;
+ }
+ catch (Exception ex)
+ {
+ LogError("TriggerParentBusyCompletionMapping - Output handler error: {0}", args: new object?[] { ex.Message });
+ return new ScriptResponse
+ {
+ Key = "output-error",
+ Data = new { error = ex.Message }
+ };
+ }
+ }
+}
diff --git a/core/Workflows/subflow-test/subflow-view-test-child.json b/core/Workflows/subflow-test/subflow-view-test-child.json
index 5707784..ca4c419 100644
--- a/core/Workflows/subflow-test/subflow-view-test-child.json
+++ b/core/Workflows/subflow-test/subflow-view-test-child.json
@@ -8,7 +8,8 @@
"child-workflow",
"view-test",
"extension-test",
- "longpolling-test"
+ "longpolling-test",
+ "nested-subflow"
],
"attributes": {
"type": "S",
@@ -36,7 +37,7 @@
"sharedTransitions": [],
"startTransition": {
"key": "start-child",
- "target": "child-active",
+ "target": "child-initial",
"triggerType": 0,
"versionStrategy": "Minor",
"labels": [
@@ -67,18 +68,130 @@
},
"states": [
{
- "key": "child-active",
+ "key": "child-initial",
"stateType": 1,
"subType": 0,
"versionStrategy": "Minor",
"labels": [
{
"language": "en-US",
- "label": "Child Workflow Active"
+ "label": "Child Initial State"
},
{
"language": "tr-TR",
- "label": "Alt Akış Aktif"
+ "label": "Alt Akış Başlangıç Durumu"
+ }
+ ],
+ "view": {
+ "view": {
+ "key": "child-workflow-view",
+ "domain": "core",
+ "version": "1.0.0",
+ "flow": "sys-views"
+ },
+ "loadData": true,
+ "extensions": [
+ "child-data-extension"
+ ]
+ },
+ "subFlow": null,
+ "onEntries": [],
+ "onExits": [],
+ "transitions": [
+ {
+ "key": "start-grandchild-subflow",
+ "target": "waiting-for-grandchild",
+ "triggerType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Start Grandchild SubFlow"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Torun Alt Akışı Başlat"
+ }
+ ],
+ "schema": null,
+ "rule": null,
+ "timer": null,
+ "view": null,
+ "onExecutionTasks": []
+ }
+ ]
+ },
+ {
+ "key": "waiting-for-grandchild",
+ "stateType": 4,
+ "subType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Waiting for Grandchild SubFlow"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Torun Alt Akış Bekleniyor"
+ }
+ ],
+ "view": null,
+ "subFlow": {
+ "type": "S",
+ "process": {
+ "key": "subflow-view-test-grandchild",
+ "domain": "core",
+ "version": "1.0.0",
+ "flow": "sys-flows"
+ },
+ "mapping": {
+ "location": "./src/ChildToGrandchildSubFlowMapping.csx",
+ "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLkR5bmFtaWM7CnVzaW5nIFN5c3RlbS5UaHJlYWRpbmcuVGFza3M7CnVzaW5nIEJCVC5Xb3JrZmxvdy5EZWZpbml0aW9uczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZy5GdW5jdGlvbnM7CgovLy8gPHN1bW1hcnk+Ci8vLyBDaGlsZCB0byBHcmFuZGNoaWxkIFN1YkZsb3cgTWFwcGluZyAtIEhhbmRsZXMgaW5wdXQvb3V0cHV0IGZvciBncmFuZGNoaWxkIHN1YmZsb3cgc3RhdGUKLy8vIFRoaXMgbWFwcGluZyBwcmVwYXJlcyBkYXRhIGZvciBncmFuZGNoaWxkIHN1YmZsb3cgYW5kIHByb2Nlc3NlcyBpdHMgcmVzdWx0LgovLy8gTWFuYWdlcyB0aGUgTGV2ZWwgMiB0byBMZXZlbCAzIHRyYW5zaXRpb24gaW4gdGhlIHN1YmZsb3cgaGllcmFyY2h5LgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgQ2hpbGRUb0dyYW5kY2hpbGRTdWJGbG93TWFwcGluZyA6IFNjcmlwdEJhc2UsIElTdWJGbG93TWFwcGluZwp7CiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gUHJlcGFyZXMgaW5wdXQgZGF0YSBmb3IgdGhlIGdyYW5kY2hpbGQgc3ViZmxvdwogICAgLy8vIDwvc3VtbWFyeT4KICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkNoaWxkVG9HcmFuZGNoaWxkU3ViRmxvd01hcHBpbmcgLSBQcmVwYXJpbmcgZ3JhbmRjaGlsZCBzdWJmbG93IGlucHV0IGRhdGEiKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFByZXBhcmUgZGF0YSB0byBwYXNzIHRvIGdyYW5kY2hpbGQgd29ya2Zsb3cgdXNpbmcgRGljdGlvbmFyeQogICAgICAgICAgICB2YXIgdGVzdENvbnRleHQgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJ0ZXN0VHlwZSJdID0gImRlZXAtbmVzdGVkLXZpZXctZXh0ZW5zaW9uLWxvbmdwb2xsaW5nIiwKICAgICAgICAgICAgICAgIFsiZXhwZWN0Vmlld0RhdGEiXSA9IHRydWUsCiAgICAgICAgICAgICAgICBbImV4cGVjdEV4dGVuc2lvbkRhdGEiXSA9IHRydWUsCiAgICAgICAgICAgICAgICBbIm5lc3RpbmdMZXZlbCJdID0gMwogICAgICAgICAgICB9OwogICAgICAgICAgICAKICAgICAgICAgICAgdmFyIGlucHV0RGF0YSA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgb2JqZWN0PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbImNoaWxkSW5zdGFuY2VJZCJdID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICBbImNoaWxkV29ya2Zsb3dJZCJdID0gY29udGV4dC5Xb3JrZmxvdz8uS2V5ID8/IHN0cmluZy5FbXB0eSwKICAgICAgICAgICAgICAgIFsicGFyZW50SW5zdGFuY2VJZCJdID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGFyZW50SW5zdGFuY2VJZCwKICAgICAgICAgICAgICAgIFsicGFyZW50V29ya2Zsb3dJZCJdID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGFyZW50V29ya2Zsb3dJZCwKICAgICAgICAgICAgICAgIFsiaW5pdGlhdGVkQXQiXSA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgIFsiaW5pdGlhdGVkQnkiXSA9ICJjaGlsZC13b3JrZmxvdyIsCiAgICAgICAgICAgICAgICBbIm5lc3RpbmdMZXZlbCJdID0gMywKICAgICAgICAgICAgICAgIFsidGVzdENvbnRleHQiXSA9IHRlc3RDb250ZXh0CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9IGNvbnRleHQuSW5zdGFuY2U/LktleSwKICAgICAgICAgICAgICAgIERhdGEgPSBpbnB1dERhdGEsCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAic3ViZmxvdy10ZXN0IiwgImdyYW5kY2hpbGQtc3ViZmxvdy1pbnB1dCIsICJsZXZlbC0zIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiQ2hpbGRUb0dyYW5kY2hpbGRTdWJGbG93TWFwcGluZyBJbnB1dEhhbmRsZXIgLSBFcnJvcjogezB9IiwgYXJnczogbmV3IG9iamVjdD9bXSB7IGV4Lk1lc3NhZ2UgfSk7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImdyYW5kY2hpbGQtc3ViZmxvdy1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+IHsgWyJlcnJvciJdID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQoKICAgIC8vLyA8c3VtbWFyeT4KICAgIC8vLyBQcm9jZXNzZXMgdGhlIHJlc3VsdCBmcm9tIHRoZSBjb21wbGV0ZWQgZ3JhbmRjaGlsZCBzdWJmbG93CiAgICAvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkNoaWxkVG9HcmFuZGNoaWxkU3ViRmxvd01hcHBpbmcgLSBQcm9jZXNzaW5nIGdyYW5kY2hpbGQgc3ViZmxvdyBvdXRwdXQgZGF0YSIpOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gR2V0IGdyYW5kY2hpbGQgc3ViZmxvdyByZXN1bHQgZGF0YQogICAgICAgICAgICB2YXIgZ3JhbmRjaGlsZFJlc3VsdCA9IGNvbnRleHQuQm9keTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHZhciBncmFuZGNoaWxkUmVzdWx0RGF0YSA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgb2JqZWN0PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbImdyYW5kY2hpbGRJbnN0YW5jZURhdGEiXSA9IGdyYW5kY2hpbGRSZXN1bHQsCiAgICAgICAgICAgICAgICBbInByb2Nlc3NlZCJdID0gdHJ1ZSwKICAgICAgICAgICAgICAgIFsidmlld1Rlc3RSZXN1bHQiXSA9ICJzdWNjZXNzIiwKICAgICAgICAgICAgICAgIFsiZXh0ZW5zaW9uVGVzdFJlc3VsdCJdID0gInN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgWyJkZWVwTmVzdGVkVGVzdFJlc3VsdCJdID0gInN1Y2Nlc3MiCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIAogICAgICAgICAgICB2YXIgY2hpbGRDb250aW51YXRpb24gPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJjYW5Qcm9jZWVkIl0gPSB0cnVlLAogICAgICAgICAgICAgICAgWyJuZXh0U3RhdGUiXSA9ICJjaGlsZC1hZnRlci1ncmFuZGNoaWxkIgogICAgICAgICAgICB9OwogICAgICAgICAgICAKICAgICAgICAgICAgdmFyIG91dHB1dERhdGEgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJncmFuZGNoaWxkU3ViZmxvd0NvbXBsZXRlZCJdID0gdHJ1ZSwKICAgICAgICAgICAgICAgIFsiY29tcGxldGVkQXQiXSA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgIFsiZ3JhbmRjaGlsZFJlc3VsdCJdID0gZ3JhbmRjaGlsZFJlc3VsdERhdGEsCiAgICAgICAgICAgICAgICBbImNoaWxkQ29udGludWF0aW9uIl0gPSBjaGlsZENvbnRpbnVhdGlvbiwKICAgICAgICAgICAgICAgIFsibmVzdGluZ0xldmVsIl0gPSAzCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJncmFuZGNoaWxkLXN1YmZsb3ctb3V0cHV0LXByb2Nlc3NlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gb3V0cHV0RGF0YSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJzdWJmbG93LXRlc3QiLCAiZ3JhbmRjaGlsZC1zdWJmbG93LW91dHB1dCIsICJjb21wbGV0ZWQiLCAibGV2ZWwtMyIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgTG9nRXJyb3IoIkNoaWxkVG9HcmFuZGNoaWxkU3ViRmxvd01hcHBpbmcgT3V0cHV0SGFuZGxlciAtIEVycm9yOiB7MH0iLCBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZ3JhbmRjaGlsZC1zdWJmbG93LW91dHB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+IHsgWyJlcnJvciJdID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cg=="
+ }
+ },
+ "onEntries": [],
+ "onExits": [],
+ "transitions": [
+ {
+ "key": "grandchild-subflow-completed",
+ "target": "child-after-grandchild",
+ "triggerType": 1,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Grandchild SubFlow Completed"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Torun Alt Akış Tamamlandı"
+ }
+ ],
+ "schema": null,
+ "rule": {
+ "location": "./src/AlwaysTrueRule.csx",
+ "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo="
+ },
+ "timer": null,
+ "view": null,
+ "onExecutionTasks": []
+ }
+ ]
+ },
+ {
+ "key": "child-after-grandchild",
+ "stateType": 2,
+ "subType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "After Grandchild SubFlow State"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Torun Alt Akış Sonrası Durumu"
}
],
"view": {
diff --git a/core/Workflows/subflow-test/subflow-view-test-grandchild.json b/core/Workflows/subflow-test/subflow-view-test-grandchild.json
new file mode 100644
index 0000000..1315292
--- /dev/null
+++ b/core/Workflows/subflow-test/subflow-view-test-grandchild.json
@@ -0,0 +1,262 @@
+{
+ "key": "subflow-view-test-grandchild",
+ "flow": "sys-flows",
+ "domain": "core",
+ "version": "1.0.0",
+ "tags": [
+ "subflow-test",
+ "grandchild-workflow",
+ "view-test",
+ "extension-test",
+ "longpolling-test",
+ "deep-nested-test",
+ "busy-state-test"
+ ],
+ "attributes": {
+ "type": "S",
+ "timeout": null,
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "SubFlow View Test - Grandchild Workflow"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Alt Akış Görünüm Testi - Torun Akış"
+ }
+ ],
+ "functions": [],
+ "features": [],
+ "extensions": [
+ {
+ "key": "grandchild-data-extension",
+ "domain": "core",
+ "version": "1.0.0",
+ "flow": "sys-extensions"
+ }
+ ],
+ "sharedTransitions": [],
+ "startTransition": {
+ "key": "start-grandchild",
+ "target": "grandchild-active",
+ "triggerType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Start Grandchild Workflow"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Torun Akışı Başlat"
+ }
+ ],
+ "onExecutionTasks": [
+ {
+ "order": 1,
+ "task": {
+ "key": "script-task",
+ "domain": "core",
+ "version": "1.0.0",
+ "flow": "sys-tasks"
+ },
+ "mapping": {
+ "location": "./src/GrandchildStartMapping.csx",
+ "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gR3JhbmRjaGlsZCBTdGFydCBNYXBwaW5nIC0gSW5pdGlhbGl6ZXMgdGhlIGdyYW5kY2hpbGQgd29ya2Zsb3cgd2l0aCBkYXRhIGZyb20gY2hpbGQKLy8vIFRoaXMgaXMgdGhlIGRlZXBlc3QgbGV2ZWwgKGxldmVsIDMpIGluIHRoZSBzdWJmbG93IGhpZXJhcmNoeS4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIEdyYW5kY2hpbGRTdGFydE1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkdyYW5kY2hpbGRTdGFydE1hcHBpbmcgLSBJbml0aWFsaXppbmcgZ3JhbmRjaGlsZCB3b3JrZmxvdyAoTGV2ZWwgMykiKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHZhciBpbnB1dERhdGEgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhOwogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZ3JhbmRjaGlsZC1zdGFydC1zdWNjZXNzIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBncmFuZGNoaWxkV29ya2Zsb3dJZCA9IGNvbnRleHQuV29ya2Zsb3c/LktleSwKICAgICAgICAgICAgICAgICAgICBncmFuZGNoaWxkSW5zdGFuY2VJZCA9IGNvbnRleHQuSW5zdGFuY2U/LklkLAogICAgICAgICAgICAgICAgICAgIGNoaWxkSW5zdGFuY2VJZCA9IGlucHV0RGF0YT8uY2hpbGRJbnN0YW5jZUlkLAogICAgICAgICAgICAgICAgICAgIGNoaWxkV29ya2Zsb3dJZCA9IGlucHV0RGF0YT8uY2hpbGRXb3JrZmxvd0lkLAogICAgICAgICAgICAgICAgICAgIHBhcmVudEluc3RhbmNlSWQgPSBpbnB1dERhdGE/LnBhcmVudEluc3RhbmNlSWQsCiAgICAgICAgICAgICAgICAgICAgcGFyZW50V29ya2Zsb3dJZCA9IGlucHV0RGF0YT8ucGFyZW50V29ya2Zsb3dJZCwKICAgICAgICAgICAgICAgICAgICBuZXN0aW5nTGV2ZWwgPSAzLAogICAgICAgICAgICAgICAgICAgIHN0YXJ0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSAiYWN0aXZlIiwKICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gIkdyYW5kY2hpbGQgd29ya2Zsb3cgc3RhcnRlZCBzdWNjZXNzZnVsbHkgKExldmVsIDMpIiwKICAgICAgICAgICAgICAgICAgICBncmFuZGNoaWxkQ29udGV4dCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXNTdWJmbG93ID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgaXNEZWVwTmVzdGVkID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tzUGFyZW50ID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdmlld1Rlc3RFbmFibGVkID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uVGVzdEVuYWJsZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBoaWVyYXJjaHlQYXRoID0gIlBhcmVudCA+IENoaWxkID4gR3JhbmRjaGlsZCIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInN1YmZsb3ctdGVzdCIsICJncmFuZGNoaWxkLXdvcmtmbG93IiwgInN0YXJ0ZWQiLCAibGV2ZWwtMyIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgTG9nRXJyb3IoIkdyYW5kY2hpbGRTdGFydE1hcHBpbmcgLSBFcnJvcjogezB9IiwgYXJnczogbmV3IG9iamVjdD9bXSB7IGV4Lk1lc3NhZ2UgfSk7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImdyYW5kY2hpbGQtc3RhcnQtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cg=="
+ }
+ }
+ ]
+ },
+ "states": [
+ {
+ "key": "grandchild-active",
+ "stateType": 1,
+ "subType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Grandchild Workflow Active"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Torun Akış Aktif"
+ }
+ ],
+ "view": {
+ "view": {
+ "key": "grandchild-workflow-view",
+ "domain": "core",
+ "version": "1.0.0",
+ "flow": "sys-views"
+ },
+ "loadData": true,
+ "extensions": [
+ "grandchild-data-extension"
+ ]
+ },
+ "subFlow": null,
+ "onEntries": [],
+ "onExits": [],
+ "transitions": [
+ {
+ "key": "enter-busy-state",
+ "target": "grandchild-busy",
+ "triggerType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Enter Busy State"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Meşgul Durumuna Geç"
+ }
+ ],
+ "schema": null,
+ "rule": null,
+ "timer": null,
+ "view": null,
+ "onExecutionTasks": []
+ }
+ ]
+ },
+ {
+ "key": "grandchild-busy",
+ "stateType": 2,
+ "subType": 5,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Grandchild Busy - Processing"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Torun Meşgul - İşleniyor"
+ }
+ ],
+ "view": null,
+ "subFlow": null,
+ "onEntries": [
+ {
+ "order": 1,
+ "task": {
+ "key": "start-busy-subprocess-task",
+ "domain": "core",
+ "version": "1.0.0",
+ "flow": "sys-tasks"
+ },
+ "mapping": {
+ "location": "./src/StartBusySubprocessMapping.csx",
+ "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gU3RhcnQgQnVzeSBTdWJQcm9jZXNzIE1hcHBpbmcgLSBTdGFydHMgdGhlIHN1YnByb2Nlc3Mgd2hlbiBncmFuZGNoaWxkIGVudGVycyBidXN5IHN0YXRlCi8vLyBUaGlzIG1hcHBpbmcgY29uZmlndXJlcyB0aGUgU3ViUHJvY2Vzc1Rhc2sgdG8gbGF1bmNoIGFuIGluZGVwZW5kZW50IHN1YnByb2Nlc3MKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFN0YXJ0QnVzeVN1YnByb2Nlc3NNYXBwaW5nIDogU2NyaXB0QmFzZSwgSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHN1YlByb2Nlc3NUYXNrID0gdGFzayBhcyBTdWJQcm9jZXNzVGFzazsKICAgICAgICAgICAgCiAgICAgICAgICAgIExvZ0luZm9ybWF0aW9uKCJTdGFydEJ1c3lTdWJwcm9jZXNzTWFwcGluZyAtIFByZXBhcmluZyB0byBzdGFydCBidXN5IHN1YnByb2Nlc3MiKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSBzdWJwcm9jZXNzCiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldERvbWFpbigiY29yZSIpOwogICAgICAgICAgICBzdWJQcm9jZXNzVGFzay5TZXRGbG93KCJzeXMtZmxvd3MiKTsKICAgICAgICAgICAgc3ViUHJvY2Vzc1Rhc2suU2V0S2V5KCJidXN5LXN1YnByb2Nlc3Mtd29ya2Zsb3ciKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFByZXBhcmUgc3VicHJvY2VzcyBkYXRhIC0gaW5jbHVkZSBwYXJlbnQgaW5zdGFuY2UgSUQgc28gc3VicHJvY2VzcyBjYW4gdHJpZ2dlciBiYWNrCiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldEJvZHkobmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGdyYW5kY2hpbGRJbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICBncmFuZGNoaWxkV29ya2Zsb3dJZCA9IGNvbnRleHQuV29ya2Zsb3c/LktleSwKICAgICAgICAgICAgICAgIHBhcmVudEluc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5jaGlsZEluc3RhbmNlSWQsCiAgICAgICAgICAgICAgICBzdGFydGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJidXN5LXN0YXRlLXByb2Nlc3NpbmciLAogICAgICAgICAgICAgICAgY29udGV4dCA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5lc3RpbmdMZXZlbCA9IDMsCiAgICAgICAgICAgICAgICAgICAgdGVzdFR5cGUgPSAiYnVzeS1zdGF0ZS10ZXN0IiwKICAgICAgICAgICAgICAgICAgICBleHBlY3RlZEJlaGF2aW9yID0gInN1YnByb2Nlc3Mtd2lsbC10cmlnZ2VyLXBhcmVudCIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiU3RhcnRCdXN5U3VicHJvY2Vzc01hcHBpbmcgLSBTdWJwcm9jZXNzIGNvbmZpZ3VyZWQgYW5kIHJlYWR5IHRvIGxhdW5jaCIpOwogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRGF0YSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGEKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiU3RhcnRCdXN5U3VicHJvY2Vzc01hcHBpbmcgLSBFcnJvcjogezB9IiwgYXJnczogbmV3IG9iamVjdD9bXSB7IGV4Lk1lc3NhZ2UgfSk7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzdWJwcm9jZXNzLXN0YXJ0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIlN0YXJ0QnVzeVN1YnByb2Nlc3NNYXBwaW5nIC0gU3VicHJvY2VzcyBsYXVuY2hlZCBzdWNjZXNzZnVsbHkiKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFN1YlByb2Nlc3MgaXMgZmlyZS1hbmQtZm9yZ2V0LCBqdXN0IHRyYWNrIHRoYXQgaXQgd2FzIGluaXRpYXRlZAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWJwcm9jZXNzTGF1bmNoZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgIHN1YnByb2Nlc3NJbnN0YW5jZUlkID0gY29udGV4dC5Cb2R5Py5kYXRhPy5pbnN0YW5jZUlkLAogICAgICAgICAgICAgICAgICAgIGxhdW5jaGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gIkJVU1kiLAogICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSAiU3VicHJvY2VzcyBsYXVuY2hlZCAtIGdyYW5kY2hpbGQgbm93IGluIGJ1c3kgc3RhdGUgd2FpdGluZyBmb3Igc3VicHJvY2VzcyB0byBjb21wbGV0ZSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0Vycm9yKCJTdGFydEJ1c3lTdWJwcm9jZXNzTWFwcGluZyAtIE91dHB1dCBoYW5kbGVyIGVycm9yOiB7MH0iLCBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAib3V0cHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQo="
+ }
+ }
+ ],
+ "onExits": [],
+ "transitions": [
+ {
+ "key": "complete-busy-state",
+ "target": "grandchild-after-busy",
+ "triggerType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Complete Busy State (Triggered by SubProcess)"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Meşgul Durumu Tamamla (Alt İşlem Tarafından Tetiklenir)"
+ }
+ ],
+ "schema": null,
+ "rule": null,
+ "timer": null,
+ "view": null,
+ "onExecutionTasks": []
+ }
+ ]
+ },
+ {
+ "key": "grandchild-after-busy",
+ "stateType": 2,
+ "subType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Grandchild After Busy State"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Torun Meşgul Sonrası"
+ }
+ ],
+ "view": null,
+ "subFlow": null,
+ "onEntries": [],
+ "onExits": [],
+ "transitions": [
+ {
+ "key": "complete-grandchild",
+ "target": "grandchild-completed",
+ "triggerType": 0,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Complete Grandchild Workflow"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Torun Akışı Tamamla"
+ }
+ ],
+ "schema": null,
+ "rule": null,
+ "timer": null,
+ "view": null,
+ "onExecutionTasks": [
+ {
+ "order": 1,
+ "task": {
+ "key": "script-task",
+ "domain": "core",
+ "version": "1.0.0",
+ "flow": "sys-tasks"
+ },
+ "mapping": {
+ "location": "./src/GrandchildCompleteMapping.csx",
+ "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gR3JhbmRjaGlsZCBDb21wbGV0ZSBNYXBwaW5nIC0gTWFya3MgdGhlIGdyYW5kY2hpbGQgd29ya2Zsb3cgYXMgY29tcGxldGVkCi8vLyBUaGlzIGRhdGEgd2lsbCBiZSByZXR1cm5lZCB0byB0aGUgY2hpbGQgd29ya2Zsb3cgKExldmVsIDIpCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBHcmFuZGNoaWxkQ29tcGxldGVNYXBwaW5nIDogU2NyaXB0QmFzZSwgSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0luZm9ybWF0aW9uKCJHcmFuZGNoaWxkQ29tcGxldGVNYXBwaW5nIC0gQ29tcGxldGluZyBncmFuZGNoaWxkIHdvcmtmbG93IChMZXZlbCAzKSIpOwogICAgICAgICAgICAKICAgICAgICAgICAgdmFyIGlucHV0RGF0YSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJncmFuZGNoaWxkLWNvbXBsZXRlLXN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9ICJjb21wbGV0ZWQiLAogICAgICAgICAgICAgICAgICAgIG5lc3RpbmdMZXZlbCA9IDMsCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBncmFuZGNoaWxkV29ya2Zsb3dJZCA9IGNvbnRleHQuV29ya2Zsb3c/LktleSwKICAgICAgICAgICAgICAgICAgICAgICAgZ3JhbmRjaGlsZEluc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZCwKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSAiR3JhbmRjaGlsZCB3b3JrZmxvdyBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5IChMZXZlbCAzKSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGb3JDaGlsZCA9IG5ldwogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmFuZGNoaWxkUmVzdWx0ID0gInByb2Nlc3NlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzaW5nVGltZSA9IDEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdUZXN0UGFzc2VkID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblRlc3RQYXNzZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVlcE5lc3RlZFRlc3RQYXNzZWQgPSB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInN1YmZsb3ctdGVzdCIsICJncmFuZGNoaWxkLXdvcmtmbG93IiwgImNvbXBsZXRlZCIsICJsZXZlbC0zIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiR3JhbmRjaGlsZENvbXBsZXRlTWFwcGluZyAtIEVycm9yOiB7MH0iLCBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZ3JhbmRjaGlsZC1jb21wbGV0ZS1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0K"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "key": "grandchild-completed",
+ "stateType": 3,
+ "subType": 1,
+ "versionStrategy": "Minor",
+ "labels": [
+ {
+ "language": "en-US",
+ "label": "Grandchild Workflow Completed"
+ },
+ {
+ "language": "tr-TR",
+ "label": "Torun Akış Tamamlandı"
+ }
+ ],
+ "view": null,
+ "subFlow": null,
+ "onEntries": [],
+ "onExits": [],
+ "transitions": []
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/core/Workflows/subflow-test/subflow-view-test.http b/core/Workflows/subflow-test/subflow-view-test.http
index bf947d9..035bef0 100644
--- a/core/Workflows/subflow-test/subflow-view-test.http
+++ b/core/Workflows/subflow-test/subflow-view-test.http
@@ -1,16 +1,19 @@
-### SubFlow View & Extension Test
-### This file tests the longpolling view endpoint with subflow, views and extensions
-### Test Goal: Verify that views and extensions work correctly for both parent and child workflows
+### SubFlow View & Extension Test - 3 Level Nested SubFlows
+### This file tests the longpolling view endpoint with deep nested subflows, views and extensions
+### Test Goal: Verify that views and extensions work correctly for parent, child, and grandchild workflows
+###
+### Hierarchy: Parent (Level 1) > Child (Level 2) > Grandchild (Level 3)
@baseUrl = http://localhost:4201
@apiVersion = 1
@domain = core
@parentWorkflow = subflow-view-test-parent
@childWorkflow = subflow-view-test-child
+@grandchildWorkflow = subflow-view-test-grandchild
@instanceKey = subflow-test-{{$timestamp}}
### ============================================
-### STEP 1: Start Parent Workflow
+### STEP 1: Start Parent Workflow (Level 1)
### This starts the parent workflow in initial state
### ============================================
@@ -20,25 +23,25 @@ Content-Type: application/json
{
"key": "{{instanceKey}}",
- "tags": ["subflow-test", "view-test", "extension-test", "longpolling-test"],
+ "tags": ["subflow-test", "view-test", "extension-test", "longpolling-test", "3-level-nested"],
"attributes": {
"testId": "subflow-view-extension-test-001",
- "testDescription": "Testing view and extension with subflow",
+ "testDescription": "Testing 3-level nested subflows with view and extension",
"createdAt": "{{$datetime iso8601}}"
}
}
### ============================================
### STEP 2: Get Parent Workflow State (Long Polling)
-### Check current state of parent workflow
+### Check current state of parent workflow - should be "parent-initial"
### ============================================
# @name getParentState
-GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/e71660b4-5ba6-4644-a9f9-13eb4acacc2a/functions/state
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/state
Accept: application/json
### ============================================
-### STEP 3: Get Parent View with Extensions
+### STEP 3: Get Parent View with Extensions (Level 1)
### THIS IS THE KEY LONGPOLLING TEST FOR PARENT
### Expected: parent-workflow-view with parent-data-extension data
### ============================================
@@ -56,16 +59,16 @@ GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/inst
Accept: application/json
### ============================================
-### STEP 5: Execute Transition to Start SubFlow
-### This triggers the subflow state - parent will wait for child
+### STEP 5: Execute Transition to Start SubFlow (Parent -> Child)
+### This triggers the child subflow state - parent will wait for child
### ============================================
-# @name startSubflow
+# @name startChildSubflow
PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/transitions/start-subflow
Content-Type: application/json
{
- "message": "Starting subflow for view and extension test"
+ "message": "Starting child subflow for 3-level nested test"
}
### ============================================
@@ -78,19 +81,16 @@ GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/inst
Accept: application/json
### ============================================
-### STEP 7: Get Child Workflow Instance
-### Find the child workflow instance that was started
-### Note: You may need to replace {{childInstanceKey}} with actual child instance key
+### STEP 7: Get Parent Data to Find Child Instance ID
+### Check parent data to find child instance ID
### ============================================
-### -- Check parent data to find child instance ID --
-
# @name getParentDataForChildId
GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/data
Accept: application/json
### ============================================
-### STEP 8: Get Child View with Extensions
+### STEP 8: Get Child View with Extensions (Level 2)
### THIS IS THE KEY LONGPOLLING TEST FOR CHILD
### Expected: child-workflow-view with child-data-extension data
### Note: Replace {{childInstanceId}} with actual child instance ID from previous step
@@ -104,6 +104,7 @@ Accept: application/json
### ============================================
### STEP 9: Get Child State
+### Child should be in "child-initial" state
### ============================================
# @name getChildState
@@ -119,8 +120,164 @@ GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/insta
Accept: application/json
### ============================================
-### STEP 11: Complete Child Workflow
-### This will trigger the subflow completion and unblock parent
+### STEP 11: Start Grandchild SubFlow (Child -> Grandchild)
+### This triggers the grandchild subflow state - child will wait for grandchild
+### ============================================
+
+# @name startGrandchildSubflow
+PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/transitions/start-grandchild-subflow
+Content-Type: application/json
+
+{
+ "message": "Starting grandchild subflow for deep nested test"
+}
+
+### ============================================
+### STEP 12: Get Child State After Grandchild SubFlow Started
+### Child should be in "waiting-for-grandchild" state now
+### ============================================
+
+# @name getChildStateAfterGrandchild
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/state
+Accept: application/json
+
+### ============================================
+### STEP 13: Get Child Data to Find Grandchild Instance ID
+### Check child data to find grandchild instance ID
+### ============================================
+
+# @name getChildDataForGrandchildId
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/data
+Accept: application/json
+
+### ============================================
+### STEP 14: Get Grandchild View with Extensions (Level 3)
+### THIS IS THE KEY LONGPOLLING TEST FOR GRANDCHILD (DEEPEST LEVEL)
+### Expected: grandchild-workflow-view with grandchild-data-extension data
+### Note: Replace {{grandchildInstanceId}} with actual grandchild instance ID from previous step
+### ============================================
+
+@grandchildInstanceId = REPLACE_WITH_GRANDCHILD_INSTANCE_ID
+
+# @name getGrandchildView
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/view
+Accept: application/json
+
+### ============================================
+### STEP 15: Get Grandchild State
+### Grandchild should be in "grandchild-active" state
+### ============================================
+
+# @name getGrandchildState
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/state
+Accept: application/json
+
+### ============================================
+### STEP 16: Get Grandchild Data
+### ============================================
+
+# @name getGrandchildData
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/data
+Accept: application/json
+
+### ============================================
+### STEP 17: Enter Busy State (Busy State Test - subType: 5)
+### This transitions grandchild to busy state and starts a subprocess
+### The subprocess will trigger the transition when complete
+### ============================================
+
+# @name enterBusyState
+PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/transitions/enter-busy-state
+Content-Type: application/json
+
+{
+ "message": "Entering busy state - subprocess will be launched"
+}
+
+### ============================================
+### STEP 18: Check Grandchild State - Should be BUSY (subType: 5)
+### The state should be "grandchild-busy" with subType: 5
+### The subprocess should be running in background
+### ============================================
+
+# @name getGrandchildBusyState
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/state
+Accept: application/json
+
+### ============================================
+### STEP 19: Get Grandchild Data During Busy State
+### Should show subprocess launched and busy status
+### ============================================
+
+# @name getGrandchildDataDuringBusy
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/data
+Accept: application/json
+
+### ============================================
+### STEP 20: Wait for SubProcess to Complete and Trigger Transition
+### The subprocess (busy-subprocess-workflow) will:
+### 1. Complete its processing
+### 2. Use DirectTriggerTask to trigger 'complete-busy-state' transition
+### 3. Grandchild will automatically move to 'grandchild-after-busy' state
+###
+### NOTE: Wait ~5-10 seconds for subprocess to complete
+### Then check state again to verify automatic transition occurred
+### ============================================
+
+### ============================================
+### STEP 21: Verify Grandchild Transitioned Out of Busy State
+### The state should now be "grandchild-after-busy" (subType: 0)
+### This confirms the subprocess successfully triggered the transition
+### ============================================
+
+# @name getGrandchildStateAfterBusy
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/state
+Accept: application/json
+
+### ============================================
+### STEP 22: Get Grandchild Data After Busy State
+### Should show subprocess completion data and trigger info
+### ============================================
+
+# @name getGrandchildDataAfterBusy
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/data
+Accept: application/json
+
+### ============================================
+### STEP 23: Complete Grandchild Workflow (Level 3 -> Level 2)
+### Now complete the grandchild workflow normally
+### This will trigger the grandchild completion and unblock child
+### ============================================
+
+# @name completeGrandchild
+PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/transitions/complete-grandchild
+Content-Type: application/json
+
+{
+ "completionMessage": "Grandchild workflow completed after busy state test"
+}
+
+### ============================================
+### STEP 24: Check Child State After Grandchild Completed
+### Child should now be in "child-after-grandchild" state
+### ============================================
+
+# @name getChildStateAfterGrandchildComplete
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/state
+Accept: application/json
+
+### ============================================
+### STEP 25: Get Child View After Grandchild SubFlow
+### Verify view and extensions still work after grandchild subflow completes
+### ============================================
+
+# @name getChildViewAfterGrandchild
+GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/view
+Accept: application/json
+
+### ============================================
+### STEP 26: Complete Child Workflow (Level 2 -> Level 1)
+### This will trigger the child completion and unblock parent
### ============================================
# @name completeChild
@@ -128,11 +285,11 @@ PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/ins
Content-Type: application/json
{
- "completionMessage": "Child workflow completed for test"
+ "completionMessage": "Child workflow completed for nested test"
}
### ============================================
-### STEP 12: Check Parent State After Child Completed
+### STEP 27: Check Parent State After Child Completed
### Parent should now be in "parent-after-subflow" state
### ============================================
@@ -141,8 +298,8 @@ GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/inst
Accept: application/json
### ============================================
-### STEP 13: Get Parent View After SubFlow (should show again)
-### Verify view and extensions still work after subflow completes
+### STEP 28: Get Parent View After SubFlow (should show again)
+### Verify view and extensions still work after child subflow completes
### ============================================
# @name getParentViewAfterSubflow
@@ -150,7 +307,7 @@ GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/inst
Accept: application/json
### ============================================
-### STEP 14: Complete Parent Workflow
+### STEP 29: Complete Parent Workflow (Level 1 Final)
### Final transition to complete the parent workflow
### ============================================
@@ -159,12 +316,12 @@ PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/in
Content-Type: application/json
{
- "finalMessage": "Parent workflow completed successfully"
+ "finalMessage": "Parent workflow completed successfully with 3-level nested subflows and busy state test"
}
### ============================================
-### STEP 15: Verify Final State
-### Both parent should be completed
+### STEP 30: Verify Final State
+### Parent should be completed
### ============================================
# @name getFinalParentState
@@ -172,7 +329,7 @@ GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/inst
Accept: application/json
### ============================================
-### STEP 16: Get Final Data
+### STEP 31: Get Final Data
### Check all test results in the data
### ============================================
@@ -185,24 +342,62 @@ Accept: application/json
### ============================================
###
### Test Objectives:
-### 1. ✅ Parent workflow starts with own view and extensions
-### 2. ✅ Parent view returns with parent-data-extension data
-### 3. ✅ Parent transitions to subflow state (blocking)
-### 4. ✅ Child workflow has its own view and extensions
-### 5. ✅ Child view returns with child-data-extension data
-### 6. ✅ Child workflow completes via manual transition
-### 7. ✅ Parent unblocks and continues after child completes
-### 8. ✅ Parent view still works after subflow
-### 9. ✅ Parent completes via manual transition
+### 1. Parent workflow starts with own view and extensions (Level 1)
+### 2. Parent view returns with parent-data-extension data
+### 3. Parent transitions to child subflow state (blocking)
+### 4. Child workflow starts with own view and extensions (Level 2)
+### 5. Child view returns with child-data-extension data
+### 6. Child transitions to grandchild subflow state (blocking)
+### 7. Grandchild workflow has its own view and extensions (Level 3 - Deepest)
+### 8. Grandchild view returns with grandchild-data-extension data
+### 9. **NEW** Grandchild enters Busy state (subType: 5)
+### 10. **NEW** Busy state launches subprocess (SubProcessTask - Type 11)
+### 11. **NEW** Grandchild waits in Busy state for subprocess
+### 12. **NEW** SubProcess completes and triggers parent transition (DirectTriggerTask - Type 12)
+### 13. **NEW** Grandchild automatically exits Busy state via triggered transition
+### 14. Grandchild workflow completes via manual transition
+### 15. Child unblocks and continues after grandchild completes
+### 16. Child view still works after grandchild subflow
+### 17. Child workflow completes via manual transition
+### 18. Parent unblocks and continues after child completes
+### 19. Parent view still works after child subflow
+### 20. Parent completes via manual transition
+###
+### Workflow Hierarchy:
+### ==================
+### Level 1: subflow-view-test-parent
+### |
+### +-- Level 2: subflow-view-test-child
+### |
+### +-- Level 3: subflow-view-test-grandchild
###
### Key Endpoints Tested:
-### - /functions/view - Long polling for view with extensions
-### - /functions/state - Long polling for state
-### - /functions/data - Instance data retrieval
-### - /transitions/{key} - Manual transition execution
+### - /functions/view - Long polling for view with extensions (all 3 levels)
+### - /functions/state - Long polling for state (all 3 levels)
+### - /functions/data - Instance data retrieval (all 3 levels)
+### - /transitions/{key} - Manual transition execution (all 3 levels)
###
### Expected Extension Data in View Response:
### - Parent: parentExtension.data.parentConfig, parentExtension.data.parentMetadata
### - Child: childExtension.data.childConfig, childExtension.data.childMetadata
+### - Grandchild: grandchildExtension.data.grandchildConfig, grandchildExtension.data.grandchildMetadata
+###
+### Busy State Test Details:
+### ========================
+### - State subType: 5 (Busy) - New state subType for busy/processing states
+### - OnEntry Task: SubProcessTask (Type 11) - Launches independent subprocess
+### - SubProcess Workflow: busy-subprocess-workflow
+### - SubProcess Actions:
+### 1. Starts and enters "processing" state
+### 2. Auto-transitions to "trigger-parent" state
+### 3. Uses DirectTriggerTask (Type 12) to trigger parent's 'complete-busy-state' transition
+### 4. Auto-transitions to "completed" final state
+### - Expected Behavior:
+### - Grandchild enters busy state → status becomes BUSY
+### - SubProcess launches in background (fire-and-forget)
+### - Grandchild waits for manual transition (triggered by subprocess)
+### - SubProcess completes → triggers grandchild transition
+### - Grandchild exits busy state → continues normal flow
+### - Demonstrates: State enters → Busy → Waits → SubProcess pings → Transition → State changes
###
diff --git a/core/Workflows/task-test/error-boundary-test-workflow.json b/core/Workflows/task-test/error-boundary-test-workflow.json
index e3b0800..6592fc3 100644
--- a/core/Workflows/task-test/error-boundary-test-workflow.json
+++ b/core/Workflows/task-test/error-boundary-test-workflow.json
@@ -137,10 +137,10 @@
"priority": 100,
"retryPolicy": {
"maxRetries": 3,
- "initialDelay": "0.00:00:02",
+ "initialDelay": "PT2S",
"backoffType": 1,
"backoffMultiplier": 2,
- "maxDelay": "0.00:00:06"
+ "maxDelay": "PT6S"
}
},
{
@@ -149,7 +149,7 @@
"500"
],
"priority": 50,
- "transition": "error-recovery"
+ "transition": "recovery-to-rollback"
}
]
}
@@ -386,10 +386,10 @@
"priority": 100,
"retryPolicy": {
"maxRetries": 5,
- "initialDelay": "0.00:00:5",
+ "initialDelay": "PT5S",
"backoffType": 0,
"backoffMultiplier": 1,
- "maxDelay": "0.00:00:25"
+ "maxDelay": "PT25S"
}
}
]
@@ -448,10 +448,10 @@
"transition": "timeout-state",
"defaultRetryPolicy": {
"maxRetries": 2,
- "initialDelay": "0.00:00:05",
+ "initialDelay": "PT5S",
"backoffType": 1,
"backoffMultiplier": 1.5,
- "maxDelay": "0.00:00:10"
+ "maxDelay": "PT10S"
}
}
},
diff --git a/package-lock.json b/package-lock.json
index 946c669..dbc7861 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,14 +10,14 @@
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
- "@burgan-tech/vnext-schema": "^0.0.28"
+ "@burgan-tech/vnext-schema": "^0.0.33"
},
"bin": {
"vnext-setup": "setup.js",
"vnext-template": "init.js"
},
"devDependencies": {
- "@burgan-tech/vnext-schema": "^0.0.28",
+ "@burgan-tech/vnext-schema": "^0.0.33",
"ajv": "^8.12.0",
"ajv-formats": "^2.1.1"
},
@@ -26,9 +26,9 @@
}
},
"node_modules/@burgan-tech/vnext-schema": {
- "version": "0.0.28",
- "resolved": "https://registry.npmjs.org/@burgan-tech/vnext-schema/-/vnext-schema-0.0.28.tgz",
- "integrity": "sha512-p+ZyGXb79N4KCYaIQuzh8+6/ku7L5TcmndQ9illDmyCxXszQPwVM68pQjb/HbvsF0cDfv8kutzmgvuo6rTbC8g==",
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/@burgan-tech/vnext-schema/-/vnext-schema-0.0.33.tgz",
+ "integrity": "sha512-xDKVPuoib0jmfAI8vYFOvXWOq8Kl+K/QyEYHLH2Veib5QupZhqhFCIrUdw/uRzivAwQ2ZogAy/dd+9PIzD23+g==",
"dev": true,
"license": "MIT",
"engines": {
diff --git a/package.json b/package.json
index 0d9f614..52a1e6c 100644
--- a/package.json
+++ b/package.json
@@ -55,11 +55,11 @@
"node": ">=16.0.0"
},
"devDependencies": {
- "@burgan-tech/vnext-schema": "^0.0.28",
+ "@burgan-tech/vnext-schema": "^0.0.33",
"ajv": "^8.12.0",
"ajv-formats": "^2.1.1"
},
"dependencies": {
- "@burgan-tech/vnext-schema": "^0.0.28"
+ "@burgan-tech/vnext-schema": "^0.0.33"
}
}
diff --git a/vnext.config.json b/vnext.config.json
index 18498f2..1c32a39 100644
--- a/vnext.config.json
+++ b/vnext.config.json
@@ -2,8 +2,8 @@
"version": "1.0.0",
"description": "core Domain Definition Configuration",
"domain": "core",
- "runtimeVersion": "0.0.28",
- "schemaVersion": "0.0.28",
+ "runtimeVersion": "0.0.32",
+ "schemaVersion": "0.0.33",
"paths": {
"componentsRoot": "core",
"tasks": "Tasks",