@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.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/job.prisma +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/system.prisma +0 -21
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +171 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/AgendaJob.ts +60 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Event.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowEventOutbox.ts +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeInstance.ts +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeType.ts +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/.env +5 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +5 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma.config.ts +14 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +4 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permissions.ts +49 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +746 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +786 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.controller.ts +6 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.service.ts +79 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.spec.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.ts +145 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/{canvas/canvas.service.spec.ts → agendaJob/agendaJob.service.spec.ts} +71 -65
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.service.ts +83 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/index.ts +2 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.module.ts +9 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +100 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +19 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.dto.ts +43 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.service.ts +317 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-node-type.controller.ts +16 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-node-type.service.ts +13 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +220 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +82 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.module.ts +16 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +505 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.spec.ts +22 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.ts +147 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.spec.ts +356 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.ts +110 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.spec.ts +22 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.ts +216 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.spec.ts +356 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.ts +168 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.spec.ts +22 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.ts +199 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.spec.ts +348 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.ts +106 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/yarn.lock +579 -1082
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +278 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/config/development-sql.yaml +5 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/docker-compose.yml +25 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/package.json +13 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/sql/create-event-trigger.sql +87 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/.env +7 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/SANDBOX.md +122 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package-lock.json +4285 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package.json +28 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/activities/code-execute.test.ts +44 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/activities/http-request.test.ts +87 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/helpers.test.ts +225 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/node-type-consistency.test.ts +101 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/code-execute.ts +51 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-execute.ts +85 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-query.ts +35 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/http-request.ts +54 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/index.ts +6 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/reporting.ts +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/send-notification.ts +47 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/config.ts +13 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/condition.ts +101 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/context.ts +58 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/graph.ts +184 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/helpers.ts +133 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/node-types.ts +57 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/types.ts +77 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/index.ts +36 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/outbox-poller.ts +226 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/workflows/dsl-workflow.ts +411 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/tsconfig.json +19 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/vitest.config.ts +8 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/yarn.lock +1905 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/package-lock.json +17555 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +5 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/App.tsx +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/sider.tsx +5 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/title.tsx +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +63 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DevShell.tsx +91 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/list.tsx +48 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/show.tsx +43 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +14 -9
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +14 -9
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +309 -56
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/show.tsx +1 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/create.tsx +108 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/edit.tsx +124 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/index.tsx +4 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/list.tsx +245 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/show.tsx +70 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +0 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx +160 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx +120 -148
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CodeFloatWindow.tsx +74 -181
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/LivePreview.tsx +15 -13
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasConfigRegistry.tsx +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasContextMenuRegistry.tsx +338 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasDefaults.ts +18 -17
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/BarChartDataSourceModal.tsx +10 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/LineChartDataSourceModal.tsx +10 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/{ChartViewerConfigModal.tsx → MultiChartConfigModal.tsx} +30 -18
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/MultiChartDataSourceModal.tsx +427 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/NumCardDataSourceModal.tsx +10 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/PromptModal.tsx +6 -14
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/RadarChartDataSourceModal.tsx +10 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/TableDataSourceModal.tsx +10 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/canvasModalProps.ts +24 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/demos.ts +45 -63
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.tsx +99 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExportModal.tsx +87 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/FlowRenderer.tsx +322 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ImportModal.tsx +175 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeEditModal.tsx +60 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +1150 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/RunWorkflowModal.tsx +101 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/StatusCards.tsx +198 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/VersionPanel.tsx +81 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +566 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useWorkflowAgent.ts +224 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +524 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +343 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instances.tsx +243 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/CreateNodeInstanceModal.tsx +363 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/DynamicConfigForm.tsx +154 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +176 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/create.tsx +77 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/edit.tsx +112 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/index.tsx +305 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/show.tsx +282 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/show.tsx +469 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +92 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/create.tsx +111 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/edit.tsx +127 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/index.tsx +4 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +254 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/show.tsx +74 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/yarn.lock +1501 -1199
- package/package.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.controller.spec.ts +0 -22
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/BarChart/index.tsx +0 -896
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartSwitcher/index.tsx +0 -219
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartViewer/index.tsx +0 -159
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Filter/index.tsx +0 -192
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/LineChart/index.tsx +0 -1034
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/NumCard.module.css +0 -8
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/index.tsx +0 -509
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumLineCard/index.tsx +0 -66
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/PieChart/index.tsx +0 -552
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/RadarChart/index.tsx +0 -263
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Section/index.tsx +0 -35
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Table/index.tsx +0 -207
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/TreemapChart/index.tsx +0 -382
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/WorldMap/index.tsx +0 -135
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/chart-constants.ts +0 -53
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/InfoIcon.tsx +0 -8
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/index.ts +0 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/config.ts +0 -31
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/nameMap.json +0 -9
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/world.geo.json +0 -39349
- 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,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
|
+
}
|