planar 0.5.0__py3-none-any.whl → 0.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. planar/_version.py +1 -1
  2. planar/ai/agent.py +155 -283
  3. planar/ai/agent_base.py +170 -0
  4. planar/ai/agent_utils.py +7 -0
  5. planar/ai/pydantic_ai.py +638 -0
  6. planar/ai/test_agent_serialization.py +1 -1
  7. planar/app.py +64 -20
  8. planar/cli.py +39 -27
  9. planar/config.py +45 -36
  10. planar/db/db.py +2 -1
  11. planar/files/storage/azure_blob.py +343 -0
  12. planar/files/storage/base.py +7 -0
  13. planar/files/storage/config.py +70 -7
  14. planar/files/storage/s3.py +6 -6
  15. planar/files/storage/test_azure_blob.py +435 -0
  16. planar/logging/formatter.py +17 -4
  17. planar/logging/test_formatter.py +327 -0
  18. planar/registry_items.py +2 -1
  19. planar/routers/agents_router.py +3 -1
  20. planar/routers/files.py +11 -2
  21. planar/routers/models.py +14 -1
  22. planar/routers/test_agents_router.py +1 -1
  23. planar/routers/test_files_router.py +49 -0
  24. planar/routers/test_routes_security.py +5 -7
  25. planar/routers/test_workflow_router.py +270 -3
  26. planar/routers/workflow.py +95 -36
  27. planar/rules/models.py +36 -39
  28. planar/rules/test_data/account_dormancy_management.json +223 -0
  29. planar/rules/test_data/airline_loyalty_points_calculator.json +262 -0
  30. planar/rules/test_data/applicant_risk_assessment.json +435 -0
  31. planar/rules/test_data/booking_fraud_detection.json +407 -0
  32. planar/rules/test_data/cellular_data_rollover_system.json +258 -0
  33. planar/rules/test_data/clinical_trial_eligibility_screener.json +437 -0
  34. planar/rules/test_data/customer_lifetime_value.json +143 -0
  35. planar/rules/test_data/import_duties_calculator.json +289 -0
  36. planar/rules/test_data/insurance_prior_authorization.json +443 -0
  37. planar/rules/test_data/online_check_in_eligibility_system.json +254 -0
  38. planar/rules/test_data/order_consolidation_system.json +375 -0
  39. planar/rules/test_data/portfolio_risk_monitor.json +471 -0
  40. planar/rules/test_data/supply_chain_risk.json +253 -0
  41. planar/rules/test_data/warehouse_cross_docking.json +237 -0
  42. planar/rules/test_rules.py +750 -6
  43. planar/scaffold_templates/planar.dev.yaml.j2 +6 -6
  44. planar/scaffold_templates/planar.prod.yaml.j2 +9 -5
  45. planar/scaffold_templates/pyproject.toml.j2 +1 -1
  46. planar/security/auth_context.py +21 -0
  47. planar/security/{jwt_middleware.py → auth_middleware.py} +70 -17
  48. planar/security/authorization.py +9 -15
  49. planar/security/tests/test_auth_middleware.py +162 -0
  50. planar/sse/proxy.py +4 -9
  51. planar/test_app.py +92 -1
  52. planar/test_cli.py +81 -59
  53. planar/test_config.py +17 -14
  54. planar/testing/fixtures.py +325 -0
  55. planar/testing/planar_test_client.py +5 -2
  56. planar/utils.py +41 -1
  57. planar/workflows/execution.py +1 -1
  58. planar/workflows/orchestrator.py +5 -0
  59. planar/workflows/serialization.py +12 -6
  60. planar/workflows/step_core.py +3 -1
  61. planar/workflows/test_serialization.py +9 -1
  62. {planar-0.5.0.dist-info → planar-0.8.0.dist-info}/METADATA +30 -5
  63. planar-0.8.0.dist-info/RECORD +166 -0
  64. planar/.__init__.py.un~ +0 -0
  65. planar/._version.py.un~ +0 -0
  66. planar/.app.py.un~ +0 -0
  67. planar/.cli.py.un~ +0 -0
  68. planar/.config.py.un~ +0 -0
  69. planar/.context.py.un~ +0 -0
  70. planar/.db.py.un~ +0 -0
  71. planar/.di.py.un~ +0 -0
  72. planar/.engine.py.un~ +0 -0
  73. planar/.files.py.un~ +0 -0
  74. planar/.log_context.py.un~ +0 -0
  75. planar/.log_metadata.py.un~ +0 -0
  76. planar/.logging.py.un~ +0 -0
  77. planar/.object_registry.py.un~ +0 -0
  78. planar/.otel.py.un~ +0 -0
  79. planar/.server.py.un~ +0 -0
  80. planar/.session.py.un~ +0 -0
  81. planar/.sqlalchemy.py.un~ +0 -0
  82. planar/.task_local.py.un~ +0 -0
  83. planar/.test_app.py.un~ +0 -0
  84. planar/.test_config.py.un~ +0 -0
  85. planar/.test_object_config.py.un~ +0 -0
  86. planar/.test_sqlalchemy.py.un~ +0 -0
  87. planar/.test_utils.py.un~ +0 -0
  88. planar/.util.py.un~ +0 -0
  89. planar/.utils.py.un~ +0 -0
  90. planar/ai/.__init__.py.un~ +0 -0
  91. planar/ai/._models.py.un~ +0 -0
  92. planar/ai/.agent.py.un~ +0 -0
  93. planar/ai/.agent_utils.py.un~ +0 -0
  94. planar/ai/.events.py.un~ +0 -0
  95. planar/ai/.files.py.un~ +0 -0
  96. planar/ai/.models.py.un~ +0 -0
  97. planar/ai/.providers.py.un~ +0 -0
  98. planar/ai/.pydantic_ai.py.un~ +0 -0
  99. planar/ai/.pydantic_ai_agent.py.un~ +0 -0
  100. planar/ai/.pydantic_ai_provider.py.un~ +0 -0
  101. planar/ai/.step.py.un~ +0 -0
  102. planar/ai/.test_agent.py.un~ +0 -0
  103. planar/ai/.test_agent_serialization.py.un~ +0 -0
  104. planar/ai/.test_providers.py.un~ +0 -0
  105. planar/ai/.utils.py.un~ +0 -0
  106. planar/ai/providers.py +0 -1088
  107. planar/ai/test_agent.py +0 -1298
  108. planar/ai/test_providers.py +0 -463
  109. planar/db/.db.py.un~ +0 -0
  110. planar/files/.config.py.un~ +0 -0
  111. planar/files/.local.py.un~ +0 -0
  112. planar/files/.local_filesystem.py.un~ +0 -0
  113. planar/files/.model.py.un~ +0 -0
  114. planar/files/.models.py.un~ +0 -0
  115. planar/files/.s3.py.un~ +0 -0
  116. planar/files/.storage.py.un~ +0 -0
  117. planar/files/.test_files.py.un~ +0 -0
  118. planar/files/storage/.__init__.py.un~ +0 -0
  119. planar/files/storage/.base.py.un~ +0 -0
  120. planar/files/storage/.config.py.un~ +0 -0
  121. planar/files/storage/.context.py.un~ +0 -0
  122. planar/files/storage/.local_directory.py.un~ +0 -0
  123. planar/files/storage/.test_local_directory.py.un~ +0 -0
  124. planar/files/storage/.test_s3.py.un~ +0 -0
  125. planar/human/.human.py.un~ +0 -0
  126. planar/human/.test_human.py.un~ +0 -0
  127. planar/logging/.__init__.py.un~ +0 -0
  128. planar/logging/.attributes.py.un~ +0 -0
  129. planar/logging/.formatter.py.un~ +0 -0
  130. planar/logging/.logger.py.un~ +0 -0
  131. planar/logging/.otel.py.un~ +0 -0
  132. planar/logging/.tracer.py.un~ +0 -0
  133. planar/modeling/.mixin.py.un~ +0 -0
  134. planar/modeling/.storage.py.un~ +0 -0
  135. planar/modeling/orm/.planar_base_model.py.un~ +0 -0
  136. planar/object_config/.object_config.py.un~ +0 -0
  137. planar/routers/.__init__.py.un~ +0 -0
  138. planar/routers/.agents_router.py.un~ +0 -0
  139. planar/routers/.crud.py.un~ +0 -0
  140. planar/routers/.decision.py.un~ +0 -0
  141. planar/routers/.event.py.un~ +0 -0
  142. planar/routers/.file_attachment.py.un~ +0 -0
  143. planar/routers/.files.py.un~ +0 -0
  144. planar/routers/.files_router.py.un~ +0 -0
  145. planar/routers/.human.py.un~ +0 -0
  146. planar/routers/.info.py.un~ +0 -0
  147. planar/routers/.models.py.un~ +0 -0
  148. planar/routers/.object_config_router.py.un~ +0 -0
  149. planar/routers/.rule.py.un~ +0 -0
  150. planar/routers/.test_object_config_router.py.un~ +0 -0
  151. planar/routers/.test_workflow_router.py.un~ +0 -0
  152. planar/routers/.workflow.py.un~ +0 -0
  153. planar/rules/.decorator.py.un~ +0 -0
  154. planar/rules/.runner.py.un~ +0 -0
  155. planar/rules/.test_rules.py.un~ +0 -0
  156. planar/security/.jwt_middleware.py.un~ +0 -0
  157. planar/sse/.constants.py.un~ +0 -0
  158. planar/sse/.example.html.un~ +0 -0
  159. planar/sse/.hub.py.un~ +0 -0
  160. planar/sse/.model.py.un~ +0 -0
  161. planar/sse/.proxy.py.un~ +0 -0
  162. planar/testing/.client.py.un~ +0 -0
  163. planar/testing/.memory_storage.py.un~ +0 -0
  164. planar/testing/.planar_test_client.py.un~ +0 -0
  165. planar/testing/.predictable_tracer.py.un~ +0 -0
  166. planar/testing/.synchronizable_tracer.py.un~ +0 -0
  167. planar/testing/.test_memory_storage.py.un~ +0 -0
  168. planar/testing/.workflow_observer.py.un~ +0 -0
  169. planar/workflows/.__init__.py.un~ +0 -0
  170. planar/workflows/.builtin_steps.py.un~ +0 -0
  171. planar/workflows/.concurrency_tracing.py.un~ +0 -0
  172. planar/workflows/.context.py.un~ +0 -0
  173. planar/workflows/.contrib.py.un~ +0 -0
  174. planar/workflows/.decorators.py.un~ +0 -0
  175. planar/workflows/.durable_test.py.un~ +0 -0
  176. planar/workflows/.errors.py.un~ +0 -0
  177. planar/workflows/.events.py.un~ +0 -0
  178. planar/workflows/.exceptions.py.un~ +0 -0
  179. planar/workflows/.execution.py.un~ +0 -0
  180. planar/workflows/.human.py.un~ +0 -0
  181. planar/workflows/.lock.py.un~ +0 -0
  182. planar/workflows/.misc.py.un~ +0 -0
  183. planar/workflows/.model.py.un~ +0 -0
  184. planar/workflows/.models.py.un~ +0 -0
  185. planar/workflows/.notifications.py.un~ +0 -0
  186. planar/workflows/.orchestrator.py.un~ +0 -0
  187. planar/workflows/.runtime.py.un~ +0 -0
  188. planar/workflows/.serialization.py.un~ +0 -0
  189. planar/workflows/.step.py.un~ +0 -0
  190. planar/workflows/.step_core.py.un~ +0 -0
  191. planar/workflows/.sub_workflow_runner.py.un~ +0 -0
  192. planar/workflows/.sub_workflow_scheduler.py.un~ +0 -0
  193. planar/workflows/.test_concurrency.py.un~ +0 -0
  194. planar/workflows/.test_concurrency_detection.py.un~ +0 -0
  195. planar/workflows/.test_human.py.un~ +0 -0
  196. planar/workflows/.test_lock_timeout.py.un~ +0 -0
  197. planar/workflows/.test_orchestrator.py.un~ +0 -0
  198. planar/workflows/.test_race_conditions.py.un~ +0 -0
  199. planar/workflows/.test_serialization.py.un~ +0 -0
  200. planar/workflows/.test_suspend_deserialization.py.un~ +0 -0
  201. planar/workflows/.test_workflow.py.un~ +0 -0
  202. planar/workflows/.tracing.py.un~ +0 -0
  203. planar/workflows/.types.py.un~ +0 -0
  204. planar/workflows/.util.py.un~ +0 -0
  205. planar/workflows/.utils.py.un~ +0 -0
  206. planar/workflows/.workflow.py.un~ +0 -0
  207. planar/workflows/.workflow_wrapper.py.un~ +0 -0
  208. planar/workflows/.wrappers.py.un~ +0 -0
  209. planar-0.5.0.dist-info/RECORD +0 -289
  210. {planar-0.5.0.dist-info → planar-0.8.0.dist-info}/WHEEL +0 -0
  211. {planar-0.5.0.dist-info → planar-0.8.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,253 @@
1
+ {
2
+ "nodes": [
3
+ {
4
+ "type": "inputNode",
5
+ "content": {
6
+ "schema": ""
7
+ },
8
+ "id": "input",
9
+ "name": "request",
10
+ "position": {
11
+ "x": 110,
12
+ "y": 114
13
+ }
14
+ },
15
+ {
16
+ "type": "decisionTableNode",
17
+ "content": {
18
+ "hitPolicy": "first",
19
+ "rules": [
20
+ {
21
+ "_id": "rule1",
22
+ "supplierLocation": "'high_risk_region'",
23
+ "historicalPerformance": "< 70",
24
+ "alternativeSources": "< 2",
25
+ "riskScore": "80",
26
+ "riskCategory": "'critical'",
27
+ "mitigation": "'Immediate action required: Identify alternative suppliers'"
28
+ },
29
+ {
30
+ "_id": "rule2",
31
+ "supplierLocation": "'high_risk_region'",
32
+ "historicalPerformance": ">= 70",
33
+ "alternativeSources": "",
34
+ "riskScore": "65",
35
+ "riskCategory": "'high'",
36
+ "mitigation": "'Develop backup suppliers and increase safety stock'"
37
+ },
38
+ {
39
+ "_id": "rule3",
40
+ "supplierLocation": "'medium_risk_region'",
41
+ "historicalPerformance": "< 80",
42
+ "alternativeSources": "< 3",
43
+ "riskScore": "60",
44
+ "riskCategory": "'high'",
45
+ "mitigation": "'Implement dual-sourcing strategy'"
46
+ },
47
+ {
48
+ "_id": "rule4",
49
+ "supplierLocation": "'medium_risk_region'",
50
+ "historicalPerformance": ">= 80",
51
+ "alternativeSources": "",
52
+ "riskScore": "40",
53
+ "riskCategory": "'medium'",
54
+ "mitigation": "'Monitor supplier performance and conduct quarterly reviews'"
55
+ },
56
+ {
57
+ "_id": "rule5",
58
+ "supplierLocation": "'low_risk_region'",
59
+ "historicalPerformance": "< 75",
60
+ "alternativeSources": "",
61
+ "riskScore": "35",
62
+ "riskCategory": "'medium'",
63
+ "mitigation": "'Schedule regular performance reviews'"
64
+ },
65
+ {
66
+ "_id": "rule6",
67
+ "supplierLocation": "'low_risk_region'",
68
+ "historicalPerformance": ">= 75",
69
+ "alternativeSources": ">= 3",
70
+ "riskScore": "15",
71
+ "riskCategory": "'low'",
72
+ "mitigation": "'Standard monitoring procedures'"
73
+ },
74
+ {
75
+ "_id": "rule7",
76
+ "supplierLocation": "",
77
+ "historicalPerformance": "",
78
+ "alternativeSources": "",
79
+ "riskScore": "50",
80
+ "riskCategory": "'medium'",
81
+ "mitigation": "'Conduct detailed supplier assessment'"
82
+ }
83
+ ],
84
+ "inputs": [
85
+ {
86
+ "id": "supplierLocation",
87
+ "name": "Supplier Location",
88
+ "field": "supplier.location"
89
+ },
90
+ {
91
+ "id": "historicalPerformance",
92
+ "name": "Historical Performance Score",
93
+ "field": "supplier.performanceScore"
94
+ },
95
+ {
96
+ "id": "alternativeSources",
97
+ "name": "Alternative Sources Count",
98
+ "field": "supplier.alternateSourcesCount"
99
+ }
100
+ ],
101
+ "outputs": [
102
+ {
103
+ "id": "riskScore",
104
+ "name": "Risk Score",
105
+ "field": "assessment.baseRiskScore"
106
+ },
107
+ {
108
+ "id": "riskCategory",
109
+ "name": "Risk Category",
110
+ "field": "assessment.baseRiskCategory"
111
+ },
112
+ {
113
+ "id": "mitigation",
114
+ "name": "Recommended Mitigation",
115
+ "field": "assessment.recommendedAction"
116
+ }
117
+ ],
118
+ "passThrough": true,
119
+ "inputField": null,
120
+ "outputPath": null,
121
+ "executionMode": "single"
122
+ },
123
+ "id": "supplierRiskEvaluation",
124
+ "name": "supplierRiskEvaluation",
125
+ "position": {
126
+ "x": 430,
127
+ "y": 114
128
+ }
129
+ },
130
+ {
131
+ "type": "expressionNode",
132
+ "content": {
133
+ "expressions": [
134
+ {
135
+ "id": "expr1",
136
+ "key": "geopoliticalFactor",
137
+ "value": "geopoliticalTensions == true ? 1.3 : 1.0"
138
+ },
139
+ {
140
+ "id": "expr2",
141
+ "key": "marketVolatilityFactor",
142
+ "value": "marketVolatility == 'high' ? 1.2 : (marketVolatility == 'medium' ? 1.1 : 1.0)"
143
+ },
144
+ {
145
+ "id": "expr3",
146
+ "key": "adjustedRiskScore",
147
+ "value": "min([round(assessment.baseRiskScore * $.geopoliticalFactor * $.marketVolatilityFactor), 100])"
148
+ }
149
+ ],
150
+ "passThrough": true,
151
+ "inputField": null,
152
+ "outputPath": null,
153
+ "executionMode": "single"
154
+ },
155
+ "id": "geopoliticalRiskCalculation",
156
+ "name": "geopoliticalRiskCalculation",
157
+ "position": {
158
+ "x": 750,
159
+ "y": 114
160
+ }
161
+ },
162
+ {
163
+ "type": "decisionTableNode",
164
+ "content": {
165
+ "hitPolicy": "first",
166
+ "rules": [
167
+ {
168
+ "_id": "finalRule1",
169
+ "adjustedRiskScore": ">= 75",
170
+ "finalCategory": "'critical'",
171
+ "leadTimeImpact": "'significant'",
172
+ "priorityLevel": "'immediate'"
173
+ },
174
+ {
175
+ "_id": "finalRule2",
176
+ "adjustedRiskScore": ">= 60",
177
+ "finalCategory": "'high'",
178
+ "leadTimeImpact": "'moderate'",
179
+ "priorityLevel": "'high'"
180
+ },
181
+ {
182
+ "_id": "finalRule3",
183
+ "adjustedRiskScore": ">= 40",
184
+ "finalCategory": "'medium'",
185
+ "leadTimeImpact": "'minor'",
186
+ "priorityLevel": "'medium'"
187
+ },
188
+ {
189
+ "_id": "finalRule4",
190
+ "adjustedRiskScore": "",
191
+ "finalCategory": "'low'",
192
+ "leadTimeImpact": "'minimal'",
193
+ "priorityLevel": "'routine'"
194
+ }
195
+ ],
196
+ "inputs": [
197
+ {
198
+ "id": "adjustedRiskScore",
199
+ "name": "Adjusted Risk Score",
200
+ "field": "adjustedRiskScore"
201
+ }
202
+ ],
203
+ "outputs": [
204
+ {
205
+ "id": "finalCategory",
206
+ "name": "Final Risk Category",
207
+ "field": "finalAssessment.riskCategory"
208
+ },
209
+ {
210
+ "id": "leadTimeImpact",
211
+ "name": "Lead Time Impact",
212
+ "field": "finalAssessment.leadTimeImpact"
213
+ },
214
+ {
215
+ "id": "priorityLevel",
216
+ "name": "Priority Level",
217
+ "field": "finalAssessment.priorityLevel"
218
+ }
219
+ ],
220
+ "passThrough": true,
221
+ "inputField": null,
222
+ "outputPath": null,
223
+ "executionMode": "single"
224
+ },
225
+ "id": "overallRiskAssessment",
226
+ "name": "overallRiskAssessment",
227
+ "position": {
228
+ "x": 1070,
229
+ "y": 114
230
+ }
231
+ }
232
+ ],
233
+ "edges": [
234
+ {
235
+ "id": "edge1",
236
+ "sourceId": "input",
237
+ "targetId": "supplierRiskEvaluation",
238
+ "type": "edge"
239
+ },
240
+ {
241
+ "id": "edge2",
242
+ "sourceId": "supplierRiskEvaluation",
243
+ "targetId": "geopoliticalRiskCalculation",
244
+ "type": "edge"
245
+ },
246
+ {
247
+ "id": "edge3",
248
+ "sourceId": "geopoliticalRiskCalculation",
249
+ "targetId": "overallRiskAssessment",
250
+ "type": "edge"
251
+ }
252
+ ]
253
+ }
@@ -0,0 +1,237 @@
1
+ {
2
+ "nodes": [
3
+ {
4
+ "type": "inputNode",
5
+ "content": {
6
+ "schema": ""
7
+ },
8
+ "id": "ip1",
9
+ "name": "shipmentRequest",
10
+ "position": {
11
+ "x": 110,
12
+ "y": 173.5
13
+ }
14
+ },
15
+ {
16
+ "type": "expressionNode",
17
+ "content": {
18
+ "expressions": [
19
+ {
20
+ "id": "e1-1",
21
+ "key": "hasMatchingOutboundOrders",
22
+ "value": "len(matchingOutboundOrders) > 0"
23
+ },
24
+ {
25
+ "id": "e1-2",
26
+ "key": "timeDifferenceHours",
27
+ "value": "(date(outboundShipmentTime) - date(inboundShipmentTime)) / 3600"
28
+ },
29
+ {
30
+ "id": "e1-3",
31
+ "key": "warehouseCapacityPercentage",
32
+ "value": "(currentStorageUsed / totalStorageCapacity) * 100"
33
+ }
34
+ ],
35
+ "passThrough": true,
36
+ "inputField": null,
37
+ "outputPath": null,
38
+ "executionMode": "single"
39
+ },
40
+ "id": "ex1",
41
+ "name": "calculateMetrics",
42
+ "position": {
43
+ "x": 430,
44
+ "y": 173.5
45
+ }
46
+ },
47
+ {
48
+ "type": "decisionTableNode",
49
+ "content": {
50
+ "hitPolicy": "first",
51
+ "rules": [
52
+ {
53
+ "_id": "r1-1",
54
+ "i1-1": "true",
55
+ "i1-2": "[0..24]",
56
+ "i1-3": "<= 36",
57
+ "o1-1": "'cross-dock'",
58
+ "o1-2": "'Matching orders available within 24 hours with sufficient capacity'"
59
+ },
60
+ {
61
+ "_id": "r1-2",
62
+ "i1-1": "true",
63
+ "i1-2": "[0..48]",
64
+ "i1-3": "<= 80",
65
+ "o1-1": "'cross-dock'",
66
+ "o1-2": "'Matching orders available within 48 hours'"
67
+ },
68
+ {
69
+ "_id": "r1-3",
70
+ "i1-1": "true",
71
+ "i1-2": "> 48",
72
+ "i1-3": ">= 90",
73
+ "o1-1": "'cross-dock'",
74
+ "o1-2": "'High warehouse capacity, cross-dock to save space'"
75
+ },
76
+ {
77
+ "_id": "r1-4",
78
+ "i1-1": "true",
79
+ "i1-2": "> 72",
80
+ "i1-3": "",
81
+ "o1-1": "'store'",
82
+ "o1-2": "'Matching orders but time difference too large'"
83
+ },
84
+ {
85
+ "_id": "r1-5",
86
+ "i1-1": "false",
87
+ "i1-2": "",
88
+ "i1-3": "",
89
+ "o1-1": "'store'",
90
+ "o1-2": "'No matching outbound orders'"
91
+ }
92
+ ],
93
+ "inputs": [
94
+ {
95
+ "id": "i1-1",
96
+ "name": "Has Matching Orders",
97
+ "field": "hasMatchingOutboundOrders"
98
+ },
99
+ {
100
+ "id": "i1-2",
101
+ "name": "Time Difference (hours)",
102
+ "field": "timeDifferenceHours"
103
+ },
104
+ {
105
+ "id": "i1-3",
106
+ "name": "Warehouse Capacity (%)",
107
+ "field": "warehouseCapacityPercentage"
108
+ }
109
+ ],
110
+ "outputs": [
111
+ {
112
+ "id": "o1-1",
113
+ "name": "Decision",
114
+ "field": "crossDockDecision"
115
+ },
116
+ {
117
+ "id": "o1-2",
118
+ "name": "Reason",
119
+ "field": "decisionReason"
120
+ }
121
+ ],
122
+ "passThrough": true,
123
+ "inputField": null,
124
+ "outputPath": null,
125
+ "executionMode": "single"
126
+ },
127
+ "id": "dt1",
128
+ "name": "crossDockingDecision",
129
+ "position": {
130
+ "x": 750,
131
+ "y": 173.5
132
+ }
133
+ },
134
+ {
135
+ "type": "switchNode",
136
+ "content": {
137
+ "hitPolicy": "first",
138
+ "statements": [
139
+ {
140
+ "id": "s1-1",
141
+ "condition": "crossDockDecision == 'cross-dock'",
142
+ "isDefault": false
143
+ },
144
+ {
145
+ "id": "s1-2",
146
+ "condition": "",
147
+ "isDefault": true
148
+ }
149
+ ]
150
+ },
151
+ "id": "sw1",
152
+ "name": "handleCrossDocking",
153
+ "position": {
154
+ "x": 1070,
155
+ "y": 173.5
156
+ }
157
+ },
158
+ {
159
+ "type": "expressionNode",
160
+ "content": {
161
+ "expressions": [
162
+ {
163
+ "id": "e2-1",
164
+ "key": "dockingBay",
165
+ "value": "crossDockingBayAssignment"
166
+ },
167
+ {
168
+ "id": "e2-2",
169
+ "key": "estimatedProcessingTime",
170
+ "value": "30"
171
+ },
172
+ {
173
+ "id": "e2-3",
174
+ "key": "priority",
175
+ "value": "timeDifferenceHours < 12 ? 'high' : 'normal'"
176
+ }
177
+ ],
178
+ "passThrough": true,
179
+ "inputField": null,
180
+ "outputPath": null,
181
+ "executionMode": "single"
182
+ },
183
+ "id": "ex2",
184
+ "name": "assignCrossDockingDetails",
185
+ "position": {
186
+ "x": 1390,
187
+ "y": 173.5
188
+ }
189
+ },
190
+ {
191
+ "type": "outputNode",
192
+ "content": {
193
+ "schema": ""
194
+ },
195
+ "id": "e1a7d99b-255e-47a2-929f-642fc0e7efc5",
196
+ "name": "response",
197
+ "position": {
198
+ "x": 1390,
199
+ "y": 305
200
+ }
201
+ }
202
+ ],
203
+ "edges": [
204
+ {
205
+ "id": "ed1",
206
+ "sourceId": "ip1",
207
+ "targetId": "ex1",
208
+ "type": "edge"
209
+ },
210
+ {
211
+ "id": "ed2",
212
+ "sourceId": "ex1",
213
+ "targetId": "dt1",
214
+ "type": "edge"
215
+ },
216
+ {
217
+ "id": "ed3",
218
+ "sourceId": "dt1",
219
+ "targetId": "sw1",
220
+ "type": "edge"
221
+ },
222
+ {
223
+ "id": "ed4",
224
+ "sourceId": "sw1",
225
+ "targetId": "ex2",
226
+ "sourceHandle": "s1-1",
227
+ "type": "edge"
228
+ },
229
+ {
230
+ "id": "7d282229-bce6-47a6-a68d-ed867787a674",
231
+ "sourceId": "sw1",
232
+ "type": "edge",
233
+ "targetId": "e1a7d99b-255e-47a2-929f-642fc0e7efc5",
234
+ "sourceHandle": "s1-2"
235
+ }
236
+ ]
237
+ }