@rytass/bpm-core-nestjs-module 0.6.0 → 0.7.0

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 (46) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +2 -0
  3. package/package.json +10 -3
  4. package/src/index.d.ts +1 -0
  5. package/src/index.js +1 -0
  6. package/src/index.js.map +1 -1
  7. package/src/lib/bpm/bpm-root.module.d.ts +18 -0
  8. package/src/lib/bpm/bpm-root.module.js +8 -0
  9. package/src/lib/bpm/bpm-root.module.js.map +1 -1
  10. package/src/lib/calendar/business-calendar.provider.d.ts +11 -0
  11. package/src/lib/calendar/business-calendar.provider.js +20 -0
  12. package/src/lib/calendar/business-calendar.provider.js.map +1 -0
  13. package/src/lib/calendar/business-calendar.token.d.ts +38 -0
  14. package/src/lib/calendar/business-calendar.token.js +5 -0
  15. package/src/lib/calendar/business-calendar.token.js.map +1 -0
  16. package/src/lib/calendar/calendar.module.d.ts +18 -0
  17. package/src/lib/calendar/calendar.module.js +32 -0
  18. package/src/lib/calendar/calendar.module.js.map +1 -0
  19. package/src/lib/calendar/index.d.ts +5 -0
  20. package/src/lib/calendar/index.js +9 -0
  21. package/src/lib/calendar/index.js.map +1 -0
  22. package/src/lib/calendar/sla-schedule.service.d.ts +33 -0
  23. package/src/lib/calendar/sla-schedule.service.js +94 -0
  24. package/src/lib/calendar/sla-schedule.service.js.map +1 -0
  25. package/src/lib/calendar/weekday-business-calendar.d.ts +15 -0
  26. package/src/lib/calendar/weekday-business-calendar.js +28 -0
  27. package/src/lib/calendar/weekday-business-calendar.js.map +1 -0
  28. package/src/lib/common/iso-duration.d.ts +11 -0
  29. package/src/lib/common/iso-duration.js +13 -4
  30. package/src/lib/common/iso-duration.js.map +1 -1
  31. package/src/lib/notification/notification-options.d.ts +10 -0
  32. package/src/lib/notification/notification-options.js +19 -0
  33. package/src/lib/notification/notification-options.js.map +1 -1
  34. package/src/lib/notification/notification.enums.d.ts +13 -0
  35. package/src/lib/notification/notification.enums.js +14 -1
  36. package/src/lib/notification/notification.enums.js.map +1 -1
  37. package/src/lib/notification/notification.service.d.ts +8 -0
  38. package/src/lib/notification/notification.service.js +19 -1
  39. package/src/lib/notification/notification.service.js.map +1 -1
  40. package/src/lib/template/workflow-definition.validator.js +75 -1
  41. package/src/lib/template/workflow-definition.validator.js.map +1 -1
  42. package/src/lib/workflow-engine/workflow-engine.service.d.ts +20 -2
  43. package/src/lib/workflow-engine/workflow-engine.service.js +35 -10
  44. package/src/lib/workflow-engine/workflow-engine.service.js.map +1 -1
  45. package/src/lib/workflow-engine/workflow-engine.tokens.d.ts +2 -1
  46. package/src/lib/workflow-engine/workflow-engine.tokens.js.map +1 -1
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WorkflowEngineService = void 0;
3
+ exports.WorkflowEngineService = exports.MANUAL_TRANSFER_DELEGATION_REASON = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const common_1 = require("@nestjs/common");
6
6
  const typeorm_1 = require("@nestjs/typeorm");
@@ -9,6 +9,7 @@ const attachment_service_1 = require("../attachment/attachment.service");
9
9
  const delegation_service_1 = require("../delegation/delegation.service");
10
10
  const form_definition_version_entity_1 = require("../form/form-definition-version.entity");
11
11
  const form_enums_1 = require("../form/form.enums");
12
+ const sla_schedule_service_1 = require("../calendar/sla-schedule.service");
12
13
  const notification_service_1 = require("../notification/notification.service");
13
14
  const notification_entity_1 = require("../notification/notification.entity");
14
15
  const notification_enums_1 = require("../notification/notification.enums");
@@ -36,6 +37,11 @@ const workflow_token_entity_1 = require("./workflow-token.entity");
36
37
  const MAX_PROCESSING_STEPS = 500;
37
38
  const DEFAULT_APPROVAL_HISTORY_TASK_LIMIT = 50;
38
39
  const SYSTEM_DRY_RUN_INSTANCE_ID = 'dry-run-instance';
40
+ /**
41
+ * Delegation-chain reason recorded for an approver-initiated transfer, as
42
+ * opposed to {@link SLA_ESCALATION_DELEGATION_REASON}.
43
+ */
44
+ exports.MANUAL_TRANSFER_DELEGATION_REASON = 'MANUAL_TRANSFER';
39
45
  const WORKFLOW_READ_ALL_PERMISSIONS = new Set([
40
46
  'bpm:*',
41
47
  'bpm.workflow.read_all',
@@ -43,7 +49,7 @@ const WORKFLOW_READ_ALL_PERMISSIONS = new Set([
43
49
  'workflow.read_all',
44
50
  ]);
45
51
  let WorkflowEngineService = class WorkflowEngineService {
46
- constructor(approvalInstanceRepository, workflowTokenRepository, taskRepository, taskCandidateRepository, taskDecisionRepository, notificationRepository, activityLogRepository, adhocDirectiveRepository, approvalTemplateRepository, approvalTemplateVersionRepository, formDefinitionVersionRepository, attachmentService, conditionService, delegationService, notificationService, signatureService, serviceTaskDispatcher = new workflow_service_task_dispatcher_token_1.DefaultWorkflowServiceTaskDispatcher()) {
52
+ constructor(approvalInstanceRepository, workflowTokenRepository, taskRepository, taskCandidateRepository, taskDecisionRepository, notificationRepository, activityLogRepository, adhocDirectiveRepository, approvalTemplateRepository, approvalTemplateVersionRepository, formDefinitionVersionRepository, attachmentService, conditionService, delegationService, notificationService, signatureService, slaScheduleService, serviceTaskDispatcher = new workflow_service_task_dispatcher_token_1.DefaultWorkflowServiceTaskDispatcher()) {
47
53
  this.approvalInstanceRepository = approvalInstanceRepository;
48
54
  this.workflowTokenRepository = workflowTokenRepository;
49
55
  this.taskRepository = taskRepository;
@@ -60,6 +66,7 @@ let WorkflowEngineService = class WorkflowEngineService {
60
66
  this.delegationService = delegationService;
61
67
  this.notificationService = notificationService;
62
68
  this.signatureService = signatureService;
69
+ this.slaScheduleService = slaScheduleService;
63
70
  this.serviceTaskDispatcher = serviceTaskDispatcher;
64
71
  }
65
72
  async submitApprovalInstance(input) {
@@ -169,7 +176,7 @@ let WorkflowEngineService = class WorkflowEngineService {
169
176
  await this.processRunningInstance(manager, instance);
170
177
  });
171
178
  }
172
- async decideTask(input) {
179
+ async decideTask(input, options = {}) {
173
180
  return this.approvalInstanceRepository.manager.transaction(async (manager) => {
174
181
  const taskRepository = manager.getRepository(task_entity_1.TaskEntity);
175
182
  const taskCandidateRepository = manager.getRepository(task_candidate_entity_1.TaskCandidateEntity);
@@ -223,6 +230,14 @@ let WorkflowEngineService = class WorkflowEngineService {
223
230
  const returnToNodeId = input.action === workflow_engine_enums_1.TaskDecisionActionEnum.RETURNED
224
231
  ? readReturnTargetNodeId(instance.workflowSnapshot, task.nodeId, input.returnToNodeId)
225
232
  : null;
233
+ // Read from the instance snapshot, not the live template: templates
234
+ // that turn `requireComment` on later must not retroactively block
235
+ // in-flight instances started against the previous version.
236
+ if (input.action === workflow_engine_enums_1.TaskDecisionActionEnum.RETURNED &&
237
+ !decisionComment &&
238
+ isReturnCommentRequired(instance.workflowSnapshot, task.nodeId)) {
239
+ throw new common_1.BadRequestException(`Return decision comment is required by workflow node ${task.nodeId}`);
240
+ }
226
241
  const decidedAt = new Date();
227
242
  const claimedTask = await taskRepository.save({
228
243
  ...task,
@@ -261,7 +276,7 @@ let WorkflowEngineService = class WorkflowEngineService {
261
276
  transferToMemberId,
262
277
  }));
263
278
  if (input.action === workflow_engine_enums_1.TaskDecisionActionEnum.TRANSFERRED) {
264
- await this.transferTask(manager, instance, claimedTask, decision, signature, transferToMemberId, decisionComment, decidedAt, claimedCandidate);
279
+ await this.transferTask(manager, instance, claimedTask, decision, signature, transferToMemberId, decisionComment, decidedAt, claimedCandidate, options.transferReason ?? exports.MANUAL_TRANSFER_DELEGATION_REASON);
265
280
  await this.notificationService.resolveTaskNotifications({
266
281
  actingMemberId: input.decidedByMemberId,
267
282
  manager,
@@ -1895,6 +1910,10 @@ let WorkflowEngineService = class WorkflowEngineService {
1895
1910
  const candidates = await this.resolveRuntimeTaskCandidates(manager, instance, node);
1896
1911
  const primaryCandidate = candidates[0];
1897
1912
  const now = new Date();
1913
+ const slaDueAt = await this.slaScheduleService.resolveTaskSlaDueAt({
1914
+ node,
1915
+ now,
1916
+ });
1898
1917
  const task = await taskRepository.save(taskRepository.create({
1899
1918
  assigneeMemberId: candidates.length === 1 ? primaryCandidate.memberId : null,
1900
1919
  assignmentType: candidates.length === 1
@@ -1908,7 +1927,7 @@ let WorkflowEngineService = class WorkflowEngineService {
1908
1927
  nodeId: node.id,
1909
1928
  openedAt: null,
1910
1929
  originalAssigneeMemberId: candidates.length === 1 ? primaryCandidate.originalMemberId : null,
1911
- slaDueAt: (0, notification_service_1.calculateTaskSlaDueAt)({ node, now }),
1930
+ slaDueAt,
1912
1931
  status: workflow_engine_enums_1.TaskStatusEnum.PENDING,
1913
1932
  tokenId: token.id,
1914
1933
  }));
@@ -2006,7 +2025,7 @@ let WorkflowEngineService = class WorkflowEngineService {
2006
2025
  }
2007
2026
  return nextCandidates;
2008
2027
  }
2009
- async transferTask(manager, instance, task, decision, signature, transferToMemberId, decisionComment, decidedAt, actorCandidate) {
2028
+ async transferTask(manager, instance, task, decision, signature, transferToMemberId, decisionComment, decidedAt, actorCandidate, transferReason) {
2010
2029
  if (!transferToMemberId) {
2011
2030
  throw new common_1.BadRequestException('Transfer target member is required');
2012
2031
  }
@@ -2021,7 +2040,7 @@ let WorkflowEngineService = class WorkflowEngineService {
2021
2040
  ...readDelegationSteps(task.delegationChain),
2022
2041
  {
2023
2042
  from: transferringMemberId,
2024
- reason: 'MANUAL_TRANSFER',
2043
+ reason: transferReason,
2025
2044
  ruleId: null,
2026
2045
  to: transferToMemberId,
2027
2046
  },
@@ -2715,8 +2734,8 @@ exports.WorkflowEngineService = WorkflowEngineService = tslib_1.__decorate([
2715
2734
  tslib_1.__param(8, (0, typeorm_1.InjectRepository)(approval_template_entity_1.ApprovalTemplateEntity)),
2716
2735
  tslib_1.__param(9, (0, typeorm_1.InjectRepository)(approval_template_version_entity_1.ApprovalTemplateVersionEntity)),
2717
2736
  tslib_1.__param(10, (0, typeorm_1.InjectRepository)(form_definition_version_entity_1.FormDefinitionVersionEntity)),
2718
- tslib_1.__param(16, (0, common_1.Optional)()),
2719
- tslib_1.__param(16, (0, common_1.Inject)(workflow_service_task_dispatcher_token_1.BPM_WORKFLOW_SERVICE_TASK_DISPATCHER)),
2737
+ tslib_1.__param(17, (0, common_1.Optional)()),
2738
+ tslib_1.__param(17, (0, common_1.Inject)(workflow_service_task_dispatcher_token_1.BPM_WORKFLOW_SERVICE_TASK_DISPATCHER)),
2720
2739
  tslib_1.__metadata("design:paramtypes", [typeorm_2.Repository,
2721
2740
  typeorm_2.Repository,
2722
2741
  typeorm_2.Repository,
@@ -2732,7 +2751,8 @@ exports.WorkflowEngineService = WorkflowEngineService = tslib_1.__decorate([
2732
2751
  condition_service_1.ConditionService,
2733
2752
  delegation_service_1.DelegationService,
2734
2753
  notification_service_1.NotificationService,
2735
- signature_service_1.SignatureService, Object])
2754
+ signature_service_1.SignatureService,
2755
+ sla_schedule_service_1.BPMSlaScheduleService, Object])
2736
2756
  ], WorkflowEngineService);
2737
2757
  function parseJsonObject(value, label) {
2738
2758
  try {
@@ -2916,6 +2936,11 @@ function readDefaultReturnTargetNodeId(workflow, currentNode) {
2916
2936
  }
2917
2937
  return previousNodeId;
2918
2938
  }
2939
+ function isReturnCommentRequired(workflow, nodeId) {
2940
+ const node = readWorkflowNodeOrThrow(workflow, nodeId);
2941
+ return (node.type === 'userTask' &&
2942
+ node.data.returnBehavior.requireComment === true);
2943
+ }
2919
2944
  function readReturnResubmitStrategy(task, instance) {
2920
2945
  const node = readWorkflowNodeOrThrow(instance.workflowSnapshot, task.nodeId);
2921
2946
  if (node.type !== 'userTask') {