rez_core 5.0.89 → 5.0.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module/meta/repository/entity-master.repository.d.ts +3 -1
- package/dist/module/meta/repository/entity-master.repository.js +10 -6
- package/dist/module/meta/repository/entity-master.repository.js.map +1 -1
- package/dist/module/meta/service/entity-relation.service.d.ts +1 -3
- package/dist/module/meta/service/entity-relation.service.js +22 -31
- package/dist/module/meta/service/entity-relation.service.js.map +1 -1
- package/dist/module/module/service/module-access.service.d.ts +3 -1
- package/dist/module/module/service/module-access.service.js +11 -4
- package/dist/module/module/service/module-access.service.js.map +1 -1
- package/dist/module/notification/controller/notification.controller.d.ts +1 -1
- package/dist/module/notification/service/notification.service.d.ts +6 -4
- package/dist/module/notification/service/notification.service.js +22 -20
- package/dist/module/notification/service/notification.service.js.map +1 -1
- package/dist/module/workflow/controller/action.controller.d.ts +5 -2
- package/dist/module/workflow/controller/form-master.controller.d.ts +4 -1
- package/dist/module/workflow/repository/action-data.repository.d.ts +2 -3
- package/dist/module/workflow/repository/action-data.repository.js +29 -18
- package/dist/module/workflow/repository/action-data.repository.js.map +1 -1
- package/dist/module/workflow/repository/action.repository.d.ts +6 -7
- package/dist/module/workflow/repository/action.repository.js +53 -61
- package/dist/module/workflow/repository/action.repository.js.map +1 -1
- package/dist/module/workflow/repository/comm-template.repository.d.ts +2 -3
- package/dist/module/workflow/repository/comm-template.repository.js +15 -9
- package/dist/module/workflow/repository/comm-template.repository.js.map +1 -1
- package/dist/module/workflow/repository/form-master.repository.d.ts +7 -4
- package/dist/module/workflow/repository/form-master.repository.js +14 -11
- package/dist/module/workflow/repository/form-master.repository.js.map +1 -1
- package/dist/module/workflow/repository/stage-group.repository.d.ts +4 -5
- package/dist/module/workflow/repository/stage-group.repository.js +34 -35
- package/dist/module/workflow/repository/stage-group.repository.js.map +1 -1
- package/dist/module/workflow/repository/stage-movement.repository.d.ts +6 -3
- package/dist/module/workflow/repository/stage-movement.repository.js +30 -17
- package/dist/module/workflow/repository/stage-movement.repository.js.map +1 -1
- package/dist/module/workflow/service/action.service.d.ts +13 -5
- package/dist/module/workflow/service/action.service.js +71 -20
- package/dist/module/workflow/service/action.service.js.map +1 -1
- package/dist/module/workflow/service/entity-modification.service.d.ts +3 -3
- package/dist/module/workflow/service/entity-modification.service.js +4 -4
- package/dist/module/workflow/service/entity-modification.service.js.map +1 -1
- package/dist/module/workflow/service/form-master.service.d.ts +4 -1
- package/dist/module/workflow/service/stage-group.service.d.ts +2 -7
- package/dist/module/workflow/service/stage-group.service.js +19 -17
- package/dist/module/workflow/service/stage-group.service.js.map +1 -1
- package/dist/module/workflow/service/stage.service.d.ts +2 -3
- package/dist/module/workflow/service/stage.service.js +24 -11
- package/dist/module/workflow/service/stage.service.js.map +1 -1
- package/dist/module/workflow/service/task.service.d.ts +2 -5
- package/dist/module/workflow/service/task.service.js +44 -45
- package/dist/module/workflow/service/task.service.js.map +1 -1
- package/dist/module/workflow/service/workflow-list-master.service.d.ts +1 -3
- package/dist/module/workflow/service/workflow-list-master.service.js +38 -26
- package/dist/module/workflow/service/workflow-list-master.service.js.map +1 -1
- package/dist/module/workflow/service/workflow-meta.service.d.ts +6 -3
- package/dist/module/workflow/service/workflow-meta.service.js +78 -50
- package/dist/module/workflow/service/workflow-meta.service.js.map +1 -1
- package/dist/module/workflow/service/workflow.service.d.ts +1 -3
- package/dist/module/workflow/service/workflow.service.js +10 -6
- package/dist/module/workflow/service/workflow.service.js.map +1 -1
- package/dist/module/workflow-schedule/processors/schedule.processor.d.ts +4 -2
- package/dist/module/workflow-schedule/processors/schedule.processor.js +51 -38
- package/dist/module/workflow-schedule/processors/schedule.processor.js.map +1 -1
- package/dist/module/workflow-schedule/service/workflow-schedule.service.d.ts +2 -3
- package/dist/module/workflow-schedule/service/workflow-schedule.service.js +15 -14
- package/dist/module/workflow-schedule/service/workflow-schedule.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/meta/repository/entity-master.repository.ts +9 -8
- package/src/module/meta/service/entity-relation.service.ts +23 -41
- package/src/module/module/service/module-access.service.ts +8 -4
- package/src/module/notification/service/notification.service.ts +24 -20
- package/src/module/workflow/repository/action-data.repository.ts +33 -28
- package/src/module/workflow/repository/action.repository.ts +74 -77
- package/src/module/workflow/repository/comm-template.repository.ts +19 -13
- package/src/module/workflow/repository/form-master.repository.ts +15 -24
- package/src/module/workflow/repository/stage-group.repository.ts +41 -52
- package/src/module/workflow/repository/stage-movement.repository.ts +35 -32
- package/src/module/workflow/service/action.service.ts +70 -43
- package/src/module/workflow/service/entity-modification.service.ts +3 -3
- package/src/module/workflow/service/stage-group.service.ts +21 -19
- package/src/module/workflow/service/stage.service.ts +36 -28
- package/src/module/workflow/service/task.service.ts +53 -56
- package/src/module/workflow/service/workflow-list-master.service.ts +42 -34
- package/src/module/workflow/service/workflow-meta.service.ts +81 -77
- package/src/module/workflow/service/workflow.service.ts +9 -5
- package/src/module/workflow-schedule/processors/schedule.processor.ts +133 -97
- package/src/module/workflow-schedule/service/workflow-schedule.service.ts +24 -26
|
@@ -20,7 +20,6 @@ export class WorkflowService extends EntityServiceImpl {
|
|
|
20
20
|
private readonly listMasterService: ListMasterService,
|
|
21
21
|
@Inject('StageGroupService')
|
|
22
22
|
private readonly stateGroupService: StageGroupService,
|
|
23
|
-
private readonly stageGroupRepository: StageGroupRepository,
|
|
24
23
|
) {
|
|
25
24
|
super();
|
|
26
25
|
}
|
|
@@ -149,10 +148,15 @@ export class WorkflowService extends EntityServiceImpl {
|
|
|
149
148
|
);
|
|
150
149
|
}
|
|
151
150
|
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
const stageGroupRepo = this.reflectionHelper.getRepoService('StageGroup');
|
|
152
|
+
|
|
153
|
+
const getAllStageGroup = await stageGroupRepo.find({
|
|
154
|
+
where: {
|
|
155
|
+
workflow_id: id,
|
|
156
|
+
level_id: loggedInUser.level_id,
|
|
157
|
+
level_type:loggedInUser.level_type
|
|
158
|
+
}
|
|
159
|
+
});
|
|
156
160
|
|
|
157
161
|
if (getAllStageGroup.length > 0) {
|
|
158
162
|
for (const stageGroup of getAllStageGroup) {
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Process,
|
|
3
|
+
Processor,
|
|
4
|
+
OnQueueActive,
|
|
5
|
+
OnQueueCompleted,
|
|
6
|
+
OnQueueFailed,
|
|
7
|
+
} from '@nestjs/bull';
|
|
8
|
+
import { Logger, Inject } from '@nestjs/common';
|
|
3
9
|
import { Job } from 'bull';
|
|
4
10
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
5
11
|
import { Repository, DataSource } from 'typeorm';
|
|
@@ -14,13 +20,13 @@ import {
|
|
|
14
20
|
EXECUTION_STATUS_FAILED,
|
|
15
21
|
EXECUTION_STATUS_PARTIAL,
|
|
16
22
|
DEFAULT_BATCH_SIZE,
|
|
17
|
-
ACTION_TYPE_SEND_EMAIL,
|
|
18
|
-
ACTION_TYPE_UPDATE_RECORDS,
|
|
19
|
-
ACTION_TYPE_CREATE_TASK,
|
|
20
|
-
ACTION_TYPE_SEND_NOTIFICATION,
|
|
21
23
|
} from '../constants/schedule.constants';
|
|
22
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
ScheduleJobData,
|
|
26
|
+
BatchProcessingResult,
|
|
27
|
+
} from '../interfaces/schedule-job-data.interface';
|
|
23
28
|
import { ScheduleHandlerService } from 'src/module/workflow-automation/service/schedule-handler.service';
|
|
29
|
+
import { ReflectionHelper } from 'src/utils/service/reflection-helper.service';
|
|
24
30
|
|
|
25
31
|
/**
|
|
26
32
|
* Schedule Processor
|
|
@@ -35,17 +41,19 @@ export class ScheduleProcessor {
|
|
|
35
41
|
private readonly scheduledWorkflowRepository: Repository<ScheduledWorkflow>,
|
|
36
42
|
@InjectRepository(WorkflowExecutionLog)
|
|
37
43
|
private readonly executionLogRepository: Repository<WorkflowExecutionLog>,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
@Inject('ScheduleHandlerService')
|
|
45
|
+
private readonly scheduleHandlerService: ScheduleHandlerService,
|
|
46
|
+
private readonly reflectionHelper: ReflectionHelper,
|
|
47
|
+
private readonly dataSource: DataSource
|
|
41
48
|
) {}
|
|
42
49
|
|
|
43
50
|
/**
|
|
44
51
|
* Main job processor for scheduled workflow execution
|
|
45
52
|
*/
|
|
46
53
|
@Process(EXECUTE_SCHEDULED_WORKFLOW_JOB)
|
|
47
|
-
|
|
48
|
-
const { scheduleId, workflowId, organizationId, triggeredBy, createdBy } =
|
|
54
|
+
async handleScheduledWorkflowExecution(job: Job<ScheduleJobData>) {
|
|
55
|
+
const { scheduleId, workflowId, organizationId, triggeredBy, createdBy } =
|
|
56
|
+
job.data;
|
|
49
57
|
|
|
50
58
|
this.logger.log(
|
|
51
59
|
`🚀 [handleScheduledWorkflowExecution] Invoked for scheduleId=${scheduleId}, workflowId=${workflowId}`,
|
|
@@ -74,7 +82,9 @@ export class ScheduleProcessor {
|
|
|
74
82
|
executionLog.started_at = new Date();
|
|
75
83
|
await this.executionLogRepository.save(executionLog);
|
|
76
84
|
|
|
77
|
-
this.logger.log(
|
|
85
|
+
this.logger.log(
|
|
86
|
+
`🏃 Workflow execution started for scheduleId=${scheduleId}`,
|
|
87
|
+
);
|
|
78
88
|
|
|
79
89
|
// Get scheduled workflow details
|
|
80
90
|
const schedule = await this.scheduledWorkflowRepository.findOne({
|
|
@@ -85,7 +95,9 @@ export class ScheduleProcessor {
|
|
|
85
95
|
throw new Error(`Scheduled workflow not found: ${scheduleId}`);
|
|
86
96
|
}
|
|
87
97
|
|
|
88
|
-
this.logger.debug(
|
|
98
|
+
this.logger.debug(
|
|
99
|
+
`📋 Loaded schedule from DB: ${JSON.stringify(schedule)}`,
|
|
100
|
+
);
|
|
89
101
|
|
|
90
102
|
// Execute workflow actions
|
|
91
103
|
this.logger.log(`⚙️ Executing workflow actions...`);
|
|
@@ -98,10 +110,11 @@ export class ScheduleProcessor {
|
|
|
98
110
|
result.failedRecords > 0 && result.successfulRecords > 0
|
|
99
111
|
? EXECUTION_STATUS_PARTIAL
|
|
100
112
|
: result.failedRecords > 0
|
|
101
|
-
|
|
102
|
-
|
|
113
|
+
? EXECUTION_STATUS_FAILED
|
|
114
|
+
: EXECUTION_STATUS_COMPLETED;
|
|
103
115
|
executionLog.completed_at = completedAt;
|
|
104
|
-
executionLog.duration_ms =
|
|
116
|
+
executionLog.duration_ms =
|
|
117
|
+
completedAt.getTime() - executionLog.started_at.getTime();
|
|
105
118
|
executionLog.total_records = result.totalRecords;
|
|
106
119
|
executionLog.successful_records = result.successfulRecords;
|
|
107
120
|
executionLog.failed_records = result.failedRecords;
|
|
@@ -136,7 +149,8 @@ export class ScheduleProcessor {
|
|
|
136
149
|
executionLog.execution_status = EXECUTION_STATUS_FAILED;
|
|
137
150
|
executionLog.completed_at = new Date();
|
|
138
151
|
executionLog.duration_ms = executionLog.started_at
|
|
139
|
-
? executionLog.completed_at.getTime() -
|
|
152
|
+
? executionLog.completed_at.getTime() -
|
|
153
|
+
executionLog.started_at.getTime()
|
|
140
154
|
: 0;
|
|
141
155
|
executionLog.error_message = error.message;
|
|
142
156
|
executionLog.error_stack = error.stack;
|
|
@@ -162,11 +176,11 @@ export class ScheduleProcessor {
|
|
|
162
176
|
errors: [],
|
|
163
177
|
};
|
|
164
178
|
|
|
165
|
-
const resultData: any =
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
179
|
+
const resultData: any =
|
|
180
|
+
await this.scheduleHandlerService.handleScheduledWorkflow(
|
|
181
|
+
jobData.workflowId,
|
|
182
|
+
jobData,
|
|
183
|
+
);
|
|
170
184
|
|
|
171
185
|
if (!schedule.actions || schedule.actions.length === 0) {
|
|
172
186
|
this.logger.warn(`No actions defined for schedule: ${schedule.id}`);
|
|
@@ -199,42 +213,44 @@ export class ScheduleProcessor {
|
|
|
199
213
|
/**
|
|
200
214
|
* Execute a single workflow action
|
|
201
215
|
*/
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
try {
|
|
206
|
-
// We’ll assume jobData contains workflowId and user info
|
|
207
|
-
const { workflowId, loggedInUser } = jobData;
|
|
216
|
+
private async executeAction(action: any, jobData: ScheduleJobData) {
|
|
217
|
+
this.logger.log(`🚀 Executing scheduled action: ${action.actionType}`);
|
|
208
218
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
workflowId,
|
|
212
|
-
|
|
213
|
-
|
|
219
|
+
try {
|
|
220
|
+
// We’ll assume jobData contains workflowId and user info
|
|
221
|
+
const { workflowId, loggedInUser } = jobData;
|
|
222
|
+
|
|
223
|
+
// 🧠 Call your handler that performs filtering and workflow execution
|
|
224
|
+
const result: any =
|
|
225
|
+
await this.scheduleHandlerService.handleScheduledWorkflow(
|
|
226
|
+
workflowId,
|
|
227
|
+
loggedInUser,
|
|
228
|
+
);
|
|
214
229
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
error
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
230
|
+
this.logger.log(
|
|
231
|
+
`✅ Scheduled workflow ${workflowId} executed successfully`,
|
|
232
|
+
);
|
|
233
|
+
return {
|
|
234
|
+
totalRecords: result?.length || 0,
|
|
235
|
+
processedRecords: result?.length || 0,
|
|
236
|
+
successfulRecords: result?.length || 0,
|
|
237
|
+
failedRecords: 0,
|
|
238
|
+
errors: [],
|
|
239
|
+
};
|
|
240
|
+
} catch (error) {
|
|
241
|
+
this.logger.error(
|
|
242
|
+
`🔥 Error executing scheduled workflow action: ${error.message}`,
|
|
243
|
+
error.stack,
|
|
244
|
+
);
|
|
245
|
+
return {
|
|
246
|
+
totalRecords: 0,
|
|
247
|
+
processedRecords: 0,
|
|
248
|
+
successfulRecords: 0,
|
|
249
|
+
failedRecords: 1,
|
|
250
|
+
errors: [{ error: error.message }],
|
|
251
|
+
};
|
|
252
|
+
}
|
|
235
253
|
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
254
|
|
|
239
255
|
/**
|
|
240
256
|
* Execute send email action
|
|
@@ -337,7 +353,9 @@ export class ScheduleProcessor {
|
|
|
337
353
|
const values = Object.values(updateFields);
|
|
338
354
|
|
|
339
355
|
if (updateValues.length > 0) {
|
|
340
|
-
const tableName = this.getTableNameForEntityType(
|
|
356
|
+
const tableName = this.getTableNameForEntityType(
|
|
357
|
+
action.targetEntityType,
|
|
358
|
+
);
|
|
341
359
|
await queryRunner.query(
|
|
342
360
|
`UPDATE ${tableName} SET ${updateValues.join(', ')} WHERE id = ?`,
|
|
343
361
|
[...values, record.id],
|
|
@@ -391,34 +409,38 @@ export class ScheduleProcessor {
|
|
|
391
409
|
|
|
392
410
|
result.totalRecords = records.length;
|
|
393
411
|
|
|
412
|
+
// Task repo (cr_wf_task)
|
|
413
|
+
const taskRepo = this.reflectionHelper.getRepoService('TaskDataEntity');
|
|
414
|
+
|
|
394
415
|
// Process in batches
|
|
395
416
|
const batches = this.chunkArray(records, DEFAULT_BATCH_SIZE);
|
|
396
417
|
|
|
397
418
|
for (const batch of batches) {
|
|
398
419
|
for (const record of batch) {
|
|
399
420
|
try {
|
|
400
|
-
//
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
);
|
|
421
|
+
// Build task object
|
|
422
|
+
const task = {
|
|
423
|
+
name: action.actionConfig.taskName || 'Scheduled Task',
|
|
424
|
+
description: action.actionConfig.taskDescription || '',
|
|
425
|
+
status: 'PENDING',
|
|
426
|
+
mapped_entity_id: record.id,
|
|
427
|
+
mapped_entity_type: action.targetEntityType,
|
|
428
|
+
organization_id: jobData.organizationId,
|
|
429
|
+
enterprise_id: jobData.enterpriseId,
|
|
430
|
+
created_by: jobData.createdBy,
|
|
431
|
+
created_date: new Date(), // NOW()
|
|
432
|
+
entity_type: 'WFTK',
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
// Insert using TypeORM repository
|
|
436
|
+
await taskRepo.insert(task);
|
|
416
437
|
|
|
417
438
|
result.processedRecords += 1;
|
|
418
439
|
result.successfulRecords += 1;
|
|
419
440
|
} catch (error) {
|
|
420
441
|
result.processedRecords += 1;
|
|
421
442
|
result.failedRecords += 1;
|
|
443
|
+
|
|
422
444
|
result.errors.push({
|
|
423
445
|
recordId: record.id,
|
|
424
446
|
error: error.message,
|
|
@@ -458,32 +480,41 @@ export class ScheduleProcessor {
|
|
|
458
480
|
|
|
459
481
|
result.totalRecords = records.length;
|
|
460
482
|
|
|
483
|
+
// Prepare repo
|
|
484
|
+
const notificationRepo = this.reflectionHelper.getRepoService(
|
|
485
|
+
'NotificationData', // cr_notification repo
|
|
486
|
+
);
|
|
487
|
+
|
|
461
488
|
// Process in batches
|
|
462
489
|
const batches = this.chunkArray(records, DEFAULT_BATCH_SIZE);
|
|
463
490
|
|
|
464
491
|
for (const batch of batches) {
|
|
465
492
|
for (const record of batch) {
|
|
466
493
|
try {
|
|
467
|
-
//
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
[
|
|
473
|
-
record.user_id || jobData.createdBy,
|
|
474
|
-
action.actionConfig.eventType || 'WORKFLOW_SCHEDULED',
|
|
494
|
+
// Build notification object
|
|
495
|
+
const notification = {
|
|
496
|
+
user_id: record.user_id || jobData.createdBy,
|
|
497
|
+
event_type: action.actionConfig.eventType || 'WORKFLOW_SCHEDULED',
|
|
498
|
+
message:
|
|
475
499
|
action.actionConfig.message || 'Scheduled workflow executed',
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
500
|
+
mapped_entity_id: record.id,
|
|
501
|
+
mapped_entity_type: action.targetEntityType,
|
|
502
|
+
is_read: 0,
|
|
503
|
+
organization_id: jobData.organizationId,
|
|
504
|
+
created_date: new Date(), // NOW()
|
|
505
|
+
entity_type: 'NOTF',
|
|
506
|
+
status: 'ACTIVE',
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
// Insert using TypeORM (replaces raw SQL)
|
|
510
|
+
await notificationRepo.insert(notification);
|
|
481
511
|
|
|
482
512
|
result.processedRecords += 1;
|
|
483
513
|
result.successfulRecords += 1;
|
|
484
514
|
} catch (error) {
|
|
485
515
|
result.processedRecords += 1;
|
|
486
516
|
result.failedRecords += 1;
|
|
517
|
+
|
|
487
518
|
result.errors.push({
|
|
488
519
|
recordId: record.id,
|
|
489
520
|
error: error.message,
|
|
@@ -506,22 +537,27 @@ export class ScheduleProcessor {
|
|
|
506
537
|
filterCriteria: any,
|
|
507
538
|
jobData: ScheduleJobData,
|
|
508
539
|
): Promise<any[]> {
|
|
509
|
-
|
|
540
|
+
// Get repository dynamically based on entityType
|
|
541
|
+
const repo = this.reflectionHelper.getRepoService(entityType);
|
|
510
542
|
|
|
511
|
-
//
|
|
512
|
-
|
|
513
|
-
const params: any[] = [];
|
|
543
|
+
// Start QueryBuilder
|
|
544
|
+
const qb = repo.createQueryBuilder('e');
|
|
514
545
|
|
|
546
|
+
// Mandatory organization filter
|
|
547
|
+
qb.where('e.organization_id = :orgId', {
|
|
548
|
+
orgId: jobData.organizationId,
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
// Apply additional filters
|
|
515
552
|
if (filterCriteria && Object.keys(filterCriteria).length > 0) {
|
|
516
|
-
Object.keys(filterCriteria)
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
553
|
+
for (const key of Object.keys(filterCriteria)) {
|
|
554
|
+
qb.andWhere(`e.${key} = :${key}`, {
|
|
555
|
+
[key]: filterCriteria[key],
|
|
556
|
+
});
|
|
557
|
+
}
|
|
520
558
|
}
|
|
521
559
|
|
|
522
|
-
const
|
|
523
|
-
const records = await this.dataSource.query(query, params);
|
|
524
|
-
|
|
560
|
+
const records = await qb.getMany();
|
|
525
561
|
return records;
|
|
526
562
|
}
|
|
527
563
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Injectable, Logger, NotFoundException
|
|
1
|
+
import { BadRequestException, Injectable, Logger, NotFoundException } from '@nestjs/common';
|
|
2
2
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
3
|
-
import {
|
|
3
|
+
import { Between, In, Repository } from 'typeorm';
|
|
4
4
|
import { InjectQueue } from '@nestjs/bull';
|
|
5
5
|
import { Queue } from 'bull';
|
|
6
6
|
import * as cronParser from 'cron-parser';
|
|
@@ -12,15 +12,15 @@ import { UpdateScheduleDto } from '../dto/update-schedule.dto';
|
|
|
12
12
|
import { GetExecutionLogsDto } from '../dto/get-execution-logs.dto';
|
|
13
13
|
import { UserData } from '../../user/entity/user.entity';
|
|
14
14
|
import {
|
|
15
|
-
|
|
16
|
-
EXECUTE_SCHEDULED_WORKFLOW_JOB,
|
|
17
|
-
SCHEDULE_STATUS_ACTIVE,
|
|
18
|
-
SCHEDULE_STATUS_PAUSED,
|
|
19
|
-
SCHEDULE_STATUS_INACTIVE,
|
|
15
|
+
DEFAULT_BACKOFF_MULTIPLIER,
|
|
20
16
|
DEFAULT_MAX_RETRIES,
|
|
21
17
|
DEFAULT_RETRY_DELAY,
|
|
22
|
-
DEFAULT_BACKOFF_MULTIPLIER,
|
|
23
18
|
DEFAULT_TIMEZONE,
|
|
19
|
+
EXECUTE_SCHEDULED_WORKFLOW_JOB,
|
|
20
|
+
SCHEDULE_STATUS_ACTIVE,
|
|
21
|
+
SCHEDULE_STATUS_INACTIVE,
|
|
22
|
+
SCHEDULE_STATUS_PAUSED,
|
|
23
|
+
WORKFLOW_SCHEDULE_QUEUE,
|
|
24
24
|
} from '../constants/schedule.constants';
|
|
25
25
|
import { ScheduleJobData } from '../interfaces/schedule-job-data.interface';
|
|
26
26
|
|
|
@@ -37,10 +37,10 @@ export class WorkflowScheduleService {
|
|
|
37
37
|
private readonly scheduledWorkflowRepository: Repository<ScheduledWorkflow>,
|
|
38
38
|
@InjectRepository(WorkflowExecutionLog)
|
|
39
39
|
private readonly executionLogRepository: Repository<WorkflowExecutionLog>,
|
|
40
|
-
@InjectQueue(WORKFLOW_SCHEDULE_QUEUE)
|
|
40
|
+
@InjectQueue(WORKFLOW_SCHEDULE_QUEUE)
|
|
41
41
|
private readonly scheduleQueue: Queue<ScheduleJobData>,
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
) {
|
|
43
|
+
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
46
|
* 1. Create a new scheduled workflow
|
|
@@ -484,21 +484,19 @@ export class WorkflowScheduleService {
|
|
|
484
484
|
async getExecutionStats(scheduleId: number, loggedInUser: UserData): Promise<any> {
|
|
485
485
|
const schedule = await this.getScheduleById(scheduleId, loggedInUser);
|
|
486
486
|
|
|
487
|
-
const
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
SUM(CASE WHEN execution_status = '
|
|
492
|
-
SUM(CASE WHEN execution_status = '
|
|
493
|
-
SUM(CASE WHEN execution_status = '
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
const result = stats[0];
|
|
487
|
+
const result = await this.executionLogRepository
|
|
488
|
+
.createQueryBuilder('log')
|
|
489
|
+
.select([
|
|
490
|
+
'COUNT(*) AS total_executions',
|
|
491
|
+
'SUM(CASE WHEN log.execution_status = \'COMPLETED\' THEN 1 ELSE 0 END) AS successful_executions',
|
|
492
|
+
'SUM(CASE WHEN log.execution_status = \'FAILED\' THEN 1 ELSE 0 END) AS failed_executions',
|
|
493
|
+
'SUM(CASE WHEN log.execution_status = \'PENDING\' THEN 1 ELSE 0 END) AS pending_executions',
|
|
494
|
+
'SUM(CASE WHEN log.execution_status = \'RUNNING\' THEN 1 ELSE 0 END) AS running_executions',
|
|
495
|
+
'AVG(log.duration_ms) AS average_duration_ms',
|
|
496
|
+
'SUM(log.total_records) AS total_records_processed',
|
|
497
|
+
])
|
|
498
|
+
.where('log.schedule_id = :scheduleId', { scheduleId })
|
|
499
|
+
.getRawOne();
|
|
502
500
|
const successRate =
|
|
503
501
|
result.total_executions > 0
|
|
504
502
|
? (result.successful_executions / result.total_executions) * 100
|