rez_core 3.1.83 → 3.1.84
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/filter/service/filter.service.d.ts +3 -1
- package/dist/module/filter/service/filter.service.js +25 -4
- package/dist/module/filter/service/filter.service.js.map +1 -1
- package/dist/module/workflow/service/action-template-mapping.service.js +1 -1
- package/dist/module/workflow-automation/service/workflow-automation-engine.service.d.ts +3 -1
- package/dist/module/workflow-automation/service/workflow-automation-engine.service.js +22 -13
- package/dist/module/workflow-automation/service/workflow-automation-engine.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/filter/service/filter.service.ts +140 -6
- package/src/module/workflow/service/action-template-mapping.service.ts +1 -1
- package/src/module/workflow-automation/service/workflow-automation-engine.service.ts +75 -19
- package/.vscode/extensions.json +0 -5
package/package.json
CHANGED
|
@@ -10,6 +10,7 @@ import { SavedFilterService } from './saved-filter.service';
|
|
|
10
10
|
import * as moment from 'moment';
|
|
11
11
|
import { EntityRelationService } from 'src/module/meta/service/entity-relation.service';
|
|
12
12
|
import { ResolverService } from 'src/module/meta/service/resolver.service';
|
|
13
|
+
import { LoggingService } from 'src/utils/service/loggingUtil.service';
|
|
13
14
|
|
|
14
15
|
@Injectable()
|
|
15
16
|
export class FilterService {
|
|
@@ -22,6 +23,7 @@ export class FilterService {
|
|
|
22
23
|
@Inject('EntityRelationService')
|
|
23
24
|
private readonly entityRelationService: EntityRelationService,
|
|
24
25
|
private readonly resolverService: ResolverService,
|
|
26
|
+
@Inject() protected readonly loggingService: LoggingService,
|
|
25
27
|
) {}
|
|
26
28
|
private readonly skipAppCodeFilterEntities = ['ORGP'];
|
|
27
29
|
private readonly skipOrgFilterEntities = ['ORGP'];
|
|
@@ -80,9 +82,16 @@ export class FilterService {
|
|
|
80
82
|
quickFilter = [],
|
|
81
83
|
savedFilterCode,
|
|
82
84
|
attributeFilter = [],
|
|
85
|
+
loggedInUser,
|
|
83
86
|
} = dto;
|
|
84
87
|
|
|
85
|
-
|
|
88
|
+
await this.loggingService.log(
|
|
89
|
+
'info',
|
|
90
|
+
'FilterService',
|
|
91
|
+
'applyFilterWrapper',
|
|
92
|
+
'Started applyFilterWrapper',
|
|
93
|
+
[dto],
|
|
94
|
+
);
|
|
86
95
|
|
|
87
96
|
// 🔹 Step 1: Collect all filters (from body + savedFilter)
|
|
88
97
|
const savedFilters = await this.getSavedFilters(
|
|
@@ -94,6 +103,14 @@ export class FilterService {
|
|
|
94
103
|
...savedFilters,
|
|
95
104
|
].filter((f) => f.filter_value !== '');
|
|
96
105
|
|
|
106
|
+
await this.loggingService.log(
|
|
107
|
+
'debug',
|
|
108
|
+
'FilterService',
|
|
109
|
+
'applyFilterWrapper',
|
|
110
|
+
'Collected all filters',
|
|
111
|
+
[allFilters],
|
|
112
|
+
);
|
|
113
|
+
|
|
97
114
|
// 🔹 Step 2: Group filters by filter_entity_type
|
|
98
115
|
const grouped = allFilters.reduce(
|
|
99
116
|
(acc, f) => {
|
|
@@ -104,6 +121,14 @@ export class FilterService {
|
|
|
104
121
|
{} as Record<string, any[]>,
|
|
105
122
|
);
|
|
106
123
|
|
|
124
|
+
await this.loggingService.log(
|
|
125
|
+
'debug',
|
|
126
|
+
'FilterService',
|
|
127
|
+
'applyFilterWrapper',
|
|
128
|
+
'Grouped filters by entity type',
|
|
129
|
+
[grouped],
|
|
130
|
+
);
|
|
131
|
+
|
|
107
132
|
// 🔹 Step 3: Handle sub-entities first
|
|
108
133
|
let intersectionIds: number[] | null = null;
|
|
109
134
|
for (const [subEntityType, filters] of Object.entries(grouped)) {
|
|
@@ -121,10 +146,23 @@ export class FilterService {
|
|
|
121
146
|
|
|
122
147
|
const subResult = await this.applyFilter(subDto);
|
|
123
148
|
|
|
124
|
-
// ✅ new way (fetch source entity IDs via relation mapping)
|
|
125
149
|
const subEntityIds = subResult.data.entity_list.map((row) => row.id);
|
|
126
150
|
|
|
151
|
+
await this.loggingService.log(
|
|
152
|
+
'debug',
|
|
153
|
+
'FilterService',
|
|
154
|
+
'applyFilterWrapper',
|
|
155
|
+
`Sub-entity ${subEntityType} returned IDs`,
|
|
156
|
+
[subEntityIds],
|
|
157
|
+
);
|
|
158
|
+
|
|
127
159
|
if (!subEntityIds.length) {
|
|
160
|
+
await this.loggingService.log(
|
|
161
|
+
'info',
|
|
162
|
+
'FilterService',
|
|
163
|
+
'applyFilterWrapper',
|
|
164
|
+
`No records found for sub-entity ${subEntityType}, returning empty result`,
|
|
165
|
+
);
|
|
128
166
|
return {
|
|
129
167
|
success: true,
|
|
130
168
|
data: { entity_tabs: [], entity_list: [], pagination: {} },
|
|
@@ -138,14 +176,26 @@ export class FilterService {
|
|
|
138
176
|
dto.loggedInUser.organization_id,
|
|
139
177
|
);
|
|
140
178
|
|
|
141
|
-
// keep intersection
|
|
142
179
|
intersectionIds =
|
|
143
180
|
intersectionIds === null
|
|
144
181
|
? relatedIds
|
|
145
182
|
: intersectionIds.filter((id) => relatedIds.includes(id));
|
|
146
183
|
|
|
147
|
-
|
|
184
|
+
await this.loggingService.log(
|
|
185
|
+
'debug',
|
|
186
|
+
'FilterService',
|
|
187
|
+
'applyFilterWrapper',
|
|
188
|
+
`Related IDs for sub-entity ${subEntityType}`,
|
|
189
|
+
[relatedIds, intersectionIds],
|
|
190
|
+
);
|
|
191
|
+
|
|
148
192
|
if (intersectionIds.length === 0) {
|
|
193
|
+
await this.loggingService.log(
|
|
194
|
+
'info',
|
|
195
|
+
'FilterService',
|
|
196
|
+
'applyFilterWrapper',
|
|
197
|
+
'No intersection IDs left, returning empty result',
|
|
198
|
+
);
|
|
149
199
|
return {
|
|
150
200
|
success: true,
|
|
151
201
|
data: { entity_tabs: [], entity_list: [], pagination: {} },
|
|
@@ -157,12 +207,11 @@ export class FilterService {
|
|
|
157
207
|
const mainFilters = grouped[entity_type] || [];
|
|
158
208
|
const mainDto: FilterRequestDto = {
|
|
159
209
|
...dto,
|
|
160
|
-
quickFilter: [...mainFilters],
|
|
210
|
+
quickFilter: [...mainFilters],
|
|
161
211
|
savedFilterCode: null,
|
|
162
212
|
attributeFilter: [],
|
|
163
213
|
};
|
|
164
214
|
|
|
165
|
-
// pass intersection ids as an extra constraint
|
|
166
215
|
if (intersectionIds && intersectionIds.length > 0) {
|
|
167
216
|
(mainDto.quickFilter ??= []).push({
|
|
168
217
|
filter_attribute: 'id',
|
|
@@ -172,6 +221,14 @@ export class FilterService {
|
|
|
172
221
|
});
|
|
173
222
|
}
|
|
174
223
|
|
|
224
|
+
await this.loggingService.log(
|
|
225
|
+
'info',
|
|
226
|
+
'FilterService',
|
|
227
|
+
'applyFilterWrapper',
|
|
228
|
+
'Calling applyFilter for main entity',
|
|
229
|
+
[mainDto],
|
|
230
|
+
);
|
|
231
|
+
|
|
175
232
|
return this.applyFilter(mainDto);
|
|
176
233
|
}
|
|
177
234
|
|
|
@@ -199,6 +256,14 @@ export class FilterService {
|
|
|
199
256
|
organization_id,
|
|
200
257
|
} = loggedInUser || {};
|
|
201
258
|
|
|
259
|
+
await this.loggingService.log(
|
|
260
|
+
'info',
|
|
261
|
+
'FilterService',
|
|
262
|
+
'applyFilter',
|
|
263
|
+
'Started applyFilter',
|
|
264
|
+
[dto],
|
|
265
|
+
);
|
|
266
|
+
|
|
202
267
|
// Fetch meta from entity table service
|
|
203
268
|
const entityMeta = await this.entityMasterService.getEntityData(
|
|
204
269
|
entity_type,
|
|
@@ -207,6 +272,12 @@ export class FilterService {
|
|
|
207
272
|
const tableName = entityMeta?.data_source; // data_souce is the table name
|
|
208
273
|
|
|
209
274
|
if (!tableName) {
|
|
275
|
+
await this.loggingService.log(
|
|
276
|
+
'error',
|
|
277
|
+
'FilterService',
|
|
278
|
+
'applyFilter',
|
|
279
|
+
`Invalid entity_type: ${entity_type}`,
|
|
280
|
+
);
|
|
210
281
|
throw new BadRequestException(`Invalid entity_type: ${entity_type}`);
|
|
211
282
|
}
|
|
212
283
|
|
|
@@ -263,6 +334,14 @@ export class FilterService {
|
|
|
263
334
|
|
|
264
335
|
console.log(baseFilters, 'STEP 1B: BASE FILTERS FOR MAIN ENTITY');
|
|
265
336
|
|
|
337
|
+
await this.loggingService.log(
|
|
338
|
+
'debug',
|
|
339
|
+
'FilterService',
|
|
340
|
+
'applyFilter',
|
|
341
|
+
'Collected base filters',
|
|
342
|
+
[baseFilters],
|
|
343
|
+
);
|
|
344
|
+
|
|
266
345
|
// Build where clauses
|
|
267
346
|
const baseWhere = this.buildWhereClauses(baseFilters, attributeMetaMap);
|
|
268
347
|
|
|
@@ -332,6 +411,14 @@ export class FilterService {
|
|
|
332
411
|
// });
|
|
333
412
|
// }
|
|
334
413
|
|
|
414
|
+
await this.loggingService.log(
|
|
415
|
+
'debug',
|
|
416
|
+
'FilterService',
|
|
417
|
+
'applyFilter',
|
|
418
|
+
'Constructed baseWhere clauses',
|
|
419
|
+
[baseWhere],
|
|
420
|
+
);
|
|
421
|
+
|
|
335
422
|
// layout preference query
|
|
336
423
|
const layoutPreference = await this.dataSource.query(
|
|
337
424
|
`SELECT mapped_json
|
|
@@ -360,6 +447,14 @@ export class FilterService {
|
|
|
360
447
|
);
|
|
361
448
|
}
|
|
362
449
|
|
|
450
|
+
await this.loggingService.log(
|
|
451
|
+
'debug',
|
|
452
|
+
'FilterService',
|
|
453
|
+
'applyFilter',
|
|
454
|
+
'Tab counts retrieved',
|
|
455
|
+
[allTabs],
|
|
456
|
+
);
|
|
457
|
+
|
|
363
458
|
let filteredTabs;
|
|
364
459
|
|
|
365
460
|
if (showList?.length > 0) {
|
|
@@ -441,6 +536,14 @@ export class FilterService {
|
|
|
441
536
|
filteredTabs = allTabs;
|
|
442
537
|
}
|
|
443
538
|
|
|
539
|
+
await this.loggingService.log(
|
|
540
|
+
'debug',
|
|
541
|
+
'FilterService',
|
|
542
|
+
'applyFilter',
|
|
543
|
+
'Filtered tabs prepared',
|
|
544
|
+
[filteredTabs],
|
|
545
|
+
);
|
|
546
|
+
|
|
444
547
|
const dataWhere = [...baseWhere];
|
|
445
548
|
|
|
446
549
|
console.log(dataWhere, 'dataWhere');
|
|
@@ -557,6 +660,14 @@ export class FilterService {
|
|
|
557
660
|
|
|
558
661
|
const entity_list = await qb.getRawMany();
|
|
559
662
|
|
|
663
|
+
await this.loggingService.log(
|
|
664
|
+
'debug',
|
|
665
|
+
'FilterService',
|
|
666
|
+
'applyFilter',
|
|
667
|
+
'Fetched entity_list',
|
|
668
|
+
[entity_list.length, entity_list.slice(0, 5)], // log first 5 rows for brevity
|
|
669
|
+
);
|
|
670
|
+
|
|
560
671
|
// 1. Extract all date-type attribute keys
|
|
561
672
|
const dateAttributes = Object.entries(attributeMetaMap)
|
|
562
673
|
.filter(([_, attr]) => attr.data_type === 'date')
|
|
@@ -590,6 +701,14 @@ export class FilterService {
|
|
|
590
701
|
),
|
|
591
702
|
);
|
|
592
703
|
|
|
704
|
+
await this.loggingService.log(
|
|
705
|
+
'debug',
|
|
706
|
+
'FilterService',
|
|
707
|
+
'applyFilter',
|
|
708
|
+
'Resolved entity data',
|
|
709
|
+
[resolvedEntityList.length],
|
|
710
|
+
);
|
|
711
|
+
|
|
593
712
|
// 6. Resolve tab values (tab_value field)
|
|
594
713
|
const resolvedTabs = await Promise.all(
|
|
595
714
|
filteredTabs.map(async (tab) => {
|
|
@@ -618,6 +737,14 @@ export class FilterService {
|
|
|
618
737
|
}),
|
|
619
738
|
);
|
|
620
739
|
|
|
740
|
+
await this.loggingService.log(
|
|
741
|
+
'debug',
|
|
742
|
+
'FilterService',
|
|
743
|
+
'applyFilter',
|
|
744
|
+
'Resolved tab values',
|
|
745
|
+
[resolvedTabs],
|
|
746
|
+
);
|
|
747
|
+
|
|
621
748
|
// Count query (without pagination)
|
|
622
749
|
const countQb = this.dataSource
|
|
623
750
|
.createQueryBuilder()
|
|
@@ -629,6 +756,13 @@ export class FilterService {
|
|
|
629
756
|
const countResult = await countQb.getRawOne();
|
|
630
757
|
const total = parseInt(countResult.count, 10);
|
|
631
758
|
|
|
759
|
+
await this.loggingService.log(
|
|
760
|
+
'info',
|
|
761
|
+
'FilterService',
|
|
762
|
+
'applyFilter',
|
|
763
|
+
'Returning final result',
|
|
764
|
+
);
|
|
765
|
+
|
|
632
766
|
return {
|
|
633
767
|
success: true,
|
|
634
768
|
data: {
|
|
@@ -26,7 +26,7 @@ export class ActionTemplateMappingService extends EntityServiceImpl {
|
|
|
26
26
|
|
|
27
27
|
const templates = await this.dataSource.query(
|
|
28
28
|
`
|
|
29
|
-
SELECT template_code FROM
|
|
29
|
+
SELECT template_code FROM cr_wf_action_resources_mapping
|
|
30
30
|
WHERE stg_act_mapping_id = ?
|
|
31
31
|
`,
|
|
32
32
|
[stgActMappingId],
|
|
@@ -4,6 +4,7 @@ import { WorkflowAutomationService } from './workflow-automation.service';
|
|
|
4
4
|
import { FilterEvaluatorService } from '../../filter/service/filter-evaluator.service';
|
|
5
5
|
import { Action } from '../interface/action.interface';
|
|
6
6
|
import { DataSource } from 'typeorm';
|
|
7
|
+
import { LoggingService } from 'src/utils/service/loggingUtil.service';
|
|
7
8
|
|
|
8
9
|
@Injectable()
|
|
9
10
|
export class WorkflowAutomationEngineService {
|
|
@@ -14,10 +15,17 @@ export class WorkflowAutomationEngineService {
|
|
|
14
15
|
private readonly wfService: WorkflowAutomationService,
|
|
15
16
|
private readonly filterEvaluator: FilterEvaluatorService,
|
|
16
17
|
private readonly dataSource: DataSource,
|
|
18
|
+
@Inject() protected readonly loggingService: LoggingService,
|
|
17
19
|
) {}
|
|
18
20
|
|
|
19
21
|
registerAction(actionName: string, actionInstance: Action) {
|
|
20
22
|
this.actions.set(actionName, actionInstance);
|
|
23
|
+
this.loggingService.log(
|
|
24
|
+
'info',
|
|
25
|
+
'WorkflowAutomationEngine',
|
|
26
|
+
'registerAction',
|
|
27
|
+
`Registered action ${actionName}`,
|
|
28
|
+
);
|
|
21
29
|
}
|
|
22
30
|
|
|
23
31
|
/**
|
|
@@ -31,10 +39,18 @@ export class WorkflowAutomationEngineService {
|
|
|
31
39
|
user: any,
|
|
32
40
|
preUpdateStates?: Record<number, boolean> | null,
|
|
33
41
|
) {
|
|
42
|
+
this.loggingService.log(
|
|
43
|
+
'info',
|
|
44
|
+
'WorkflowAutomationEngine',
|
|
45
|
+
'handleEntityEvent',
|
|
46
|
+
`Handling entity event: ${eventType} for entityType: ${entityType}`,
|
|
47
|
+
[newEntity?.id, preUpdateStates],
|
|
48
|
+
);
|
|
49
|
+
|
|
34
50
|
const workflows = await this.wfService.getActiveRules(
|
|
35
51
|
entityType,
|
|
36
52
|
eventType,
|
|
37
|
-
user
|
|
53
|
+
user,
|
|
38
54
|
);
|
|
39
55
|
|
|
40
56
|
for (const wf of workflows) {
|
|
@@ -43,7 +59,7 @@ export class WorkflowAutomationEngineService {
|
|
|
43
59
|
|
|
44
60
|
if (eventType === 'CREATE') {
|
|
45
61
|
triggerMatched = await this.filterEvaluator.evaluateCriteria(
|
|
46
|
-
|
|
62
|
+
wf.applicable_entity_type,
|
|
47
63
|
wf.condition_filter_code,
|
|
48
64
|
newEntity.id,
|
|
49
65
|
user,
|
|
@@ -51,7 +67,7 @@ export class WorkflowAutomationEngineService {
|
|
|
51
67
|
} else if (eventType === 'UPDATE' && preUpdateStates) {
|
|
52
68
|
const before = preUpdateStates[wf.id] ?? false;
|
|
53
69
|
const after = await this.filterEvaluator.evaluateCriteria(
|
|
54
|
-
|
|
70
|
+
wf.applicable_entity_type,
|
|
55
71
|
wf.condition_filter_code,
|
|
56
72
|
newEntity.id,
|
|
57
73
|
user,
|
|
@@ -60,25 +76,37 @@ export class WorkflowAutomationEngineService {
|
|
|
60
76
|
}
|
|
61
77
|
|
|
62
78
|
// 🔍 Log Step 1 result
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
79
|
+
this.loggingService.log(
|
|
80
|
+
'debug',
|
|
81
|
+
'WorkflowAutomationEngine',
|
|
82
|
+
'handleEntityEvent',
|
|
83
|
+
`Step 1 - Trigger matched`,
|
|
84
|
+
[wf.id, triggerMatched],
|
|
66
85
|
);
|
|
67
86
|
|
|
68
87
|
if (!triggerMatched) continue;
|
|
69
88
|
|
|
70
89
|
// Step 2️⃣ Final criteria evaluation
|
|
90
|
+
|
|
91
|
+
const entityIdToUse =
|
|
92
|
+
wf.mapped_entity_type === wf.applicable_entity_type
|
|
93
|
+
? newEntity.id
|
|
94
|
+
: newEntity.parent_id;
|
|
95
|
+
|
|
71
96
|
const criteriaMatched = await this.filterEvaluator.evaluateCriteria(
|
|
72
|
-
|
|
97
|
+
wf.mapped_entity_type,
|
|
73
98
|
wf.criteria_filter_code,
|
|
74
|
-
|
|
99
|
+
entityIdToUse,
|
|
75
100
|
user,
|
|
76
101
|
);
|
|
77
102
|
|
|
78
103
|
// 🔍 Log Step 2 result
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
104
|
+
this.loggingService.log(
|
|
105
|
+
'debug',
|
|
106
|
+
'WorkflowAutomationEngine',
|
|
107
|
+
'handleEntityEvent',
|
|
108
|
+
`Step 2 - Criteria matched`,
|
|
109
|
+
[wf.id, criteriaMatched],
|
|
82
110
|
);
|
|
83
111
|
|
|
84
112
|
if (!criteriaMatched) continue;
|
|
@@ -99,7 +127,12 @@ export class WorkflowAutomationEngineService {
|
|
|
99
127
|
);
|
|
100
128
|
|
|
101
129
|
if (!actions.length) {
|
|
102
|
-
|
|
130
|
+
this.loggingService.log(
|
|
131
|
+
'warn',
|
|
132
|
+
'WorkflowAutomationEngine',
|
|
133
|
+
'executeActions',
|
|
134
|
+
`No actions found for workflow ${workflow_automation_id}`,
|
|
135
|
+
);
|
|
103
136
|
return;
|
|
104
137
|
}
|
|
105
138
|
|
|
@@ -112,7 +145,10 @@ export class WorkflowAutomationEngineService {
|
|
|
112
145
|
);
|
|
113
146
|
|
|
114
147
|
if (!category?.action_decorator) {
|
|
115
|
-
|
|
148
|
+
this.loggingService.log(
|
|
149
|
+
'warn',
|
|
150
|
+
'WorkflowAutomationEngine',
|
|
151
|
+
'executeActions',
|
|
116
152
|
`No action_decorator found for category_id=${action.action_category_id}`,
|
|
117
153
|
);
|
|
118
154
|
continue;
|
|
@@ -124,11 +160,22 @@ export class WorkflowAutomationEngineService {
|
|
|
124
160
|
const impl = this.actions.get(decorator);
|
|
125
161
|
|
|
126
162
|
if (!impl) {
|
|
127
|
-
|
|
163
|
+
this.loggingService.log(
|
|
164
|
+
'warn',
|
|
165
|
+
'WorkflowAutomationEngine',
|
|
166
|
+
'executeActions',
|
|
167
|
+
`No implementation found for action: ${decorator}`,
|
|
168
|
+
);
|
|
128
169
|
continue;
|
|
129
170
|
}
|
|
130
171
|
|
|
131
|
-
|
|
172
|
+
this.loggingService.log(
|
|
173
|
+
'info',
|
|
174
|
+
'WorkflowAutomationEngine',
|
|
175
|
+
'executeActions',
|
|
176
|
+
`Executing action ${decorator} for entity ${entity.id}`,
|
|
177
|
+
[workflow_automation_id],
|
|
178
|
+
);
|
|
132
179
|
|
|
133
180
|
// 4️ Execute action with required context
|
|
134
181
|
await impl.execute({
|
|
@@ -137,11 +184,20 @@ export class WorkflowAutomationEngineService {
|
|
|
137
184
|
config: action.payload, // from cr_wf_action table
|
|
138
185
|
});
|
|
139
186
|
|
|
140
|
-
|
|
187
|
+
this.loggingService.log(
|
|
188
|
+
'info',
|
|
189
|
+
'WorkflowAutomationEngine',
|
|
190
|
+
'executeActions',
|
|
191
|
+
`Action ${decorator} executed successfully`,
|
|
192
|
+
[workflow_automation_id],
|
|
193
|
+
);
|
|
141
194
|
} catch (err) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
195
|
+
this.loggingService.log(
|
|
196
|
+
'error',
|
|
197
|
+
'WorkflowAutomationEngine',
|
|
198
|
+
'executeActions',
|
|
199
|
+
`Error executing action (category_id=${action.action_category_id})`,
|
|
200
|
+
[err],
|
|
145
201
|
);
|
|
146
202
|
}
|
|
147
203
|
}
|