@gadmin2n/schematics 0.0.143 → 0.0.145

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 (279) hide show
  1. package/dist/lib/application/files/gadmin2-game-angle-demo/config/.types.d.ts +10 -0
  2. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/approval.prisma +2 -0
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +140 -19
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +2 -2
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/data-mngt.seed.ts +0 -2
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +694 -327
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-outbox.ts +57 -0
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +35 -5
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +224 -59
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-executor.spec.ts +23 -0
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-executor.ts +16 -5
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.controller.spec.ts +98 -0
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.controller.ts +26 -6
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.dto.ts +17 -2
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.spec.ts +1 -0
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.ts +3 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.dto.ts +0 -2
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-signal-outbox.service.spec.ts +30 -0
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-signal-outbox.service.ts +28 -6
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction.service.spec.ts +63 -0
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction.service.ts +151 -38
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-wait.handler.ts +4 -1
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/human-approval.handler.spec.ts +16 -5
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/human-approval.handler.ts +23 -6
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.controller.spec.ts +130 -0
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.controller.ts +62 -62
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.dto.ts +15 -1
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.util.spec.ts +70 -9
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.util.ts +31 -7
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-signal-outbox.service.spec.ts +30 -0
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-signal-outbox.service.ts +28 -6
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-subject-source.util.spec.ts +50 -3
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-subject-source.util.ts +26 -3
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.dto.ts +53 -47
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.errors.ts +0 -1
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.service.spec.ts +541 -0
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.service.ts +442 -200
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/outbox-retry.util.ts +1 -0
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.controller.spec.ts +150 -0
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.controller.ts +56 -40
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.dto.ts +16 -60
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.controller.ts +13 -0
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.service.spec.ts +44 -0
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.service.ts +6 -0
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.spec.ts +258 -12
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.ts +127 -14
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/manual-workflow-execution.spec.ts +85 -0
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/manual-workflow-execution.ts +108 -0
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/parameter-binding.ts +5 -5
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.spec.ts +96 -25
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +77 -34
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.spec.ts +23 -34
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.ts +0 -21
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-cancellation.spec.ts +245 -0
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.spec.ts +639 -188
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.ts +408 -235
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.types.ts +1 -3
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-data-edge.util.spec.ts +279 -95
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-data-edge.util.ts +360 -80
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-event-catalog.spec.ts +323 -0
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution-idempotency.spec.ts +773 -0
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +7 -13
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.dto.ts +0 -16
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.service.spec.ts +184 -0
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.service.ts +69 -138
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-handle-validator.spec.ts +113 -0
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-handle-validator.ts +59 -13
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-runtime.facade.ts +86 -0
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-switch-config.spec.ts +25 -0
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-switch-config.ts +45 -0
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.spec.ts +78 -43
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +103 -40
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +57 -0
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.module.ts +3 -1
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +1000 -240
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +2184 -317
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/node-config-validator.service.spec.ts +279 -2
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/node-config-validator.service.ts +5 -1
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/subject-config-validator.service.spec.ts +4 -1
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/subject-config-validator.service.ts +5 -1
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.spec.ts +12 -3
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.ts +10 -1
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.spec.ts +2 -24
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.ts +3 -70
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +3 -1
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/RowActions.tsx +25 -5
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/WorkflowActionButton.test.tsx +71 -0
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/WorkflowActionButton.tsx +89 -0
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/index.ts +1 -0
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/header.tsx +52 -12
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +12 -0
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/constants/layout.ts +2 -2
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddDataModal.tsx +10 -33
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddPageModal.tsx +13 -37
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DevShell.tsx +55 -7
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/style.css +14 -0
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/http.ts +10 -0
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/list.tsx +1 -0
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/workflowAction.ts +19 -0
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/index.ts +1 -0
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/types.ts +3 -1
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +1 -6
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useReferenceUpload.ts +95 -0
  104. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +2 -2
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/workflow.json +672 -110
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +2 -2
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/workflow.json +676 -114
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/plugins/devShellPlugin.ts +13 -1
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +1 -0
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasEditPage.tsx +38 -4
  111. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +276 -376
  112. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/CanvasAiModal.tsx +126 -6
  113. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/DecisionModal.test.tsx +50 -0
  114. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/DecisionModal.tsx +48 -11
  115. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/inbox.tsx +32 -34
  116. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/RegisterBusinessEventModal.test.tsx +111 -0
  117. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/RegisterBusinessEventModal.tsx +167 -0
  118. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/business-events.css +99 -0
  119. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/detail.test.tsx +106 -0
  120. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/detail.tsx +324 -0
  121. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/index.test.tsx +73 -0
  122. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/index.tsx +359 -0
  123. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CanvasZoomControls.tsx +46 -0
  124. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CreateNodeInstanceDrawer.tsx +9 -1
  125. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.test.tsx +105 -4
  126. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.tsx +90 -48
  127. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DeletableEdge.tsx +3 -2
  128. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DslView.test.tsx +259 -0
  129. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DslView.tsx +167 -103
  130. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/EnhancedFlowRenderer.tsx +142 -140
  131. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.test.tsx +60 -15
  132. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.tsx +25 -12
  133. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/FlowRenderer.tsx +364 -200
  134. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NewNodeDefaults.test.tsx +220 -52
  135. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeOutputSummary.test.tsx +260 -0
  136. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeOutputSummary.tsx +300 -130
  137. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.test.tsx +507 -33
  138. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +630 -592
  139. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ParameterBindingEditor.tsx +67 -70
  140. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ReadonlyNodePanel.test.tsx +90 -0
  141. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ReadonlyNodePanel.tsx +325 -0
  142. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/RunWorkflowModal.test.tsx +52 -0
  143. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/RunWorkflowModal.tsx +14 -9
  144. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/StatusCards.tsx +2 -1
  145. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/VersionPanel.tsx +2 -1
  146. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/WorkflowCodeEditor.test.tsx +42 -0
  147. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/WorkflowCodeEditor.tsx +76 -0
  148. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/WorkflowWorkspaceHeader.tsx +56 -0
  149. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/parameter-binding-editor.css +46 -0
  150. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/workflow-code-editor.css +34 -0
  151. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/ConnectionModal.test.tsx +53 -7
  152. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/ConnectionModal.tsx +123 -62
  153. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/connections.css +85 -0
  154. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/connectionsApi.ts +29 -0
  155. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/index.test.tsx +75 -0
  156. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/index.tsx +69 -36
  157. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.test.tsx +494 -0
  158. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +665 -194
  159. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useReferencedNodeInstanceConfigs.test.tsx +92 -0
  160. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useReferencedNodeInstanceConfigs.ts +96 -0
  161. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useWorkflowAgent.test.tsx +297 -0
  162. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useWorkflowAgent.ts +135 -65
  163. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +53 -42
  164. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +344 -155
  165. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instances.tsx +79 -58
  166. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/CreateNodeInstanceModal.tsx +123 -144
  167. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +169 -98
  168. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/node-instance-form.css +91 -0
  169. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/index.tsx +54 -31
  170. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/node-config.css +854 -0
  171. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/SchemaField.tsx +41 -14
  172. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/SchemaForm.test.tsx +75 -0
  173. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/SchemaForm.tsx +3 -0
  174. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/default-widgets.tsx +20 -2
  175. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/widget-registry.tsx +2 -1
  176. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/show.tsx +61 -66
  177. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApprovalRuleEditor.test.tsx +33 -1
  178. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApprovalRuleEditor.tsx +47 -15
  179. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/BranchConfigEditors.test.tsx +104 -0
  180. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CallableInputParametersEditor.tsx +22 -52
  181. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CodeConfigEditor.test.tsx +72 -0
  182. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CodeConfigEditor.tsx +78 -70
  183. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CronTriggerConfigEditor.tsx +569 -0
  184. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/DbExecuteConfigEditor.tsx +130 -0
  185. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/DelayConfigEditor.tsx +100 -0
  186. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/EventTriggerConfigEditor.tsx +620 -0
  187. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalRequestConfigEditor.test.tsx +22 -45
  188. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalRequestConfigEditor.tsx +25 -92
  189. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalWaitConfigEditor.tsx +3 -11
  190. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ForEachConfigEditor.test.tsx +58 -0
  191. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ForEachConfigEditor.tsx +107 -0
  192. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HttpRequestConfigEditor.test.tsx +212 -31
  193. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HttpRequestConfigEditor.tsx +214 -304
  194. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.test.tsx +175 -40
  195. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.tsx +693 -293
  196. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/IfElseConfigEditor.tsx +190 -0
  197. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ManualTriggerConfigEditor.test.tsx +152 -0
  198. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ManualTriggerConfigEditor.tsx +286 -0
  199. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ParallelConfigEditor.tsx +101 -0
  200. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ParameterBindingListEditor.tsx +99 -0
  201. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SimplifiedNodeEditors.test.tsx +495 -0
  202. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubWorkflowConfigEditor.test.tsx +124 -0
  203. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubWorkflowConfigEditor.tsx +222 -0
  204. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubjectPicker.tsx +2 -4
  205. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SwitchConfigEditor.tsx +204 -0
  206. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/UserGroupCreateModal.tsx +3 -1
  207. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/UserGroupEditModal.tsx +9 -6
  208. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/callable-workflow.ts +4 -0
  209. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/code-config.css +96 -0
  210. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/event-catalog.api.ts +117 -0
  211. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/http-request-config.css +242 -0
  212. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/human-approval-config.css +194 -0
  213. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/show.tsx +264 -167
  214. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +6 -9
  215. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types/parameter-binding.ts +19 -16
  216. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +28 -4
  217. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/useWorkflowFormValidation.test.tsx +59 -0
  218. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/useWorkflowFormValidation.ts +24 -0
  219. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/forEachConnection.test.ts +311 -0
  220. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/forEachConnection.ts +198 -0
  221. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/mainFlowConnection.test.ts +143 -0
  222. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/mainFlowConnection.ts +19 -0
  223. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/newNodeConfig.ts +103 -5
  224. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/removeWorkflowEdges.test.ts +158 -3
  225. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/removeWorkflowEdges.ts +117 -9
  226. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveEffectiveOutput.test.ts +70 -0
  227. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveEffectiveOutput.ts +48 -0
  228. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveLookupPorts.test.ts +55 -0
  229. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveLookupPorts.ts +95 -22
  230. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.test.ts +148 -1
  231. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.ts +62 -11
  232. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveWorkflowDisplay.test.ts +19 -0
  233. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveWorkflowDisplay.ts +1 -1
  234. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/subWorkflowChange.test.ts +45 -0
  235. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/subWorkflowChange.ts +26 -0
  236. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/validateWorkflowDsl.test.ts +502 -0
  237. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/validateWorkflowDsl.ts +694 -0
  238. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowDateTime.test.ts +27 -0
  239. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowDateTime.ts +33 -0
  240. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowHistory.test.ts +34 -0
  241. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowHistory.ts +52 -0
  242. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowPublishError.test.ts +99 -0
  243. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowPublishError.ts +91 -0
  244. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowSkillPrompt.test.ts +74 -0
  245. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowSkillPrompt.ts +120 -0
  246. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/workflow-ui.css +481 -0
  247. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/index.css +1 -1
  248. package/package.json +1 -1
  249. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowEventOutbox.ts +0 -62
  250. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/migrate-human-approval-configs.ts +0 -86
  251. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-event-trigger.ts +0 -60
  252. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.external-decision.spec.ts +0 -183
  253. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/legacy-approval-config-migration.ts +0 -227
  254. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.spec.ts +0 -82
  255. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.ts +0 -111
  256. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.spec.ts +0 -54
  257. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.ts +0 -147
  258. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.module.ts +0 -10
  259. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.spec.ts +0 -350
  260. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.ts +0 -110
  261. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/index.ts +0 -1
  262. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/InstanceRequiredDialog.tsx +0 -106
  263. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/LookupConnectionDialog.test.tsx +0 -45
  264. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/LookupConnectionDialog.tsx +0 -43
  265. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeTypeBadge.tsx +0 -36
  266. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useNodeInstanceLibrary.ts +0 -41
  267. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApproverSourceEditor.test.tsx +0 -47
  268. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApproverSourceEditor.tsx +0 -182
  269. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.test.tsx +0 -34
  270. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.tsx +0 -16
  271. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/approver-source.test.ts +0 -25
  272. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/approver-source.ts +0 -42
  273. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/lookupConnection.test.ts +0 -208
  274. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/lookupConnection.ts +0 -246
  275. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/create.tsx +0 -111
  276. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/edit.tsx +0 -127
  277. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/index.tsx +0 -4
  278. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +0 -282
  279. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/show.tsx +0 -74
@@ -1,183 +0,0 @@
1
- import { hashNodeInstanceConfig } from '../workflowNodeInstance/node-instance-config.util';
2
- import { HumanApprovalService } from './human-approval.service';
3
-
4
- describe('HumanApprovalService external decisions', () => {
5
- const request = {
6
- id: BigInt(41),
7
- workflowInstanceId: BigInt(7),
8
- nodeId: 'approval-1',
9
- status: 'PENDING',
10
- configSnapshot: { approvalWorkflowId: '11' },
11
- approvalRule: { mode: 'ANY' },
12
- rejectionRule: { mode: 'ANY' },
13
- candidates: [
14
- {
15
- id: BigInt(91),
16
- principalRef: 'alice',
17
- invalidatedAt: null,
18
- },
19
- ],
20
- decisions: [],
21
- };
22
- const tx = {
23
- approvalRequest: {
24
- findUnique: jest.fn().mockResolvedValue(request),
25
- updateMany: jest.fn().mockResolvedValue({ count: 1 }),
26
- create: jest.fn().mockResolvedValue({
27
- id: BigInt(42),
28
- status: 'PENDING',
29
- }),
30
- },
31
- approvalDecision: {
32
- create: jest.fn().mockResolvedValue({
33
- id: BigInt(101),
34
- decision: 'APPROVE',
35
- }),
36
- },
37
- approvalSignalOutbox: {
38
- upsert: jest.fn().mockResolvedValue({ id: BigInt(201) }),
39
- },
40
- };
41
- const prisma = {
42
- $transaction: jest.fn((callback) => callback(tx)),
43
- approvalRequest: {
44
- findUnique: jest.fn().mockResolvedValue(null),
45
- findUniqueOrThrow: jest.fn(),
46
- },
47
- workflow: {
48
- findUnique: jest.fn().mockResolvedValue({
49
- isEnabled: true,
50
- status: 'PUBLISHED',
51
- }),
52
- },
53
- };
54
- const providers = {
55
- get: jest.fn().mockReturnValue({
56
- preview: jest.fn().mockResolvedValue({
57
- items: [{ ref: 'alice', revision: 1 }],
58
- }),
59
- resolve: jest.fn().mockResolvedValue([
60
- {
61
- principalType: 'USER',
62
- principalRef: 'alice',
63
- displayName: 'Alice',
64
- sourceRefs: ['alice'],
65
- },
66
- ]),
67
- }),
68
- };
69
- const service = new HumanApprovalService(prisma as any, providers as any);
70
-
71
- beforeEach(() => {
72
- jest.clearAllMocks();
73
- });
74
-
75
- it('maps a returned Workflow result to the configured approval candidate', async () => {
76
- await service.submitExternalDecision(BigInt(41), {
77
- approvalWorkflowId: '11',
78
- eventId: 'myoa:workitem:123',
79
- approverId: 'alice',
80
- decision: 'APPROVE',
81
- payload: { sourceStatus: 200 },
82
- });
83
-
84
- expect(tx.approvalDecision.create).toHaveBeenCalledWith({
85
- data: expect.objectContaining({
86
- requestId: BigInt(41),
87
- candidateId: BigInt(91),
88
- decision: 'APPROVE',
89
- creator: 'external:11:alice',
90
- payload: {
91
- sourceStatus: 200,
92
- externalEventId: 'myoa:workitem:123',
93
- approvalWorkflowId: '11',
94
- },
95
- }),
96
- });
97
- expect(tx.approvalSignalOutbox.upsert).toHaveBeenCalled();
98
- });
99
-
100
- it('rejects a result from a Workflow not selected by the approval node', async () => {
101
- await expect(
102
- service.submitExternalDecision(BigInt(41), {
103
- approvalWorkflowId: '12',
104
- eventId: 'event-2',
105
- approverId: 'alice',
106
- decision: 'APPROVE',
107
- }),
108
- ).rejects.toMatchObject({
109
- response: { code: 'APPROVAL_WORKFLOW_MISMATCH' },
110
- });
111
- expect(tx.approvalDecision.create).not.toHaveBeenCalled();
112
- });
113
-
114
- it('starts the selected approval Workflow with business and system inputs', async () => {
115
- const externalInteractions = {
116
- createInteractionInTransaction: jest.fn().mockResolvedValue({
117
- interactionId: '51',
118
- callbackToken: 'ext_cb_approval',
119
- status: 'PENDING',
120
- }),
121
- };
122
- const integratedService = new HumanApprovalService(
123
- prisma as any,
124
- providers as any,
125
- externalInteractions as any,
126
- );
127
- const configSnapshot = {
128
- approvalWorkflowId: '11',
129
- subjects: [
130
- { source: 'STATIC' as const, provider: 'USER', refs: ['alice'] },
131
- ],
132
- approvalRule: { mode: 'ANY' as const },
133
- rejectionRule: { mode: 'ANY' as const },
134
- timeout: { durationSeconds: 0, action: 'REJECTED' as const },
135
- };
136
-
137
- const result = await integratedService.startRequest(
138
- {
139
- workflowInstanceId: '7',
140
- workflowVersionId: '3',
141
- tenantNamespace: 'tenant-a',
142
- temporalRunId: 'wf-7',
143
- approvalWorkflowRunId: 'wf-approval-7-approval-1',
144
- callbackToken: 'ext_cb_approval',
145
- nodeId: 'approval-1',
146
- configHash: hashNodeInstanceConfig(configSnapshot),
147
- configSnapshot,
148
- dynamicInputs: { orderId: 'SO-1001' },
149
- approvalWorkflowInputs: {
150
- title: '服务器权限申请',
151
- content: { orderId: 'SO-1001' },
152
- },
153
- },
154
- { userId: 'runtime:default' },
155
- );
156
-
157
- expect(result).toMatchObject({
158
- approvalWorkflowInvocation: {
159
- workflowId: '11',
160
- workflow: {
161
- title: '服务器权限申请',
162
- content: { orderId: 'SO-1001' },
163
- requestId: '42',
164
- callbackToken: 'ext_cb_approval',
165
- expiresAt: null,
166
- candidates: [expect.objectContaining({ approverId: 'alice' })],
167
- },
168
- },
169
- });
170
- expect(
171
- externalInteractions.createInteractionInTransaction,
172
- ).toHaveBeenCalledWith(
173
- expect.objectContaining({
174
- callbackToken: 'ext_cb_approval',
175
- handlerType: 'EXTERNAL_WAIT',
176
- handlerConfig: { allowedOutcomes: ['RECEIVED'] },
177
- temporalRunId: 'wf-approval-7-approval-1',
178
- nodeId: 'approval-1',
179
- }),
180
- tx,
181
- );
182
- });
183
- });
@@ -1,227 +0,0 @@
1
- import { ApprovalConfigSnapshotDto } from './human-approval.dto';
2
-
3
- type ProviderKey = 'USER' | 'USER_GROUP';
4
- type MappingEntry = { provider: ProviderKey; ref: string };
5
- export type ApprovalSubjectMapping = Record<string, MappingEntry>;
6
-
7
- export type LegacyApprovalNormalization =
8
- | { status: 'READY'; config: ApprovalConfigSnapshotDto }
9
- | { status: 'ALREADY_CURRENT'; config: ApprovalConfigSnapshotDto }
10
- | { status: 'REQUIRES_MAPPING'; refs: string[] }
11
- | { status: 'INVALID'; errors: string[] };
12
-
13
- export function normalizeLegacyApprovalConfig(
14
- input: unknown,
15
- mapping: ApprovalSubjectMapping = {},
16
- ): LegacyApprovalNormalization {
17
- if (!isRecord(input)) return invalid('Config must be an object');
18
- if (Array.isArray(input.subjects)) {
19
- const normalized: Record<string, unknown> = {
20
- ...input,
21
- subjects: input.subjects.map((subject) =>
22
- isRecord(subject) && subject.source === undefined
23
- ? { ...subject, source: 'STATIC' }
24
- : subject,
25
- ),
26
- };
27
- delete normalized.membershipPolicy;
28
- const current = validateCurrent(normalized);
29
- return current.length
30
- ? { status: 'INVALID', errors: current }
31
- : {
32
- status:
33
- input.membershipPolicy === undefined &&
34
- input.subjects.every(
35
- (subject) => isRecord(subject) && subject.source !== undefined,
36
- )
37
- ? 'ALREADY_CURRENT'
38
- : 'READY',
39
- config: normalized as unknown as ApprovalConfigSnapshotDto,
40
- };
41
- }
42
-
43
- const subjects = new Map<ProviderKey, string[]>();
44
- const add = (provider: ProviderKey, ref: unknown, errors: string[]) => {
45
- if (typeof ref !== 'string' || !ref.trim()) {
46
- errors.push(`Invalid ${provider} reference`);
47
- return;
48
- }
49
- const refs = subjects.get(provider) ?? [];
50
- if (!refs.includes(ref.trim())) refs.push(ref.trim());
51
- subjects.set(provider, refs);
52
- };
53
- const errors: string[] = [];
54
- const unresolved: string[] = [];
55
-
56
- for (const ref of array(input.approverUsers)) add('USER', ref, errors);
57
- for (const ref of array(input.approverGroups)) add('USER_GROUP', ref, errors);
58
- for (const approver of array(input.approvers)) {
59
- if (typeof approver === 'string') {
60
- const mapped = mapping[approver];
61
- if (!mapped) unresolved.push(approver);
62
- else add(mapped.provider, mapped.ref, errors);
63
- continue;
64
- }
65
- if (!isRecord(approver)) {
66
- errors.push('Invalid approver entry');
67
- continue;
68
- }
69
- const provider =
70
- approver.type === 'user'
71
- ? 'USER'
72
- : approver.type === 'group'
73
- ? 'USER_GROUP'
74
- : undefined;
75
- if (!provider) errors.push('Approver type must be user or group');
76
- else add(provider, approver.id, errors);
77
- }
78
- if (unresolved.length)
79
- return {
80
- status: 'REQUIRES_MAPPING',
81
- refs: [...new Set(unresolved)].sort(),
82
- };
83
- if (!subjects.size) errors.push('At least one approver is required');
84
-
85
- const approvalRule = normalizeRule(input, errors);
86
- const rejectionRule = normalizeExplicitRule(input.rejectionRule, errors) ?? {
87
- mode: 'ANY' as const,
88
- };
89
- const timeout = normalizeTimeout(input, errors);
90
- if (errors.length || !approvalRule || !timeout)
91
- return { status: 'INVALID', errors };
92
-
93
- return {
94
- status: 'READY',
95
- config: {
96
- subjects: [...subjects].map(([provider, refs]) => ({
97
- source: 'STATIC' as const,
98
- provider,
99
- refs,
100
- })),
101
- approvalRule,
102
- rejectionRule,
103
- timeout,
104
- },
105
- };
106
- }
107
-
108
- function validateCurrent(input: Record<string, unknown>): string[] {
109
- const errors: string[] = [];
110
- normalizeExplicitRule(input.approvalRule, errors);
111
- normalizeExplicitRule(input.rejectionRule, errors);
112
- if (!isRecord(input.timeout)) errors.push('Invalid timeout');
113
- else {
114
- if (!nonNegativeInteger(input.timeout.durationSeconds))
115
- errors.push('Invalid timeout durationSeconds');
116
- if (!['APPROVED', 'REJECTED'].includes(String(input.timeout.action)))
117
- errors.push('Invalid timeout action');
118
- }
119
- for (const subject of input.subjects as unknown[]) {
120
- if (
121
- !isRecord(subject) ||
122
- !['STATIC', 'DYNAMIC'].includes(String(subject.source)) ||
123
- typeof subject.provider !== 'string' ||
124
- (subject.source === 'STATIC' &&
125
- (!Array.isArray(subject.refs) || subject.refs.length === 0)) ||
126
- (subject.source === 'DYNAMIC' &&
127
- (typeof subject.inputKey !== 'string' || !subject.inputKey.trim()))
128
- )
129
- errors.push('Invalid subject');
130
- }
131
- return errors;
132
- }
133
-
134
- function normalizeRule(input: Record<string, unknown>, errors: string[]) {
135
- const explicit = normalizeExplicitRule(input.approvalRule, errors);
136
- if (explicit) return explicit;
137
- const mode = input.approvalMode ?? 'any';
138
- if (mode === 'any') return { mode: 'ANY' as const };
139
- if (mode === 'all') return { mode: 'ALL' as const };
140
- if (mode === 'percentage') {
141
- const percentage = input.minApprovalCount;
142
- if (!positiveInteger(percentage) || Number(percentage) > 100) {
143
- errors.push(
144
- 'Percentage approval requires minApprovalCount from 1 to 100',
145
- );
146
- return undefined;
147
- }
148
- return { mode: 'PERCENTAGE' as const, percentage: Number(percentage) };
149
- }
150
- errors.push('Invalid approvalMode');
151
- return undefined;
152
- }
153
-
154
- function normalizeExplicitRule(value: unknown, errors: string[]) {
155
- if (value === undefined) return undefined;
156
- if (!isRecord(value)) {
157
- errors.push('Rule must be an object');
158
- return undefined;
159
- }
160
- if (!['ANY', 'ALL', 'COUNT', 'PERCENTAGE'].includes(String(value.mode))) {
161
- errors.push('Invalid rule mode');
162
- return undefined;
163
- }
164
- const mode = value.mode as 'ANY' | 'ALL' | 'COUNT' | 'PERCENTAGE';
165
- if (mode === 'COUNT' && !positiveInteger(value.count)) {
166
- errors.push('COUNT rule requires a positive count');
167
- return undefined;
168
- }
169
- if (
170
- mode === 'PERCENTAGE' &&
171
- (!positiveInteger(value.percentage) || Number(value.percentage) > 100)
172
- ) {
173
- errors.push('PERCENTAGE rule requires a percentage from 1 to 100');
174
- return undefined;
175
- }
176
- return {
177
- mode,
178
- ...(mode === 'COUNT' && { count: Number(value.count) }),
179
- ...(mode === 'PERCENTAGE' && {
180
- percentage: Number(value.percentage),
181
- }),
182
- };
183
- }
184
-
185
- function normalizeTimeout(input: Record<string, unknown>, errors: string[]) {
186
- if (isRecord(input.timeout)) {
187
- if (!nonNegativeInteger(input.timeout.durationSeconds))
188
- errors.push('Invalid timeout durationSeconds');
189
- if (!['APPROVED', 'REJECTED'].includes(String(input.timeout.action)))
190
- errors.push('Invalid timeout action');
191
- if (errors.length) return undefined;
192
- return {
193
- durationSeconds: Number(input.timeout.durationSeconds),
194
- action: input.timeout.action as 'APPROVED' | 'REJECTED',
195
- };
196
- }
197
- const durationSeconds = input.timeout ?? 0;
198
- if (!nonNegativeInteger(durationSeconds)) {
199
- errors.push('Timeout must be a non-negative integer');
200
- return undefined;
201
- }
202
- const legacyAction = input.timeoutAction ?? 'auto_reject';
203
- if (!['auto_approve', 'auto_reject'].includes(String(legacyAction))) {
204
- errors.push('Legacy timeout action must be auto_approve or auto_reject');
205
- return undefined;
206
- }
207
- return {
208
- durationSeconds: Number(durationSeconds),
209
- action: legacyAction === 'auto_approve' ? 'APPROVED' : 'REJECTED',
210
- } as const;
211
- }
212
-
213
- function invalid(message: string): LegacyApprovalNormalization {
214
- return { status: 'INVALID', errors: [message] };
215
- }
216
- function array(value: unknown): unknown[] {
217
- return value === undefined ? [] : Array.isArray(value) ? value : [value];
218
- }
219
- function nonNegativeInteger(value: unknown): boolean {
220
- return typeof value === 'number' && Number.isInteger(value) && value >= 0;
221
- }
222
- function positiveInteger(value: unknown): boolean {
223
- return typeof value === 'number' && Number.isInteger(value) && value > 0;
224
- }
225
- function isRecord(value: unknown): value is Record<string, unknown> {
226
- return value !== null && typeof value === 'object' && !Array.isArray(value);
227
- }
@@ -1,82 +0,0 @@
1
- import { validateWebhookResponseWorkflow } from './workflow-http-response';
2
-
3
- const trigger = {
4
- id: 'webhook',
5
- type: 'webhook_trigger',
6
- config: {
7
- responseMode: 'WAIT_FOR_RESULT',
8
- responseTimeoutSeconds: 60,
9
- },
10
- };
11
-
12
- const returnNode = (id: string) => ({
13
- id,
14
- type: 'return_result',
15
- config: {},
16
- });
17
-
18
- describe('webhook function response contract', () => {
19
- it('accepts conditional branches that each return their previous result', () => {
20
- expect(() =>
21
- validateWebhookResponseWorkflow({
22
- nodes: [
23
- trigger,
24
- { id: 'branch', type: 'if_else', config: {} },
25
- returnNode('accepted'),
26
- returnNode('rejected'),
27
- ],
28
- edges: [
29
- { source: 'webhook', target: 'branch', kind: 'FLOW' },
30
- { source: 'branch', target: 'accepted', kind: 'FLOW' },
31
- { source: 'branch', target: 'rejected', kind: 'FLOW' },
32
- ],
33
- }),
34
- ).not.toThrow();
35
- });
36
-
37
- it('accepts returning the external request data directly', () => {
38
- expect(() =>
39
- validateWebhookResponseWorkflow({
40
- nodes: [trigger, returnNode('return')],
41
- edges: [{ source: 'webhook', target: 'return', kind: 'FLOW' }],
42
- }),
43
- ).not.toThrow();
44
- });
45
-
46
- it('rejects a function-mode webhook with a terminal branch that does not return', () => {
47
- expect(() =>
48
- validateWebhookResponseWorkflow({
49
- nodes: [
50
- trigger,
51
- { id: 'branch', type: 'if_else', config: {} },
52
- returnNode('accepted'),
53
- { id: 'unfinished', type: 'code', config: {} },
54
- ],
55
- edges: [
56
- { source: 'webhook', target: 'branch', kind: 'FLOW' },
57
- { source: 'branch', target: 'accepted', kind: 'FLOW' },
58
- { source: 'branch', target: 'unfinished', kind: 'FLOW' },
59
- ],
60
- }),
61
- ).toThrow('等待返回结果时,每个流程分支都必须以“返回调用”结束');
62
- });
63
-
64
- it('rejects a return node with more than one previous node', () => {
65
- expect(() =>
66
- validateWebhookResponseWorkflow({
67
- nodes: [
68
- trigger,
69
- { id: 'left', type: 'code', config: {} },
70
- { id: 'right', type: 'code', config: {} },
71
- returnNode('return'),
72
- ],
73
- edges: [
74
- { source: 'webhook', target: 'left', kind: 'FLOW' },
75
- { source: 'webhook', target: 'right', kind: 'FLOW' },
76
- { source: 'left', target: 'return', kind: 'FLOW' },
77
- { source: 'right', target: 'return', kind: 'FLOW' },
78
- ],
79
- }),
80
- ).toThrow('“返回调用”前需要连接一个节点');
81
- });
82
- });
@@ -1,111 +0,0 @@
1
- type DslNode = {
2
- id?: unknown;
3
- type?: unknown;
4
- config?: unknown;
5
- };
6
-
7
- type DslEdge = {
8
- source?: unknown;
9
- target?: unknown;
10
- kind?: unknown;
11
- pairId?: unknown;
12
- };
13
-
14
- type DslLike = {
15
- nodes?: DslNode[];
16
- edges?: DslEdge[];
17
- };
18
-
19
- export function validateWebhookResponseWorkflow(dsl: unknown): void {
20
- const graph = asDsl(dsl);
21
- const nodes = graph.nodes ?? [];
22
- const edges = (graph.edges ?? []).filter(
23
- (edge) => (!edge.kind || edge.kind === 'FLOW') && !edge.pairId,
24
- );
25
- const waitingTriggers = nodes.filter(
26
- (node) =>
27
- node.type === 'webhook_trigger' &&
28
- asRecord(node.config).responseMode === 'WAIT_FOR_RESULT',
29
- );
30
-
31
- for (const trigger of waitingTriggers) {
32
- const config = asRecord(trigger.config);
33
- const timeout = config.responseTimeoutSeconds ?? 60;
34
- if (
35
- typeof timeout !== 'number' ||
36
- !Number.isInteger(timeout) ||
37
- timeout < 1 ||
38
- timeout > 300
39
- ) {
40
- throw new Error('等待返回结果的超时时间必须是 1 到 300 秒');
41
- }
42
- validateReturningBranches(nodes, edges, String(trigger.id));
43
- }
44
- }
45
-
46
- function validateReturningBranches(
47
- nodes: DslNode[],
48
- edges: DslEdge[],
49
- triggerId: string,
50
- ): void {
51
- const nodeById = new Map(
52
- nodes
53
- .filter((node) => typeof node.id === 'string')
54
- .map((node) => [String(node.id), node]),
55
- );
56
- const outgoing = new Map<string, string[]>();
57
- const incoming = new Map<string, string[]>();
58
- for (const edge of edges) {
59
- if (typeof edge.source !== 'string' || typeof edge.target !== 'string')
60
- continue;
61
- const targets = outgoing.get(edge.source) ?? [];
62
- targets.push(edge.target);
63
- outgoing.set(edge.source, targets);
64
- const sources = incoming.get(edge.target) ?? [];
65
- sources.push(edge.source);
66
- incoming.set(edge.target, sources);
67
- }
68
-
69
- const queue = [...(outgoing.get(triggerId) ?? [])];
70
- const visited = new Set<string>();
71
- if (queue.length === 0) {
72
- throw new Error('等待返回结果时,每个流程分支都必须以“返回调用”结束');
73
- }
74
-
75
- while (queue.length > 0) {
76
- const nodeId = queue.shift()!;
77
- if (visited.has(nodeId)) continue;
78
- visited.add(nodeId);
79
- const node = nodeById.get(nodeId);
80
- if (!node) continue;
81
- const next = outgoing.get(nodeId) ?? [];
82
-
83
- if (node.type === 'return_result') {
84
- validateReturnNode(next, incoming.get(nodeId) ?? []);
85
- continue;
86
- }
87
- if (next.length === 0) {
88
- throw new Error('等待返回结果时,每个流程分支都必须以“返回调用”结束');
89
- }
90
- queue.push(...next);
91
- }
92
- }
93
-
94
- function validateReturnNode(next: string[], previous: string[]): void {
95
- if (next.length > 0) {
96
- throw new Error('“返回调用”必须是流程分支的最后一个节点');
97
- }
98
- if (previous.length !== 1) throw new Error('“返回调用”前需要连接一个节点');
99
- }
100
-
101
- function asDsl(value: unknown): DslLike {
102
- return value && typeof value === 'object' && !Array.isArray(value)
103
- ? (value as DslLike)
104
- : {};
105
- }
106
-
107
- function asRecord(value: unknown): Record<string, unknown> {
108
- return value && typeof value === 'object' && !Array.isArray(value)
109
- ? (value as Record<string, unknown>)
110
- : {};
111
- }
@@ -1,54 +0,0 @@
1
- /// <reference types="jest" />
2
- import { ConfigService } from '@nestjs/config';
3
- import { Test, TestingModule } from '@nestjs/testing';
4
- import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
5
- import { WorkflowEventOutboxController } from './workflowEventOutbox.controller';
6
- import { WorkflowEventOutboxService } from './workflowEventOutbox.service';
7
-
8
- // Mock WorkflowEventOutboxService:用空对象屏蔽真实 Service 的依赖(PrismaService 等),
9
- // 避免 NestJS 在测试模块编译时去解析 Service 的构造参数。
10
- const mockWorkflowEventOutboxService = {};
11
-
12
- // Mock ConfigService
13
- const mockConfigService = {
14
- get: jest.fn(),
15
- };
16
-
17
- // Mock Logger
18
- const mockLogger = {
19
- child: jest.fn().mockReturnThis(),
20
- info: jest.fn(),
21
- error: jest.fn(),
22
- warn: jest.fn(),
23
- debug: jest.fn(),
24
- };
25
-
26
- describe('WorkflowEventOutboxController', () => {
27
- let controller: WorkflowEventOutboxController;
28
-
29
- beforeEach(async () => {
30
- const module: TestingModule = await Test.createTestingModule({
31
- controllers: [WorkflowEventOutboxController],
32
- providers: [
33
- {
34
- provide: WorkflowEventOutboxService,
35
- useValue: mockWorkflowEventOutboxService,
36
- },
37
- { provide: ConfigService, useValue: mockConfigService },
38
- { provide: WINSTON_MODULE_PROVIDER, useValue: mockLogger },
39
- ],
40
- })
41
- // 兜底:自动 mock 任何未显式提供的依赖
42
- // (例如 ACGuard 内部的 __roles_builder__ token)
43
- .useMocker(() => ({}))
44
- .compile();
45
-
46
- controller = module.get<WorkflowEventOutboxController>(
47
- WorkflowEventOutboxController,
48
- );
49
- });
50
-
51
- it('should be defined', () => {
52
- expect(controller).toBeDefined();
53
- });
54
- });