rez_core 5.0.207 → 5.0.208
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/.idea/250218_ether_core.iml +12 -0
- package/.idea/codeStyles/Project.xml +59 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/dist/module/meta/service/resolver.service.js +28 -32
- package/dist/module/meta/service/resolver.service.js.map +1 -1
- package/dist/module/notification/notification.module.js +2 -0
- package/dist/module/notification/notification.module.js.map +1 -1
- package/dist/module/notification/repository/notification.repository.d.ts +7 -0
- package/dist/module/notification/repository/notification.repository.js +43 -0
- package/dist/module/notification/repository/notification.repository.js.map +1 -0
- package/dist/module/notification/service/notification.service.d.ts +3 -1
- package/dist/module/notification/service/notification.service.js +25 -38
- package/dist/module/notification/service/notification.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/meta/service/resolver.service.ts +50 -38
- package/src/module/notification/notification.module.ts +2 -0
- package/src/module/notification/repository/notification.repository.ts +33 -0
- package/src/module/notification/service/notification.service.ts +42 -60
package/package.json
CHANGED
|
@@ -111,9 +111,8 @@ export class ResolverService {
|
|
|
111
111
|
attr.element_type === 'date' ||
|
|
112
112
|
attr.element_type === 'datetime'
|
|
113
113
|
) {
|
|
114
|
-
|
|
115
|
-
const dateValue = moment(codeValue,
|
|
116
|
-
|
|
114
|
+
const dateFormat = attr.element_type === 'date' ? "DD-MM-YYYY" : "DD-MM-YYYY HH:mm:ss";
|
|
115
|
+
const dateValue = moment(codeValue,dateFormat).utcOffset('+05:30'); // IST
|
|
117
116
|
if (dateValue.isValid()) {
|
|
118
117
|
resolvedEntityData[field] =
|
|
119
118
|
attr.element_type === 'date'
|
|
@@ -159,75 +158,88 @@ export class ResolverService {
|
|
|
159
158
|
attrKey,
|
|
160
159
|
loggedInUser.enterprise_id,
|
|
161
160
|
);
|
|
162
|
-
if (!attr) return rawValue;
|
|
163
161
|
|
|
164
|
-
|
|
162
|
+
if (!attr) return rawValue;
|
|
163
|
+
// ----------- ENTITY TYPE RESOLUTION -------------------
|
|
165
164
|
if (attr.data_source_type === 'entity') {
|
|
166
165
|
const entityDef = await this.entityMasterRepo.getEntityByMappedEntityType(
|
|
167
166
|
attr.datasource_list,
|
|
168
167
|
loggedInUser.enterprise_id,
|
|
169
168
|
);
|
|
170
|
-
|
|
171
169
|
if (!entityDef) return rawValue;
|
|
172
170
|
|
|
173
171
|
const tableName = entityDef.db_table_name;
|
|
174
172
|
|
|
173
|
+
// --- If array (multi-select) ---
|
|
175
174
|
if (Array.isArray(rawValue)) {
|
|
176
175
|
const resolvedValues: string[] = [];
|
|
176
|
+
|
|
177
177
|
for (const value of rawValue) {
|
|
178
178
|
const query =
|
|
179
179
|
tableName === 'sso_organization'
|
|
180
|
-
? `SELECT *
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
FROM ${tableName}
|
|
185
|
-
WHERE id = $1`;
|
|
186
|
-
const params = tableName === 'sso_organization' ? [value] : [value];
|
|
187
|
-
|
|
188
|
-
const [item] = await this.entityManger.query(query, params);
|
|
180
|
+
? `SELECT * FROM ${tableName} WHERE code = $1`
|
|
181
|
+
: `SELECT * FROM ${tableName} WHERE id = $1`;
|
|
182
|
+
|
|
183
|
+
const [item] = await this.entityManger.query(query, [value]);
|
|
189
184
|
resolvedValues.push(item?.[attr.data_source_attribute] ?? value);
|
|
190
185
|
}
|
|
191
|
-
return resolvedValues;
|
|
192
|
-
} else {
|
|
193
|
-
const query = `SELECT *
|
|
194
|
-
FROM ${tableName}
|
|
195
|
-
WHERE id = $1`;
|
|
196
|
-
const params = [rawValue];
|
|
197
186
|
|
|
198
|
-
|
|
199
|
-
return item?.[attr.data_source_attribute] ?? rawValue;
|
|
187
|
+
return resolvedValues;
|
|
200
188
|
}
|
|
189
|
+
|
|
190
|
+
// --- Single value ---
|
|
191
|
+
const query = `SELECT * FROM ${tableName} WHERE id = $1`;
|
|
192
|
+
const [item] = await this.entityManger.query(query, [rawValue]);
|
|
193
|
+
|
|
194
|
+
return item?.[attr.data_source_attribute] ?? rawValue;
|
|
201
195
|
}
|
|
202
196
|
|
|
203
|
-
//
|
|
204
|
-
|
|
197
|
+
// ----------- MASTER TYPE RESOLUTION -------------------
|
|
198
|
+
if (attr.data_source_type === 'master') {
|
|
205
199
|
const repo = this.reflectionHelper.getRepoService('ListMasterItems');
|
|
206
|
-
|
|
200
|
+
|
|
201
|
+
let value = rawValue;
|
|
202
|
+
|
|
203
|
+
// 🟦 If rawValue is a JSON string representing array → parse it
|
|
204
|
+
if (typeof rawValue === 'string') {
|
|
205
|
+
try {
|
|
206
|
+
const parsed = JSON.parse(rawValue);
|
|
207
|
+
if (Array.isArray(parsed)) value = parsed;
|
|
208
|
+
} catch (e) {
|
|
209
|
+
// keep as string
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// 🟩 If value is array → resolve each
|
|
214
|
+
if (Array.isArray(value)) {
|
|
207
215
|
const resolvedValues: string[] = [];
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
},
|
|
216
|
+
|
|
217
|
+
for (const id of value) {
|
|
218
|
+
const item = await repo.findOne({
|
|
219
|
+
where: { id: Number(id) },
|
|
213
220
|
});
|
|
214
|
-
resolvedValues.push(item?.[attr.data_source_attribute] ??
|
|
221
|
+
resolvedValues.push(item?.[attr.data_source_attribute] ?? id);
|
|
215
222
|
}
|
|
223
|
+
|
|
216
224
|
return resolvedValues;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
},
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// 🟨 Single value (must be number)
|
|
228
|
+
if (!isNaN(rawValue)) {
|
|
229
|
+
const item = await repo.findOne({
|
|
230
|
+
where: { id: Number(rawValue) },
|
|
223
231
|
});
|
|
232
|
+
|
|
224
233
|
return item?.[attr.data_source_attribute] ?? rawValue;
|
|
225
234
|
}
|
|
235
|
+
|
|
236
|
+
return rawValue;
|
|
226
237
|
}
|
|
227
238
|
|
|
228
239
|
return rawValue;
|
|
229
240
|
}
|
|
230
241
|
|
|
242
|
+
|
|
231
243
|
async getResolvedId(
|
|
232
244
|
loggedInUser: UserData,
|
|
233
245
|
attrKey: string,
|
|
@@ -17,6 +17,7 @@ import { NotificationsController } from './controller/notification.controller';
|
|
|
17
17
|
import { NotificationsService } from './service/notification.service';
|
|
18
18
|
import { EntityModule } from '../meta/entity.module';
|
|
19
19
|
import { FirebaseAdminProvider } from './firebase-admin.config';
|
|
20
|
+
import { NotificationRepository } from './repository/notification.repository';
|
|
20
21
|
|
|
21
22
|
@Module({
|
|
22
23
|
imports: [
|
|
@@ -57,6 +58,7 @@ import { FirebaseAdminProvider } from './firebase-admin.config';
|
|
|
57
58
|
EmailService,
|
|
58
59
|
NotificationsService,
|
|
59
60
|
FirebaseAdminProvider,
|
|
61
|
+
NotificationRepository,
|
|
60
62
|
],
|
|
61
63
|
exports: [
|
|
62
64
|
OtpService,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { InjectRepository } from '@nestjs/typeorm';
|
|
3
|
+
import { Repository, EntityManager } from 'typeorm';
|
|
4
|
+
import { NotificationData } from '../entity/notification.entity';
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class NotificationRepository {
|
|
8
|
+
constructor(
|
|
9
|
+
@InjectRepository(NotificationData)
|
|
10
|
+
private readonly notificationRepo: Repository<NotificationData>,
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
async getAllNotifications(
|
|
14
|
+
userId: number,
|
|
15
|
+
levelId: number,
|
|
16
|
+
levelType: string,
|
|
17
|
+
isReadFilter?,
|
|
18
|
+
) {
|
|
19
|
+
const qb = this.notificationRepo
|
|
20
|
+
.createQueryBuilder('n')
|
|
21
|
+
.where('n.user_id = :userId', { userId })
|
|
22
|
+
.andWhere('n.level_id = :levelId', { levelId })
|
|
23
|
+
.andWhere('n.level_type = :levelType', { levelType });
|
|
24
|
+
|
|
25
|
+
if (isReadFilter !== undefined) {
|
|
26
|
+
qb.andWhere('n.is_read = :isRead', { isRead: isReadFilter });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
qb.orderBy('n.created_date', 'DESC');
|
|
30
|
+
|
|
31
|
+
return await qb.getMany();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -5,6 +5,7 @@ import * as admin from 'firebase-admin';
|
|
|
5
5
|
import axios from 'axios';
|
|
6
6
|
import { ConfigService } from '@nestjs/config';
|
|
7
7
|
import { ReflectionHelper } from 'src/utils/service/reflection-helper.service';
|
|
8
|
+
import { NotificationRepository } from '../repository/notification.repository';
|
|
8
9
|
|
|
9
10
|
@Injectable()
|
|
10
11
|
export class NotificationsService {
|
|
@@ -14,6 +15,7 @@ export class NotificationsService {
|
|
|
14
15
|
private readonly configService: ConfigService,
|
|
15
16
|
private readonly reflectionHelper: ReflectionHelper,
|
|
16
17
|
@Inject('FIREBASE_ADMIN') private readonly firebaseAdmin: typeof admin,
|
|
18
|
+
private readonly notificationRepository: NotificationRepository,
|
|
17
19
|
) {}
|
|
18
20
|
|
|
19
21
|
private tokens: Map<string, string> = new Map(); // store in memory for now
|
|
@@ -69,73 +71,53 @@ export class NotificationsService {
|
|
|
69
71
|
loggedInUser: any,
|
|
70
72
|
filterQuery?: { is_read?: string },
|
|
71
73
|
) {
|
|
72
|
-
const { id, level_id, level_type } = loggedInUser;
|
|
73
|
-
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
// Build base SQL
|
|
85
|
-
//
|
|
86
|
-
let paramIndex = 1;
|
|
87
|
-
let sql = `
|
|
88
|
-
SELECT n.*
|
|
89
|
-
FROM frm_notification n
|
|
90
|
-
WHERE n.user_id = $${paramIndex}
|
|
91
|
-
AND n.level_id = $${paramIndex + 1}
|
|
92
|
-
AND n.level_type = $${paramIndex + 2}
|
|
93
|
-
`;
|
|
94
|
-
|
|
95
|
-
const params: string[] = [String(id), String(level_id), String(level_type)];
|
|
96
|
-
paramIndex += 3;
|
|
97
|
-
|
|
98
|
-
//
|
|
99
|
-
// Apply optional filter
|
|
100
|
-
//
|
|
101
|
-
if (isReadFilter !== undefined) {
|
|
102
|
-
sql += ` AND n.is_read = $${paramIndex}`;
|
|
103
|
-
params.push(String(isReadFilter));
|
|
104
|
-
paramIndex++;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
sql += ` ORDER BY n.created_date DESC`;
|
|
74
|
+
const { id: userId, level_id, level_type } = loggedInUser;
|
|
75
|
+
|
|
76
|
+
// Fetch notifications from repository
|
|
77
|
+
const notifications: any =
|
|
78
|
+
await this.notificationRepository.getAllNotifications(
|
|
79
|
+
userId,
|
|
80
|
+
level_id,
|
|
81
|
+
level_type,
|
|
82
|
+
filterQuery?.is_read,
|
|
83
|
+
);
|
|
108
84
|
|
|
109
85
|
//
|
|
110
|
-
//
|
|
86
|
+
// Avoid duplicate API calls for each user_id
|
|
111
87
|
//
|
|
112
|
-
const
|
|
88
|
+
const mediaCache = new Map<
|
|
89
|
+
number,
|
|
90
|
+
{ name: string; profile_image: string }
|
|
91
|
+
>();
|
|
113
92
|
|
|
114
|
-
|
|
115
|
-
// Enrich profile image + user name
|
|
116
|
-
//
|
|
117
|
-
const mediaCache = new Map();
|
|
93
|
+
const baseUrl = this.configService.get<string>('REDIRECT_BE_URL');
|
|
118
94
|
|
|
119
95
|
for (const notification of notifications) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
96
|
+
const uid = notification?.user_id;
|
|
97
|
+
|
|
98
|
+
if (uid && !mediaCache.has(uid)) {
|
|
99
|
+
try {
|
|
100
|
+
const queryParams = new URLSearchParams({
|
|
101
|
+
loggedInUser: JSON.stringify(loggedInUser),
|
|
102
|
+
}).toString();
|
|
103
|
+
|
|
104
|
+
const response = await axios.get(
|
|
105
|
+
`${baseUrl}/users/profile-image-url/${uid}?entity_type=USR&${queryParams}`,
|
|
106
|
+
{ headers: { 'Content-Type': 'application/json' } },
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
mediaCache.set(uid, {
|
|
110
|
+
name: response.data.name,
|
|
111
|
+
profile_image: response.data.profile_image,
|
|
112
|
+
});
|
|
113
|
+
} catch (err) {
|
|
114
|
+
console.error('⚠️ Internal Entity API call failed:', err.message);
|
|
115
|
+
}
|
|
138
116
|
}
|
|
117
|
+
|
|
118
|
+
const cachedData = mediaCache.get(uid);
|
|
119
|
+
notification.user_name = cachedData?.name;
|
|
120
|
+
notification.user_profile = cachedData?.profile_image;
|
|
139
121
|
}
|
|
140
122
|
|
|
141
123
|
return notifications;
|