@gadmin2n/schematics 0.0.142 → 0.0.144

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 (140) hide show
  1. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +5 -23
  2. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/lib/page-helpers.ts +4 -2
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/page-manage.ts +36 -1
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/agenda.seed.ts +14 -14
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/bootstrap.ts +18 -13
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/canvas.seed.ts +14 -14
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +1 -1
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +67 -404
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +16 -40
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +12 -124
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.module.ts +3 -0
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/config/index.ts +0 -21
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.controller.ts +3 -10
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/codeRuntime.module.ts +1 -2
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-callback.controller.spec.ts +48 -0
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-callback.controller.ts +96 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.spec.ts +1 -59
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.ts +8 -43
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.dto.ts +0 -23
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction.service.ts +2 -0
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-wait.handler.ts +2 -0
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/externalInteraction.module.ts +7 -3
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/workflow-callback-url.controller.ts +2 -2
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/workflow-callback-url.service.spec.ts +18 -123
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/workflow-callback-url.service.ts +4 -0
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.controller.ts +3 -10
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/httpRequest.module.ts +1 -2
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.controller.ts +0 -10
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.dto.ts +12 -4
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.errors.ts +1 -1
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.external-decision.spec.ts +42 -209
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.service.ts +108 -225
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/humanApproval.module.ts +0 -2
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.controller.ts +27 -22
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.dto.ts +9 -1
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/runtime-token.guard.spec.ts +30 -0
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/runtime-token.guard.ts +8 -15
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/index.ts +0 -2
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/runtime-connectivity-probe.service.spec.ts +14 -0
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/runtime-connectivity-probe.service.ts +37 -0
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.spec.ts +41 -0
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.ts +53 -0
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.module.ts +7 -2
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/workflow-runtime-health.controller.ts +21 -0
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.spec.ts +2 -2
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.spec.ts +16 -88
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.ts +23 -59
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.spec.ts +125 -39
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.ts +95 -28
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-handle-validator.ts +0 -20
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.spec.ts +23 -26
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.ts +6 -52
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +2 -2
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +24 -0
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +26 -21
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.spec.ts +0 -1
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.ts +0 -1
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowRuntimeConfig/workflow-runtime-config.service.spec.ts +32 -0
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowRuntimeConfig/workflow-runtime-config.service.ts +41 -0
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowRuntimeConfig/workflowRuntimeConfig.module.ts +10 -0
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/server/tsconfig.build.json +10 -1
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +16 -12
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +1 -1
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/PageHeader.tsx +1 -1
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/inspectorActions.ts +19 -19
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/contexts/color-mode/index.tsx +1 -1
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/header.tsx +15 -11
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +0 -6
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddDataModal.tsx +3 -3
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddPageModal.tsx +1 -1
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DeleteDataConfirm.tsx +1 -1
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/EditDataModal.tsx +1 -1
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +1 -0
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/workflow.json +85 -95
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/workflow.json +85 -95
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +2 -2
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/list.tsx +21 -2
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/game/list.tsx +21 -2
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/inbox.tsx +14 -66
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/list.tsx +4 -4
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/list.tsx +3 -3
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/list.tsx +3 -3
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.test.tsx +29 -0
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.tsx +4 -2
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/EnhancedFlowRenderer.tsx +4 -6
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.test.tsx +3 -0
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.tsx +3 -1
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/FlowRenderer.tsx +4 -6
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NewNodeDefaults.test.tsx +23 -92
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeOutputSummary.tsx +200 -0
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.test.tsx +61 -136
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +96 -195
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeTypeBadge.tsx +36 -0
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/CreateNodeInstanceModal.tsx +5 -10
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +47 -22
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/create.tsx +7 -5
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/edit.tsx +8 -6
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/node-config.css +35 -0
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/default-widgets.tsx +1 -6
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApproverSourceEditor.tsx +1 -4
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CodeConfigEditor.tsx +1 -1
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalRequestConfigEditor.tsx +1 -1
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalWaitConfigEditor.tsx +82 -259
  104. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HttpRequestConfigEditor.tsx +1 -2
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.test.tsx +7 -6
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.tsx +77 -71
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.test.tsx +10 -57
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.tsx +8 -273
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.test.tsx +54 -0
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +110 -20
  111. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/newNodeConfig.ts +4 -34
  112. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.test.ts +3 -10
  113. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.ts +2 -37
  114. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +26 -2
  115. package/package.json +1 -1
  116. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.controller.ts +0 -89
  117. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.dto.ts +0 -68
  118. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.service.spec.ts +0 -177
  119. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.service.ts +0 -283
  120. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approvalChannel.module.ts +0 -10
  121. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/ApprovalChannelModal.test.tsx +0 -84
  122. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/ApprovalChannelModal.tsx +0 -141
  123. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/approval-channel.types.ts +0 -16
  124. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/index.tsx +0 -210
  125. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApprovalRequestTriggerConfigEditor.tsx +0 -39
  126. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubmitApprovalResultConfigEditor.tsx +0 -104
  127. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubmitExternalResultConfigEditor.tsx +0 -98
  128. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/AssignRolesModal.tsx +0 -0
  129. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/CreatePageModal.tsx +0 -0
  130. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/EditPageModal.tsx +0 -0
  131. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/PageDetailDrawer.tsx +0 -0
  132. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/PageFormModal.tsx +0 -0
  133. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/CreateModal.tsx +0 -0
  134. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/EditModal.tsx +0 -0
  135. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/ResourceDetailDrawer.tsx +0 -0
  136. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/modal.tsx +0 -0
  137. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/CreateModal.tsx +0 -0
  138. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/EditModal.tsx +0 -0
  139. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/RoleDetailDrawer.tsx +0 -0
  140. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/modal.tsx +0 -0
@@ -1,64 +1,6 @@
1
1
  import { ExternalInteractionRuntimeController } from './external-interaction-runtime.controller';
2
2
 
3
3
  describe('ExternalInteractionRuntimeController', () => {
4
- const input = {
5
- tenantNamespace: 'tenant-a',
6
- workflowInstanceId: '901',
7
- workflowVersionId: '71',
8
- temporalRunId: 'wf-callback-901',
9
- nodeId: 'submit-result-1',
10
- callbackToken: 'ext_cb_token',
11
- eventId: 'provider-1001',
12
- outcome: 'SIGNED',
13
- };
14
-
15
- it('submits a normalized result for the configured tenant', async () => {
16
- const service = {
17
- submitResult: jest.fn().mockResolvedValue({
18
- accepted: true,
19
- duplicate: false,
20
- interactionStatus: 'RESOLVED',
21
- resolvedOutcome: 'SIGNED',
22
- }),
23
- };
24
- const controller = new ExternalInteractionRuntimeController(
25
- service as any,
26
- {
27
- get: jest.fn().mockReturnValue({ tenantNamespace: 'tenant-a' }),
28
- } as any,
29
- { resolve: jest.fn() } as any,
30
- );
31
-
32
- await expect(controller.submitResult(input)).resolves.toEqual({
33
- accepted: true,
34
- duplicate: false,
35
- interactionStatus: 'RESOLVED',
36
- resolvedOutcome: 'SIGNED',
37
- });
38
- });
39
-
40
- it('rejects callback activity metadata from another tenant', async () => {
41
- const controller = new ExternalInteractionRuntimeController(
42
- { submitResult: jest.fn() } as any,
43
- {
44
- get: jest.fn().mockReturnValue({ tenantNamespace: 'tenant-a' }),
45
- } as any,
46
- { resolve: jest.fn() } as any,
47
- );
48
-
49
- expect(() =>
50
- controller.submitResult({ ...input, tenantNamespace: 'tenant-b' }),
51
- ).toThrow(
52
- expect.objectContaining({
53
- response: {
54
- code: 'WORKFLOW_RUNTIME_TENANT_MISMATCH',
55
- message: 'Runtime tenant does not match this application',
56
- retryable: false,
57
- },
58
- }),
59
- );
60
- });
61
-
62
4
  it('starts an external wait and resolves the selected callback Workflow', async () => {
63
5
  const service = {
64
6
  createInteraction: jest.fn().mockResolvedValue({
@@ -77,7 +19,7 @@ describe('ExternalInteractionRuntimeController', () => {
77
19
  const controller = new ExternalInteractionRuntimeController(
78
20
  service as any,
79
21
  {
80
- get: jest.fn().mockReturnValue({ tenantNamespace: 'tenant-a' }),
22
+ assertTenant: jest.fn().mockResolvedValue(undefined),
81
23
  } as any,
82
24
  callbackUrls as any,
83
25
  );
@@ -1,17 +1,10 @@
1
- import {
2
- BadRequestException,
3
- Body,
4
- Controller,
5
- Post,
6
- UseGuards,
7
- } from '@nestjs/common';
8
- import { ConfigService } from '@nestjs/config';
1
+ import { Body, Controller, Post, UseGuards } from '@nestjs/common';
9
2
  import { AllowUnauthorizedRequest } from '../../lib/auth.guard';
10
3
  import { RuntimeTokenGuard } from '../humanApproval/runtime/runtime-token.guard';
4
+ import { WorkflowRuntimeConfigService } from '../workflowRuntimeConfig/workflow-runtime-config.service';
11
5
  import {
12
6
  CloseExternalInteractionRuntimeDto,
13
7
  StartExternalInteractionRuntimeDto,
14
- SubmitExternalResultRuntimeDto,
15
8
  } from './external-interaction-runtime.dto';
16
9
  import { ExternalInteractionService } from './external-interaction.service';
17
10
  import { WorkflowCallbackUrlService } from './workflow-callback-url.service';
@@ -21,14 +14,14 @@ import { WorkflowCallbackUrlService } from './workflow-callback-url.service';
21
14
  export class ExternalInteractionRuntimeController {
22
15
  constructor(
23
16
  private readonly interactions: ExternalInteractionService,
24
- private readonly config: ConfigService,
17
+ private readonly runtimeConfig: WorkflowRuntimeConfigService,
25
18
  private readonly callbackUrls: WorkflowCallbackUrlService,
26
19
  ) {}
27
20
 
28
21
  @Post('start')
29
22
  @AllowUnauthorizedRequest()
30
23
  async start(@Body() input: StartExternalInteractionRuntimeDto) {
31
- this.assertTenant(input.tenantNamespace);
24
+ await this.runtimeConfig.assertTenant(input.tenantNamespace);
32
25
  const callbackUrl = input.callbackWorkflowId
33
26
  ? await this.callbackUrls.resolve(input.callbackWorkflowId)
34
27
  : undefined;
@@ -48,8 +41,8 @@ export class ExternalInteractionRuntimeController {
48
41
 
49
42
  @Post('expire')
50
43
  @AllowUnauthorizedRequest()
51
- expire(@Body() input: CloseExternalInteractionRuntimeDto) {
52
- this.assertTenant(input.tenantNamespace);
44
+ async expire(@Body() input: CloseExternalInteractionRuntimeDto) {
45
+ await this.runtimeConfig.assertTenant(input.tenantNamespace);
53
46
  return this.interactions.expireInteraction(
54
47
  input.tenantNamespace,
55
48
  input.callbackToken,
@@ -58,39 +51,11 @@ export class ExternalInteractionRuntimeController {
58
51
 
59
52
  @Post('cancel')
60
53
  @AllowUnauthorizedRequest()
61
- cancel(@Body() input: CloseExternalInteractionRuntimeDto) {
62
- this.assertTenant(input.tenantNamespace);
54
+ async cancel(@Body() input: CloseExternalInteractionRuntimeDto) {
55
+ await this.runtimeConfig.assertTenant(input.tenantNamespace);
63
56
  return this.interactions.cancelInteraction(
64
57
  input.tenantNamespace,
65
58
  input.callbackToken,
66
59
  );
67
60
  }
68
-
69
- @Post('results')
70
- @AllowUnauthorizedRequest()
71
- submitResult(@Body() input: SubmitExternalResultRuntimeDto) {
72
- this.assertTenant(input.tenantNamespace);
73
- const {
74
- tenantNamespace,
75
- workflowInstanceId: _workflowInstanceId,
76
- workflowVersionId: _workflowVersionId,
77
- temporalRunId: _temporalRunId,
78
- nodeId: _nodeId,
79
- ...result
80
- } = input;
81
- return this.interactions.submitResult(tenantNamespace, result);
82
- }
83
-
84
- private assertTenant(tenantNamespace: string): void {
85
- const runtime = this.config.get<{ tenantNamespace: string }>(
86
- 'humanApprovalRuntime',
87
- );
88
- if (tenantNamespace !== runtime?.tenantNamespace) {
89
- throw new BadRequestException({
90
- code: 'WORKFLOW_RUNTIME_TENANT_MISMATCH',
91
- message: 'Runtime tenant does not match this application',
92
- retryable: false,
93
- });
94
- }
95
- }
96
61
  }
@@ -3,7 +3,6 @@ import {
3
3
  IsArray,
4
4
  IsISO8601,
5
5
  IsNotEmpty,
6
- IsObject,
7
6
  IsOptional,
8
7
  IsString,
9
8
  } from 'class-validator';
@@ -54,25 +53,3 @@ export class CloseExternalInteractionRuntimeDto extends ExternalInteractionRunti
54
53
  @IsNotEmpty()
55
54
  callbackToken!: string;
56
55
  }
57
-
58
- export class SubmitExternalResultRuntimeDto extends ExternalInteractionRuntimeMetadataDto {
59
- @IsString()
60
- @IsNotEmpty()
61
- callbackToken!: string;
62
-
63
- @IsString()
64
- @IsNotEmpty()
65
- eventId!: string;
66
-
67
- @IsString()
68
- @IsNotEmpty()
69
- outcome!: string;
70
-
71
- @IsOptional()
72
- @IsString()
73
- operatorId?: string;
74
-
75
- @IsOptional()
76
- @IsObject()
77
- data?: Record<string, unknown>;
78
- }
@@ -201,6 +201,8 @@ export class ExternalInteractionService {
201
201
  signalName: result.signal?.name ?? 'externalInteractionResolved',
202
202
  payload: (result.signal?.payload ?? {
203
203
  nodeId: interaction.nodeId,
204
+ callbackToken: input.callbackToken,
205
+ eventId: input.eventId,
204
206
  outcome: result.outcome,
205
207
  ...(input.operatorId && { operatorId: input.operatorId }),
206
208
  ...(input.data && { data: input.data }),
@@ -32,6 +32,8 @@ export class ExternalWaitHandler implements ExternalInteractionHandler {
32
32
  state: 'RESOLVED',
33
33
  outcome: event.outcome,
34
34
  output: {
35
+ callbackToken: event.callbackToken,
36
+ eventId: event.eventId,
35
37
  outcome: event.outcome,
36
38
  ...(event.operatorId && { operatorId: event.operatorId }),
37
39
  ...(event.data && { data: event.data }),
@@ -1,6 +1,6 @@
1
1
  import { Injectable, Module, OnModuleInit } from '@nestjs/common';
2
- import { RuntimeTokenGuard } from '../humanApproval/runtime/runtime-token.guard';
3
2
  import { TemporalModule } from '../workflow/temporal.module';
3
+ import { ExternalCallbackController } from './external-callback.controller';
4
4
  import { ExternalInteractionHandlerRegistry } from './external-interaction-handler.registry';
5
5
  import { ExternalInteractionRuntimeController } from './external-interaction-runtime.controller';
6
6
  import { ExternalInteractionSignalOutboxService } from './external-interaction-signal-outbox.service';
@@ -24,6 +24,7 @@ class ExternalInteractionHandlerRegistrar implements OnModuleInit {
24
24
  @Module({
25
25
  imports: [TemporalModule],
26
26
  controllers: [
27
+ ExternalCallbackController,
27
28
  ExternalInteractionRuntimeController,
28
29
  WorkflowCallbackUrlController,
29
30
  ],
@@ -34,8 +35,11 @@ class ExternalInteractionHandlerRegistrar implements OnModuleInit {
34
35
  ExternalInteractionHandlerRegistrar,
35
36
  ExternalInteractionSignalOutboxService,
36
37
  WorkflowCallbackUrlService,
37
- RuntimeTokenGuard,
38
38
  ],
39
- exports: [ExternalInteractionHandlerRegistry, ExternalInteractionService],
39
+ exports: [
40
+ ExternalInteractionHandlerRegistry,
41
+ ExternalInteractionService,
42
+ WorkflowCallbackUrlService,
43
+ ],
40
44
  })
41
45
  export class ExternalInteractionModule {}
@@ -6,7 +6,7 @@ export class WorkflowCallbackUrlController {
6
6
  constructor(private readonly callbackUrls: WorkflowCallbackUrlService) {}
7
7
 
8
8
  @Get('endpoint')
9
- resolveEndpoint(@Query('path') path = ''): { endpoint: string } {
10
- return { endpoint: this.callbackUrls.resolvePath(path) };
9
+ async resolveEndpoint(@Query('path') path = '') {
10
+ return { endpoint: await this.callbackUrls.resolvePath(path) };
11
11
  }
12
12
  }
@@ -39,6 +39,19 @@ describe('WorkflowCallbackUrlService', () => {
39
39
  );
40
40
  });
41
41
 
42
+ it('resolves the platform callback through the shared public URL generator', () => {
43
+ const service = new WorkflowCallbackUrlService(
44
+ {} as any,
45
+ {
46
+ get: jest.fn().mockReturnValue('https://gadmin.example.com/'),
47
+ } as any,
48
+ );
49
+
50
+ expect(service.resolveExternalCallback()).toBe(
51
+ 'https://gadmin.example.com/api/workflow/external-callback',
52
+ );
53
+ });
54
+
42
55
  it('rejects a callback Workflow with multiple external request triggers', async () => {
43
56
  const service = new WorkflowCallbackUrlService(
44
57
  {
@@ -63,13 +76,11 @@ describe('WorkflowCallbackUrlService', () => {
63
76
  );
64
77
 
65
78
  await expect(service.resolve('44')).rejects.toMatchObject({
66
- response: {
67
- code: 'CALLBACK_WORKFLOW_TRIGGER_INVALID',
68
- },
79
+ response: { code: 'CALLBACK_WORKFLOW_TRIGGER_INVALID' },
69
80
  });
70
81
  });
71
82
 
72
- it('uses the PM2-assigned server port and a reachable IPv4 address when no public base URL is configured', async () => {
83
+ it('uses the server port and a reachable IPv4 address by default', () => {
73
84
  jest.spyOn(os, 'networkInterfaces').mockReturnValue({
74
85
  lo: [
75
86
  {
@@ -93,123 +104,7 @@ describe('WorkflowCallbackUrlService', () => {
93
104
  ],
94
105
  });
95
106
  const service = new WorkflowCallbackUrlService(
96
- {
97
- workflow: {
98
- findUnique: jest.fn().mockResolvedValue({
99
- status: 'PUBLISHED',
100
- isEnabled: true,
101
- versions: [
102
- {
103
- dsl: {
104
- nodes: [
105
- {
106
- type: 'webhook_trigger',
107
- config: { path: 'myoa-callback' },
108
- },
109
- ],
110
- },
111
- },
112
- ],
113
- }),
114
- },
115
- } as any,
116
- {
117
- get: jest.fn((key: string) => {
118
- if (key === 'workflow.publicBaseUrl') return '';
119
- if (key === 'workflow.publicHost') return '';
120
- if (key === 'nest.port') return 14003;
121
- return undefined;
122
- }),
123
- } as any,
124
- );
125
-
126
- await expect(service.resolve('44')).resolves.toBe(
127
- 'http://10.20.30.40:14003/api/workflow/webhook/myoa-callback',
128
- );
129
- });
130
-
131
- it('lets deployments override the automatically detected host', async () => {
132
- jest.spyOn(os, 'networkInterfaces').mockReturnValue({});
133
- const service = new WorkflowCallbackUrlService(
134
- {
135
- workflow: {
136
- findUnique: jest.fn().mockResolvedValue({
137
- status: 'PUBLISHED',
138
- isEnabled: true,
139
- versions: [
140
- {
141
- dsl: {
142
- nodes: [
143
- {
144
- type: 'webhook_trigger',
145
- config: { path: 'myoa-callback' },
146
- },
147
- ],
148
- },
149
- },
150
- ],
151
- }),
152
- },
153
- } as any,
154
- {
155
- get: jest.fn((key: string) => {
156
- if (key === 'workflow.publicBaseUrl') return '';
157
- if (key === 'workflow.publicHost') return '10.50.60.70';
158
- if (key === 'nest.port') return 14009;
159
- return undefined;
160
- }),
161
- } as any,
162
- );
163
-
164
- await expect(service.resolve('44')).resolves.toBe(
165
- 'http://10.50.60.70:14009/api/workflow/webhook/myoa-callback',
166
- );
167
- });
168
-
169
- it('does not expose a Docker bridge address as the callback host', async () => {
170
- jest.spyOn(os, 'networkInterfaces').mockReturnValue({
171
- docker0: [
172
- {
173
- address: '172.17.0.1',
174
- netmask: '255.255.0.0',
175
- family: 'IPv4',
176
- mac: '00:00:00:00:00:01',
177
- internal: false,
178
- cidr: '172.17.0.1/16',
179
- },
180
- ],
181
- eth0: [
182
- {
183
- address: '11.22.33.44',
184
- netmask: '255.255.255.0',
185
- family: 'IPv4',
186
- mac: '00:11:22:33:44:55',
187
- internal: false,
188
- cidr: '11.22.33.44/24',
189
- },
190
- ],
191
- });
192
- const service = new WorkflowCallbackUrlService(
193
- {
194
- workflow: {
195
- findUnique: jest.fn().mockResolvedValue({
196
- status: 'PUBLISHED',
197
- isEnabled: true,
198
- versions: [
199
- {
200
- dsl: {
201
- nodes: [
202
- {
203
- type: 'webhook_trigger',
204
- config: { path: 'myoa-callback' },
205
- },
206
- ],
207
- },
208
- },
209
- ],
210
- }),
211
- },
212
- } as any,
107
+ {} as any,
213
108
  {
214
109
  get: jest.fn((key: string) => {
215
110
  if (key === 'workflow.publicBaseUrl') return '';
@@ -220,8 +115,8 @@ describe('WorkflowCallbackUrlService', () => {
220
115
  } as any,
221
116
  );
222
117
 
223
- await expect(service.resolve('44')).resolves.toBe(
224
- 'http://11.22.33.44:14003/api/workflow/webhook/myoa-callback',
118
+ expect(service.resolveExternalCallback()).toBe(
119
+ 'http://10.20.30.40:14003/api/workflow/external-callback',
225
120
  );
226
121
  });
227
122
  });
@@ -71,6 +71,10 @@ export class WorkflowCallbackUrlService {
71
71
  )}`;
72
72
  }
73
73
 
74
+ resolveExternalCallback(): string {
75
+ return `${this.resolvePublicBaseUrl()}/api/workflow/external-callback`;
76
+ }
77
+
74
78
  private resolvePublicBaseUrl(): string {
75
79
  const configuredBaseUrl = this.config
76
80
  .get<string>('workflow.publicBaseUrl')
@@ -7,13 +7,13 @@ import {
7
7
  Post,
8
8
  UseGuards,
9
9
  } from '@nestjs/common';
10
- import { ConfigService } from '@nestjs/config';
11
10
  import axios from 'axios';
12
11
  import { PrismaService } from 'nestjs-prisma';
13
12
  import { Agent as HttpsAgent } from 'node:https';
14
13
  import { AllowUnauthorizedRequest } from '../../lib/auth.guard';
15
14
  import { RuntimeTokenGuard } from '../humanApproval/runtime/runtime-token.guard';
16
15
  import { IntegrationConnectionService } from '../integrationConnection/integration-connection.service';
16
+ import { WorkflowRuntimeConfigService } from '../workflowRuntimeConfig/workflow-runtime-config.service';
17
17
  import { ExecuteHttpRequestRuntimeDto } from './http-request-runtime.dto';
18
18
  import {
19
19
  HttpRequestNodeConfig,
@@ -26,7 +26,7 @@ export class HttpRequestRuntimeController {
26
26
  constructor(
27
27
  private readonly prisma: PrismaService,
28
28
  private readonly connections: IntegrationConnectionService,
29
- private readonly config: ConfigService,
29
+ private readonly runtimeConfig: WorkflowRuntimeConfigService,
30
30
  ) {}
31
31
 
32
32
  @Post('execute')
@@ -36,14 +36,7 @@ export class HttpRequestRuntimeController {
36
36
  data: unknown;
37
37
  headers: Record<string, unknown>;
38
38
  }> {
39
- const runtime = this.config.get<{ tenantNamespace: string }>(
40
- 'humanApprovalRuntime',
41
- );
42
- if (input.tenantNamespace !== runtime?.tenantNamespace)
43
- throw runtimeError(
44
- 'WORKFLOW_RUNTIME_TENANT_MISMATCH',
45
- 'Runtime tenant does not match this application',
46
- );
39
+ await this.runtimeConfig.assertTenant(input.tenantNamespace);
47
40
 
48
41
  const instanceId = parseId(input.workflowInstanceId);
49
42
  const versionId = parseId(input.workflowVersionId);
@@ -1,5 +1,4 @@
1
1
  import { Injectable, Module, OnModuleInit } from '@nestjs/common';
2
- import { RuntimeTokenGuard } from '../humanApproval/runtime/runtime-token.guard';
3
2
  import { IntegrationConnectionModule } from '../integrationConnection/integrationConnection.module';
4
3
  import { WidgetCatalogService } from '../workflowConfig/widget-catalog.service';
5
4
  import { WorkflowConfigModule } from '../workflowConfig/workflowConfig.module';
@@ -17,6 +16,6 @@ class HttpRequestWidgetRegistrar implements OnModuleInit {
17
16
  @Module({
18
17
  imports: [IntegrationConnectionModule, WorkflowConfigModule],
19
18
  controllers: [HttpRequestRuntimeController],
20
- providers: [RuntimeTokenGuard, HttpRequestWidgetRegistrar],
19
+ providers: [HttpRequestWidgetRegistrar],
21
20
  })
22
21
  export class HttpRequestModule {}
@@ -48,16 +48,6 @@ export class HumanApprovalController {
48
48
  actorContextFromRequest(request),
49
49
  );
50
50
  }
51
-
52
- @Post(':requestId/retry-dispatch')
53
- @UseRoles({
54
- resource: 'humanApproval',
55
- action: 'update',
56
- possession: 'any',
57
- })
58
- retryDispatch(@Param('requestId') requestId: string) {
59
- return this.service.retryDispatch(parseBigIntParam(requestId));
60
- }
61
51
  }
62
52
 
63
53
  function parseBigIntParam(value: string): bigint {
@@ -45,11 +45,11 @@ export class ApprovalConfigSnapshotDto {
45
45
  @IsOptional()
46
46
  @IsString()
47
47
  @IsNotEmpty()
48
- channelRef?: string;
48
+ approvalWorkflowId?: string;
49
49
 
50
50
  @IsOptional()
51
51
  @IsObject()
52
- channelInputBindings?: Record<string, unknown>;
52
+ approvalWorkflowInputBindings?: Record<string, unknown>;
53
53
 
54
54
  @IsArray()
55
55
  @ValidateNested({ each: true })
@@ -84,6 +84,14 @@ export class StartApprovalRequestDto {
84
84
  @IsString()
85
85
  temporalRunId?: string;
86
86
 
87
+ @IsOptional()
88
+ @IsString()
89
+ approvalWorkflowRunId?: string;
90
+
91
+ @IsOptional()
92
+ @IsString()
93
+ callbackToken?: string;
94
+
87
95
  @IsString()
88
96
  @IsNotEmpty()
89
97
  configHash: string;
@@ -98,7 +106,7 @@ export class StartApprovalRequestDto {
98
106
 
99
107
  @IsOptional()
100
108
  @IsObject()
101
- channelInputs?: Record<string, unknown>;
109
+ approvalWorkflowInputs?: Record<string, unknown>;
102
110
 
103
111
  @IsOptional()
104
112
  @IsArray()
@@ -132,7 +140,7 @@ export class SubmitApprovalDecisionDto {
132
140
  export class SubmitExternalApprovalDecisionDto extends SubmitApprovalDecisionDto {
133
141
  @IsString()
134
142
  @IsNotEmpty()
135
- channelRef!: string;
143
+ approvalWorkflowId!: string;
136
144
 
137
145
  @IsString()
138
146
  @IsNotEmpty()
@@ -5,7 +5,7 @@ export type HumanApprovalErrorCode =
5
5
  | 'APPROVAL_REQUEST_NOT_FOUND'
6
6
  | 'APPROVAL_REQUEST_CLOSED'
7
7
  | 'APPROVAL_NOT_CANDIDATE'
8
- | 'APPROVAL_CHANNEL_MISMATCH'
8
+ | 'APPROVAL_WORKFLOW_MISMATCH'
9
9
  | 'APPROVAL_DECISION_CONFLICT';
10
10
 
11
11
  export class HumanApprovalDomainError extends HttpException {