@gadmin2n/schematics 0.0.152 → 0.0.154

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 (110) hide show
  1. package/dist/lib/application/files/gadmin2-game-angle-demo/.git-blame-ignore-revs +5 -0
  2. package/dist/lib/application/files/gadmin2-game-angle-demo/.nvmrc +1 -0
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/CODEBUDDY.local.md +8 -0
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/CODEBUDDY.md +4 -4
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile.codegen +16 -9
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile.server +21 -13
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile.web +11 -11
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/Jenkinsfile +1 -1
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/PRODUCT.md +1 -1
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/compose-ctl.sh +1 -1
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +1 -0
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/docker-compose.yml +4 -4
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/readme.md +22 -22
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.oxfmtrc.json +13 -0
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.oxlintrc.json +17 -0
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.seed-timestamp +1 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +14 -13
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/pnpm-workspace.yaml +23 -0
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +2 -1
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permission.seed.ts +23 -44
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +25 -4
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +74 -64
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/auth.guard.ts +4 -1
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/structured-all-exceptions.filter.ts +2 -2
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/tracing.ts +4 -6
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.service.ts +2 -2
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.controller.ts +1 -1
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.controller.ts +6 -6
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.controller.ts +1 -1
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.controller.ts +6 -6
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.util.ts +4 -4
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-subject-source.util.ts +1 -1
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.service.ts +4 -4
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.controller.ts +1 -1
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.service.ts +2 -2
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.controller.ts +1 -1
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/permTransfer/page-transfer.service.ts +1 -1
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.controller.ts +1 -1
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.controller.ts +1 -1
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.controller.ts +1 -1
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/staffDirectory/staff-directory.service.spec.ts +1 -1
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/subjectProvider/subject-provider.errors.ts +4 -1
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/subjectProvider/subject-provider.registry.ts +4 -4
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/subjectProvider/subject-provider.types.ts +4 -4
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.controller.ts +1 -1
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.service.ts +2 -2
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/parameter-binding.ts +4 -4
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +0 -7
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-cancellation.spec.ts +17 -0
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.spec.ts +58 -3
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.ts +66 -6
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-data-edge.util.ts +5 -5
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution-idempotency.spec.ts +61 -149
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +1 -1
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-handle-validator.ts +2 -2
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle-runtime.controller.spec.ts +1 -1
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle-runtime.controller.ts +1 -1
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle.service.spec.ts +2 -2
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.spec.ts +38 -0
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +18 -7
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +1 -0
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +142 -253
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/subject-config-validator.service.ts +3 -1
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.ts +1 -1
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.ts +1 -1
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/server/start-prod.sh +4 -4
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/web/.oxfmtrc.json +12 -0
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/web/.oxlintrc.json +24 -0
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/web/README.MD +2 -2
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/web/nginx.conf +0 -4
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +17 -17
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/web/pnpm-workspace.yaml +13 -0
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/VanillaJSONEditor/index.jsx +4 -4
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/propPatcher.ts +36 -8
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.test.ts +7 -5
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +6 -36
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/style.css +24 -7
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +0 -4
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/workflow.json +29 -7
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/workflow.json +29 -7
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/plugins/devShellPlugin.ts +2 -2
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/components/action-cell.css +1 -1
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/people-groups/index.tsx +20 -17
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/person-directory/index.tsx +38 -35
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/detail.tsx +6 -1
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/index.tsx +24 -22
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/EnhancedFlowRenderer.tsx +0 -11
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/StatusCards.tsx +24 -0
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/index.tsx +20 -18
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +7 -0
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +28 -79
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instances.tsx +5 -0
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +0 -1
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/DbExecuteConfigEditor.tsx +227 -97
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SimplifiedNodeEditors.test.tsx +62 -0
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/settings/index.tsx +73 -0
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +21 -46
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +2 -0
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/newNodeConfig.ts +1 -0
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/index.css +1 -1
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/test/setup.ts +1 -1
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/vite.config.ts +53 -41
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/vitest.config.ts +8 -2
  104. package/package.json +1 -1
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.eslintrc.js +0 -28
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.prettierignore +0 -7
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.prettierrc +0 -4
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/.eslintrc.json +0 -38
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/.prettierignore +0 -2
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/.prettierrc +0 -4
@@ -12,8 +12,9 @@ import {
12
12
  *
13
13
  * 职责(仅本模块自家):
14
14
  * 1. permission 父分组 page (顶级 admin/administration → permission)
15
- * 2. 7 个 leaf page: permission_readme / person_directory / user /
16
- * people_group / role / page / resource
15
+ * 2. 5 个 leaf page,均挂在 permission 下
16
+ * (原 person_directory / people_group 已并入 Workflow 的「功能设置」页,
17
+ * 由 workflow.seed.ts 声明并迁移)
17
18
  * 3. permission 模块所需 resource 及页面绑定
18
19
  * 4. PageResource 绑定(page ↔ resource,多对多)
19
20
  * 5. SYSTEM_ADMIN 对上述全部 page + resource 的全量授权
@@ -54,32 +55,35 @@ export async function seedPermissionModule(
54
55
  zhName: '菜单指引',
55
56
  enName: 'Menu Guide',
56
57
  sortOrder: 1005,
57
- },
58
- {
59
- code: 'person_directory',
60
- zhName: '人员目录',
61
- enName: 'People Directory',
62
- sortOrder: 1010,
58
+ parentId: permissionPage.id,
63
59
  },
64
60
  {
65
61
  code: 'user',
66
- zhName: '访问授权',
67
- enName: 'Access Grants',
62
+ zhName: '用户管理',
63
+ enName: 'User Mgnt',
68
64
  sortOrder: 1020,
65
+ parentId: permissionPage.id,
66
+ },
67
+ {
68
+ code: 'role',
69
+ zhName: '角色管理',
70
+ enName: 'Role Mgnt',
71
+ sortOrder: 1040,
72
+ parentId: permissionPage.id,
69
73
  },
70
74
  {
71
- code: 'people_group',
72
- zhName: '人员组',
73
- enName: 'People Groups',
74
- sortOrder: 1030,
75
+ code: 'page',
76
+ zhName: '页面管理',
77
+ enName: 'Page Mgnt',
78
+ sortOrder: 1050,
79
+ parentId: permissionPage.id,
75
80
  },
76
- { code: 'role', zhName: '角色管理', enName: 'Role Mgnt', sortOrder: 1040 },
77
- { code: 'page', zhName: '页面管理', enName: 'Page Mgnt', sortOrder: 1050 },
78
81
  {
79
82
  code: 'resource',
80
83
  zhName: '资源管理',
81
84
  enName: 'Resource Management',
82
85
  sortOrder: 1060,
86
+ parentId: permissionPage.id,
83
87
  },
84
88
  ];
85
89
 
@@ -95,13 +99,13 @@ export async function seedPermissionModule(
95
99
  zhName: def.zhName,
96
100
  enName: def.enName,
97
101
  sortOrder: def.sortOrder,
98
- parentId: permissionPage.id,
102
+ parentId: def.parentId,
99
103
  },
100
104
  {
101
105
  zhName: def.zhName,
102
106
  enName: def.enName,
103
107
  sortOrder: def.sortOrder,
104
- parentId: permissionPage.id,
108
+ parentId: def.parentId,
105
109
  },
106
110
  );
107
111
  pagesByCode.set(p.code, p.id);
@@ -114,32 +118,7 @@ export async function seedPermissionModule(
114
118
  description: string;
115
119
  pageCode: string;
116
120
  }[] = [
117
- {
118
- code: 'user',
119
- description: 'People directory',
120
- pageCode: 'person_directory',
121
- },
122
- {
123
- code: 'staffDirectory',
124
- description: 'Search the shared staff directory',
125
- pageCode: 'person_directory',
126
- },
127
- { code: 'user', description: 'Access grants', pageCode: 'user' },
128
- {
129
- code: 'userGroup:read',
130
- description: 'Read reusable people groups',
131
- pageCode: 'people_group',
132
- },
133
- {
134
- code: 'userGroup:create',
135
- description: 'Maintain reusable people groups',
136
- pageCode: 'people_group',
137
- },
138
- {
139
- code: 'user',
140
- description: 'Read people for group membership',
141
- pageCode: 'people_group',
142
- },
121
+ { code: 'user', description: 'User management', pageCode: 'user' },
143
122
  { code: 'role', description: 'Role management', pageCode: 'role' },
144
123
  {
145
124
  code: 'rolePages',
@@ -452,12 +452,17 @@ const NODE_DEFINITIONS: BaseNodeTypeSeed[] = [
452
452
  {
453
453
  type: 'db_execute',
454
454
  category: 'ACTION',
455
- label: '数据库 Function',
455
+ label: '数据库操作',
456
456
  icon: 'ConsoleSqlOutlined',
457
- description: '调用当前 GAdmin 数据库 workflow_api 中的 Function',
457
+ description: '执行 Raw SQL 或调用当前 GAdmin 数据库中的 Function',
458
458
  configSchema: {
459
459
  type: 'object',
460
460
  properties: {
461
+ mode: {
462
+ type: 'string',
463
+ enum: ['FUNCTION', 'SQL'],
464
+ description: '执行方式',
465
+ },
461
466
  functionRef: {
462
467
  type: 'object',
463
468
  properties: {
@@ -473,6 +478,19 @@ const NODE_DEFINITIONS: BaseNodeTypeSeed[] = [
473
478
  items: PARAMETER_BINDING_SCHEMA,
474
479
  description: '按 Function 参数顺序提供的值',
475
480
  },
481
+ allowWrite: {
482
+ type: 'boolean',
483
+ description: 'Raw SQL 是否允许新增、更新或删除数据',
484
+ },
485
+ sql: {
486
+ type: 'string',
487
+ description: '要执行的单条 SQL',
488
+ },
489
+ parameters: {
490
+ type: 'array',
491
+ items: PARAMETER_BINDING_SCHEMA,
492
+ description: 'Raw SQL 参数占位符对应的值',
493
+ },
476
494
  timeoutSeconds: {
477
495
  type: 'integer',
478
496
  minimum: 1,
@@ -480,7 +498,6 @@ const NODE_DEFINITIONS: BaseNodeTypeSeed[] = [
480
498
  description: '执行超时时间(秒)',
481
499
  },
482
500
  },
483
- required: ['functionRef', 'argumentBindings'],
484
501
  additionalProperties: false,
485
502
  },
486
503
  inputSchema: { description: '上一个节点的完整结果' },
@@ -488,6 +505,10 @@ const NODE_DEFINITIONS: BaseNodeTypeSeed[] = [
488
505
  type: 'object',
489
506
  properties: {
490
507
  result: { description: 'Function 返回值' },
508
+ rows: { type: 'array' },
509
+ rowCount: { type: 'number' },
510
+ affectedRows: { type: 'number' },
511
+ insertedId: { type: 'string' },
491
512
  },
492
513
  },
493
514
  outputs: [],
@@ -1316,7 +1337,7 @@ const dedicatedEditorNodes: NodeTypeSeed[] = [
1316
1337
  type === 'event_trigger'
1317
1338
  ? 6
1318
1339
  : type === 'db_execute'
1319
- ? 5
1340
+ ? 6
1320
1341
  : type === 'parallel'
1321
1342
  ? 6
1322
1343
  : ['if_else', 'switch'].includes(type)
@@ -67,38 +67,22 @@ export async function seedWorkflowModule(prisma: PrismaClient): Promise<void> {
67
67
  resourceCode: 'workflowNodeInstance',
68
68
  resourceDescription: 'Workflow node instance management',
69
69
  },
70
- {
71
- code: 'workflow_connections',
72
- zhName: '连接管理',
73
- enName: 'Connections',
74
- sortOrder: 3,
75
- resourceCode: 'integrationConnection',
76
- resourceDescription: 'Reusable external system connections',
77
- },
78
- {
79
- code: 'workflow_temporal_tenant',
80
- zhName: '服务注册',
81
- enName: 'Service Registration',
82
- sortOrder: 4,
83
- resourceCode: 'temporalTenantConfig',
84
- resourceDescription: 'Temporal tenant config management',
85
- },
86
- {
87
- code: 'workflow_event_catalog',
88
- zhName: '业务事件',
89
- enName: 'Business Events',
90
- sortOrder: 5,
91
- resourceCode: 'workflow',
92
- resourceDescription: 'Read registered Workflow business events',
93
- },
94
70
  {
95
71
  code: 'approval_tasks',
96
72
  zhName: '审批任务',
97
73
  enName: 'Approval Tasks',
98
- sortOrder: 6,
74
+ sortOrder: 3,
99
75
  resourceCode: 'humanApproval',
100
76
  resourceDescription: 'Read and decide assigned Human Approval tasks',
101
77
  },
78
+ {
79
+ code: 'workflow_settings',
80
+ zhName: '功能设置',
81
+ enName: 'Feature Settings',
82
+ sortOrder: 6,
83
+ resourceCode: 'integrationConnection',
84
+ resourceDescription: 'Reusable external system connections',
85
+ },
102
86
  ];
103
87
 
104
88
  const allPages = [{ id: workflowPage.id, code: workflowPage.code }];
@@ -114,7 +98,7 @@ export async function seedWorkflowModule(prisma: PrismaClient): Promise<void> {
114
98
  sortOrder: def.sortOrder,
115
99
  parentId: workflowPage.id,
116
100
  },
117
- def.code === 'approval_tasks'
101
+ def.code === 'approval_tasks' || def.code === 'workflow_settings'
118
102
  ? { parentId: workflowPage.id, sortOrder: def.sortOrder }
119
103
  : {},
120
104
  );
@@ -129,18 +113,6 @@ export async function seedWorkflowModule(prisma: PrismaClient): Promise<void> {
129
113
  );
130
114
  console.log(`[workflow] PageResource: ${def.code} ↔ ${def.resourceCode}`);
131
115
 
132
- if (def.code === 'workflow_event_catalog') {
133
- await bindResourceToPage(
134
- prisma,
135
- p.id,
136
- 'workflowEventRegistration',
137
- 'Register database-backed Workflow business events',
138
- );
139
- console.log(
140
- '[workflow] PageResource: workflow_event_catalog ↔ workflowEventRegistration',
141
- );
142
- }
143
-
144
116
  if (def.code === 'workflow_list') {
145
117
  await bindResourceToPage(
146
118
  prisma,
@@ -151,6 +123,26 @@ export async function seedWorkflowModule(prisma: PrismaClient): Promise<void> {
151
123
  console.log('[workflow] PageResource: workflow_list ↔ workflowExecution');
152
124
  }
153
125
 
126
+ // 功能设置合并了原服务注册/连接管理/业务事件/人员目录/人员组 5 个页面的全部资源
127
+ if (def.code === 'workflow_settings') {
128
+ const mergedResources = [
129
+ ['temporalTenantConfig', 'Temporal tenant config management'],
130
+ ['workflow', 'Read registered Workflow business events'],
131
+ [
132
+ 'workflowEventRegistration',
133
+ 'Register database-backed Workflow business events',
134
+ ],
135
+ ['user', 'People directory'],
136
+ ['staffDirectory', 'Search the shared staff directory'],
137
+ ['userGroup:read', 'Read reusable people groups'],
138
+ ['userGroup:create', 'Maintain reusable people groups'],
139
+ ] as const;
140
+ for (const [code, description] of mergedResources) {
141
+ await bindResourceToPage(prisma, p.id, code, description);
142
+ console.log(`[workflow] PageResource: ${def.code} ↔ ${code}`);
143
+ }
144
+ }
145
+
154
146
  // Provider actions live inside the existing Node Instance page. Resolve is
155
147
  // seeded now for the later publish/runtime call path; it has no HTTP route yet.
156
148
  if (def.code === 'workflow_node_instance') {
@@ -197,35 +189,53 @@ export async function seedWorkflowModule(prisma: PrismaClient): Promise<void> {
197
189
  }
198
190
  }
199
191
 
200
- // Connection management is part of creating and maintaining reusable Node
201
- // Templates. Keep its page access aligned with the existing Node Template
202
- // page instead of limiting it to SYSTEM_ADMIN on installations that already
203
- // granted workflow authoring to other roles.
204
- const nodeTemplatePage = allPages.find(
205
- (page) => page.code === 'workflow_node_instance',
206
- );
207
- const connectionsPage = allPages.find(
208
- (page) => page.code === 'workflow_connections',
192
+ // ── 旧页面合并迁移 ─────────────────────────────────────────────────────────
193
+ // 「功能设置」(workflow_settings) 取代了服务注册/连接管理/业务事件/人员目录/
194
+ // 人员组 5 个旧页面:已授权旧页面的角色改授新页面以保留访问,随后删除旧 page
195
+ // 及其 RolePages/PageResource 关联(RoleResource 保留——资源仍绑定在新页面上)。
196
+ // 旧页面已删除的环境重跑 seed 时本块为 no-op。
197
+ const settingsPage = allPages.find(
198
+ (page) => page.code === 'workflow_settings',
209
199
  );
210
- if (nodeTemplatePage && connectionsPage) {
211
- const authorRoles = await prisma.rolePages.findMany({
212
- where: { pageId: nodeTemplatePage.id },
213
- select: { roleId: true },
214
- });
215
- const connectionResourceIds = await getPageResourceIds(
200
+ if (settingsPage) {
201
+ const settingsResourceIds = await getPageResourceIds(
216
202
  prisma,
217
- connectionsPage.id,
203
+ settingsPage.id,
218
204
  );
219
- for (const { roleId } of authorRoles) {
220
- await grantRoleAccess(
221
- prisma,
222
- roleId,
223
- connectionsPage.id,
224
- connectionResourceIds,
225
- );
226
- console.log(
227
- `[workflow] Grant: role#${roleId} → workflow_connections (inherits Node Template access)`,
228
- );
205
+ const legacyPages = await prisma.page.findMany({
206
+ where: {
207
+ code: {
208
+ in: [
209
+ 'workflow_temporal_tenant',
210
+ 'workflow_connections',
211
+ 'workflow_event_catalog',
212
+ 'person_directory',
213
+ 'people_group',
214
+ ],
215
+ },
216
+ },
217
+ select: { id: true, code: true },
218
+ });
219
+ for (const legacy of legacyPages) {
220
+ const grants = await prisma.rolePages.findMany({
221
+ where: { pageId: legacy.id },
222
+ select: { roleId: true },
223
+ });
224
+ for (const { roleId } of grants) {
225
+ await grantRoleAccess(
226
+ prisma,
227
+ roleId,
228
+ settingsPage.id,
229
+ settingsResourceIds,
230
+ );
231
+ console.log(
232
+ `[workflow] Migrate: role#${roleId} ${legacy.code} → workflow_settings`,
233
+ );
234
+ }
235
+ await prisma.rolePages.deleteMany({ where: { pageId: legacy.id } });
236
+ await prisma.pageResource.deleteMany({ where: { pageId: legacy.id } });
237
+ await prisma.page.delete({ where: { id: legacy.id } });
238
+ console.log(`[workflow] Migrate: removed legacy page ${legacy.code}`);
229
239
  }
230
240
  }
231
241
 
@@ -97,7 +97,10 @@ async function issueGAdminTokenCookie(res, user: UserType) {
97
97
 
98
98
  @Injectable()
99
99
  export default class AuthGuard implements CanActivate {
100
- constructor(private reflector: Reflector, private userService: UserService) {}
100
+ constructor(
101
+ private reflector: Reflector,
102
+ private userService: UserService,
103
+ ) {}
101
104
 
102
105
  private async getApikeyIdentity(req): Promise<UserType> {
103
106
  const apiKey = req.headers['x-api-key'] ?? req.query.api_key;
@@ -56,8 +56,8 @@ export class StructuredAllExceptionsFilter implements ExceptionFilter {
56
56
  typeof payload === 'string'
57
57
  ? payload
58
58
  : statusCode === HttpStatus.INTERNAL_SERVER_ERROR
59
- ? 'Internal server error.'
60
- : controlled?.message ?? error,
59
+ ? 'Internal server error.'
60
+ : (controlled?.message ?? error),
61
61
  error,
62
62
  path,
63
63
  });
@@ -58,12 +58,10 @@ class PrismaDbSpanProcessor implements SpanProcessor {
58
58
  mutableSpan.attributes['db.name'] = dbInfo.name;
59
59
  mutableSpan.attributes['db.instance'] = dbInfo.name;
60
60
  mutableSpan.attributes['db.ip'] = dbInfo.host;
61
- mutableSpan.attributes[
62
- 'peer.service'
63
- ] = `${dbInfo.name}@${dbInfo.host}:${dbInfo.port}`;
64
- mutableSpan.attributes[
65
- 'peer.filled'
66
- ] = `${dbInfo.name}@${dbInfo.host}:${dbInfo.port}`;
61
+ mutableSpan.attributes['peer.service'] =
62
+ `${dbInfo.name}@${dbInfo.host}:${dbInfo.port}`;
63
+ mutableSpan.attributes['peer.filled'] =
64
+ `${dbInfo.name}@${dbInfo.host}:${dbInfo.port}`;
67
65
  }
68
66
  this.inner.onEnd(span);
69
67
  }
@@ -440,8 +440,8 @@ export class AgendaService
440
440
  ? toggle === 'active'
441
441
  ? stateFiltered.filter((j) => !j.disabled)
442
442
  : toggle === 'paused'
443
- ? stateFiltered.filter((j) => j.disabled)
444
- : stateFiltered
443
+ ? stateFiltered.filter((j) => j.disabled)
444
+ : stateFiltered
445
445
  : stateFiltered;
446
446
 
447
447
  const total = toggleFiltered.length;
@@ -130,7 +130,7 @@ export class AuditController {
130
130
  @Body() body: UpdateAuditDto,
131
131
  @ACAttrFilter() acAttrFilter,
132
132
  ) {
133
- /*
133
+ /*
134
134
  const origin = (await this.auditService.findUnique(id, {
135
135
  id: true,
136
136
  // 这里需要根据实际情况填写
@@ -61,12 +61,12 @@ export class CodeRuntimeController {
61
61
  node?.runtimeKey === 'code' && !input.configKey
62
62
  ? node.config
63
63
  : node?.runtimeKey === 'human_approval' &&
64
- input.configKey === 'creationResult'
65
- ? node.config.external?.creationResult
66
- : node?.runtimeKey === 'human_approval' &&
67
- input.configKey === 'approverLookupResult'
68
- ? dynamicSubject?.lookup?.result
69
- : undefined;
64
+ input.configKey === 'creationResult'
65
+ ? node.config.external?.creationResult
66
+ : node?.runtimeKey === 'human_approval' &&
67
+ input.configKey === 'approverLookupResult'
68
+ ? dynamicSubject?.lookup?.result
69
+ : undefined;
70
70
  if (
71
71
  !version ||
72
72
  version.workflowId !== instance.workflowId ||
@@ -128,7 +128,7 @@ export class GameController {
128
128
  @Body() body: UpdateGameDto,
129
129
  @ACAttrFilter() acAttrFilter,
130
130
  ) {
131
- /*
131
+ /*
132
132
  const origin = (await this.gameService.findUnique(id, {
133
133
  id: true,
134
134
  // 这里需要根据实际情况填写
@@ -73,12 +73,12 @@ export class HttpRequestRuntimeController {
73
73
  node?.runtimeKey === 'http_request' && !input.configKey
74
74
  ? node.config
75
75
  : node?.runtimeKey === 'human_approval' &&
76
- input.configKey === 'externalRequest'
77
- ? node.config.external?.request
78
- : node?.runtimeKey === 'human_approval' &&
79
- input.configKey === 'approverLookupRequest'
80
- ? dynamicSubject?.lookup?.request
81
- : undefined;
76
+ input.configKey === 'externalRequest'
77
+ ? node.config.external?.request
78
+ : node?.runtimeKey === 'human_approval' &&
79
+ input.configKey === 'approverLookupRequest'
80
+ ? dynamicSubject?.lookup?.request
81
+ : undefined;
82
82
  if (
83
83
  !version ||
84
84
  version.workflowId !== instance.workflowId ||
@@ -104,8 +104,8 @@ export function materializeHttpRequest(
104
104
  config.bodyMode === 'JSON'
105
105
  ? resolveTemplates(config.body, data)
106
106
  : Object.keys(config.bodyBindings ?? {}).length > 0
107
- ? resolveBindings(config.bodyBindings ?? {}, data)
108
- : undefined;
107
+ ? resolveBindings(config.bodyBindings ?? {}, data)
108
+ : undefined;
109
109
 
110
110
  return {
111
111
  url: url.toString().replace(/\/$/, resolvedPath.endsWith('/') ? '/' : ''),
@@ -188,8 +188,8 @@ function requireReference(data: HttpRequestData, path: string): unknown {
188
188
  source === 'input'
189
189
  ? data.input
190
190
  : source === 'workflow'
191
- ? data.workflow
192
- : data.approval;
191
+ ? data.workflow
192
+ : data.approval;
193
193
  for (const part of parts) {
194
194
  if (!current || typeof current !== 'object' || !(part in current))
195
195
  throw new Error(`HTTP_TEMPLATE_RESOLUTION_FAILED:${normalized}`);
@@ -24,7 +24,7 @@ export function materializeApprovalSubjects(
24
24
 
25
25
  for (const source of sources) {
26
26
  const provider =
27
- source.source === 'DYNAMIC' ? 'USER' : source.provider ?? 'USER';
27
+ source.source === 'DYNAMIC' ? 'USER' : (source.provider ?? 'USER');
28
28
  const refs = normalizeRefs(
29
29
  source.source === 'DYNAMIC'
30
30
  ? normalizeDynamicRefs(dynamicInputs[source.inputKey], source.inputKey)
@@ -317,7 +317,7 @@ export class HumanApprovalService {
317
317
  expiresAt:
318
318
  request.expiresAt instanceof Date
319
319
  ? request.expiresAt.toISOString()
320
- : request.expiresAt ?? null,
320
+ : (request.expiresAt ?? null),
321
321
  task: request.task,
322
322
  candidates: request.candidates.map((candidate) => ({
323
323
  approverId: candidate.principalRef,
@@ -678,7 +678,7 @@ function attachExternalApproval(
678
678
  expiresAt:
679
679
  request.expiresAt instanceof Date
680
680
  ? request.expiresAt.toISOString()
681
- : request.expiresAt ?? null,
681
+ : (request.expiresAt ?? null),
682
682
  task: input.task,
683
683
  candidates: candidates
684
684
  .filter((candidate) => candidate.principalType === 'USER')
@@ -802,8 +802,8 @@ function attachCompletedResolution<T extends Record<string, any>>(request: T) {
802
802
  typeof payload.decidedAt === 'string'
803
803
  ? payload.decidedAt
804
804
  : request.completedAt instanceof Date
805
- ? request.completedAt.toISOString()
806
- : new Date().toISOString(),
805
+ ? request.completedAt.toISOString()
806
+ : new Date().toISOString(),
807
807
  },
808
808
  };
809
809
  }
@@ -102,7 +102,7 @@ export class HumanApprovalRuntimeController {
102
102
  expiresAt:
103
103
  request.expiresAt instanceof Date
104
104
  ? request.expiresAt.toISOString()
105
- : request.expiresAt ?? null,
105
+ : (request.expiresAt ?? null),
106
106
  ...(externalApproval && {
107
107
  externalApproval,
108
108
  }),
@@ -252,8 +252,8 @@ export class IntegrationConnectionService {
252
252
  authType === 'BASIC'
253
253
  ? ['username', 'password']
254
254
  : authType === 'BEARER'
255
- ? ['token']
256
- : ['apiKey'];
255
+ ? ['token']
256
+ : ['apiKey'];
257
257
  if (
258
258
  !allowEmpty &&
259
259
  required.some((key) => typeof secrets[key] !== 'string' || !secrets[key])
@@ -133,7 +133,7 @@ export class PageResourceController {
133
133
  @Body() body: UpdatePageResourceDto,
134
134
  @ACAttrFilter() acAttrFilter,
135
135
  ) {
136
- /*
136
+ /*
137
137
  const origin = (await this.pageResourceService.findUnique(id, {
138
138
  id: true,
139
139
  // 这里需要根据实际情况填写
@@ -117,7 +117,7 @@ export class PageTransferService {
117
117
  for (const row of rows) {
118
118
  parentCodeById.set(
119
119
  row.id,
120
- row.parentId === null ? null : codeById.get(row.parentId) ?? null,
120
+ row.parentId === null ? null : (codeById.get(row.parentId) ?? null),
121
121
  );
122
122
  }
123
123
 
@@ -140,7 +140,7 @@ export class ResourceController {
140
140
  @Body() body: UpdateResourceDto,
141
141
  @ACAttrFilter() acAttrFilter,
142
142
  ) {
143
- /*
143
+ /*
144
144
  const origin = (await this.resourceService.findUnique(id, {
145
145
  id: true,
146
146
  // 这里需要根据实际情况填写
@@ -133,7 +133,7 @@ export class RolePagesController {
133
133
  @Body() body: UpdateRolePagesDto,
134
134
  @ACAttrFilter() acAttrFilter,
135
135
  ) {
136
- /*
136
+ /*
137
137
  const origin = (await this.rolePagesService.findUnique(id, {
138
138
  id: true,
139
139
  // 这里需要根据实际情况填写
@@ -133,7 +133,7 @@ export class RoleResourceController {
133
133
  @Body() body: UpdateRoleResourceDto,
134
134
  @ACAttrFilter() acAttrFilter,
135
135
  ) {
136
- /*
136
+ /*
137
137
  const origin = (await this.roleResourceService.findUnique(id, {
138
138
  id: true,
139
139
  // 这里需要根据实际情况填写
@@ -22,7 +22,7 @@ describe('StaffDirectoryService', () => {
22
22
  'staffDirectory.baseUrl': 'https://erp.example.com/',
23
23
  'staffDirectory.apiKey': 'secret',
24
24
  'staffDirectory.searchPath': '/api/staff/search',
25
- }[key]),
25
+ })[key],
26
26
  ),
27
27
  } as never);
28
28
 
@@ -9,7 +9,10 @@ export type SubjectProviderCapabilityErrorCode =
9
9
  | 'SUBJECT_PROVIDER_PREVIEW_NOT_SUPPORTED';
10
10
 
11
11
  export class SubjectProviderError extends Error {
12
- constructor(public readonly code: SubjectProviderErrorCode, message: string) {
12
+ constructor(
13
+ public readonly code: SubjectProviderErrorCode,
14
+ message: string,
15
+ ) {
13
16
  super(message);
14
17
  this.name = 'SubjectProviderError';
15
18
  Object.setPrototypeOf(this, new.target.prototype);
@@ -109,7 +109,7 @@ function cloneAndFreeze<T>(value: T): FrozenValue<T> {
109
109
  type FrozenValue<T> = T extends SubjectProviderDescriptor
110
110
  ? FrozenSubjectProviderDescriptor
111
111
  : T extends readonly (infer U)[]
112
- ? readonly FrozenValue<U>[]
113
- : T extends object
114
- ? { readonly [K in keyof T]: FrozenValue<T[K]> }
115
- : T;
112
+ ? readonly FrozenValue<U>[]
113
+ : T extends object
114
+ ? { readonly [K in keyof T]: FrozenValue<T[K]> }
115
+ : T;