@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
@@ -0,0 +1,541 @@
1
+ import { hashNodeInstanceConfig } from '../workflowNodeInstance/node-instance-config.util';
2
+ import { HumanApprovalService } from './human-approval.service';
3
+
4
+ describe('HumanApprovalService', () => {
5
+ it('stores the resolved task in the built-in approval request', async () => {
6
+ const create = jest.fn().mockResolvedValue({
7
+ id: BigInt(40),
8
+ status: 'PENDING',
9
+ });
10
+ const prisma = {
11
+ approvalRequest: {
12
+ findUnique: jest.fn().mockResolvedValue(null),
13
+ findFirst: jest.fn().mockResolvedValue(null),
14
+ },
15
+ workflowInstance: {
16
+ findUnique: jest.fn().mockResolvedValue({
17
+ id: BigInt(10),
18
+ workflowId: BigInt(30),
19
+ versionId: BigInt(20),
20
+ context: {},
21
+ }),
22
+ findMany: jest.fn().mockResolvedValue([{ id: BigInt(10) }]),
23
+ },
24
+ };
25
+ const tx = {
26
+ approvalRequest: { ...prisma.approvalRequest, create },
27
+ workflowInstance: prisma.workflowInstance,
28
+ };
29
+ Object.assign(prisma, {
30
+ $transaction: jest.fn((callback) => callback(tx)),
31
+ });
32
+ const provider = {
33
+ preview: jest.fn().mockResolvedValue({
34
+ items: [{ ref: 'alice', label: 'Alice' }],
35
+ }),
36
+ resolve: jest.fn().mockResolvedValue([
37
+ {
38
+ principalType: 'USER',
39
+ principalRef: 'alice',
40
+ displayName: 'Alice',
41
+ sourceRefs: ['alice'],
42
+ },
43
+ ]),
44
+ };
45
+ const configSnapshot = {
46
+ task: {
47
+ title: {
48
+ source: 'FIXED',
49
+ valueType: 'STRING',
50
+ value: '采购审批',
51
+ },
52
+ description: {
53
+ source: 'FIXED',
54
+ valueType: 'STRING',
55
+ value: '',
56
+ },
57
+ details: [],
58
+ },
59
+ subjects: [
60
+ { source: 'STATIC' as const, provider: 'USER', refs: ['alice'] },
61
+ ],
62
+ approvalRule: { mode: 'ANY' as const },
63
+ rejectionRule: { mode: 'ANY' as const },
64
+ timeout: { durationSeconds: 0, action: 'REJECTED' as const },
65
+ };
66
+ const task = {
67
+ title: '采购审批',
68
+ description: '请核对预算',
69
+ details: [{ key: 'amount', label: '申请金额', value: 1200 }],
70
+ };
71
+ const service = new HumanApprovalService(
72
+ prisma as any,
73
+ { get: jest.fn().mockReturnValue(provider) } as any,
74
+ );
75
+
76
+ await expect(
77
+ service.startRequest(
78
+ {
79
+ workflowInstanceId: '10',
80
+ workflowVersionId: '20',
81
+ nodeId: 'approval-1',
82
+ configHash: hashNodeInstanceConfig(configSnapshot),
83
+ configSnapshot,
84
+ task,
85
+ input: { purchaseId: 'PO-1' },
86
+ },
87
+ { userId: 'runtime' },
88
+ ),
89
+ ).resolves.toMatchObject({ id: BigInt(40), status: 'PENDING' });
90
+
91
+ const firstRequestHash = create.mock.calls[0][0].data.requestHash;
92
+ await service.startRequest(
93
+ {
94
+ workflowInstanceId: '11',
95
+ workflowVersionId: '20',
96
+ nodeId: 'approval-1',
97
+ configHash: hashNodeInstanceConfig(configSnapshot),
98
+ configSnapshot,
99
+ task: {
100
+ ...task,
101
+ details: [{ key: 'amount', label: '申请金额', value: 1300 }],
102
+ },
103
+ input: { purchaseId: 'PO-1' },
104
+ },
105
+ { userId: 'runtime' },
106
+ );
107
+ const secondRequestHash = create.mock.calls[1][0].data.requestHash;
108
+
109
+ expect(firstRequestHash).toMatch(/^[a-f0-9]{64}$/);
110
+ expect(secondRequestHash).toMatch(/^[a-f0-9]{64}$/);
111
+ expect(secondRequestHash).not.toBe(firstRequestHash);
112
+
113
+ prisma.approvalRequest.findFirst.mockResolvedValueOnce({
114
+ id: BigInt(39),
115
+ status: 'APPROVED',
116
+ requestHash: firstRequestHash,
117
+ expiresAt: null,
118
+ completedAt: new Date('2026-08-13T01:00:00.000Z'),
119
+ candidates: [],
120
+ signalOutboxes: [
121
+ {
122
+ payload: {
123
+ reason: 'RULE_SATISFIED',
124
+ decidedAt: '2026-08-13T01:00:00.000Z',
125
+ },
126
+ },
127
+ ],
128
+ });
129
+ await expect(
130
+ service.startRequest(
131
+ {
132
+ workflowInstanceId: '12',
133
+ workflowVersionId: '20',
134
+ nodeId: 'approval-1',
135
+ configHash: hashNodeInstanceConfig(configSnapshot),
136
+ configSnapshot,
137
+ task,
138
+ input: { purchaseId: 'PO-1' },
139
+ },
140
+ { userId: 'runtime' },
141
+ ),
142
+ ).resolves.toMatchObject({
143
+ id: BigInt(39),
144
+ reusedResolution: { result: 'APPROVED' },
145
+ });
146
+ expect(prisma.approvalRequest.findFirst).toHaveBeenLastCalledWith(
147
+ expect.objectContaining({
148
+ where: expect.objectContaining({ requestHash: firstRequestHash }),
149
+ }),
150
+ );
151
+ expect(create).toHaveBeenCalledTimes(2);
152
+
153
+ expect(create).toHaveBeenCalledWith({
154
+ data: expect.objectContaining({
155
+ task,
156
+ status: 'PENDING',
157
+ subjects: { create: [expect.objectContaining({ ref: 'alice' })] },
158
+ candidates: {
159
+ create: [expect.objectContaining({ principalRef: 'alice' })],
160
+ },
161
+ }),
162
+ include: { candidates: true },
163
+ });
164
+ });
165
+
166
+ it('creates the callback interaction and returns internal dispatch inputs', async () => {
167
+ const candidates = [
168
+ {
169
+ principalType: 'USER',
170
+ principalRef: 'alice',
171
+ displayName: 'Alice',
172
+ sourceRefs: ['alice'],
173
+ invalidatedAt: null,
174
+ },
175
+ ];
176
+ const request = {
177
+ id: BigInt(41),
178
+ status: 'PENDING',
179
+ expiresAt: new Date('2026-08-12T10:00:00.000Z'),
180
+ candidates,
181
+ };
182
+ const prisma = {
183
+ approvalRequest: {
184
+ findUnique: jest.fn().mockResolvedValue(null),
185
+ findFirst: jest.fn().mockResolvedValue(null),
186
+ },
187
+ workflowInstance: {
188
+ findUnique: jest.fn().mockResolvedValue({
189
+ id: BigInt(10),
190
+ workflowId: BigInt(30),
191
+ versionId: BigInt(20),
192
+ context: {},
193
+ }),
194
+ findMany: jest.fn().mockResolvedValue([{ id: BigInt(10) }]),
195
+ },
196
+ };
197
+ const tx = {
198
+ approvalRequest: {
199
+ ...prisma.approvalRequest,
200
+ create: jest.fn().mockResolvedValue(request),
201
+ },
202
+ workflowInstance: prisma.workflowInstance,
203
+ };
204
+ Object.assign(prisma, {
205
+ $transaction: jest.fn((callback) => callback(tx)),
206
+ });
207
+ const provider = {
208
+ preview: jest.fn().mockResolvedValue({ items: [{ ref: 'alice' }] }),
209
+ resolve: jest.fn().mockResolvedValue(candidates),
210
+ };
211
+ const interactions = {
212
+ createInteractionInTransaction: jest.fn().mockResolvedValue({
213
+ interactionId: '51',
214
+ callbackToken: 'ext_cb_test',
215
+ status: 'PENDING',
216
+ }),
217
+ };
218
+ const service = new HumanApprovalService(
219
+ prisma as any,
220
+ { get: jest.fn().mockReturnValue(provider) } as any,
221
+ interactions as any,
222
+ );
223
+ const configSnapshot = {
224
+ external: {
225
+ request: {},
226
+ creationResult: { script: 'return response;' },
227
+ callbackResult: { script: 'return callback.body;' },
228
+ },
229
+ task: {},
230
+ subjects: [
231
+ { source: 'STATIC' as const, provider: 'USER', refs: ['alice'] },
232
+ ],
233
+ approvalRule: { mode: 'ANY' as const },
234
+ rejectionRule: { mode: 'ANY' as const },
235
+ timeout: { durationSeconds: 60, action: 'REJECTED' as const },
236
+ };
237
+ const task = { title: '采购审批', details: [] };
238
+
239
+ await expect(
240
+ service.startRequest(
241
+ {
242
+ workflowInstanceId: '10',
243
+ workflowVersionId: '20',
244
+ nodeId: 'approval-1',
245
+ configHash: hashNodeInstanceConfig(configSnapshot),
246
+ configSnapshot,
247
+ task,
248
+ input: { purchaseId: 'PO-1' },
249
+ tenantNamespace: 'tenant-a',
250
+ temporalRunId: 'run-1',
251
+ callbackToken: 'ext_cb_test',
252
+ callbackUrl:
253
+ 'https://gadmin.example.com/api/workflow/external-callback',
254
+ },
255
+ { userId: 'runtime' },
256
+ ),
257
+ ).resolves.toMatchObject({
258
+ externalApproval: {
259
+ requestId: '41',
260
+ callbackToken: 'ext_cb_test',
261
+ callbackUrl:
262
+ 'https://gadmin.example.com/api/workflow/external-callback',
263
+ expiresAt: '2026-08-12T10:00:00.000Z',
264
+ task,
265
+ candidates: [{ approverId: 'alice', displayName: 'Alice' }],
266
+ },
267
+ });
268
+ expect(interactions.createInteractionInTransaction).toHaveBeenCalledWith(
269
+ expect.objectContaining({
270
+ callbackToken: 'ext_cb_test',
271
+ handlerType: 'HUMAN_APPROVAL',
272
+ handlerConfig: {
273
+ approvalRequestId: '41',
274
+ input: { purchaseId: 'PO-1' },
275
+ callbackUrl:
276
+ 'https://gadmin.example.com/api/workflow/external-callback',
277
+ },
278
+ temporalRunId: 'run-1',
279
+ nodeId: 'approval-1',
280
+ }),
281
+ tx,
282
+ );
283
+ });
284
+
285
+ it('accepts a GAdmin decision for the same request sent to an external system', async () => {
286
+ const candidate = {
287
+ id: BigInt(91),
288
+ principalType: 'USER',
289
+ principalRef: 'alice',
290
+ displayName: 'Alice',
291
+ invalidatedAt: null,
292
+ };
293
+ const decision = {
294
+ id: BigInt(101),
295
+ candidateId: candidate.id,
296
+ decision: 'APPROVE',
297
+ };
298
+ const tx = {
299
+ $queryRawUnsafe: jest
300
+ .fn()
301
+ .mockResolvedValueOnce([{ id: BigInt(10), status: 'RUNNING' }])
302
+ .mockResolvedValue([]),
303
+ approvalRequest: {
304
+ findUnique: jest.fn().mockResolvedValue({
305
+ id: BigInt(41),
306
+ workflowInstanceId: BigInt(10),
307
+ nodeId: 'approval-1',
308
+ status: 'PENDING',
309
+ configSnapshot: {
310
+ external: { request: {} },
311
+ blockCancellationOnResolved: true,
312
+ },
313
+ approvalRule: { mode: 'ANY' },
314
+ rejectionRule: { mode: 'ANY' },
315
+ candidates: [candidate],
316
+ decisions: [],
317
+ }),
318
+ updateMany: jest.fn().mockResolvedValue({ count: 1 }),
319
+ },
320
+ approvalDecision: { create: jest.fn().mockResolvedValue(decision) },
321
+ approvalSignalOutbox: { upsert: jest.fn().mockResolvedValue({}) },
322
+ workflowInstance: {
323
+ updateMany: jest.fn().mockResolvedValue({ count: 1 }),
324
+ },
325
+ };
326
+ const service = new HumanApprovalService(
327
+ { $transaction: jest.fn((callback) => callback(tx)) } as any,
328
+ {} as any,
329
+ );
330
+
331
+ await expect(
332
+ service.submitDecision(
333
+ BigInt(41),
334
+ { decision: 'APPROVE' },
335
+ { userId: 'alice' },
336
+ ),
337
+ ).resolves.toEqual(decision);
338
+ expect(tx.$queryRawUnsafe.mock.calls[0][0]).toContain(
339
+ 'FROM t_workflow_instance workflow',
340
+ );
341
+ expect(tx.$queryRawUnsafe.mock.calls[0][0]).toContain(
342
+ 'FOR UPDATE OF workflow',
343
+ );
344
+ expect(tx.$queryRawUnsafe).toHaveBeenCalledWith(
345
+ 'SELECT id FROM t_approval_request WHERE id = $1 FOR UPDATE',
346
+ BigInt(41),
347
+ );
348
+ expect(tx.$queryRawUnsafe.mock.invocationCallOrder[0]).toBeLessThan(
349
+ tx.approvalRequest.findUnique.mock.invocationCallOrder[0],
350
+ );
351
+ expect(tx.approvalRequest.updateMany).toHaveBeenCalledWith({
352
+ where: { id: BigInt(41), status: 'PENDING' },
353
+ data: { status: 'APPROVED', completedAt: expect.any(Date) },
354
+ });
355
+ expect(tx.approvalSignalOutbox.upsert).toHaveBeenCalled();
356
+ expect(tx.workflowInstance.updateMany).toHaveBeenCalledWith({
357
+ where: {
358
+ id: BigInt(10),
359
+ cancellationBlockedAt: null,
360
+ },
361
+ data: {
362
+ cancellationBlockedAt: expect.any(Date),
363
+ cancellationBlockedByNodeId: 'approval-1',
364
+ },
365
+ });
366
+ });
367
+
368
+ it('does not accept an approval decision after Workflow cancellation wins', async () => {
369
+ const tx = {
370
+ $queryRawUnsafe: jest
371
+ .fn()
372
+ .mockResolvedValueOnce([{ id: BigInt(10), status: 'CANCELLED' }]),
373
+ approvalRequest: {
374
+ findUnique: jest.fn(),
375
+ },
376
+ approvalDecision: { create: jest.fn() },
377
+ };
378
+ const service = new HumanApprovalService(
379
+ { $transaction: jest.fn((callback) => callback(tx)) } as any,
380
+ {} as any,
381
+ );
382
+
383
+ await expect(
384
+ service.submitDecision(
385
+ BigInt(41),
386
+ { decision: 'APPROVE' },
387
+ { userId: 'alice' },
388
+ ),
389
+ ).rejects.toMatchObject({
390
+ response: { code: 'APPROVAL_REQUEST_CLOSED' },
391
+ });
392
+ expect(tx.approvalDecision.create).not.toHaveBeenCalled();
393
+ });
394
+
395
+ it('converts an external callback inside the approval node before recording it', async () => {
396
+ const candidates = [
397
+ {
398
+ id: BigInt(91),
399
+ principalType: 'USER',
400
+ principalRef: 'alice',
401
+ displayName: 'Alice',
402
+ invalidatedAt: null,
403
+ },
404
+ {
405
+ id: BigInt(92),
406
+ principalType: 'USER',
407
+ principalRef: 'bob',
408
+ displayName: 'Bob',
409
+ invalidatedAt: null,
410
+ },
411
+ ];
412
+ const tx = {
413
+ $queryRawUnsafe: jest
414
+ .fn()
415
+ .mockResolvedValueOnce([{ id: BigInt(10), status: 'RUNNING' }])
416
+ .mockResolvedValue([]),
417
+ approvalRequest: {
418
+ findUnique: jest.fn().mockResolvedValue({
419
+ id: BigInt(41),
420
+ workflowInstanceId: BigInt(10),
421
+ nodeId: 'approval-1',
422
+ status: 'PENDING',
423
+ task: { title: '采购审批', details: [] },
424
+ configSnapshot: {
425
+ external: {
426
+ callbackResult: {
427
+ mode: 'runOnceForAll',
428
+ timeout: 1000,
429
+ script: `const body = callback.body;
430
+ return {
431
+ result: body.decision,
432
+ eventId: callback.eventId,
433
+ operatorId: body.userId,
434
+ comment: body.comment + ':' + workflow.requesterId + ':' + input.title + ':' + approval.requestId,
435
+ };`,
436
+ },
437
+ },
438
+ },
439
+ approvalRule: { mode: 'ALL' },
440
+ rejectionRule: { mode: 'ANY' },
441
+ candidates,
442
+ decisions: [],
443
+ }),
444
+ },
445
+ workflowInstance: {
446
+ findUnique: jest.fn().mockResolvedValue({
447
+ context: {
448
+ workflow: { requesterId: 'requester-1' },
449
+ nodes: {},
450
+ },
451
+ }),
452
+ },
453
+ approvalDecision: {
454
+ create: jest.fn().mockResolvedValue({
455
+ id: BigInt(101),
456
+ decision: 'APPROVE',
457
+ }),
458
+ },
459
+ };
460
+ const service = new HumanApprovalService({} as any, {} as any);
461
+
462
+ await expect(
463
+ service.handleExternalInteractionDecision(
464
+ tx,
465
+ BigInt(41),
466
+ {
467
+ callbackToken: 'ext_cb_test',
468
+ eventId: 'external:workitem-1',
469
+ outcome: 'RECEIVED',
470
+ data: {
471
+ callback: {
472
+ decision: 'APPROVED',
473
+ userId: 'alice',
474
+ comment: '同意',
475
+ },
476
+ },
477
+ },
478
+ { title: '服务器权限申请' },
479
+ 'https://gadmin.example.com/api/workflow/external-callback',
480
+ ),
481
+ ).resolves.toBe('PENDING');
482
+
483
+ expect(tx.$queryRawUnsafe).toHaveBeenCalledWith(
484
+ 'SELECT id FROM t_approval_request WHERE id = $1 FOR UPDATE',
485
+ BigInt(41),
486
+ );
487
+ expect(tx.$queryRawUnsafe.mock.invocationCallOrder[0]).toBeLessThan(
488
+ tx.approvalRequest.findUnique.mock.invocationCallOrder[0],
489
+ );
490
+ expect(tx.approvalDecision.create).toHaveBeenCalledWith({
491
+ data: expect.objectContaining({
492
+ requestId: BigInt(41),
493
+ candidateId: BigInt(91),
494
+ decision: 'APPROVE',
495
+ comment: '同意:requester-1:服务器权限申请:41',
496
+ creator: 'external-token:alice',
497
+ payload: { externalEventId: 'external:workitem-1' },
498
+ }),
499
+ });
500
+ expect(tx.workflowInstance.findUnique).toHaveBeenCalledWith({
501
+ where: { id: BigInt(10) },
502
+ select: { context: true },
503
+ });
504
+ });
505
+
506
+ it('serializes cancellation with approval decisions', async () => {
507
+ const pending = {
508
+ id: BigInt(41),
509
+ workflowInstanceId: BigInt(10),
510
+ nodeId: 'approval-1',
511
+ status: 'PENDING',
512
+ };
513
+ const cancelled = { ...pending, status: 'CANCELLED' };
514
+ const tx = {
515
+ $queryRawUnsafe: jest.fn().mockResolvedValue([]),
516
+ approvalRequest: {
517
+ findUnique: jest
518
+ .fn()
519
+ .mockResolvedValueOnce(pending)
520
+ .mockResolvedValueOnce(cancelled),
521
+ updateMany: jest.fn().mockResolvedValue({ count: 1 }),
522
+ },
523
+ approvalSignalOutbox: { upsert: jest.fn().mockResolvedValue({}) },
524
+ };
525
+ const service = new HumanApprovalService(
526
+ { $transaction: jest.fn((callback) => callback(tx)) } as any,
527
+ {} as any,
528
+ );
529
+
530
+ await expect(service.cancelRequest(BigInt(41))).resolves.toEqual(cancelled);
531
+
532
+ expect(tx.$queryRawUnsafe.mock.invocationCallOrder[0]).toBeLessThan(
533
+ tx.approvalRequest.findUnique.mock.invocationCallOrder[0],
534
+ );
535
+ expect(tx.approvalRequest.updateMany).toHaveBeenCalledWith({
536
+ where: { id: BigInt(41), status: 'PENDING' },
537
+ data: { status: 'CANCELLED', completedAt: expect.any(Date) },
538
+ });
539
+ expect(tx.approvalSignalOutbox.upsert).toHaveBeenCalledTimes(1);
540
+ });
541
+ });