@gadmin2n/schematics 0.0.72 → 0.0.74

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,83 @@
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { AgendaJob, Prisma } 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 AgendaJobService {
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(agendaJobCreateArgs: Prisma.AgendaJobCreateArgs) {
18
+ return await this.prisma.agendaJob.create(agendaJobCreateArgs);
19
+ }
20
+
21
+ async createMany(data: Prisma.AgendaJobCreateManyArgs['data']) {
22
+ return await this.prisma.agendaJob.createMany({
23
+ data,
24
+ skipDuplicates: true,
25
+ });
26
+ }
27
+
28
+ async findMany(
29
+ agendaJobFindManyArgs: Prisma.AgendaJobFindManyArgs,
30
+ ): Promise<{ itemCount: number; entities: AgendaJob[] }> {
31
+ const itemCount = await this.prisma.agendaJob.count({
32
+ where: agendaJobFindManyArgs.where,
33
+ });
34
+ const entities = await this.prisma.agendaJob.findMany(
35
+ agendaJobFindManyArgs,
36
+ );
37
+ return { itemCount, entities };
38
+ }
39
+
40
+ async findUnique(
41
+ id: string,
42
+ select: Prisma.AgendaJobFindUniqueArgs['select'],
43
+ ) {
44
+ return await this.prisma.agendaJob.findUnique({
45
+ where: { id: id },
46
+ select,
47
+ });
48
+ }
49
+
50
+ async updateMany(agendaJobUpdateManyArgs: Prisma.AgendaJobUpdateManyArgs) {
51
+ return await this.prisma.agendaJob.updateMany(agendaJobUpdateManyArgs);
52
+ }
53
+
54
+ async updateUnique(id: string, data: Prisma.AgendaJobUpdateManyArgs['data']) {
55
+ return await this.prisma.agendaJob.update({
56
+ where: { id: id },
57
+ data,
58
+ });
59
+ }
60
+
61
+ async deleteMany(agendaJobDeleteManyArgs: Prisma.AgendaJobDeleteManyArgs) {
62
+ return await this.prisma.agendaJob.deleteMany(agendaJobDeleteManyArgs);
63
+ }
64
+
65
+ async deleteUnique(id: string) {
66
+ await this.prisma.agendaJob.delete({
67
+ where: { id: id },
68
+ });
69
+ return { count: 1 };
70
+ }
71
+
72
+ async count(agendaJobCountArgs?: Prisma.AgendaJobCountArgs) {
73
+ return await this.prisma.agendaJob.count(agendaJobCountArgs);
74
+ }
75
+
76
+ async groupBy(agendaJobGroupByArgs: Prisma.AgendaJobGroupByArgs) {
77
+ return await this.prisma.agendaJob.groupBy(agendaJobGroupByArgs as any);
78
+ }
79
+
80
+ async aggregate(agendaJobAggregateArgs: Prisma.AgendaJobAggregateArgs) {
81
+ return await this.prisma.agendaJob.aggregate(agendaJobAggregateArgs);
82
+ }
83
+ }
@@ -1,4 +1,5 @@
1
1
  import generatedModules from '../generated/modules.index';
2
2
  import { CanvasModule } from './canvas/canvas.module';
3
+ import { WorkflowModule } from './workflow/workflow.module';
3
4
 
4
- export default [...generatedModules, CanvasModule];
5
+ export default [...generatedModules, CanvasModule, WorkflowModule];
@@ -0,0 +1,9 @@
1
+ import { Global, Module } from '@nestjs/common';
2
+ import { TemporalService } from './temporal.service';
3
+
4
+ @Global()
5
+ @Module({
6
+ providers: [TemporalService],
7
+ exports: [TemporalService],
8
+ })
9
+ export class TemporalModule {}
@@ -0,0 +1,100 @@
1
+ import {
2
+ Injectable,
3
+ Logger,
4
+ OnModuleDestroy,
5
+ OnModuleInit,
6
+ } from '@nestjs/common';
7
+ import { Client, Connection } from '@temporalio/client';
8
+
9
+ const TEMPORAL_ADDRESS = process.env.TEMPORAL_ADDRESS || 'localhost:7233';
10
+ const TEMPORAL_NAMESPACE = process.env.TEMPORAL_NAMESPACE || 'default';
11
+ const TASK_QUEUE = process.env.TEMPORAL_TASK_QUEUE || 'workflow-execution';
12
+
13
+ @Injectable()
14
+ export class TemporalService implements OnModuleInit, OnModuleDestroy {
15
+ private connection: Connection;
16
+ private client: Client;
17
+ private readonly logger = new Logger(TemporalService.name);
18
+
19
+ async onModuleInit() {
20
+ try {
21
+ this.connection = await Connection.connect({ address: TEMPORAL_ADDRESS });
22
+ this.client = new Client({
23
+ connection: this.connection,
24
+ namespace: TEMPORAL_NAMESPACE,
25
+ });
26
+ this.logger.log(`Connected to Temporal at ${TEMPORAL_ADDRESS}`);
27
+ } catch (err) {
28
+ this.logger.warn(
29
+ `Failed to connect to Temporal at ${TEMPORAL_ADDRESS}: ${err.message}. Workflow execution will be unavailable.`,
30
+ );
31
+ }
32
+ }
33
+
34
+ async onModuleDestroy() {
35
+ await this.connection?.close();
36
+ }
37
+
38
+ /**
39
+ * Start a workflow execution via Temporal.
40
+ */
41
+ async startWorkflow(params: {
42
+ instanceId: number;
43
+ workflowId: number;
44
+ versionId: number;
45
+ dsl: any;
46
+ context: Record<string, any>;
47
+ }): Promise<{ temporalRunId: string }> {
48
+ if (!this.client) {
49
+ throw new Error('Temporal client not connected');
50
+ }
51
+
52
+ const workflowId = `wf-${params.workflowId}-${params.instanceId}`;
53
+
54
+ const handle = await this.client.workflow.start('dslWorkflow', {
55
+ taskQueue: TASK_QUEUE,
56
+ workflowId,
57
+ args: [params],
58
+ });
59
+
60
+ return { temporalRunId: handle.workflowId };
61
+ }
62
+
63
+ /**
64
+ * Cancel a running workflow.
65
+ */
66
+ async cancelWorkflow(temporalRunId: string): Promise<void> {
67
+ if (!this.client) throw new Error('Temporal client not connected');
68
+ const handle = this.client.workflow.getHandle(temporalRunId);
69
+ await handle.cancel();
70
+ }
71
+
72
+ /**
73
+ * Send a signal to a running workflow (e.g., approval).
74
+ */
75
+ async signalWorkflow(
76
+ temporalRunId: string,
77
+ signalName: string,
78
+ payload: any,
79
+ ): Promise<void> {
80
+ if (!this.client) throw new Error('Temporal client not connected');
81
+ const handle = this.client.workflow.getHandle(temporalRunId);
82
+ await handle.signal(signalName, payload);
83
+ }
84
+
85
+ /**
86
+ * Query a workflow for its current progress.
87
+ */
88
+ async queryWorkflow(temporalRunId: string, queryName: string): Promise<any> {
89
+ if (!this.client) throw new Error('Temporal client not connected');
90
+ const handle = this.client.workflow.getHandle(temporalRunId);
91
+ return await handle.query(queryName);
92
+ }
93
+
94
+ /**
95
+ * Check if Temporal client is available.
96
+ */
97
+ isAvailable(): boolean {
98
+ return !!this.client;
99
+ }
100
+ }
@@ -0,0 +1,19 @@
1
+ import { IsInt, IsObject, IsOptional, IsString } from 'class-validator';
2
+
3
+ export class ExecuteWorkflowDto {
4
+ @IsOptional()
5
+ @IsObject()
6
+ context?: Record<string, any>;
7
+
8
+ @IsOptional()
9
+ @IsInt()
10
+ versionId?: number;
11
+ }
12
+
13
+ export class SignalWorkflowDto {
14
+ @IsString()
15
+ signalName: string;
16
+
17
+ @IsObject()
18
+ payload: Record<string, any>;
19
+ }
@@ -0,0 +1,43 @@
1
+ import { IsObject } from 'class-validator';
2
+
3
+ export class ImportPayloadDto {
4
+ @IsObject()
5
+ payload: ExportPayload;
6
+ }
7
+
8
+ export interface ExportPayload {
9
+ version: number;
10
+ exportedAt: string;
11
+ workflow: {
12
+ code: string;
13
+ name: string;
14
+ description: string | null;
15
+ status: string;
16
+ dsl: any;
17
+ };
18
+ nodeInstances: Array<{
19
+ sourceId: string;
20
+ code: string;
21
+ name: string;
22
+ description: string | null;
23
+ nodeTypeKey: string;
24
+ config: any;
25
+ isEnabled: boolean;
26
+ }>;
27
+ nodeTypes: Array<{
28
+ type: string;
29
+ category: string;
30
+ label: string;
31
+ icon: string;
32
+ description: string | null;
33
+ configSchema: any;
34
+ inputSchema: any;
35
+ outputSchema: any;
36
+ isBuiltin: boolean;
37
+ }>;
38
+ }
39
+
40
+ export interface ImportPreviewResponse {
41
+ current: Partial<ExportPayload> | null;
42
+ incoming: ExportPayload;
43
+ }
@@ -0,0 +1,317 @@
1
+ import {
2
+ BadRequestException,
3
+ Injectable,
4
+ NotFoundException,
5
+ UnauthorizedException,
6
+ } from '@nestjs/common';
7
+ import * as jwt from 'jsonwebtoken';
8
+ import { PrismaService } from 'nestjs-prisma';
9
+ import { ExportPayload, ImportPreviewResponse } from './workflow-export.dto';
10
+
11
+ const EXPORT_TOKEN_SECRET =
12
+ process.env.TAIHU_ODC_APP_TOKEN || 'gadmin-default-secret';
13
+ const EXPORT_TOKEN_EXPIRY = 30 * 60; // 30 minutes in seconds
14
+
15
+ interface ExportTokenPayload {
16
+ workflowCode: string;
17
+ }
18
+
19
+ @Injectable()
20
+ export class WorkflowExportService {
21
+ constructor(private prisma: PrismaService) {}
22
+
23
+ /** Generate a JWT export token for a workflow */
24
+ async generateExportToken(
25
+ workflowId: bigint,
26
+ baseUrl: string,
27
+ ): Promise<{ url: string }> {
28
+ const workflow = await this.prisma.workflow.findUnique({
29
+ where: { id: workflowId },
30
+ select: { code: true },
31
+ });
32
+ if (!workflow) throw new NotFoundException('Workflow not found');
33
+
34
+ const token = jwt.sign(
35
+ { workflowCode: workflow.code } as ExportTokenPayload,
36
+ EXPORT_TOKEN_SECRET,
37
+ { expiresIn: EXPORT_TOKEN_EXPIRY },
38
+ );
39
+
40
+ const url = `${baseUrl}/workflow/export/${workflow.code}?token=${token}`;
41
+ return { url };
42
+ }
43
+
44
+ /** Verify export token and return the full export payload */
45
+ async getExportPayload(code: string, token: string): Promise<ExportPayload> {
46
+ let decoded: ExportTokenPayload;
47
+ try {
48
+ decoded = jwt.verify(token, EXPORT_TOKEN_SECRET) as ExportTokenPayload;
49
+ } catch {
50
+ throw new UnauthorizedException('Export token is invalid or expired');
51
+ }
52
+
53
+ if (decoded.workflowCode !== code) {
54
+ throw new UnauthorizedException('Token does not match this workflow');
55
+ }
56
+
57
+ const workflow = await this.prisma.workflow.findUnique({
58
+ where: { code },
59
+ include: { versions: { orderBy: { version: 'desc' }, take: 1 } },
60
+ });
61
+ if (!workflow) throw new NotFoundException('Workflow not found');
62
+
63
+ // Use latest published version DSL, fallback to draft DSL
64
+ const dsl = (workflow.versions[0]?.dsl ?? workflow.dsl) as any;
65
+
66
+ // Collect referenced NodeInstance IDs from DSL
67
+ const instanceIds = new Set<bigint>();
68
+ if (dsl?.nodes) {
69
+ for (const node of dsl.nodes) {
70
+ if (node.instanceRef?.instanceId) {
71
+ instanceIds.add(BigInt(node.instanceRef.instanceId));
72
+ }
73
+ }
74
+ }
75
+
76
+ // Fetch referenced NodeInstances
77
+ const nodeInstances =
78
+ instanceIds.size > 0
79
+ ? await this.prisma.workflowNodeInstance.findMany({
80
+ where: { id: { in: Array.from(instanceIds) } },
81
+ include: { nodeType: true },
82
+ })
83
+ : [];
84
+
85
+ // Collect NodeType keys from instances + DSL nodes
86
+ const nodeTypeKeys = new Set<string>();
87
+ for (const ni of nodeInstances) {
88
+ nodeTypeKeys.add(ni.nodeType.type);
89
+ }
90
+ if (dsl?.nodes) {
91
+ for (const node of dsl.nodes) {
92
+ if (node.type) nodeTypeKeys.add(node.type);
93
+ }
94
+ }
95
+
96
+ // Fetch NodeTypes
97
+ const nodeTypes =
98
+ nodeTypeKeys.size > 0
99
+ ? await this.prisma.workflowNodeType.findMany({
100
+ where: { type: { in: Array.from(nodeTypeKeys) } },
101
+ })
102
+ : [];
103
+
104
+ return {
105
+ version: 1,
106
+ exportedAt: new Date().toISOString(),
107
+ workflow: {
108
+ code: workflow.code,
109
+ name: workflow.name,
110
+ description: workflow.description,
111
+ status: workflow.status,
112
+ dsl,
113
+ },
114
+ nodeInstances: nodeInstances.map((ni) => ({
115
+ sourceId: String(ni.id),
116
+ code: ni.code,
117
+ name: ni.name,
118
+ description: ni.description,
119
+ nodeTypeKey: ni.nodeType.type,
120
+ config: ni.config,
121
+ isEnabled: ni.isEnabled,
122
+ })),
123
+ nodeTypes: nodeTypes.map((nt) => ({
124
+ type: nt.type,
125
+ category: nt.category,
126
+ label: nt.label,
127
+ icon: nt.icon,
128
+ description: nt.description,
129
+ configSchema: nt.configSchema as any,
130
+ inputSchema: nt.inputSchema as any,
131
+ outputSchema: nt.outputSchema as any,
132
+ isBuiltin: nt.isBuiltin,
133
+ })),
134
+ };
135
+ }
136
+
137
+ /** Preview import — return current state vs incoming for diff */
138
+ async importPreview(payload: ExportPayload): Promise<ImportPreviewResponse> {
139
+ if (!payload?.workflow?.code) {
140
+ throw new BadRequestException('Invalid payload: missing workflow code');
141
+ }
142
+
143
+ // Look up current state by code
144
+ const existingWorkflow = await this.prisma.workflow.findUnique({
145
+ where: { code: payload.workflow.code },
146
+ include: { versions: { orderBy: { version: 'desc' }, take: 1 } },
147
+ });
148
+
149
+ // Look up existing node instances by code
150
+ const incomingCodes = payload.nodeInstances.map((ni) => ni.code);
151
+ const existingInstances =
152
+ incomingCodes.length > 0
153
+ ? await this.prisma.workflowNodeInstance.findMany({
154
+ where: { code: { in: incomingCodes } },
155
+ include: { nodeType: true },
156
+ })
157
+ : [];
158
+
159
+ // Look up existing node types by type key
160
+ const incomingTypes = payload.nodeTypes.map((nt) => nt.type);
161
+ const existingTypes =
162
+ incomingTypes.length > 0
163
+ ? await this.prisma.workflowNodeType.findMany({
164
+ where: { type: { in: incomingTypes } },
165
+ })
166
+ : [];
167
+
168
+ const current: Partial<ExportPayload> | null = existingWorkflow
169
+ ? {
170
+ workflow: {
171
+ code: existingWorkflow.code,
172
+ name: existingWorkflow.name,
173
+ description: existingWorkflow.description,
174
+ status: existingWorkflow.status,
175
+ dsl: (existingWorkflow.versions[0]?.dsl ??
176
+ existingWorkflow.dsl) as any,
177
+ },
178
+ nodeInstances: existingInstances.map((ni) => ({
179
+ sourceId: String(ni.id),
180
+ code: ni.code,
181
+ name: ni.name,
182
+ description: ni.description,
183
+ nodeTypeKey: ni.nodeType.type,
184
+ config: ni.config as any,
185
+ isEnabled: ni.isEnabled,
186
+ })),
187
+ nodeTypes: existingTypes.map((nt) => ({
188
+ type: nt.type,
189
+ category: nt.category,
190
+ label: nt.label,
191
+ icon: nt.icon,
192
+ description: nt.description,
193
+ configSchema: nt.configSchema as any,
194
+ inputSchema: nt.inputSchema as any,
195
+ outputSchema: nt.outputSchema as any,
196
+ isBuiltin: nt.isBuiltin,
197
+ })),
198
+ }
199
+ : null;
200
+
201
+ return { current, incoming: payload };
202
+ }
203
+
204
+ /** Confirm import — execute upsert with DSL remapping in a transaction */
205
+ async importConfirm(
206
+ payload: ExportPayload,
207
+ creator: string,
208
+ ): Promise<{ success: boolean; workflowId: string; workflowName: string }> {
209
+ if (!payload?.workflow?.code) {
210
+ throw new BadRequestException('Invalid payload: missing workflow code');
211
+ }
212
+
213
+ return this.prisma.$transaction(async (tx) => {
214
+ // 1. Upsert NodeTypes by `type`
215
+ for (const nt of payload.nodeTypes) {
216
+ await tx.workflowNodeType.upsert({
217
+ where: { type: nt.type },
218
+ create: {
219
+ type: nt.type,
220
+ category: nt.category as any,
221
+ label: nt.label,
222
+ icon: nt.icon,
223
+ description: nt.description,
224
+ configSchema: nt.configSchema,
225
+ inputSchema: nt.inputSchema,
226
+ outputSchema: nt.outputSchema,
227
+ isBuiltin: nt.isBuiltin,
228
+ creator,
229
+ },
230
+ update: {
231
+ category: nt.category as any,
232
+ label: nt.label,
233
+ icon: nt.icon,
234
+ description: nt.description,
235
+ configSchema: nt.configSchema,
236
+ inputSchema: nt.inputSchema,
237
+ outputSchema: nt.outputSchema,
238
+ },
239
+ });
240
+ }
241
+
242
+ // 2. Upsert NodeInstances by `code`, build sourceId → newId map
243
+ const idMap = new Map<string, string>();
244
+
245
+ for (const ni of payload.nodeInstances) {
246
+ const nodeType = await tx.workflowNodeType.findUnique({
247
+ where: { type: ni.nodeTypeKey },
248
+ });
249
+ if (!nodeType) {
250
+ throw new BadRequestException(
251
+ `NodeType "${ni.nodeTypeKey}" not found after upsert`,
252
+ );
253
+ }
254
+
255
+ const record = await tx.workflowNodeInstance.upsert({
256
+ where: { code: ni.code },
257
+ create: {
258
+ code: ni.code,
259
+ nodeTypeId: nodeType.id,
260
+ name: ni.name,
261
+ description: ni.description,
262
+ config: ni.config,
263
+ isEnabled: ni.isEnabled,
264
+ creator,
265
+ },
266
+ update: {
267
+ nodeTypeId: nodeType.id,
268
+ name: ni.name,
269
+ description: ni.description,
270
+ config: ni.config,
271
+ isEnabled: ni.isEnabled,
272
+ },
273
+ });
274
+
275
+ idMap.set(ni.sourceId, String(record.id));
276
+ }
277
+
278
+ // 3. Remap DSL instanceRef.instanceId
279
+ const dsl = JSON.parse(JSON.stringify(payload.workflow.dsl));
280
+ if (dsl?.nodes) {
281
+ for (const node of dsl.nodes) {
282
+ if (node.instanceRef?.instanceId) {
283
+ const newId = idMap.get(node.instanceRef.instanceId);
284
+ if (newId) {
285
+ node.instanceRef.instanceId = newId;
286
+ }
287
+ }
288
+ }
289
+ }
290
+
291
+ // 4. Upsert Workflow by `code`, always set to DRAFT
292
+ const workflow = await tx.workflow.upsert({
293
+ where: { code: payload.workflow.code },
294
+ create: {
295
+ code: payload.workflow.code,
296
+ name: payload.workflow.name,
297
+ description: payload.workflow.description,
298
+ status: 'DRAFT',
299
+ dsl,
300
+ creator,
301
+ },
302
+ update: {
303
+ name: payload.workflow.name,
304
+ description: payload.workflow.description,
305
+ status: 'DRAFT',
306
+ dsl,
307
+ },
308
+ });
309
+
310
+ return {
311
+ success: true,
312
+ workflowId: String(workflow.id),
313
+ workflowName: workflow.name,
314
+ };
315
+ });
316
+ }
317
+ }
@@ -0,0 +1,16 @@
1
+ import { Controller, Get, UseGuards } from '@nestjs/common';
2
+ import { ApiTags } from '@nestjs/swagger';
3
+ import AuthGuard from '../../lib/auth.guard';
4
+ import { WorkflowNodeTypeService } from './workflow-node-type.service';
5
+
6
+ @ApiTags('workflow-node-types')
7
+ @UseGuards(AuthGuard)
8
+ @Controller('workflow-node-types')
9
+ export class WorkflowNodeTypeController {
10
+ constructor(private readonly service: WorkflowNodeTypeService) {}
11
+
12
+ @Get()
13
+ findAll() {
14
+ return this.service.findAll();
15
+ }
16
+ }
@@ -0,0 +1,13 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { PrismaService } from 'nestjs-prisma';
3
+
4
+ @Injectable()
5
+ export class WorkflowNodeTypeService {
6
+ constructor(private prisma: PrismaService) {}
7
+
8
+ findAll() {
9
+ return this.prisma.workflowNodeType.findMany({
10
+ orderBy: [{ category: 'asc' }, { type: 'asc' }],
11
+ });
12
+ }
13
+ }