@rytass/bpm-core-nestjs-module 0.20.1 → 0.21.1
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/CHANGELOG.md +81 -0
- package/README.md +109 -5
- package/package.json +2 -2
- package/src/lib/attachment/attachment.service.js +2 -10
- package/src/lib/attachment/attachment.service.js.map +1 -1
- package/src/lib/attachment/file-upload-value-ids.d.ts +8 -0
- package/src/lib/attachment/file-upload-value-ids.js +15 -0
- package/src/lib/attachment/file-upload-value-ids.js.map +1 -0
- package/src/lib/bpm/bpm-root-options.d.ts +18 -0
- package/src/lib/bpm/bpm-root-options.js.map +1 -1
- package/src/lib/bpm/bpm-root.module.d.ts +11 -0
- package/src/lib/bpm/bpm-root.module.js +9 -4
- package/src/lib/bpm/bpm-root.module.js.map +1 -1
- package/src/lib/form/form-data-issue.d.ts +34 -0
- package/src/lib/form/form-data-issue.js +59 -0
- package/src/lib/form/form-data-issue.js.map +1 -0
- package/src/lib/form/form-member-value.validator.d.ts +2 -2
- package/src/lib/form/form-member-value.validator.js +2 -3
- package/src/lib/form/form-member-value.validator.js.map +1 -1
- package/src/lib/form/form-org-unit-value.validator.d.ts +2 -2
- package/src/lib/form/form-org-unit-value.validator.js +4 -1
- package/src/lib/form/form-org-unit-value.validator.js.map +1 -1
- package/src/lib/form/form-schema.validator.js +40 -0
- package/src/lib/form/form-schema.validator.js.map +1 -1
- package/src/lib/form-data-source/form-data-source.module.d.ts +8 -0
- package/src/lib/form-data-source/form-data-source.module.js +1 -1
- package/src/lib/form-data-source/form-data-source.module.js.map +1 -1
- package/src/lib/form-data-source/form-data-source.service.js +1 -1
- package/src/lib/form-data-source/form-data-source.service.js.map +1 -1
- package/src/lib/migrations/0000000031000-approval-instance-form-data-gin.d.ts +29 -0
- package/src/lib/migrations/0000000031000-approval-instance-form-data-gin.js +44 -0
- package/src/lib/migrations/0000000031000-approval-instance-form-data-gin.js.map +1 -0
- package/src/lib/migrations/index.d.ts +1 -0
- package/src/lib/migrations/index.js +3 -0
- package/src/lib/migrations/index.js.map +1 -1
- package/src/lib/notification/notification.service.js +6 -0
- package/src/lib/notification/notification.service.js.map +1 -1
- package/src/lib/organization/organization-time-zone.d.ts +4 -2
- package/src/lib/organization/organization-time-zone.js +3 -6
- package/src/lib/organization/organization-time-zone.js.map +1 -1
- package/src/lib/template/filterable-field-guard.d.ts +49 -0
- package/src/lib/template/filterable-field-guard.js +141 -0
- package/src/lib/template/filterable-field-guard.js.map +1 -0
- package/src/lib/template/filterable-field-issue.object.d.ts +21 -0
- package/src/lib/template/filterable-field-issue.object.js +65 -0
- package/src/lib/template/filterable-field-issue.object.js.map +1 -0
- package/src/lib/template/filterable-field.queries.d.ts +20 -0
- package/src/lib/template/filterable-field.queries.js +80 -0
- package/src/lib/template/filterable-field.queries.js.map +1 -0
- package/src/lib/template/index.d.ts +1 -0
- package/src/lib/template/index.js +1 -0
- package/src/lib/template/index.js.map +1 -1
- package/src/lib/template/template.module.js +2 -0
- package/src/lib/template/template.module.js.map +1 -1
- package/src/lib/template/template.service.d.ts +39 -0
- package/src/lib/template/template.service.js +218 -49
- package/src/lib/template/template.service.js.map +1 -1
- package/src/lib/template/workflow-definition.validator.js +84 -2
- package/src/lib/template/workflow-definition.validator.js.map +1 -1
- package/src/lib/workflow-engine/approval-instance-field-filter.compiler.d.ts +49 -0
- package/src/lib/workflow-engine/approval-instance-field-filter.compiler.js +501 -0
- package/src/lib/workflow-engine/approval-instance-field-filter.compiler.js.map +1 -0
- package/src/lib/workflow-engine/approval-instance-filterable-field.policy.d.ts +15 -0
- package/src/lib/workflow-engine/approval-instance-filterable-field.policy.js +20 -0
- package/src/lib/workflow-engine/approval-instance-filterable-field.policy.js.map +1 -0
- package/src/lib/workflow-engine/dto/approval-instance-field-filter.input.d.ts +15 -0
- package/src/lib/workflow-engine/dto/approval-instance-field-filter.input.js +55 -0
- package/src/lib/workflow-engine/dto/approval-instance-field-filter.input.js.map +1 -0
- package/src/lib/workflow-engine/dto/approval-instance-list-args.d.ts +9 -0
- package/src/lib/workflow-engine/dto/approval-instance-list-args.js +24 -0
- package/src/lib/workflow-engine/dto/approval-instance-list-args.js.map +1 -0
- package/src/lib/workflow-engine/dto/approval-instance-sort.input.d.ts +10 -0
- package/src/lib/workflow-engine/dto/approval-instance-sort.input.js +32 -0
- package/src/lib/workflow-engine/dto/approval-instance-sort.input.js.map +1 -0
- package/src/lib/workflow-engine/index.d.ts +1 -0
- package/src/lib/workflow-engine/index.js +1 -0
- package/src/lib/workflow-engine/index.js.map +1 -1
- package/src/lib/workflow-engine/initiator-custom-fields-resolver.token.d.ts +108 -0
- package/src/lib/workflow-engine/initiator-custom-fields-resolver.token.js +9 -0
- package/src/lib/workflow-engine/initiator-custom-fields-resolver.token.js.map +1 -0
- package/src/lib/workflow-engine/workflow-engine.enums.d.ts +13 -0
- package/src/lib/workflow-engine/workflow-engine.enums.js +22 -1
- package/src/lib/workflow-engine/workflow-engine.enums.js.map +1 -1
- package/src/lib/workflow-engine/workflow-engine.module.d.ts +2 -0
- package/src/lib/workflow-engine/workflow-engine.module.js +9 -3
- package/src/lib/workflow-engine/workflow-engine.module.js.map +1 -1
- package/src/lib/workflow-engine/workflow-engine.queries.d.ts +6 -4
- package/src/lib/workflow-engine/workflow-engine.queries.js +35 -12
- package/src/lib/workflow-engine/workflow-engine.queries.js.map +1 -1
- package/src/lib/workflow-engine/workflow-engine.service.d.ts +166 -18
- package/src/lib/workflow-engine/workflow-engine.service.js +918 -139
- package/src/lib/workflow-engine/workflow-engine.service.js.map +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MemberMetadata } from '@rytass/bpm-core-shared';
|
|
1
|
+
import { MemberMetadata, type ApprovalInstanceFieldFilter, type ApprovalInstanceSort } from '@rytass/bpm-core-shared';
|
|
2
2
|
import { WorkflowWebhookDeliveryService } from '../workflow-webhook/workflow-webhook-delivery.service';
|
|
3
3
|
import { Repository } from 'typeorm';
|
|
4
4
|
import { AttachmentService } from '../attachment/attachment.service';
|
|
@@ -29,6 +29,7 @@ import { TaskCandidateEntity } from './task-candidate.entity';
|
|
|
29
29
|
import { TaskEntity } from './task.entity';
|
|
30
30
|
import { ApprovalInstanceListViewEnum, ApprovalInstanceStateEnum, MemberTaskRoleEnum, TaskCandidateStatusEnum, TaskReassignmentErrorCodeEnum, TaskReassignmentOutcomeEnum } from './workflow-engine.enums';
|
|
31
31
|
import { WorkflowDryRunResultObject } from './workflow-dry-run.object';
|
|
32
|
+
import { BPMInitiatorCustomFieldsResolver } from './initiator-custom-fields-resolver.token';
|
|
32
33
|
import { BPMWorkflowServiceTaskDispatcher } from './workflow-service-task-dispatcher.token';
|
|
33
34
|
import { WorkflowTokenEntity } from './workflow-token.entity';
|
|
34
35
|
import { BPMRootRuntimeOptions } from '../bpm/bpm-root-options';
|
|
@@ -140,10 +141,14 @@ export interface DecideTaskOptions {
|
|
|
140
141
|
*/
|
|
141
142
|
readonly transferReason?: string;
|
|
142
143
|
}
|
|
143
|
-
interface ListApprovalInstancesOptions {
|
|
144
|
+
export interface ListApprovalInstancesOptions {
|
|
145
|
+
/** ADR 25 §7: conditions on form fields. Needs `templateId` when not empty. */
|
|
146
|
+
readonly fieldFilters?: readonly ApprovalInstanceFieldFilter[];
|
|
144
147
|
readonly page?: number;
|
|
145
148
|
readonly pageSize?: number;
|
|
146
149
|
readonly searchText?: string;
|
|
150
|
+
/** ADR 25 §7.5: sort keys in order; the list always ends with `id`. */
|
|
151
|
+
readonly sort?: readonly ApprovalInstanceSort[];
|
|
147
152
|
readonly state?: readonly ApprovalInstanceStateEnum[];
|
|
148
153
|
readonly templateId?: string;
|
|
149
154
|
readonly view?: ApprovalInstanceListViewEnum;
|
|
@@ -174,8 +179,11 @@ export declare class WorkflowEngineService {
|
|
|
174
179
|
private readonly formDataSourceValueResolver?;
|
|
175
180
|
private readonly webhookDeliveryService?;
|
|
176
181
|
private readonly logger;
|
|
177
|
-
|
|
182
|
+
private readonly approvalInstanceFieldFilterCompiler;
|
|
183
|
+
private readonly approvalInstanceFilterableFieldPolicy;
|
|
184
|
+
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, injectedInitiatorCustomFieldsResolver?: BPMInitiatorCustomFieldsResolver);
|
|
178
185
|
private readonly serviceTaskDispatcher;
|
|
186
|
+
private readonly initiatorCustomFieldsResolver;
|
|
179
187
|
/** Webhooks each open engine transaction will send once it has committed. */
|
|
180
188
|
private readonly deferredWebhookDispatches;
|
|
181
189
|
private readonly organizationTimeZone;
|
|
@@ -310,8 +318,20 @@ export declare class WorkflowEngineService {
|
|
|
310
318
|
*/
|
|
311
319
|
private readDryRunMemberIds;
|
|
312
320
|
getApprovalInstance(id: string, scope?: WorkflowReadScope): Promise<ApprovalInstanceEntity>;
|
|
321
|
+
/**
|
|
322
|
+
* ADR 25 §6: a value written to a filterable field must fit its type, on
|
|
323
|
+
* every path that writes form data. The fields checked are the ones the
|
|
324
|
+
* template's *current* version marks filterable, not the instance's own
|
|
325
|
+
* snapshot: an older instance can be re-filled, resubmitted or written by a
|
|
326
|
+
* service task after a newer version enabled filtering on a field, and the
|
|
327
|
+
* enable check (ADR 25 §5.4) guarantees the type is the same in every version
|
|
328
|
+
* that holds instances, so the current definition judges the old value too.
|
|
329
|
+
*/
|
|
330
|
+
private assertCurrentFilterableFormDataValues;
|
|
331
|
+
/** The form schema of the template's current version, or `null` when there is none. */
|
|
332
|
+
private readCurrentFormSchema;
|
|
313
333
|
listApprovalInstances(scope?: WorkflowReadScope, options?: ListApprovalInstancesOptions): Promise<readonly ApprovalInstanceEntity[]>;
|
|
314
|
-
countApprovalInstances(scope?: WorkflowReadScope, options?: Omit<ListApprovalInstancesOptions, 'page' | 'pageSize'>): Promise<number>;
|
|
334
|
+
countApprovalInstances(scope?: WorkflowReadScope, options?: Omit<ListApprovalInstancesOptions, 'page' | 'pageSize' | 'sort'>): Promise<number>;
|
|
315
335
|
readApprovalInstancePageInfo(scope?: WorkflowReadScope, options?: ListApprovalInstancesOptions): Promise<{
|
|
316
336
|
readonly hasNextPage: boolean;
|
|
317
337
|
readonly hasPreviousPage: boolean;
|
|
@@ -320,7 +340,20 @@ export declare class WorkflowEngineService {
|
|
|
320
340
|
readonly totalCount: number;
|
|
321
341
|
readonly totalPages: number;
|
|
322
342
|
}>;
|
|
323
|
-
private
|
|
343
|
+
private createFilteredApprovalInstanceQuery;
|
|
344
|
+
/**
|
|
345
|
+
* The WHERE conditions and sort keys of the field filters and sort on the
|
|
346
|
+
* approval-instance list (ADR 25 §7). The template's current schema is read,
|
|
347
|
+
* and the static option lists of every version holding instances, only when
|
|
348
|
+
* a condition or a non-time sort key needs them.
|
|
349
|
+
*/
|
|
350
|
+
private compileApprovalInstanceFieldQuery;
|
|
351
|
+
/**
|
|
352
|
+
* Static option lists by field path, across the current schema and the form
|
|
353
|
+
* version of every template version that holds instances (ADR 25 §7.3): a
|
|
354
|
+
* CONTAINS on a retired option still matches its name.
|
|
355
|
+
*/
|
|
356
|
+
private readStaticOptionsByPathForTemplate;
|
|
324
357
|
private applyReadableInstanceFilter;
|
|
325
358
|
readWorkflowDashboardSummary(scope?: WorkflowReadScope, options?: WorkflowDashboardSummaryOptions): Promise<{
|
|
326
359
|
readonly activeInstanceCount: number;
|
|
@@ -331,7 +364,12 @@ export declare class WorkflowEngineService {
|
|
|
331
364
|
readonly totalInstanceCount: number;
|
|
332
365
|
}>;
|
|
333
366
|
private readDashboardOpenTasks;
|
|
334
|
-
|
|
367
|
+
/**
|
|
368
|
+
* The active templates `memberId` may start now. `authContext` is handed to
|
|
369
|
+
* the host's initiator `customFields` resolver; a host calling this without
|
|
370
|
+
* one gets a bare context for the member, as a submission does.
|
|
371
|
+
*/
|
|
372
|
+
listLaunchableApprovalTemplates(memberId: string, authContext?: BPMAuthContext): Promise<readonly ApprovalTemplateEntity[]>;
|
|
335
373
|
listWorkflowTokens(instanceId: string, scope?: WorkflowReadScope): Promise<readonly WorkflowTokenEntity[]>;
|
|
336
374
|
listTasks(instanceId: string, scope?: WorkflowReadScope): Promise<readonly TaskEntity[]>;
|
|
337
375
|
listInboxTasks(assigneeMemberId: string): Promise<readonly TaskEntity[]>;
|
|
@@ -363,6 +401,54 @@ export declare class WorkflowEngineService {
|
|
|
363
401
|
*/
|
|
364
402
|
private readTaskNodeSummaries;
|
|
365
403
|
private readDefaultInitiatorMetadataSnapshot;
|
|
404
|
+
/**
|
|
405
|
+
* The initiator snapshot the engine builds itself: what it knows of the
|
|
406
|
+
* initiator, with `customFields` filled by the host's resolver when there is
|
|
407
|
+
* one. Without a resolver this is exactly the default snapshot
|
|
408
|
+
* (`customFields` is `{}`). A submission (`submission` set) stores it and
|
|
409
|
+
* judges the initiator policy with it; the launchable template list
|
|
410
|
+
* (`submission: null`) only judges the policies with it, so both see the same
|
|
411
|
+
* `customFields` for the same member.
|
|
412
|
+
*
|
|
413
|
+
* Only `customFields` comes from the host. The other keys are the engine's
|
|
414
|
+
* and are written back after the resolver returns, so nothing it does can
|
|
415
|
+
* change who the initiator is. The resolver gets copies of the snapshot and
|
|
416
|
+
* of the form data for the same reason; `authContext` is the caller's own
|
|
417
|
+
* object, as every other host hook receives it.
|
|
418
|
+
*
|
|
419
|
+
* The two callers treat a resolver failure (an error, a bad value, the
|
|
420
|
+
* timeout) differently, on purpose:
|
|
421
|
+
*
|
|
422
|
+
* - A submission fails, and no case is created. Its snapshot is stored and
|
|
423
|
+
* routes the case from then on, so carrying on with `{}` would start a
|
|
424
|
+
* case on data the host never gave. It runs before the engine
|
|
425
|
+
* transaction, so a failure leaves nothing behind and a slow lookup holds
|
|
426
|
+
* no lock.
|
|
427
|
+
* - The list carries on with `customFields: {}` and logs a warning: one
|
|
428
|
+
* failing lookup must not take the whole list away. That fails closed: a
|
|
429
|
+
* policy that reads `initiator.customFields` then throws on the missing key
|
|
430
|
+
* and the list's per-template catch leaves that template out, while a
|
|
431
|
+
* template whose policy does not read it is listed as usual. Submitting is
|
|
432
|
+
* still judged against the resolver's real answer.
|
|
433
|
+
*/
|
|
434
|
+
private buildInitiatorMetadataSnapshot;
|
|
435
|
+
/**
|
|
436
|
+
* Calls the host's initiator `customFields` resolver within
|
|
437
|
+
* {@link INITIATOR_CUSTOM_FIELDS_RESOLVER_TIMEOUT_MS} and returns what it
|
|
438
|
+
* gave as the object the snapshot keeps.
|
|
439
|
+
*
|
|
440
|
+
* Every failure becomes an `InternalServerErrorException` with a message
|
|
441
|
+
* meant for the member, and the cause goes to the log only, so nothing of
|
|
442
|
+
* the host's lookup reaches the client: running out of time, an error that
|
|
443
|
+
* is not an `HttpException`, and a value that is not a plain JSON object. An
|
|
444
|
+
* `HttpException` the resolver throws is passed on as it is, because the
|
|
445
|
+
* host chose that answer for the member.
|
|
446
|
+
*
|
|
447
|
+
* A resolver that settles after the time has run out is not waited for; what
|
|
448
|
+
* it settles with is logged and dropped, so a late rejection is never left
|
|
449
|
+
* unhandled.
|
|
450
|
+
*/
|
|
451
|
+
private resolveInitiatorCustomFields;
|
|
366
452
|
listActivityLogs(instanceId: string, scope?: WorkflowReadScope): Promise<readonly ActivityLogEntity[]>;
|
|
367
453
|
private assertTaskReadable;
|
|
368
454
|
private isApprovalInstanceReadableByMember;
|
|
@@ -393,10 +479,11 @@ export declare class WorkflowEngineService {
|
|
|
393
479
|
* Re-resolves the delegation of a candidate whose turn has come. When the
|
|
394
480
|
* delegate already holds another candidate row on the task, the stored values
|
|
395
481
|
* are kept: (task_id, member_id) is unique, and that member signs from the
|
|
396
|
-
* row they already have. On a node that
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
482
|
+
* row they already have. On a node that keeps members out (the initiator and
|
|
483
|
+
* submitter, or the approvers of earlier stages) the stored values are kept
|
|
484
|
+
* as well when the new delegation path would run through one of them:
|
|
485
|
+
* creation already filtered such paths out, and a delegation added while the
|
|
486
|
+
* candidate waited must not bring them back.
|
|
400
487
|
*/
|
|
401
488
|
private resolveActivationDelegation;
|
|
402
489
|
private markTaskCandidateDecision;
|
|
@@ -499,12 +586,52 @@ export declare class WorkflowEngineService {
|
|
|
499
586
|
*/
|
|
500
587
|
private notifySeatReplaced;
|
|
501
588
|
/**
|
|
502
|
-
* Resolves who gets the node's task.
|
|
503
|
-
* skipped (`excludeInitiator.whenEmpty
|
|
504
|
-
*
|
|
505
|
-
* token instead.
|
|
589
|
+
* Resolves who gets the node's task. A {@link SkippedRuntimeTask} means the
|
|
590
|
+
* node asked to be skipped (`excludeInitiator.whenEmpty` or
|
|
591
|
+
* `excludeNodeActors.whenEmpty` = SKIP_NODE) because everyone left was kept
|
|
592
|
+
* out: the sole caller creates no task and advances the token instead.
|
|
593
|
+
*
|
|
594
|
+
* With both exclusions set the initiator rule runs first. When it alone
|
|
595
|
+
* leaves nobody, `excludeInitiator.whenEmpty` decides; when it leaves
|
|
596
|
+
* somebody and the earlier-stage rule then removes them all,
|
|
597
|
+
* `excludeNodeActors.whenEmpty` decides.
|
|
506
598
|
*/
|
|
507
599
|
private resolveRuntimeTaskCandidates;
|
|
600
|
+
/**
|
|
601
|
+
* Everyone `node` keeps out of its approvers, per rule: the initiator and
|
|
602
|
+
* the submitter for `excludeInitiator`, and everyone who actually approved
|
|
603
|
+
* one of the listed earlier stages for `excludeNodeActors`. Read through
|
|
604
|
+
* `manager` so an approval written earlier in this transaction counts.
|
|
605
|
+
*/
|
|
606
|
+
private readNodeExclusions;
|
|
607
|
+
/**
|
|
608
|
+
* The people who approved any of `nodeIds`, each listed node read on its own
|
|
609
|
+
* with the `NODE_ACTOR` rules ({@link readNodeActorMemberIds}) and the
|
|
610
|
+
* results combined. A source reads only the most recent of its listed nodes;
|
|
611
|
+
* an exclusion must cover every listed node, so it asks one node at a time.
|
|
612
|
+
*
|
|
613
|
+
* There is no round boundary here: a node's newest batch is what counts. The
|
|
614
|
+
* publish lint makes that the right batch, since every listed node runs and
|
|
615
|
+
* is signed by a person on every path to this node (a return to the start
|
|
616
|
+
* runs it again; a return to a stage below it leaves its earlier approval
|
|
617
|
+
* standing, and the exclusion with it).
|
|
618
|
+
*/
|
|
619
|
+
private readExcludedNodeActorMemberIds;
|
|
620
|
+
/**
|
|
621
|
+
* Whether `targetMemberId` may not take a seat on `node` under
|
|
622
|
+
* `excludeNodeActors`, checked the way task creation checks a candidate: the
|
|
623
|
+
* target is one of the excluded members, or one end of a delegation between
|
|
624
|
+
* the target and an excluded member is on the path. A delegation is read in
|
|
625
|
+
* both directions, since the target may be the delegate of an excluded
|
|
626
|
+
* member, or delegate an excluded member's seat onward.
|
|
627
|
+
*/
|
|
628
|
+
private isExcludedNodeActorTarget;
|
|
629
|
+
/**
|
|
630
|
+
* The principals the approvals stand for: a delegate who approved counts as
|
|
631
|
+
* the member who delegated to them, read from the candidate row each approval
|
|
632
|
+
* was signed on (see {@link readRuleDelegatorMemberIds}).
|
|
633
|
+
*/
|
|
634
|
+
private readApprovalPrincipalMemberIds;
|
|
508
635
|
private resolveInitiatorManagerReplacements;
|
|
509
636
|
private buildDelegationContext;
|
|
510
637
|
private delegateResolvedCandidates;
|
|
@@ -569,6 +696,12 @@ export declare class WorkflowEngineService {
|
|
|
569
696
|
* tasks and approvals the SLA timeout made do not count.
|
|
570
697
|
*/
|
|
571
698
|
private readNodeActorMemberIds;
|
|
699
|
+
/**
|
|
700
|
+
* The real approvals (earliest first) of the most recent batch among
|
|
701
|
+
* `nodeIds`: the rows {@link readNodeActorMemberIds} reads the approvers from.
|
|
702
|
+
* Kept as decisions so the exclusion can also reach each decision's task.
|
|
703
|
+
*/
|
|
704
|
+
private readNodeActorApprovals;
|
|
572
705
|
private resolvePositionCandidates;
|
|
573
706
|
/**
|
|
574
707
|
* The members who hold the position today (organisation time zone) within
|
|
@@ -578,12 +711,27 @@ export declare class WorkflowEngineService {
|
|
|
578
711
|
private readActivePositionMemberIds;
|
|
579
712
|
private resolveInitiatorManagerCandidates;
|
|
580
713
|
/**
|
|
581
|
-
* Walks up
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
*
|
|
714
|
+
* Walks up a manager chain, nearest manager first, until a manager whose
|
|
715
|
+
* position level reaches `minPositionLevel` is added. The chain starts at
|
|
716
|
+
* the initiator unless `startFrom` names someone else, and the start person
|
|
717
|
+
* is never on it: the walk begins at their direct manager. The list is
|
|
718
|
+
* returned nearest manager first. Members in `skippedMemberIds` are walked
|
|
719
|
+
* past without joining the chain or counting as the stopping point, and so
|
|
720
|
+
* are managers below `startPositionLevel`, until the first one at or above
|
|
721
|
+
* it starts the chain.
|
|
585
722
|
*/
|
|
586
723
|
private resolveOrgManagerChainCandidates;
|
|
724
|
+
/**
|
|
725
|
+
* Whose manager an `ORG_MANAGER_CHAIN` starts from. `memberId` is `null`
|
|
726
|
+
* when the start names nobody (an empty form field, an earlier stage nobody
|
|
727
|
+
* approved), with `missingReason` saying why; `description` is the lead-in
|
|
728
|
+
* of the "no manager reaches the level" reason, empty for the initiator so
|
|
729
|
+
* a chain without a start keeps today's wording.
|
|
730
|
+
*
|
|
731
|
+
* A start that picks more than one person is refused rather than guessed,
|
|
732
|
+
* the same as a manager rule that names several managers at one priority.
|
|
733
|
+
*/
|
|
734
|
+
private resolveOrgManagerChainStart;
|
|
587
735
|
/** Highest position level over the member's active memberships, or `null`. */
|
|
588
736
|
private readMemberPositionLevel;
|
|
589
737
|
/**
|