@rytass/bpm-core-nestjs-module 0.15.0 → 0.17.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 (97) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/README.md +421 -271
  3. package/package.json +5 -5
  4. package/src/lib/attachment/attachment-options.d.ts +23 -10
  5. package/src/lib/attachment/attachment-options.js +17 -31
  6. package/src/lib/attachment/attachment-options.js.map +1 -1
  7. package/src/lib/attachment/attachment-request-origin.d.ts +19 -0
  8. package/src/lib/attachment/attachment-request-origin.js +51 -0
  9. package/src/lib/attachment/attachment-request-origin.js.map +1 -0
  10. package/src/lib/attachment/attachment.module.d.ts +1 -2
  11. package/src/lib/attachment/attachment.module.js.map +1 -1
  12. package/src/lib/attachment/attachment.queries.d.ts +2 -2
  13. package/src/lib/attachment/attachment.queries.js +9 -4
  14. package/src/lib/attachment/attachment.queries.js.map +1 -1
  15. package/src/lib/attachment/attachment.service.d.ts +6 -1
  16. package/src/lib/attachment/attachment.service.js +6 -4
  17. package/src/lib/attachment/attachment.service.js.map +1 -1
  18. package/src/lib/bpm/bpm-root-options.d.ts +1 -2
  19. package/src/lib/bpm/bpm-root-options.js.map +1 -1
  20. package/src/lib/bpm/bpm-root.module.d.ts +1 -2
  21. package/src/lib/bpm/bpm-root.module.js.map +1 -1
  22. package/src/lib/bpm-auth/bpm-auth.options.d.ts +1 -2
  23. package/src/lib/calendar/calendar.module.d.ts +1 -2
  24. package/src/lib/calendar/calendar.module.js.map +1 -1
  25. package/src/lib/delegation/delegation-rule.entity.js +3 -1
  26. package/src/lib/delegation/delegation-rule.entity.js.map +1 -1
  27. package/src/lib/delegation/delegation.service.d.ts +4 -0
  28. package/src/lib/delegation/delegation.service.js +19 -3
  29. package/src/lib/delegation/delegation.service.js.map +1 -1
  30. package/src/lib/delegation/dto/delegation-rule.input.js +6 -2
  31. package/src/lib/delegation/dto/delegation-rule.input.js.map +1 -1
  32. package/src/lib/form-data-source/form-data-source.module.d.ts +1 -2
  33. package/src/lib/form-data-source/form-data-source.module.js.map +1 -1
  34. package/src/lib/identity/identity.module.d.ts +1 -2
  35. package/src/lib/identity/identity.module.js.map +1 -1
  36. package/src/lib/migrations/0000000000001-enable-postgres-extensions.js +6 -2
  37. package/src/lib/migrations/0000000000001-enable-postgres-extensions.js.map +1 -1
  38. package/src/lib/notification/notification-options.d.ts +5 -5
  39. package/src/lib/notification/notification-options.module.d.ts +1 -2
  40. package/src/lib/notification/notification-options.module.js.map +1 -1
  41. package/src/lib/notification/notification.service.js +5 -2
  42. package/src/lib/notification/notification.service.js.map +1 -1
  43. package/src/lib/organization/index.d.ts +1 -0
  44. package/src/lib/organization/index.js +1 -0
  45. package/src/lib/organization/index.js.map +1 -1
  46. package/src/lib/organization/org-unit-retirement-impact.object.d.ts +18 -0
  47. package/src/lib/organization/org-unit-retirement-impact.object.js +34 -0
  48. package/src/lib/organization/org-unit-retirement-impact.object.js.map +1 -0
  49. package/src/lib/organization/organization.mutations.d.ts +1 -1
  50. package/src/lib/organization/organization.mutations.js +7 -4
  51. package/src/lib/organization/organization.mutations.js.map +1 -1
  52. package/src/lib/organization/organization.queries.d.ts +2 -0
  53. package/src/lib/organization/organization.queries.js +13 -0
  54. package/src/lib/organization/organization.queries.js.map +1 -1
  55. package/src/lib/organization/organization.service.d.ts +32 -1
  56. package/src/lib/organization/organization.service.js +157 -16
  57. package/src/lib/organization/organization.service.js.map +1 -1
  58. package/src/lib/signature/signature.module.d.ts +1 -2
  59. package/src/lib/signature/signature.module.js.map +1 -1
  60. package/src/lib/template/template.service.js +91 -57
  61. package/src/lib/template/template.service.js.map +1 -1
  62. package/src/lib/template/workflow-definition.validator.js +11 -0
  63. package/src/lib/template/workflow-definition.validator.js.map +1 -1
  64. package/src/lib/workflow-engine/dto/reassign-member-tasks.input.d.ts +7 -0
  65. package/src/lib/workflow-engine/dto/reassign-member-tasks.input.js +34 -0
  66. package/src/lib/workflow-engine/dto/reassign-member-tasks.input.js.map +1 -0
  67. package/src/lib/workflow-engine/dto/reassign-task.input.d.ts +8 -0
  68. package/src/lib/workflow-engine/dto/reassign-task.input.js +39 -0
  69. package/src/lib/workflow-engine/dto/reassign-task.input.js.map +1 -0
  70. package/src/lib/workflow-engine/index.d.ts +3 -0
  71. package/src/lib/workflow-engine/index.js +3 -0
  72. package/src/lib/workflow-engine/index.js.map +1 -1
  73. package/src/lib/workflow-engine/task-reassignment.object.d.ts +26 -0
  74. package/src/lib/workflow-engine/task-reassignment.object.js +97 -0
  75. package/src/lib/workflow-engine/task-reassignment.object.js.map +1 -0
  76. package/src/lib/workflow-engine/workflow-dashboard-summary.object.js +18 -6
  77. package/src/lib/workflow-engine/workflow-dashboard-summary.object.js.map +1 -1
  78. package/src/lib/workflow-engine/workflow-engine.enums.d.ts +29 -0
  79. package/src/lib/workflow-engine/workflow-engine.enums.js +42 -1
  80. package/src/lib/workflow-engine/workflow-engine.enums.js.map +1 -1
  81. package/src/lib/workflow-engine/workflow-engine.module.d.ts +1 -2
  82. package/src/lib/workflow-engine/workflow-engine.module.js.map +1 -1
  83. package/src/lib/workflow-engine/workflow-engine.mutations.d.ts +5 -0
  84. package/src/lib/workflow-engine/workflow-engine.mutations.js +48 -0
  85. package/src/lib/workflow-engine/workflow-engine.mutations.js.map +1 -1
  86. package/src/lib/workflow-engine/workflow-engine.queries.d.ts +2 -0
  87. package/src/lib/workflow-engine/workflow-engine.queries.js +15 -0
  88. package/src/lib/workflow-engine/workflow-engine.queries.js.map +1 -1
  89. package/src/lib/workflow-engine/workflow-engine.service.d.ts +160 -1
  90. package/src/lib/workflow-engine/workflow-engine.service.js +749 -53
  91. package/src/lib/workflow-engine/workflow-engine.service.js.map +1 -1
  92. package/src/lib/workflow-engine/workflow-engine.tokens.d.ts +2 -1
  93. package/src/lib/workflow-engine/workflow-engine.tokens.js.map +1 -1
  94. package/src/lib/workflow-webhook/workflow-webhook-options.module.d.ts +1 -2
  95. package/src/lib/workflow-webhook/workflow-webhook-options.module.js.map +1 -1
  96. package/src/lib/workflow-webhook/workflow-webhook.module.d.ts +1 -2
  97. package/src/lib/workflow-webhook/workflow-webhook.module.js.map +1 -1
@@ -26,7 +26,7 @@ import { ApprovalInstanceEntity } from './approval-instance.entity';
26
26
  import { TaskDecisionEntity } from './task-decision.entity';
27
27
  import { TaskCandidateEntity } from './task-candidate.entity';
28
28
  import { TaskEntity } from './task.entity';
29
- import { ApprovalInstanceListViewEnum, ApprovalInstanceStateEnum } from './workflow-engine.enums';
29
+ import { ApprovalInstanceListViewEnum, ApprovalInstanceStateEnum, MemberTaskRoleEnum, TaskCandidateStatusEnum, TaskReassignmentErrorCodeEnum, TaskReassignmentOutcomeEnum } from './workflow-engine.enums';
30
30
  import { WorkflowDryRunResultObject } from './workflow-dry-run.object';
31
31
  import { BPMWorkflowServiceTaskDispatcher } from './workflow-service-task-dispatcher.token';
32
32
  import { WorkflowTokenEntity } from './workflow-token.entity';
@@ -60,10 +60,54 @@ export declare const MAX_APPROVAL_INSTANCE_BUSINESS_KEY_LENGTH = 200;
60
60
  * opposed to {@link SLA_ESCALATION_DELEGATION_REASON}.
61
61
  */
62
62
  export declare const MANUAL_TRANSFER_DELEGATION_REASON = "MANUAL_TRANSFER";
63
+ /**
64
+ * Delegation-chain reason for a seat an administrator moved to another member
65
+ * (see {@link WorkflowEngineService.reassignTask}). The step's `actorMemberId`
66
+ * names the administrator and `comment` carries the reason they typed.
67
+ */
68
+ export declare const ADMIN_REASSIGN_DELEGATION_REASON = "ADMIN_REASSIGN";
69
+ export interface TaskReassignmentResult {
70
+ readonly errorCode: TaskReassignmentErrorCodeEnum | null;
71
+ readonly instanceId: string;
72
+ readonly message: string | null;
73
+ readonly nodeId: string;
74
+ readonly outcome: TaskReassignmentOutcomeEnum;
75
+ readonly taskId: string;
76
+ }
77
+ export interface ReassignTaskOptions {
78
+ readonly actorMemberId: string;
79
+ readonly dryRun?: boolean | null;
80
+ readonly fromMemberId: string;
81
+ readonly reason: string;
82
+ readonly toMemberId: string;
83
+ }
84
+ export interface MemberOpenTaskRecord {
85
+ readonly candidateStatus: TaskCandidateStatusEnum | null;
86
+ readonly createdAt: Date;
87
+ readonly decisionPolicyType: string;
88
+ readonly businessKey: string | null;
89
+ readonly instanceId: string;
90
+ readonly instanceTitle: string;
91
+ readonly memberRole: MemberTaskRoleEnum;
92
+ readonly nodeId: string;
93
+ readonly nodeLabel: string | null;
94
+ readonly slaDueAt: Date | null;
95
+ readonly taskId: string;
96
+ readonly templateId: string;
97
+ readonly templateName: string | null;
98
+ }
63
99
  /**
64
100
  * Engine-internal decision knobs that are deliberately kept out of
65
101
  * {@link DecideTaskInput} so they never reach the GraphQL schema.
66
102
  */
103
+ /** Input of {@link WorkflowEngineService.expireApprovalInstance}. */
104
+ export interface ExpireApprovalInstanceCommand {
105
+ readonly comment?: string | null;
106
+ readonly instanceId: string;
107
+ /** The overdue task's node and the task itself, for the activity record. */
108
+ readonly nodeId?: string | null;
109
+ readonly taskId?: string | null;
110
+ }
67
111
  export interface DecideTaskOptions {
68
112
  /**
69
113
  * Reason stamped on the delegation-chain step when the decision is a
@@ -104,6 +148,7 @@ export declare class WorkflowEngineService {
104
148
  private readonly slaScheduleService;
105
149
  private readonly formDataSourceValueResolver?;
106
150
  private readonly webhookDeliveryService?;
151
+ private readonly logger;
107
152
  constructor(approvalInstanceRepository: Repository<ApprovalInstanceEntity>, workflowTokenRepository: Repository<WorkflowTokenEntity>, taskRepository: Repository<TaskEntity>, taskCandidateRepository: Repository<TaskCandidateEntity>, taskDecisionRepository: Repository<TaskDecisionEntity>, notificationRepository: Repository<NotificationEntity>, activityLogRepository: Repository<ActivityLogEntity>, adhocDirectiveRepository: Repository<AdhocDirectiveEntity>, approvalTemplateRepository: Repository<ApprovalTemplateEntity>, approvalTemplateVersionRepository: Repository<ApprovalTemplateVersionEntity>, formDefinitionVersionRepository: Repository<FormDefinitionVersionEntity>, attachmentService: AttachmentService, conditionService: ConditionService, delegationService: DelegationService, notificationService: NotificationService, signatureService: SignatureService, slaScheduleService: BPMSlaScheduleService, injectedServiceTaskDispatcher?: BPMWorkflowServiceTaskDispatcher, formDataSourceValueResolver?: BPMFormDataSourceValueResolver | undefined, rootOptions?: BPMRootRuntimeOptions, webhookDeliveryService?: WorkflowWebhookDeliveryService | undefined);
108
153
  private readonly serviceTaskDispatcher;
109
154
  private readonly organizationTimeZone;
@@ -127,6 +172,16 @@ export declare class WorkflowEngineService {
127
172
  processInstance(instanceId: string): Promise<void>;
128
173
  decideTask(input: DecideTaskInput, options?: DecideTaskOptions): Promise<TaskDecisionEntity>;
129
174
  cancelApprovalInstance(input: CancelApprovalInstanceInput): Promise<ApprovalInstanceEntity>;
175
+ /**
176
+ * Ends a running or returned instance because a task on it ran past its SLA
177
+ * with `onTimeout: 'TERMINATE_INSTANCE'`. It closes the instance exactly as
178
+ * a cancellation does, but lands in `EXPIRED` and is recorded with no actor:
179
+ * nobody chose to end it. An instance that is already closed — another
180
+ * overdue task of it got here first, or someone decided it meanwhile — is
181
+ * returned unchanged.
182
+ */
183
+ expireApprovalInstance(input: ExpireApprovalInstanceCommand): Promise<ApprovalInstanceEntity>;
184
+ private closeInstance;
130
185
  resubmitApprovalInstance(input: ResubmitApprovalInstanceCommand, authContext?: BPMAuthContext): Promise<ApprovalInstanceEntity>;
131
186
  requestAdhocCountersign({ comment, requestedByMemberId, target, taskId, }: {
132
187
  readonly comment?: string | null;
@@ -226,10 +281,20 @@ export declare class WorkflowEngineService {
226
281
  readonly rejectedInstanceCount: number;
227
282
  readonly totalInstanceCount: number;
228
283
  }>;
284
+ private readDashboardOpenTasks;
229
285
  listLaunchableApprovalTemplates(memberId: string): Promise<readonly ApprovalTemplateEntity[]>;
230
286
  listWorkflowTokens(instanceId: string, scope?: WorkflowReadScope): Promise<readonly WorkflowTokenEntity[]>;
231
287
  listTasks(instanceId: string, scope?: WorkflowReadScope): Promise<readonly TaskEntity[]>;
232
288
  listInboxTasks(assigneeMemberId: string): Promise<readonly TaskEntity[]>;
289
+ /**
290
+ * The open tasks that are this member's own to act on — the single
291
+ * definition behind both the inbox list and the dashboard counters, so the
292
+ * two can never disagree. A task is theirs when it is assigned to them, or
293
+ * when they hold a PENDING or CLAIMED candidate row on it. A sequential
294
+ * chain's later candidates sit in WAITING until it is their turn, so a task
295
+ * that has not reached them is not theirs yet.
296
+ */
297
+ private readOpenInboxTasks;
233
298
  listApprovalHistoryTasks(assigneeMemberId: string): Promise<readonly TaskEntity[]>;
234
299
  listTaskDecisions(taskId: string, scope?: WorkflowReadScope): Promise<readonly TaskDecisionEntity[]>;
235
300
  listTaskCandidates(taskId: string, scope?: WorkflowReadScope): Promise<readonly TaskCandidateEntity[]>;
@@ -284,6 +349,80 @@ export declare class WorkflowEngineService {
284
349
  private resolveActivationDelegation;
285
350
  private markTaskCandidateDecision;
286
351
  private transferTask;
352
+ /**
353
+ * Administrator reassignment of one open task, moved in place: the task keeps
354
+ * its id, decision policy, SLA and every other seat. Only `fromMemberId`'s
355
+ * seat (and the assignee field, when it is theirs) moves to `toMemberId`.
356
+ *
357
+ * This is not a decision by the holder: it writes no TaskDecision and no
358
+ * signature. It is recorded as a TASK_REASSIGNED activity and an
359
+ * {@link ADMIN_REASSIGN_DELEGATION_REASON} delegation step.
360
+ *
361
+ * Unlike the holder's transfer, the target is NOT run through the delegation
362
+ * rules (a rule for `toMemberId` does not apply). The initiator and submitter
363
+ * exclusions and the grade check of ORG_MANAGER_CHAIN nodes still do.
364
+ *
365
+ * A refused reassignment is reported as `REJECTED` with an error code. When
366
+ * `dryRun` is off, a refusal is thrown as a ConflictException whose message
367
+ * carries that code.
368
+ */
369
+ reassignTask(taskId: string, options: ReassignTaskOptions): Promise<TaskReassignmentResult>;
370
+ /**
371
+ * Runs {@link reassignTask} for every open task `fromMemberId` holds, each in
372
+ * its own transaction, and reports one result per task. A failing task does
373
+ * not stop the others: a refusal is a REJECTED result, and an unexpected
374
+ * error is reported as REJECTED with UNEXPECTED_ERROR for that task alone.
375
+ */
376
+ reassignMemberTasks(options: ReassignTaskOptions): Promise<readonly TaskReassignmentResult[]>;
377
+ /**
378
+ * The open tasks a member holds, for the administrator's reassignment screen.
379
+ * Same definition as the inbox, plus WAITING sequential seats, restricted to
380
+ * RUNNING instances.
381
+ */
382
+ listMemberOpenTasks(memberId: string): Promise<readonly MemberOpenTaskRecord[]>;
383
+ /**
384
+ * The open tasks `memberId` holds on RUNNING instances, with the instance
385
+ * each belongs to. The instance filter is applied here, not only in the query.
386
+ */
387
+ private readRunningMemberTasks;
388
+ private executeTaskReassignment;
389
+ /**
390
+ * Checks every rule of an administrator reassignment under the instance lock,
391
+ * against the rows as they are now. Writes nothing; a refusal throws
392
+ * {@link TaskReassignmentRejectedError}.
393
+ */
394
+ private planTaskReassignment;
395
+ private applyTaskReassignment;
396
+ /**
397
+ * A holder's transfer of their seat on a group stage (PARALLEL_ALL,
398
+ * PARALLEL_ANY, QUORUM). The stage stays open: the transferring seat moves
399
+ * to the target in place, the other seats keep their state, and the task
400
+ * keeps its id. Unlike transferTask, no replacement SINGLE task is created
401
+ * and the other voters are not superseded. The transferring member's
402
+ * decision and signature are kept on the task.
403
+ */
404
+ private transferGroupSeat;
405
+ /**
406
+ * Moves one open seat from `fromMemberId` to `toMemberId` on the same task.
407
+ *
408
+ * With a source candidate row: that row is marked TRANSFERRED, and the target
409
+ * takes a row with the same sequence, source type and original member. A
410
+ * WAITING seat stays WAITING; anything else becomes PENDING. A closed row the
411
+ * target already has (CANCELLED, SUPERSEDED, TRANSFERRED) is reused, because
412
+ * the database allows one row per (task, member).
413
+ *
414
+ * Without one (a direct assignee with no candidate row) only the assignee
415
+ * field moves. When the source is the assignee, the assignee moves too and
416
+ * the step is appended to the task's chain.
417
+ */
418
+ private replaceOpenSeat;
419
+ /**
420
+ * Notifications for a replaced seat: the member who gave it up is resolved as
421
+ * TRANSFERRED (their notifications on this task only), and the member who
422
+ * takes it is notified now if the seat is active. A WAITING seat notifies
423
+ * when its turn comes, through the normal sequential activation.
424
+ */
425
+ private notifySeatReplaced;
287
426
  /**
288
427
  * Resolves who gets the node's task. `null` means the node asked to be
289
428
  * skipped (`excludeInitiator.whenEmpty = SKIP_NODE`) because the initiator
@@ -304,8 +443,21 @@ export declare class WorkflowEngineService {
304
443
  * constraint.
305
444
  */
306
445
  private assertTransferTargetGrade;
446
+ /**
447
+ * The grade a transfer target must reach, or `null` when the target passes.
448
+ * Seniority is measured from the member being replaced: the first delegator
449
+ * on their chain, or that member themselves. Shared by the user transfer
450
+ * (which throws) and the administrator reassignment (which reports).
451
+ */
452
+ private readTransferTargetRequiredGrade;
307
453
  private resolveApproverResolver;
308
454
  private resolvePositionCandidates;
455
+ /**
456
+ * The members who hold the position today (organisation time zone) within
457
+ * their effective period. Primary memberships come first, then the most
458
+ * recently started. Empty when nobody holds it; never throws.
459
+ */
460
+ private readActivePositionMemberIds;
309
461
  private resolveInitiatorManagerCandidates;
310
462
  /**
311
463
  * Walks up the initiator's manager chain, nearest manager first, until a
@@ -321,6 +473,13 @@ export declare class WorkflowEngineService {
321
473
  * requested member is in the map, `null` when they hold no graded position.
322
474
  */
323
475
  private readMemberPositionLevels;
476
+ /**
477
+ * Every member a manager resolver's fallback yields. A `DIRECT` or `NONE`
478
+ * fallback yields at most one; a `POSITION` fallback yields the position's
479
+ * current holders, minus the initiator unless the fallback allows self
480
+ * approval. Failure throws, as the single-member path does.
481
+ */
482
+ private resolveFallbackAssignees;
324
483
  private resolveFallbackAssignee;
325
484
  private resolveManagerMemberIdsFromOrganization;
326
485
  private resolveManagerMemberIdsAtLevel;