@gadmin2n/schematics 0.0.72 → 0.0.75

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 (173) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +2 -0
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/job.prisma +62 -0
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/system.prisma +0 -21
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +171 -0
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/AgendaJob.ts +60 -0
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Event.ts +1 -1
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowEventOutbox.ts +62 -0
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeInstance.ts +62 -0
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeType.ts +62 -0
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.env +5 -0
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +5 -4
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma.config.ts +14 -7
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +4 -0
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permissions.ts +49 -3
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +746 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +786 -0
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.controller.ts +6 -0
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.service.ts +79 -0
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.spec.ts +20 -0
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.ts +145 -0
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.module.ts +10 -0
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/{canvas/canvas.service.spec.ts → agendaJob/agendaJob.service.spec.ts} +71 -65
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.service.ts +83 -0
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/index.ts +2 -1
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.module.ts +9 -0
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +100 -0
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +19 -0
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.dto.ts +43 -0
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.service.ts +317 -0
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-node-type.controller.ts +16 -0
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-node-type.service.ts +13 -0
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +220 -0
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +82 -0
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.module.ts +16 -0
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +505 -0
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.spec.ts +22 -0
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.ts +147 -0
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.module.ts +10 -0
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.spec.ts +356 -0
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.ts +110 -0
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.spec.ts +22 -0
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.ts +216 -0
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.module.ts +10 -0
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.spec.ts +356 -0
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.ts +168 -0
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.spec.ts +22 -0
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.ts +199 -0
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.module.ts +10 -0
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.spec.ts +348 -0
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.ts +106 -0
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/server/yarn.lock +579 -1082
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +278 -0
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/config/development-sql.yaml +5 -0
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/docker-compose.yml +25 -0
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/package.json +13 -0
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/sql/create-event-trigger.sql +87 -0
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/.env +7 -0
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/SANDBOX.md +122 -0
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package-lock.json +4285 -0
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package.json +28 -0
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/activities/code-execute.test.ts +44 -0
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/activities/http-request.test.ts +87 -0
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/helpers.test.ts +225 -0
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/node-type-consistency.test.ts +101 -0
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/code-execute.ts +51 -0
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-execute.ts +85 -0
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-query.ts +35 -0
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/http-request.ts +54 -0
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/index.ts +6 -0
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/reporting.ts +62 -0
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/send-notification.ts +47 -0
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/config.ts +13 -0
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/condition.ts +101 -0
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/context.ts +58 -0
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/graph.ts +184 -0
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/helpers.ts +133 -0
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/node-types.ts +57 -0
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/types.ts +77 -0
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/index.ts +36 -0
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/outbox-poller.ts +226 -0
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/workflows/dsl-workflow.ts +411 -0
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/tsconfig.json +19 -0
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/vitest.config.ts +8 -0
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/yarn.lock +1905 -0
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package-lock.json +17555 -0
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +5 -2
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/App.tsx +1 -0
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/sider.tsx +5 -1
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/title.tsx +1 -1
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +63 -0
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DevShell.tsx +91 -2
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/list.tsx +48 -2
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/show.tsx +43 -2
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +14 -9
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +14 -9
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +309 -56
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/show.tsx +1 -3
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/create.tsx +108 -0
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/edit.tsx +124 -0
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/index.tsx +4 -0
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/list.tsx +245 -0
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/show.tsx +70 -0
  104. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +0 -1
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx +160 -2
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx +120 -148
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CodeFloatWindow.tsx +74 -181
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/LivePreview.tsx +15 -13
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasConfigRegistry.tsx +2 -2
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasContextMenuRegistry.tsx +338 -3
  111. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasDefaults.ts +18 -17
  112. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/BarChartDataSourceModal.tsx +10 -4
  113. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/LineChartDataSourceModal.tsx +10 -4
  114. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/{ChartViewerConfigModal.tsx → MultiChartConfigModal.tsx} +30 -18
  115. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/MultiChartDataSourceModal.tsx +427 -0
  116. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/NumCardDataSourceModal.tsx +10 -4
  117. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/PromptModal.tsx +6 -14
  118. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/RadarChartDataSourceModal.tsx +10 -4
  119. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/TableDataSourceModal.tsx +10 -4
  120. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/canvasModalProps.ts +24 -0
  121. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/demos.ts +45 -63
  122. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.tsx +99 -0
  123. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExportModal.tsx +87 -0
  124. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/FlowRenderer.tsx +322 -0
  125. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ImportModal.tsx +175 -0
  126. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeEditModal.tsx +60 -0
  127. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +1150 -0
  128. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/RunWorkflowModal.tsx +101 -0
  129. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/StatusCards.tsx +198 -0
  130. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/VersionPanel.tsx +81 -0
  131. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +566 -0
  132. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useWorkflowAgent.ts +224 -0
  133. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +524 -0
  134. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +343 -0
  135. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instances.tsx +243 -0
  136. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/CreateNodeInstanceModal.tsx +363 -0
  137. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/DynamicConfigForm.tsx +154 -0
  138. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +176 -0
  139. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/create.tsx +77 -0
  140. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/edit.tsx +112 -0
  141. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/index.tsx +305 -0
  142. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/show.tsx +282 -0
  143. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/show.tsx +469 -0
  144. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +92 -0
  145. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/create.tsx +111 -0
  146. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/edit.tsx +127 -0
  147. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/index.tsx +4 -0
  148. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +254 -0
  149. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/show.tsx +74 -0
  150. package/dist/lib/application/files/gadmin2-game-angle-demo/web/yarn.lock +1501 -1199
  151. package/package.json +1 -1
  152. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.controller.spec.ts +0 -22
  153. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/BarChart/index.tsx +0 -896
  154. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartSwitcher/index.tsx +0 -219
  155. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartViewer/index.tsx +0 -159
  156. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Filter/index.tsx +0 -192
  157. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/LineChart/index.tsx +0 -1034
  158. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/NumCard.module.css +0 -8
  159. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/index.tsx +0 -509
  160. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumLineCard/index.tsx +0 -66
  161. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/PieChart/index.tsx +0 -552
  162. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/RadarChart/index.tsx +0 -263
  163. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Section/index.tsx +0 -35
  164. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Table/index.tsx +0 -207
  165. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/TreemapChart/index.tsx +0 -382
  166. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/WorldMap/index.tsx +0 -135
  167. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/chart-constants.ts +0 -53
  168. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/InfoIcon.tsx +0 -8
  169. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/index.ts +0 -1
  170. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/config.ts +0 -31
  171. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/nameMap.json +0 -9
  172. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/world.geo.json +0 -39349
  173. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/metric-info-tooltip/index.tsx +0 -19
@@ -0,0 +1,356 @@
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
+
6
+ // Mock nestjs-prisma 模块
7
+ jest.mock('nestjs-prisma', () => ({
8
+ PrismaService: jest.fn(),
9
+ }));
10
+
11
+ import { PrismaService } from 'nestjs-prisma';
12
+ import { WorkflowEventOutboxService } from './workflowEventOutbox.service';
13
+
14
+ // Mock PrismaService
15
+ const mockPrismaService = {
16
+ workflowEventOutbox: {
17
+ create: jest.fn(),
18
+ createMany: jest.fn(),
19
+ findMany: jest.fn(),
20
+ findUnique: jest.fn(),
21
+ update: jest.fn(),
22
+ updateMany: jest.fn(),
23
+ delete: jest.fn(),
24
+ deleteMany: jest.fn(),
25
+ count: jest.fn(),
26
+ groupBy: jest.fn(),
27
+ aggregate: jest.fn(),
28
+ },
29
+ };
30
+
31
+ // Mock Logger
32
+ const mockLogger = {
33
+ child: jest.fn().mockReturnThis(),
34
+ info: jest.fn(),
35
+ error: jest.fn(),
36
+ warn: jest.fn(),
37
+ debug: jest.fn(),
38
+ };
39
+
40
+ // Mock ConfigService
41
+ const mockConfigService = {
42
+ get: jest.fn(),
43
+ };
44
+
45
+ describe('WorkflowEventOutboxService', () => {
46
+ let service: WorkflowEventOutboxService;
47
+ let prisma: typeof mockPrismaService;
48
+
49
+ beforeEach(async () => {
50
+ // 每个测试前重置所有 mock
51
+ jest.clearAllMocks();
52
+
53
+ const module: TestingModule = await Test.createTestingModule({
54
+ providers: [
55
+ WorkflowEventOutboxService,
56
+ { provide: PrismaService, useValue: mockPrismaService },
57
+ { provide: ConfigService, useValue: mockConfigService },
58
+ { provide: WINSTON_MODULE_PROVIDER, useValue: mockLogger },
59
+ ],
60
+ }).compile();
61
+
62
+ service = module.get<WorkflowEventOutboxService>(
63
+ WorkflowEventOutboxService,
64
+ );
65
+ prisma = mockPrismaService;
66
+ });
67
+
68
+ it('should be defined', () => {
69
+ expect(service).toBeDefined();
70
+ });
71
+
72
+ describe('createOne', () => {
73
+ it('should create a single workflowEventOutbox record', async () => {
74
+ const createArgs = {
75
+ data: {
76
+ eventName: 'test_eventName',
77
+ payload: {},
78
+ processed: false,
79
+ processedAt: new Date(),
80
+ retryCount: 0,
81
+ },
82
+ };
83
+ const expectedResult = { id: BigInt(1), ...createArgs.data };
84
+
85
+ prisma.workflowEventOutbox.create.mockResolvedValue(expectedResult);
86
+
87
+ const result = await service.createOne(createArgs);
88
+
89
+ expect(prisma.workflowEventOutbox.create).toHaveBeenCalledWith(
90
+ createArgs,
91
+ );
92
+ expect(prisma.workflowEventOutbox.create).toHaveBeenCalledTimes(1);
93
+ expect(result).toEqual(expectedResult);
94
+ });
95
+
96
+ it('should throw error when create fails', async () => {
97
+ const createArgs = {
98
+ data: {
99
+ eventName: 'test_eventName',
100
+ payload: {},
101
+ processed: false,
102
+ processedAt: new Date(),
103
+ retryCount: 0,
104
+ },
105
+ };
106
+ const error = new Error('Database connection failed');
107
+
108
+ prisma.workflowEventOutbox.create.mockRejectedValue(error);
109
+
110
+ await expect(service.createOne(createArgs)).rejects.toThrow(
111
+ 'Database connection failed',
112
+ );
113
+ });
114
+ });
115
+
116
+ describe('createMany', () => {
117
+ it('should create multiple workflowEventOutbox records with skipDuplicates', async () => {
118
+ const data = [
119
+ {
120
+ eventName: 'test_eventName',
121
+ payload: {},
122
+ processed: false,
123
+ processedAt: new Date(),
124
+ retryCount: 0,
125
+ },
126
+ {
127
+ eventName: 'test_eventName',
128
+ payload: {},
129
+ processed: false,
130
+ processedAt: new Date(),
131
+ retryCount: 0,
132
+ },
133
+ ];
134
+ const expectedResult = { count: 2 };
135
+
136
+ prisma.workflowEventOutbox.createMany.mockResolvedValue(expectedResult);
137
+
138
+ const result = await service.createMany(data);
139
+
140
+ expect(prisma.workflowEventOutbox.createMany).toHaveBeenCalledWith({
141
+ data,
142
+ skipDuplicates: true,
143
+ });
144
+ expect(result).toEqual(expectedResult);
145
+ });
146
+ });
147
+
148
+ describe('findMany', () => {
149
+ it('should return entities with itemCount', async () => {
150
+ const findArgs = {
151
+ where: {},
152
+ take: 10,
153
+ skip: 0,
154
+ };
155
+ const mockEntities = [{ id: BigInt(1) }, { id: BigInt(1) }];
156
+
157
+ prisma.workflowEventOutbox.count.mockResolvedValue(2);
158
+ prisma.workflowEventOutbox.findMany.mockResolvedValue(mockEntities);
159
+
160
+ const result = await service.findMany(findArgs);
161
+
162
+ expect(prisma.workflowEventOutbox.count).toHaveBeenCalledWith({
163
+ where: findArgs.where,
164
+ });
165
+ expect(prisma.workflowEventOutbox.findMany).toHaveBeenCalledWith(
166
+ findArgs,
167
+ );
168
+ expect(result).toEqual({
169
+ itemCount: 2,
170
+ entities: mockEntities,
171
+ });
172
+ });
173
+
174
+ it('should return empty result when no records found', async () => {
175
+ const findArgs = { where: {} };
176
+
177
+ prisma.workflowEventOutbox.count.mockResolvedValue(0);
178
+ prisma.workflowEventOutbox.findMany.mockResolvedValue([]);
179
+
180
+ const result = await service.findMany(findArgs);
181
+
182
+ expect(result).toEqual({ itemCount: 0, entities: [] });
183
+ });
184
+ });
185
+
186
+ describe('findUnique', () => {
187
+ it('should find a single workflowEventOutbox record by id', async () => {
188
+ const id = BigInt(1);
189
+ const select = { id: true };
190
+ const expectedResult = { id: BigInt(1) };
191
+
192
+ prisma.workflowEventOutbox.findUnique.mockResolvedValue(expectedResult);
193
+
194
+ const result = await service.findUnique(id, select);
195
+
196
+ expect(prisma.workflowEventOutbox.findUnique).toHaveBeenCalledWith({
197
+ where: { id },
198
+ select,
199
+ });
200
+ expect(result).toEqual(expectedResult);
201
+ });
202
+
203
+ it('should return null when record not found', async () => {
204
+ prisma.workflowEventOutbox.findUnique.mockResolvedValue(null);
205
+
206
+ const result = await service.findUnique(BigInt(1), { id: true });
207
+
208
+ expect(result).toBeNull();
209
+ });
210
+ });
211
+
212
+ describe('updateUnique', () => {
213
+ it('should update a single workflowEventOutbox record', async () => {
214
+ const id = BigInt(1);
215
+ const data = {
216
+ eventName: 'test_eventName',
217
+ payload: {},
218
+ processed: false,
219
+ processedAt: new Date(),
220
+ retryCount: 0,
221
+ };
222
+ const expectedResult = { id: BigInt(1), ...data };
223
+
224
+ prisma.workflowEventOutbox.update.mockResolvedValue(expectedResult);
225
+
226
+ const result = await service.updateUnique(id, data);
227
+
228
+ expect(prisma.workflowEventOutbox.update).toHaveBeenCalledWith({
229
+ where: { id },
230
+ data,
231
+ });
232
+ expect(result).toEqual(expectedResult);
233
+ });
234
+ });
235
+
236
+ describe('updateMany', () => {
237
+ it('should update multiple workflowEventOutbox records', async () => {
238
+ const updateArgs = {
239
+ where: {},
240
+ data: {
241
+ eventName: 'test_eventName',
242
+ payload: {},
243
+ processed: false,
244
+ processedAt: new Date(),
245
+ retryCount: 0,
246
+ },
247
+ };
248
+ const expectedResult = { count: 5 };
249
+
250
+ prisma.workflowEventOutbox.updateMany.mockResolvedValue(expectedResult);
251
+
252
+ const result = await service.updateMany(updateArgs);
253
+
254
+ expect(prisma.workflowEventOutbox.updateMany).toHaveBeenCalledWith(
255
+ updateArgs,
256
+ );
257
+ expect(result).toEqual(expectedResult);
258
+ });
259
+ });
260
+
261
+ describe('deleteUnique', () => {
262
+ it('should delete a single workflowEventOutbox record and return count', async () => {
263
+ const id = BigInt(1);
264
+
265
+ prisma.workflowEventOutbox.delete.mockResolvedValue({ id: BigInt(1) });
266
+
267
+ const result = await service.deleteUnique(id);
268
+
269
+ expect(prisma.workflowEventOutbox.delete).toHaveBeenCalledWith({
270
+ where: { id },
271
+ });
272
+ expect(result).toEqual({ count: 1 });
273
+ });
274
+ });
275
+
276
+ describe('deleteMany', () => {
277
+ it('should delete multiple workflowEventOutbox records', async () => {
278
+ const deleteArgs = { where: {} };
279
+ const expectedResult = { count: 3 };
280
+
281
+ prisma.workflowEventOutbox.deleteMany.mockResolvedValue(expectedResult);
282
+
283
+ const result = await service.deleteMany(deleteArgs);
284
+
285
+ expect(prisma.workflowEventOutbox.deleteMany).toHaveBeenCalledWith(
286
+ deleteArgs,
287
+ );
288
+ expect(result).toEqual(expectedResult);
289
+ });
290
+ });
291
+
292
+ describe('count', () => {
293
+ it('should count workflowEventOutbox records with filter', async () => {
294
+ const countArgs = { where: {} };
295
+
296
+ prisma.workflowEventOutbox.count.mockResolvedValue(10);
297
+
298
+ const result = await service.count(countArgs);
299
+
300
+ expect(prisma.workflowEventOutbox.count).toHaveBeenCalledWith(countArgs);
301
+ expect(result).toBe(10);
302
+ });
303
+
304
+ it('should count all records when no filter provided', async () => {
305
+ prisma.workflowEventOutbox.count.mockResolvedValue(100);
306
+
307
+ const result = await service.count();
308
+
309
+ expect(prisma.workflowEventOutbox.count).toHaveBeenCalledWith(undefined);
310
+ expect(result).toBe(100);
311
+ });
312
+ });
313
+
314
+ describe('groupBy', () => {
315
+ it('should group workflowEventOutbox records by specified field', async () => {
316
+ const groupByArgs = {
317
+ by: ['id'],
318
+ _count: { id: true },
319
+ };
320
+ const expectedResult = [{ id: BigInt(1), _count: { id: 50 } }];
321
+
322
+ prisma.workflowEventOutbox.groupBy.mockResolvedValue(expectedResult);
323
+
324
+ const result = await service.groupBy(groupByArgs as any);
325
+
326
+ expect(prisma.workflowEventOutbox.groupBy).toHaveBeenCalledWith(
327
+ groupByArgs,
328
+ );
329
+ expect(result).toEqual(expectedResult);
330
+ });
331
+ });
332
+
333
+ describe('aggregate', () => {
334
+ it('should aggregate workflowEventOutbox records', async () => {
335
+ const aggregateArgs = {
336
+ _count: true,
337
+ _max: { id: true },
338
+ _min: { id: true },
339
+ } as const;
340
+ const expectedResult = {
341
+ _count: 100,
342
+ _max: { id: BigInt(1) },
343
+ _min: { id: BigInt(1) },
344
+ };
345
+
346
+ prisma.workflowEventOutbox.aggregate.mockResolvedValue(expectedResult);
347
+
348
+ const result = await service.aggregate(aggregateArgs);
349
+
350
+ expect(prisma.workflowEventOutbox.aggregate).toHaveBeenCalledWith(
351
+ aggregateArgs,
352
+ );
353
+ expect(result).toEqual(expectedResult);
354
+ });
355
+ });
356
+ });
@@ -0,0 +1,110 @@
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { Prisma, WorkflowEventOutbox } from '@prisma/client';
3
+ import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
4
+ import { PrismaService } from 'nestjs-prisma';
5
+ import { Logger } from 'winston';
6
+
7
+ import { ConfigService } from '@nestjs/config';
8
+
9
+ @Injectable()
10
+ export class WorkflowEventOutboxService {
11
+ constructor(
12
+ private prisma: PrismaService,
13
+ private readonly config: ConfigService,
14
+ @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
15
+ ) {}
16
+
17
+ async createOne(
18
+ workflowEventOutboxCreateArgs: Prisma.WorkflowEventOutboxCreateArgs,
19
+ ) {
20
+ return await this.prisma.workflowEventOutbox.create(
21
+ workflowEventOutboxCreateArgs,
22
+ );
23
+ }
24
+
25
+ async createMany(data: Prisma.WorkflowEventOutboxCreateManyArgs['data']) {
26
+ return await this.prisma.workflowEventOutbox.createMany({
27
+ data,
28
+ skipDuplicates: true,
29
+ });
30
+ }
31
+
32
+ async findMany(
33
+ workflowEventOutboxFindManyArgs: Prisma.WorkflowEventOutboxFindManyArgs,
34
+ ): Promise<{ itemCount: number; entities: WorkflowEventOutbox[] }> {
35
+ const itemCount = await this.prisma.workflowEventOutbox.count({
36
+ where: workflowEventOutboxFindManyArgs.where,
37
+ });
38
+ const entities = await this.prisma.workflowEventOutbox.findMany(
39
+ workflowEventOutboxFindManyArgs,
40
+ );
41
+ return { itemCount, entities };
42
+ }
43
+
44
+ async findUnique(
45
+ id: number,
46
+ select: Prisma.WorkflowEventOutboxFindUniqueArgs['select'],
47
+ ) {
48
+ return await this.prisma.workflowEventOutbox.findUnique({
49
+ where: { id: id },
50
+ select,
51
+ });
52
+ }
53
+
54
+ async updateMany(
55
+ workflowEventOutboxUpdateManyArgs: Prisma.WorkflowEventOutboxUpdateManyArgs,
56
+ ) {
57
+ return await this.prisma.workflowEventOutbox.updateMany(
58
+ workflowEventOutboxUpdateManyArgs,
59
+ );
60
+ }
61
+
62
+ async updateUnique(
63
+ id: number,
64
+ data: Prisma.WorkflowEventOutboxUpdateManyArgs['data'],
65
+ ) {
66
+ return await this.prisma.workflowEventOutbox.update({
67
+ where: { id: id },
68
+ data,
69
+ });
70
+ }
71
+
72
+ async deleteMany(
73
+ workflowEventOutboxDeleteManyArgs: Prisma.WorkflowEventOutboxDeleteManyArgs,
74
+ ) {
75
+ return await this.prisma.workflowEventOutbox.deleteMany(
76
+ workflowEventOutboxDeleteManyArgs,
77
+ );
78
+ }
79
+
80
+ async deleteUnique(id: number) {
81
+ await this.prisma.workflowEventOutbox.delete({
82
+ where: { id: id },
83
+ });
84
+ return { count: 1 };
85
+ }
86
+
87
+ async count(
88
+ workflowEventOutboxCountArgs?: Prisma.WorkflowEventOutboxCountArgs,
89
+ ) {
90
+ return await this.prisma.workflowEventOutbox.count(
91
+ workflowEventOutboxCountArgs,
92
+ );
93
+ }
94
+
95
+ async groupBy(
96
+ workflowEventOutboxGroupByArgs: Prisma.WorkflowEventOutboxGroupByArgs,
97
+ ) {
98
+ return await this.prisma.workflowEventOutbox.groupBy(
99
+ workflowEventOutboxGroupByArgs as any,
100
+ );
101
+ }
102
+
103
+ async aggregate(
104
+ workflowEventOutboxAggregateArgs: Prisma.WorkflowEventOutboxAggregateArgs,
105
+ ) {
106
+ return await this.prisma.workflowEventOutbox.aggregate(
107
+ workflowEventOutboxAggregateArgs,
108
+ );
109
+ }
110
+ }
@@ -0,0 +1,22 @@
1
+ import { Test, TestingModule } from '@nestjs/testing';
2
+ import { WorkflowNodeInstanceController } from './workflowNodeInstance.controller';
3
+ import { WorkflowNodeInstanceService } from './workflowNodeInstance.service';
4
+
5
+ describe('WorkflowNodeInstanceController', () => {
6
+ let controller: WorkflowNodeInstanceController;
7
+
8
+ beforeEach(async () => {
9
+ const module: TestingModule = await Test.createTestingModule({
10
+ controllers: [WorkflowNodeInstanceController],
11
+ providers: [WorkflowNodeInstanceService],
12
+ }).compile();
13
+
14
+ controller = module.get<WorkflowNodeInstanceController>(
15
+ WorkflowNodeInstanceController,
16
+ );
17
+ });
18
+
19
+ it('should be defined', () => {
20
+ expect(controller).toBeDefined();
21
+ });
22
+ });
@@ -0,0 +1,216 @@
1
+ import {
2
+ ACAttrFilter,
3
+ ACGuard,
4
+ ApiPaginatedResponse,
5
+ diskStorage,
6
+ PageDto,
7
+ PageMetaDto,
8
+ PageOptionsDto,
9
+ pick,
10
+ UserType,
11
+ } from '@gadmin2n/nest-common';
12
+ import {
13
+ Body,
14
+ Controller,
15
+ Delete,
16
+ Inject,
17
+ NotFoundException,
18
+ Param,
19
+ ParseIntPipe,
20
+ Patch,
21
+ Post,
22
+ Req,
23
+ UploadedFile,
24
+ UseGuards,
25
+ UseInterceptors,
26
+ } from '@nestjs/common';
27
+ import {
28
+ ApiCreatedResponse,
29
+ ApiNotFoundResponse,
30
+ ApiOkResponse,
31
+ ApiTags,
32
+ } from '@nestjs/swagger';
33
+ import { Prisma } from '@prisma/client';
34
+ import { UseRoles } from 'nest-access-control';
35
+ import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
36
+ import { Logger } from 'winston';
37
+ import { CreateWorkflowNodeInstanceDto } from '../../generated/workflowNodeInstance/dto/create-workflowNodeInstance.dto';
38
+ import { UpdateWorkflowNodeInstanceDto } from '../../generated/workflowNodeInstance/dto/update-workflowNodeInstance.dto';
39
+ import {
40
+ EffectedCount,
41
+ UploudResponse,
42
+ WorkflowNodeInstanceFindManyArgs,
43
+ WorkflowNodeInstanceWhereSelect,
44
+ } from '../../generated/workflowNodeInstance/dto/workflowNodeInstance-types.dto';
45
+ import { WorkflowNodeInstanceEntity } from '../../generated/workflowNodeInstance/entities/workflowNodeInstance.entity';
46
+ import { WorkflowNodeInstanceService } from './workflowNodeInstance.service';
47
+
48
+ import { ConfigService } from '@nestjs/config';
49
+ import { FileInterceptor } from '@nestjs/platform-express';
50
+
51
+ @UseGuards(ACGuard)
52
+ @Controller('workflowNodeInstance')
53
+ @ApiTags('workflowNodeInstance')
54
+ export class WorkflowNodeInstanceController {
55
+ constructor(
56
+ private readonly workflowNodeInstanceService: WorkflowNodeInstanceService,
57
+ private readonly config: ConfigService,
58
+ @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
59
+ ) {}
60
+
61
+ @Post('createOne')
62
+ @UseRoles({
63
+ resource: 'workflowNodeInstance',
64
+ action: 'create',
65
+ possession: 'any',
66
+ })
67
+ @ApiCreatedResponse({ type: WorkflowNodeInstanceEntity })
68
+ async createOne(
69
+ @Body() body: CreateWorkflowNodeInstanceDto,
70
+ @ACAttrFilter() acAttrFilter,
71
+ @Req() request: Request & { user: UserType },
72
+ ) {
73
+ body.creator = request.user.username;
74
+ return new WorkflowNodeInstanceEntity(
75
+ await this.workflowNodeInstanceService.createOne({
76
+ data: acAttrFilter(body),
77
+ }),
78
+ );
79
+ }
80
+
81
+ @Post('findMany')
82
+ @UseRoles({
83
+ resource: 'workflowNodeInstance',
84
+ action: 'read',
85
+ possession: 'any',
86
+ })
87
+ @ApiPaginatedResponse(WorkflowNodeInstanceEntity)
88
+ async findMany(
89
+ @Body() body: WorkflowNodeInstanceFindManyArgs,
90
+ @ACAttrFilter() acAttrFilter,
91
+ ): Promise<PageDto<WorkflowNodeInstanceEntity>> {
92
+ const { itemCount, entities } =
93
+ await this.workflowNodeInstanceService.findMany(
94
+ body as Prisma.WorkflowNodeInstanceFindManyArgs,
95
+ );
96
+ const { skip = 0, take = 10 } =
97
+ body as Prisma.WorkflowNodeInstanceFindManyArgs;
98
+ const pageOptionsDto: PageOptionsDto = { skip, take };
99
+ const pageMetaDto = new PageMetaDto({ itemCount, pageOptionsDto });
100
+
101
+ return new PageDto(
102
+ entities.map(
103
+ (item) => new WorkflowNodeInstanceEntity(acAttrFilter(item)),
104
+ ),
105
+ pageMetaDto,
106
+ );
107
+ }
108
+
109
+ @Post('/findUnique/:id')
110
+ @UseRoles({
111
+ resource: 'workflowNodeInstance',
112
+ action: 'read',
113
+ possession: 'any',
114
+ })
115
+ @ApiOkResponse({ type: WorkflowNodeInstanceEntity })
116
+ @ApiNotFoundResponse({ description: 'Cannot found this record.' })
117
+ async findUnique(
118
+ @Param('id', ParseIntPipe) id: number,
119
+ @Body() body: WorkflowNodeInstanceWhereSelect,
120
+ @ACAttrFilter() acAttrFilter,
121
+ ) {
122
+ const item = await this.workflowNodeInstanceService.findUnique(id, body);
123
+ if (!item) {
124
+ throw new NotFoundException();
125
+ }
126
+ return new WorkflowNodeInstanceEntity(acAttrFilter(item));
127
+ }
128
+
129
+ @Patch('updateUnique/:id')
130
+ @UseRoles({
131
+ resource: 'workflowNodeInstance',
132
+ action: 'update',
133
+ possession: 'any',
134
+ })
135
+ @ApiOkResponse({ type: WorkflowNodeInstanceEntity })
136
+ @ApiNotFoundResponse({ description: 'Cannot found this record.' })
137
+ async updateUnique(
138
+ @Param('id', ParseIntPipe) id: number,
139
+ @Body() body: UpdateWorkflowNodeInstanceDto,
140
+ @ACAttrFilter() acAttrFilter,
141
+ ) {
142
+ /*
143
+ const origin = (await this.workflowNodeInstanceService.findUnique(id, {
144
+ id: true,
145
+ // 这里需要根据实际情况填写
146
+ })) as WorkflowNodeInstanceEntity | null;
147
+ if (!origin) {
148
+ throw new NotFoundException();
149
+ }
150
+ // 需要兼容从列表页change_value入口进来的情况,这里进来的是只有少量字段的数据
151
+ const newBody = {
152
+ ...origin,
153
+ ...body,
154
+ };
155
+
156
+ // 其他个性化逻辑
157
+ */
158
+
159
+ const item = await this.workflowNodeInstanceService.updateUnique(
160
+ id,
161
+ acAttrFilter(body),
162
+ );
163
+ return new WorkflowNodeInstanceEntity(acAttrFilter(item));
164
+ }
165
+
166
+ @Delete('deleteUnique/:id')
167
+ @UseRoles({
168
+ resource: 'workflowNodeInstance',
169
+ action: 'delete',
170
+ possession: 'any',
171
+ })
172
+ @ApiOkResponse({ type: EffectedCount })
173
+ @ApiNotFoundResponse({ description: 'Cannot found this record.' })
174
+ async deleteUnique(@Param('id', ParseIntPipe) id: number) {
175
+ const res = await this.workflowNodeInstanceService.deleteUnique(id);
176
+ if (!res.count) {
177
+ throw new NotFoundException();
178
+ }
179
+ return res;
180
+ }
181
+
182
+ @Post(':id/references')
183
+ @UseRoles({
184
+ resource: 'workflowNodeInstance',
185
+ action: 'read',
186
+ possession: 'any',
187
+ })
188
+ @ApiOkResponse({ description: 'List of workflows referencing this instance' })
189
+ async findReferences(@Param('id', ParseIntPipe) id: number) {
190
+ return this.workflowNodeInstanceService.findReferences(id);
191
+ }
192
+
193
+ @Post('upload')
194
+ @UseRoles({
195
+ resource: 'workflowNodeInstance',
196
+ action: 'create',
197
+ possession: 'any',
198
+ })
199
+ @ApiCreatedResponse({ type: UploudResponse })
200
+ @UseInterceptors(FileInterceptor('file'))
201
+ async uploadFile(@UploadedFile() file: Express.Multer.File) {
202
+ const fileName = await diskStorage(
203
+ file,
204
+ this.config.get('media')['rootDir'] + '/workflowNodeInstance/',
205
+ );
206
+
207
+ return {
208
+ ...pick(file, ['mimetype', 'originalname', 'size']),
209
+ url:
210
+ this.config.get('media')['address'] +
211
+ '/workflowNodeInstance/' +
212
+ fileName,
213
+ name: fileName,
214
+ };
215
+ }
216
+ }
@@ -0,0 +1,10 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { WorkflowNodeInstanceController } from './workflowNodeInstance.controller';
3
+ import { WorkflowNodeInstanceService } from './workflowNodeInstance.service';
4
+
5
+ @Module({
6
+ controllers: [WorkflowNodeInstanceController],
7
+ providers: [WorkflowNodeInstanceService],
8
+ exports: [WorkflowNodeInstanceService],
9
+ })
10
+ export class WorkflowNodeInstanceModule {}