@blackcode_sa/metaestetics-api 1.6.15 → 1.6.16
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/admin/index.js +160 -76
- package/dist/admin/index.mjs +160 -76
- package/package.json +1 -1
- package/src/admin/notifications/notifications.admin.ts +140 -28
package/dist/admin/index.js
CHANGED
|
@@ -142,6 +142,64 @@ var UserRole = /* @__PURE__ */ ((UserRole2) => {
|
|
|
142
142
|
return UserRole2;
|
|
143
143
|
})(UserRole || {});
|
|
144
144
|
|
|
145
|
+
// src/admin/logger/index.ts
|
|
146
|
+
var firebaseFunctionsLogger;
|
|
147
|
+
try {
|
|
148
|
+
firebaseFunctionsLogger = require("firebase-functions/logger");
|
|
149
|
+
require("firebase-functions/logger/compat");
|
|
150
|
+
} catch (e) {
|
|
151
|
+
}
|
|
152
|
+
var Logger = class {
|
|
153
|
+
/**
|
|
154
|
+
* Log an error message
|
|
155
|
+
* @param message Message to log
|
|
156
|
+
* @param data Optional data to include
|
|
157
|
+
*/
|
|
158
|
+
static error(message, data) {
|
|
159
|
+
if (firebaseFunctionsLogger) {
|
|
160
|
+
firebaseFunctionsLogger.error(message, data);
|
|
161
|
+
} else {
|
|
162
|
+
console.error(message, data !== void 0 ? data : "");
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Log a warning message
|
|
167
|
+
* @param message Message to log
|
|
168
|
+
* @param data Optional data to include
|
|
169
|
+
*/
|
|
170
|
+
static warn(message, data) {
|
|
171
|
+
if (firebaseFunctionsLogger) {
|
|
172
|
+
firebaseFunctionsLogger.warn(message, data);
|
|
173
|
+
} else {
|
|
174
|
+
console.warn(message, data !== void 0 ? data : "");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Log an info message
|
|
179
|
+
* @param message Message to log
|
|
180
|
+
* @param data Optional data to include
|
|
181
|
+
*/
|
|
182
|
+
static info(message, data) {
|
|
183
|
+
if (firebaseFunctionsLogger) {
|
|
184
|
+
firebaseFunctionsLogger.info(message, data);
|
|
185
|
+
} else {
|
|
186
|
+
console.info(message, data !== void 0 ? data : "");
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Log a debug message
|
|
191
|
+
* @param message Message to log
|
|
192
|
+
* @param data Optional data to include
|
|
193
|
+
*/
|
|
194
|
+
static debug(message, data) {
|
|
195
|
+
if (firebaseFunctionsLogger) {
|
|
196
|
+
firebaseFunctionsLogger.debug(message, data);
|
|
197
|
+
} else {
|
|
198
|
+
console.debug(message, data !== void 0 ? data : "");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
145
203
|
// src/admin/notifications/notifications.admin.ts
|
|
146
204
|
var NotificationsAdmin = class {
|
|
147
205
|
constructor(firestore12) {
|
|
@@ -171,7 +229,18 @@ var NotificationsAdmin = class {
|
|
|
171
229
|
* Priprema Expo poruku za slanje
|
|
172
230
|
*/
|
|
173
231
|
prepareExpoMessage(notification) {
|
|
174
|
-
|
|
232
|
+
const validTokens = notification.notificationTokens.filter(
|
|
233
|
+
(token) => import_expo_server_sdk.Expo.isExpoPushToken(token)
|
|
234
|
+
);
|
|
235
|
+
Logger.info(
|
|
236
|
+
`[NotificationsAdmin] Preparing Expo messages for notification ${notification.id}`,
|
|
237
|
+
{
|
|
238
|
+
totalTokens: notification.notificationTokens.length,
|
|
239
|
+
validTokens: validTokens.length,
|
|
240
|
+
invalidTokensCount: notification.notificationTokens.length - validTokens.length
|
|
241
|
+
}
|
|
242
|
+
);
|
|
243
|
+
return validTokens.map((token) => ({
|
|
175
244
|
to: token,
|
|
176
245
|
sound: "default",
|
|
177
246
|
title: notification.title,
|
|
@@ -203,45 +272,94 @@ var NotificationsAdmin = class {
|
|
|
203
272
|
* Šalje notifikaciju kroz Expo servis sa boljim error handlingom
|
|
204
273
|
*/
|
|
205
274
|
async sendPushNotification(notification) {
|
|
275
|
+
var _a;
|
|
206
276
|
try {
|
|
277
|
+
Logger.info(
|
|
278
|
+
`[NotificationsAdmin] Processing notification ${notification.id} for sending`,
|
|
279
|
+
{
|
|
280
|
+
userId: notification.userId,
|
|
281
|
+
tokenCount: ((_a = notification.notificationTokens) == null ? void 0 : _a.length) || 0,
|
|
282
|
+
type: notification.notificationType
|
|
283
|
+
}
|
|
284
|
+
);
|
|
207
285
|
const messages = this.prepareExpoMessage(notification);
|
|
208
286
|
if (messages.length === 0) {
|
|
287
|
+
const errorMsg = "No valid notification tokens found";
|
|
288
|
+
Logger.error(
|
|
289
|
+
`[NotificationsAdmin] ${errorMsg} for notification ${notification.id}`
|
|
290
|
+
);
|
|
209
291
|
await this.updateNotificationStatus(
|
|
210
292
|
notification.id,
|
|
211
293
|
"failed" /* FAILED */,
|
|
212
|
-
|
|
294
|
+
errorMsg
|
|
213
295
|
);
|
|
214
296
|
return false;
|
|
215
297
|
}
|
|
216
298
|
const chunks = this.expo.chunkPushNotifications(messages);
|
|
299
|
+
Logger.info(
|
|
300
|
+
`[NotificationsAdmin] Sending ${messages.length} messages in ${chunks.length} chunks for notification ${notification.id}`
|
|
301
|
+
);
|
|
217
302
|
const tickets = [];
|
|
218
|
-
for (
|
|
303
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
304
|
+
const chunk = chunks[i];
|
|
219
305
|
try {
|
|
306
|
+
Logger.info(
|
|
307
|
+
`[NotificationsAdmin] Sending chunk ${i + 1}/${chunks.length} with ${chunk.length} messages`
|
|
308
|
+
);
|
|
220
309
|
const ticketChunk = await this.expo.sendPushNotificationsAsync(chunk);
|
|
310
|
+
Logger.info(
|
|
311
|
+
`[NotificationsAdmin] Received ${ticketChunk.length} tickets for chunk ${i + 1}`
|
|
312
|
+
);
|
|
221
313
|
tickets.push(ticketChunk);
|
|
222
314
|
} catch (error) {
|
|
223
|
-
|
|
315
|
+
Logger.error(
|
|
316
|
+
`[NotificationsAdmin] Chunk ${i + 1} sending error:`,
|
|
317
|
+
error
|
|
318
|
+
);
|
|
224
319
|
throw error;
|
|
225
320
|
}
|
|
226
321
|
}
|
|
227
322
|
let hasErrors = false;
|
|
228
323
|
const errors = [];
|
|
229
|
-
tickets.flat()
|
|
324
|
+
const ticketsFlat = tickets.flat();
|
|
325
|
+
const ticketResults = {
|
|
326
|
+
total: ticketsFlat.length,
|
|
327
|
+
success: 0,
|
|
328
|
+
error: 0,
|
|
329
|
+
errorDetails: {}
|
|
330
|
+
};
|
|
331
|
+
ticketsFlat.forEach((ticket, index) => {
|
|
230
332
|
if (ticket.status === "error") {
|
|
231
333
|
hasErrors = true;
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
);
|
|
334
|
+
ticketResults.error++;
|
|
335
|
+
const errorMessage = ticket.message || "Unknown error";
|
|
336
|
+
ticketResults.errorDetails[errorMessage] = (ticketResults.errorDetails[errorMessage] || 0) + 1;
|
|
337
|
+
const tokenInfo = index < notification.notificationTokens.length ? `Token ${notification.notificationTokens[index]}` : `Token at index ${index}`;
|
|
338
|
+
errors.push(`${tokenInfo}: ${errorMessage}`);
|
|
339
|
+
} else {
|
|
340
|
+
ticketResults.success++;
|
|
235
341
|
}
|
|
236
342
|
});
|
|
343
|
+
Logger.info(
|
|
344
|
+
`[NotificationsAdmin] Ticket results for notification ${notification.id}`,
|
|
345
|
+
ticketResults
|
|
346
|
+
);
|
|
237
347
|
if (hasErrors) {
|
|
348
|
+
const errorSummary = errors.join("; ");
|
|
349
|
+
Logger.warn(
|
|
350
|
+
`[NotificationsAdmin] Partial success or errors in notification ${notification.id}`,
|
|
351
|
+
{ errorCount: errors.length, errorSummary }
|
|
352
|
+
);
|
|
238
353
|
await this.updateNotificationStatus(
|
|
239
354
|
notification.id,
|
|
240
|
-
"partialSuccess" /* PARTIAL_SUCCESS */,
|
|
241
|
-
|
|
355
|
+
ticketResults.success > 0 ? "partialSuccess" /* PARTIAL_SUCCESS */ : "failed" /* FAILED */,
|
|
356
|
+
errorSummary
|
|
242
357
|
);
|
|
243
|
-
return
|
|
358
|
+
return ticketResults.success > 0;
|
|
244
359
|
}
|
|
360
|
+
Logger.info(
|
|
361
|
+
`[NotificationsAdmin] Successfully sent notification ${notification.id} to all recipients`
|
|
362
|
+
);
|
|
245
363
|
await this.updateNotificationStatus(
|
|
246
364
|
notification.id,
|
|
247
365
|
"sent" /* SENT */
|
|
@@ -249,7 +367,10 @@ var NotificationsAdmin = class {
|
|
|
249
367
|
return true;
|
|
250
368
|
} catch (error) {
|
|
251
369
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
252
|
-
|
|
370
|
+
Logger.error(
|
|
371
|
+
`[NotificationsAdmin] Critical error sending notification ${notification.id}:`,
|
|
372
|
+
error
|
|
373
|
+
);
|
|
253
374
|
await this.updateNotificationStatus(
|
|
254
375
|
notification.id,
|
|
255
376
|
"failed" /* FAILED */,
|
|
@@ -263,13 +384,28 @@ var NotificationsAdmin = class {
|
|
|
263
384
|
*/
|
|
264
385
|
async processPendingNotifications(batchSize = 100) {
|
|
265
386
|
const now = admin.firestore.Timestamp.now();
|
|
387
|
+
Logger.info(
|
|
388
|
+
`[NotificationsAdmin] Starting to process pending notifications with batch size ${batchSize}`
|
|
389
|
+
);
|
|
266
390
|
const pendingNotifications = await this.db.collection("notifications").where("status", "==", "pending" /* PENDING */).where("notificationTime", "<=", now).limit(batchSize).get();
|
|
391
|
+
Logger.info(
|
|
392
|
+
`[NotificationsAdmin] Found ${pendingNotifications.size} pending notifications to process`
|
|
393
|
+
);
|
|
394
|
+
if (pendingNotifications.empty) {
|
|
395
|
+
Logger.info(
|
|
396
|
+
"[NotificationsAdmin] No pending notifications found to process"
|
|
397
|
+
);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
267
400
|
const results = await Promise.allSettled(
|
|
268
401
|
pendingNotifications.docs.map(async (doc) => {
|
|
269
402
|
const notification = {
|
|
270
403
|
id: doc.id,
|
|
271
404
|
...doc.data()
|
|
272
405
|
};
|
|
406
|
+
Logger.info(
|
|
407
|
+
`[NotificationsAdmin] Processing notification ${notification.id} of type ${notification.notificationType}`
|
|
408
|
+
);
|
|
273
409
|
return this.sendPushNotification(notification);
|
|
274
410
|
})
|
|
275
411
|
);
|
|
@@ -279,8 +415,8 @@ var NotificationsAdmin = class {
|
|
|
279
415
|
const failed = results.filter(
|
|
280
416
|
(r) => r.status === "rejected" || r.status === "fulfilled" && !r.value
|
|
281
417
|
).length;
|
|
282
|
-
|
|
283
|
-
`Processed ${results.length} notifications: ${successful} successful, ${failed} failed`
|
|
418
|
+
Logger.info(
|
|
419
|
+
`[NotificationsAdmin] Processed ${results.length} notifications: ${successful} successful, ${failed} failed`
|
|
284
420
|
);
|
|
285
421
|
}
|
|
286
422
|
/**
|
|
@@ -289,6 +425,10 @@ var NotificationsAdmin = class {
|
|
|
289
425
|
async cleanupOldNotifications(daysOld = 30, batchSize = 500) {
|
|
290
426
|
const cutoffDate = /* @__PURE__ */ new Date();
|
|
291
427
|
cutoffDate.setDate(cutoffDate.getDate() - daysOld);
|
|
428
|
+
Logger.info(
|
|
429
|
+
`[NotificationsAdmin] Starting cleanup of notifications older than ${daysOld} days`
|
|
430
|
+
);
|
|
431
|
+
let totalDeleted = 0;
|
|
292
432
|
while (true) {
|
|
293
433
|
const oldNotifications = await this.db.collection("notifications").where(
|
|
294
434
|
"createdAt",
|
|
@@ -296,6 +436,9 @@ var NotificationsAdmin = class {
|
|
|
296
436
|
admin.firestore.Timestamp.fromDate(cutoffDate)
|
|
297
437
|
).limit(batchSize).get();
|
|
298
438
|
if (oldNotifications.empty) {
|
|
439
|
+
Logger.info(
|
|
440
|
+
`[NotificationsAdmin] No more old notifications to delete. Total deleted: ${totalDeleted}`
|
|
441
|
+
);
|
|
299
442
|
break;
|
|
300
443
|
}
|
|
301
444
|
const batch = this.db.batch();
|
|
@@ -303,8 +446,9 @@ var NotificationsAdmin = class {
|
|
|
303
446
|
batch.delete(doc.ref);
|
|
304
447
|
});
|
|
305
448
|
await batch.commit();
|
|
306
|
-
|
|
307
|
-
|
|
449
|
+
totalDeleted += oldNotifications.size;
|
|
450
|
+
Logger.info(
|
|
451
|
+
`[NotificationsAdmin] Deleted batch of ${oldNotifications.size} old notifications. Running total: ${totalDeleted}`
|
|
308
452
|
);
|
|
309
453
|
}
|
|
310
454
|
}
|
|
@@ -2436,66 +2580,6 @@ var PatientRequirementsAdminService = class {
|
|
|
2436
2580
|
|
|
2437
2581
|
// src/admin/calendar/calendar.admin.service.ts
|
|
2438
2582
|
var admin8 = __toESM(require("firebase-admin"));
|
|
2439
|
-
|
|
2440
|
-
// src/admin/logger/index.ts
|
|
2441
|
-
var firebaseFunctionsLogger;
|
|
2442
|
-
try {
|
|
2443
|
-
firebaseFunctionsLogger = require("firebase-functions/logger");
|
|
2444
|
-
require("firebase-functions/logger/compat");
|
|
2445
|
-
} catch (e) {
|
|
2446
|
-
}
|
|
2447
|
-
var Logger = class {
|
|
2448
|
-
/**
|
|
2449
|
-
* Log an error message
|
|
2450
|
-
* @param message Message to log
|
|
2451
|
-
* @param data Optional data to include
|
|
2452
|
-
*/
|
|
2453
|
-
static error(message, data) {
|
|
2454
|
-
if (firebaseFunctionsLogger) {
|
|
2455
|
-
firebaseFunctionsLogger.error(message, data);
|
|
2456
|
-
} else {
|
|
2457
|
-
console.error(message, data !== void 0 ? data : "");
|
|
2458
|
-
}
|
|
2459
|
-
}
|
|
2460
|
-
/**
|
|
2461
|
-
* Log a warning message
|
|
2462
|
-
* @param message Message to log
|
|
2463
|
-
* @param data Optional data to include
|
|
2464
|
-
*/
|
|
2465
|
-
static warn(message, data) {
|
|
2466
|
-
if (firebaseFunctionsLogger) {
|
|
2467
|
-
firebaseFunctionsLogger.warn(message, data);
|
|
2468
|
-
} else {
|
|
2469
|
-
console.warn(message, data !== void 0 ? data : "");
|
|
2470
|
-
}
|
|
2471
|
-
}
|
|
2472
|
-
/**
|
|
2473
|
-
* Log an info message
|
|
2474
|
-
* @param message Message to log
|
|
2475
|
-
* @param data Optional data to include
|
|
2476
|
-
*/
|
|
2477
|
-
static info(message, data) {
|
|
2478
|
-
if (firebaseFunctionsLogger) {
|
|
2479
|
-
firebaseFunctionsLogger.info(message, data);
|
|
2480
|
-
} else {
|
|
2481
|
-
console.info(message, data !== void 0 ? data : "");
|
|
2482
|
-
}
|
|
2483
|
-
}
|
|
2484
|
-
/**
|
|
2485
|
-
* Log a debug message
|
|
2486
|
-
* @param message Message to log
|
|
2487
|
-
* @param data Optional data to include
|
|
2488
|
-
*/
|
|
2489
|
-
static debug(message, data) {
|
|
2490
|
-
if (firebaseFunctionsLogger) {
|
|
2491
|
-
firebaseFunctionsLogger.debug(message, data);
|
|
2492
|
-
} else {
|
|
2493
|
-
console.debug(message, data !== void 0 ? data : "");
|
|
2494
|
-
}
|
|
2495
|
-
}
|
|
2496
|
-
};
|
|
2497
|
-
|
|
2498
|
-
// src/admin/calendar/calendar.admin.service.ts
|
|
2499
2583
|
var CalendarAdminService = class {
|
|
2500
2584
|
constructor(firestore12) {
|
|
2501
2585
|
this.db = firestore12 || admin8.firestore();
|
package/dist/admin/index.mjs
CHANGED
|
@@ -87,6 +87,64 @@ var UserRole = /* @__PURE__ */ ((UserRole2) => {
|
|
|
87
87
|
return UserRole2;
|
|
88
88
|
})(UserRole || {});
|
|
89
89
|
|
|
90
|
+
// src/admin/logger/index.ts
|
|
91
|
+
var firebaseFunctionsLogger;
|
|
92
|
+
try {
|
|
93
|
+
firebaseFunctionsLogger = __require("firebase-functions/logger");
|
|
94
|
+
__require("firebase-functions/logger/compat");
|
|
95
|
+
} catch (e) {
|
|
96
|
+
}
|
|
97
|
+
var Logger = class {
|
|
98
|
+
/**
|
|
99
|
+
* Log an error message
|
|
100
|
+
* @param message Message to log
|
|
101
|
+
* @param data Optional data to include
|
|
102
|
+
*/
|
|
103
|
+
static error(message, data) {
|
|
104
|
+
if (firebaseFunctionsLogger) {
|
|
105
|
+
firebaseFunctionsLogger.error(message, data);
|
|
106
|
+
} else {
|
|
107
|
+
console.error(message, data !== void 0 ? data : "");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Log a warning message
|
|
112
|
+
* @param message Message to log
|
|
113
|
+
* @param data Optional data to include
|
|
114
|
+
*/
|
|
115
|
+
static warn(message, data) {
|
|
116
|
+
if (firebaseFunctionsLogger) {
|
|
117
|
+
firebaseFunctionsLogger.warn(message, data);
|
|
118
|
+
} else {
|
|
119
|
+
console.warn(message, data !== void 0 ? data : "");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Log an info message
|
|
124
|
+
* @param message Message to log
|
|
125
|
+
* @param data Optional data to include
|
|
126
|
+
*/
|
|
127
|
+
static info(message, data) {
|
|
128
|
+
if (firebaseFunctionsLogger) {
|
|
129
|
+
firebaseFunctionsLogger.info(message, data);
|
|
130
|
+
} else {
|
|
131
|
+
console.info(message, data !== void 0 ? data : "");
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Log a debug message
|
|
136
|
+
* @param message Message to log
|
|
137
|
+
* @param data Optional data to include
|
|
138
|
+
*/
|
|
139
|
+
static debug(message, data) {
|
|
140
|
+
if (firebaseFunctionsLogger) {
|
|
141
|
+
firebaseFunctionsLogger.debug(message, data);
|
|
142
|
+
} else {
|
|
143
|
+
console.debug(message, data !== void 0 ? data : "");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
90
148
|
// src/admin/notifications/notifications.admin.ts
|
|
91
149
|
var NotificationsAdmin = class {
|
|
92
150
|
constructor(firestore12) {
|
|
@@ -116,7 +174,18 @@ var NotificationsAdmin = class {
|
|
|
116
174
|
* Priprema Expo poruku za slanje
|
|
117
175
|
*/
|
|
118
176
|
prepareExpoMessage(notification) {
|
|
119
|
-
|
|
177
|
+
const validTokens = notification.notificationTokens.filter(
|
|
178
|
+
(token) => Expo.isExpoPushToken(token)
|
|
179
|
+
);
|
|
180
|
+
Logger.info(
|
|
181
|
+
`[NotificationsAdmin] Preparing Expo messages for notification ${notification.id}`,
|
|
182
|
+
{
|
|
183
|
+
totalTokens: notification.notificationTokens.length,
|
|
184
|
+
validTokens: validTokens.length,
|
|
185
|
+
invalidTokensCount: notification.notificationTokens.length - validTokens.length
|
|
186
|
+
}
|
|
187
|
+
);
|
|
188
|
+
return validTokens.map((token) => ({
|
|
120
189
|
to: token,
|
|
121
190
|
sound: "default",
|
|
122
191
|
title: notification.title,
|
|
@@ -148,45 +217,94 @@ var NotificationsAdmin = class {
|
|
|
148
217
|
* Šalje notifikaciju kroz Expo servis sa boljim error handlingom
|
|
149
218
|
*/
|
|
150
219
|
async sendPushNotification(notification) {
|
|
220
|
+
var _a;
|
|
151
221
|
try {
|
|
222
|
+
Logger.info(
|
|
223
|
+
`[NotificationsAdmin] Processing notification ${notification.id} for sending`,
|
|
224
|
+
{
|
|
225
|
+
userId: notification.userId,
|
|
226
|
+
tokenCount: ((_a = notification.notificationTokens) == null ? void 0 : _a.length) || 0,
|
|
227
|
+
type: notification.notificationType
|
|
228
|
+
}
|
|
229
|
+
);
|
|
152
230
|
const messages = this.prepareExpoMessage(notification);
|
|
153
231
|
if (messages.length === 0) {
|
|
232
|
+
const errorMsg = "No valid notification tokens found";
|
|
233
|
+
Logger.error(
|
|
234
|
+
`[NotificationsAdmin] ${errorMsg} for notification ${notification.id}`
|
|
235
|
+
);
|
|
154
236
|
await this.updateNotificationStatus(
|
|
155
237
|
notification.id,
|
|
156
238
|
"failed" /* FAILED */,
|
|
157
|
-
|
|
239
|
+
errorMsg
|
|
158
240
|
);
|
|
159
241
|
return false;
|
|
160
242
|
}
|
|
161
243
|
const chunks = this.expo.chunkPushNotifications(messages);
|
|
244
|
+
Logger.info(
|
|
245
|
+
`[NotificationsAdmin] Sending ${messages.length} messages in ${chunks.length} chunks for notification ${notification.id}`
|
|
246
|
+
);
|
|
162
247
|
const tickets = [];
|
|
163
|
-
for (
|
|
248
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
249
|
+
const chunk = chunks[i];
|
|
164
250
|
try {
|
|
251
|
+
Logger.info(
|
|
252
|
+
`[NotificationsAdmin] Sending chunk ${i + 1}/${chunks.length} with ${chunk.length} messages`
|
|
253
|
+
);
|
|
165
254
|
const ticketChunk = await this.expo.sendPushNotificationsAsync(chunk);
|
|
255
|
+
Logger.info(
|
|
256
|
+
`[NotificationsAdmin] Received ${ticketChunk.length} tickets for chunk ${i + 1}`
|
|
257
|
+
);
|
|
166
258
|
tickets.push(ticketChunk);
|
|
167
259
|
} catch (error) {
|
|
168
|
-
|
|
260
|
+
Logger.error(
|
|
261
|
+
`[NotificationsAdmin] Chunk ${i + 1} sending error:`,
|
|
262
|
+
error
|
|
263
|
+
);
|
|
169
264
|
throw error;
|
|
170
265
|
}
|
|
171
266
|
}
|
|
172
267
|
let hasErrors = false;
|
|
173
268
|
const errors = [];
|
|
174
|
-
tickets.flat()
|
|
269
|
+
const ticketsFlat = tickets.flat();
|
|
270
|
+
const ticketResults = {
|
|
271
|
+
total: ticketsFlat.length,
|
|
272
|
+
success: 0,
|
|
273
|
+
error: 0,
|
|
274
|
+
errorDetails: {}
|
|
275
|
+
};
|
|
276
|
+
ticketsFlat.forEach((ticket, index) => {
|
|
175
277
|
if (ticket.status === "error") {
|
|
176
278
|
hasErrors = true;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
);
|
|
279
|
+
ticketResults.error++;
|
|
280
|
+
const errorMessage = ticket.message || "Unknown error";
|
|
281
|
+
ticketResults.errorDetails[errorMessage] = (ticketResults.errorDetails[errorMessage] || 0) + 1;
|
|
282
|
+
const tokenInfo = index < notification.notificationTokens.length ? `Token ${notification.notificationTokens[index]}` : `Token at index ${index}`;
|
|
283
|
+
errors.push(`${tokenInfo}: ${errorMessage}`);
|
|
284
|
+
} else {
|
|
285
|
+
ticketResults.success++;
|
|
180
286
|
}
|
|
181
287
|
});
|
|
288
|
+
Logger.info(
|
|
289
|
+
`[NotificationsAdmin] Ticket results for notification ${notification.id}`,
|
|
290
|
+
ticketResults
|
|
291
|
+
);
|
|
182
292
|
if (hasErrors) {
|
|
293
|
+
const errorSummary = errors.join("; ");
|
|
294
|
+
Logger.warn(
|
|
295
|
+
`[NotificationsAdmin] Partial success or errors in notification ${notification.id}`,
|
|
296
|
+
{ errorCount: errors.length, errorSummary }
|
|
297
|
+
);
|
|
183
298
|
await this.updateNotificationStatus(
|
|
184
299
|
notification.id,
|
|
185
|
-
"partialSuccess" /* PARTIAL_SUCCESS */,
|
|
186
|
-
|
|
300
|
+
ticketResults.success > 0 ? "partialSuccess" /* PARTIAL_SUCCESS */ : "failed" /* FAILED */,
|
|
301
|
+
errorSummary
|
|
187
302
|
);
|
|
188
|
-
return
|
|
303
|
+
return ticketResults.success > 0;
|
|
189
304
|
}
|
|
305
|
+
Logger.info(
|
|
306
|
+
`[NotificationsAdmin] Successfully sent notification ${notification.id} to all recipients`
|
|
307
|
+
);
|
|
190
308
|
await this.updateNotificationStatus(
|
|
191
309
|
notification.id,
|
|
192
310
|
"sent" /* SENT */
|
|
@@ -194,7 +312,10 @@ var NotificationsAdmin = class {
|
|
|
194
312
|
return true;
|
|
195
313
|
} catch (error) {
|
|
196
314
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
197
|
-
|
|
315
|
+
Logger.error(
|
|
316
|
+
`[NotificationsAdmin] Critical error sending notification ${notification.id}:`,
|
|
317
|
+
error
|
|
318
|
+
);
|
|
198
319
|
await this.updateNotificationStatus(
|
|
199
320
|
notification.id,
|
|
200
321
|
"failed" /* FAILED */,
|
|
@@ -208,13 +329,28 @@ var NotificationsAdmin = class {
|
|
|
208
329
|
*/
|
|
209
330
|
async processPendingNotifications(batchSize = 100) {
|
|
210
331
|
const now = admin.firestore.Timestamp.now();
|
|
332
|
+
Logger.info(
|
|
333
|
+
`[NotificationsAdmin] Starting to process pending notifications with batch size ${batchSize}`
|
|
334
|
+
);
|
|
211
335
|
const pendingNotifications = await this.db.collection("notifications").where("status", "==", "pending" /* PENDING */).where("notificationTime", "<=", now).limit(batchSize).get();
|
|
336
|
+
Logger.info(
|
|
337
|
+
`[NotificationsAdmin] Found ${pendingNotifications.size} pending notifications to process`
|
|
338
|
+
);
|
|
339
|
+
if (pendingNotifications.empty) {
|
|
340
|
+
Logger.info(
|
|
341
|
+
"[NotificationsAdmin] No pending notifications found to process"
|
|
342
|
+
);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
212
345
|
const results = await Promise.allSettled(
|
|
213
346
|
pendingNotifications.docs.map(async (doc) => {
|
|
214
347
|
const notification = {
|
|
215
348
|
id: doc.id,
|
|
216
349
|
...doc.data()
|
|
217
350
|
};
|
|
351
|
+
Logger.info(
|
|
352
|
+
`[NotificationsAdmin] Processing notification ${notification.id} of type ${notification.notificationType}`
|
|
353
|
+
);
|
|
218
354
|
return this.sendPushNotification(notification);
|
|
219
355
|
})
|
|
220
356
|
);
|
|
@@ -224,8 +360,8 @@ var NotificationsAdmin = class {
|
|
|
224
360
|
const failed = results.filter(
|
|
225
361
|
(r) => r.status === "rejected" || r.status === "fulfilled" && !r.value
|
|
226
362
|
).length;
|
|
227
|
-
|
|
228
|
-
`Processed ${results.length} notifications: ${successful} successful, ${failed} failed`
|
|
363
|
+
Logger.info(
|
|
364
|
+
`[NotificationsAdmin] Processed ${results.length} notifications: ${successful} successful, ${failed} failed`
|
|
229
365
|
);
|
|
230
366
|
}
|
|
231
367
|
/**
|
|
@@ -234,6 +370,10 @@ var NotificationsAdmin = class {
|
|
|
234
370
|
async cleanupOldNotifications(daysOld = 30, batchSize = 500) {
|
|
235
371
|
const cutoffDate = /* @__PURE__ */ new Date();
|
|
236
372
|
cutoffDate.setDate(cutoffDate.getDate() - daysOld);
|
|
373
|
+
Logger.info(
|
|
374
|
+
`[NotificationsAdmin] Starting cleanup of notifications older than ${daysOld} days`
|
|
375
|
+
);
|
|
376
|
+
let totalDeleted = 0;
|
|
237
377
|
while (true) {
|
|
238
378
|
const oldNotifications = await this.db.collection("notifications").where(
|
|
239
379
|
"createdAt",
|
|
@@ -241,6 +381,9 @@ var NotificationsAdmin = class {
|
|
|
241
381
|
admin.firestore.Timestamp.fromDate(cutoffDate)
|
|
242
382
|
).limit(batchSize).get();
|
|
243
383
|
if (oldNotifications.empty) {
|
|
384
|
+
Logger.info(
|
|
385
|
+
`[NotificationsAdmin] No more old notifications to delete. Total deleted: ${totalDeleted}`
|
|
386
|
+
);
|
|
244
387
|
break;
|
|
245
388
|
}
|
|
246
389
|
const batch = this.db.batch();
|
|
@@ -248,8 +391,9 @@ var NotificationsAdmin = class {
|
|
|
248
391
|
batch.delete(doc.ref);
|
|
249
392
|
});
|
|
250
393
|
await batch.commit();
|
|
251
|
-
|
|
252
|
-
|
|
394
|
+
totalDeleted += oldNotifications.size;
|
|
395
|
+
Logger.info(
|
|
396
|
+
`[NotificationsAdmin] Deleted batch of ${oldNotifications.size} old notifications. Running total: ${totalDeleted}`
|
|
253
397
|
);
|
|
254
398
|
}
|
|
255
399
|
}
|
|
@@ -2381,66 +2525,6 @@ var PatientRequirementsAdminService = class {
|
|
|
2381
2525
|
|
|
2382
2526
|
// src/admin/calendar/calendar.admin.service.ts
|
|
2383
2527
|
import * as admin8 from "firebase-admin";
|
|
2384
|
-
|
|
2385
|
-
// src/admin/logger/index.ts
|
|
2386
|
-
var firebaseFunctionsLogger;
|
|
2387
|
-
try {
|
|
2388
|
-
firebaseFunctionsLogger = __require("firebase-functions/logger");
|
|
2389
|
-
__require("firebase-functions/logger/compat");
|
|
2390
|
-
} catch (e) {
|
|
2391
|
-
}
|
|
2392
|
-
var Logger = class {
|
|
2393
|
-
/**
|
|
2394
|
-
* Log an error message
|
|
2395
|
-
* @param message Message to log
|
|
2396
|
-
* @param data Optional data to include
|
|
2397
|
-
*/
|
|
2398
|
-
static error(message, data) {
|
|
2399
|
-
if (firebaseFunctionsLogger) {
|
|
2400
|
-
firebaseFunctionsLogger.error(message, data);
|
|
2401
|
-
} else {
|
|
2402
|
-
console.error(message, data !== void 0 ? data : "");
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
2405
|
-
/**
|
|
2406
|
-
* Log a warning message
|
|
2407
|
-
* @param message Message to log
|
|
2408
|
-
* @param data Optional data to include
|
|
2409
|
-
*/
|
|
2410
|
-
static warn(message, data) {
|
|
2411
|
-
if (firebaseFunctionsLogger) {
|
|
2412
|
-
firebaseFunctionsLogger.warn(message, data);
|
|
2413
|
-
} else {
|
|
2414
|
-
console.warn(message, data !== void 0 ? data : "");
|
|
2415
|
-
}
|
|
2416
|
-
}
|
|
2417
|
-
/**
|
|
2418
|
-
* Log an info message
|
|
2419
|
-
* @param message Message to log
|
|
2420
|
-
* @param data Optional data to include
|
|
2421
|
-
*/
|
|
2422
|
-
static info(message, data) {
|
|
2423
|
-
if (firebaseFunctionsLogger) {
|
|
2424
|
-
firebaseFunctionsLogger.info(message, data);
|
|
2425
|
-
} else {
|
|
2426
|
-
console.info(message, data !== void 0 ? data : "");
|
|
2427
|
-
}
|
|
2428
|
-
}
|
|
2429
|
-
/**
|
|
2430
|
-
* Log a debug message
|
|
2431
|
-
* @param message Message to log
|
|
2432
|
-
* @param data Optional data to include
|
|
2433
|
-
*/
|
|
2434
|
-
static debug(message, data) {
|
|
2435
|
-
if (firebaseFunctionsLogger) {
|
|
2436
|
-
firebaseFunctionsLogger.debug(message, data);
|
|
2437
|
-
} else {
|
|
2438
|
-
console.debug(message, data !== void 0 ? data : "");
|
|
2439
|
-
}
|
|
2440
|
-
}
|
|
2441
|
-
};
|
|
2442
|
-
|
|
2443
|
-
// src/admin/calendar/calendar.admin.service.ts
|
|
2444
2528
|
var CalendarAdminService = class {
|
|
2445
2529
|
constructor(firestore12) {
|
|
2446
2530
|
this.db = firestore12 || admin8.firestore();
|
package/package.json
CHANGED
|
@@ -9,6 +9,7 @@ import { Appointment, PaymentStatus } from "../../types/appointment";
|
|
|
9
9
|
import { UserRole } from "../../types";
|
|
10
10
|
import { Timestamp as FirebaseClientTimestamp } from "@firebase/firestore";
|
|
11
11
|
import { TimestampUtils } from "../../utils/TimestampUtils";
|
|
12
|
+
import { Logger } from "../logger";
|
|
12
13
|
|
|
13
14
|
export class NotificationsAdmin {
|
|
14
15
|
private expo: Expo;
|
|
@@ -46,19 +47,31 @@ export class NotificationsAdmin {
|
|
|
46
47
|
* Priprema Expo poruku za slanje
|
|
47
48
|
*/
|
|
48
49
|
private prepareExpoMessage(notification: Notification): ExpoPushMessage[] {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
50
|
+
const validTokens = notification.notificationTokens.filter((token) =>
|
|
51
|
+
Expo.isExpoPushToken(token)
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
Logger.info(
|
|
55
|
+
`[NotificationsAdmin] Preparing Expo messages for notification ${notification.id}`,
|
|
56
|
+
{
|
|
57
|
+
totalTokens: notification.notificationTokens.length,
|
|
58
|
+
validTokens: validTokens.length,
|
|
59
|
+
invalidTokensCount:
|
|
60
|
+
notification.notificationTokens.length - validTokens.length,
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return validTokens.map((token) => ({
|
|
65
|
+
to: token,
|
|
66
|
+
sound: "default",
|
|
67
|
+
title: notification.title,
|
|
68
|
+
body: notification.body,
|
|
69
|
+
data: {
|
|
70
|
+
notificationId: notification.id,
|
|
71
|
+
notificationType: notification.notificationType,
|
|
72
|
+
userId: notification.userId,
|
|
73
|
+
},
|
|
74
|
+
}));
|
|
62
75
|
}
|
|
63
76
|
|
|
64
77
|
/**
|
|
@@ -93,27 +106,58 @@ export class NotificationsAdmin {
|
|
|
93
106
|
*/
|
|
94
107
|
async sendPushNotification(notification: Notification): Promise<boolean> {
|
|
95
108
|
try {
|
|
109
|
+
Logger.info(
|
|
110
|
+
`[NotificationsAdmin] Processing notification ${notification.id} for sending`,
|
|
111
|
+
{
|
|
112
|
+
userId: notification.userId,
|
|
113
|
+
tokenCount: notification.notificationTokens?.length || 0,
|
|
114
|
+
type: notification.notificationType,
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
|
|
96
118
|
const messages = this.prepareExpoMessage(notification);
|
|
97
119
|
|
|
98
120
|
if (messages.length === 0) {
|
|
121
|
+
const errorMsg = "No valid notification tokens found";
|
|
122
|
+
Logger.error(
|
|
123
|
+
`[NotificationsAdmin] ${errorMsg} for notification ${notification.id}`
|
|
124
|
+
);
|
|
99
125
|
await this.updateNotificationStatus(
|
|
100
126
|
notification.id!,
|
|
101
127
|
NotificationStatus.FAILED,
|
|
102
|
-
|
|
128
|
+
errorMsg
|
|
103
129
|
);
|
|
104
130
|
return false;
|
|
105
131
|
}
|
|
106
132
|
|
|
107
133
|
const chunks = this.expo.chunkPushNotifications(messages);
|
|
134
|
+
Logger.info(
|
|
135
|
+
`[NotificationsAdmin] Sending ${messages.length} messages in ${chunks.length} chunks for notification ${notification.id}`
|
|
136
|
+
);
|
|
137
|
+
|
|
108
138
|
const tickets: ExpoPushTicket[][] = [];
|
|
109
139
|
|
|
110
140
|
// Šaljemo sve chunks
|
|
111
|
-
for (
|
|
141
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
142
|
+
const chunk = chunks[i];
|
|
112
143
|
try {
|
|
144
|
+
Logger.info(
|
|
145
|
+
`[NotificationsAdmin] Sending chunk ${i + 1}/${
|
|
146
|
+
chunks.length
|
|
147
|
+
} with ${chunk.length} messages`
|
|
148
|
+
);
|
|
113
149
|
const ticketChunk = await this.expo.sendPushNotificationsAsync(chunk);
|
|
150
|
+
Logger.info(
|
|
151
|
+
`[NotificationsAdmin] Received ${
|
|
152
|
+
ticketChunk.length
|
|
153
|
+
} tickets for chunk ${i + 1}`
|
|
154
|
+
);
|
|
114
155
|
tickets.push(ticketChunk);
|
|
115
156
|
} catch (error) {
|
|
116
|
-
|
|
157
|
+
Logger.error(
|
|
158
|
+
`[NotificationsAdmin] Chunk ${i + 1} sending error:`,
|
|
159
|
+
error
|
|
160
|
+
);
|
|
117
161
|
throw error;
|
|
118
162
|
}
|
|
119
163
|
}
|
|
@@ -121,25 +165,62 @@ export class NotificationsAdmin {
|
|
|
121
165
|
// Proveravamo rezultate
|
|
122
166
|
let hasErrors = false;
|
|
123
167
|
const errors: string[] = [];
|
|
168
|
+
const ticketsFlat = tickets.flat();
|
|
124
169
|
|
|
125
|
-
|
|
170
|
+
// Log detailed ticket information
|
|
171
|
+
const ticketResults = {
|
|
172
|
+
total: ticketsFlat.length,
|
|
173
|
+
success: 0,
|
|
174
|
+
error: 0,
|
|
175
|
+
errorDetails: {} as Record<string, number>,
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
ticketsFlat.forEach((ticket, index) => {
|
|
126
179
|
if (ticket.status === "error") {
|
|
127
180
|
hasErrors = true;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
181
|
+
ticketResults.error++;
|
|
182
|
+
|
|
183
|
+
// Count each error type
|
|
184
|
+
const errorMessage = ticket.message || "Unknown error";
|
|
185
|
+
ticketResults.errorDetails[errorMessage] =
|
|
186
|
+
(ticketResults.errorDetails[errorMessage] || 0) + 1;
|
|
187
|
+
|
|
188
|
+
const tokenInfo =
|
|
189
|
+
index < notification.notificationTokens.length
|
|
190
|
+
? `Token ${notification.notificationTokens[index]}`
|
|
191
|
+
: `Token at index ${index}`;
|
|
192
|
+
|
|
193
|
+
errors.push(`${tokenInfo}: ${errorMessage}`);
|
|
194
|
+
} else {
|
|
195
|
+
ticketResults.success++;
|
|
131
196
|
}
|
|
132
197
|
});
|
|
133
198
|
|
|
199
|
+
Logger.info(
|
|
200
|
+
`[NotificationsAdmin] Ticket results for notification ${notification.id}`,
|
|
201
|
+
ticketResults
|
|
202
|
+
);
|
|
203
|
+
|
|
134
204
|
if (hasErrors) {
|
|
205
|
+
const errorSummary = errors.join("; ");
|
|
206
|
+
Logger.warn(
|
|
207
|
+
`[NotificationsAdmin] Partial success or errors in notification ${notification.id}`,
|
|
208
|
+
{ errorCount: errors.length, errorSummary }
|
|
209
|
+
);
|
|
210
|
+
|
|
135
211
|
await this.updateNotificationStatus(
|
|
136
212
|
notification.id!,
|
|
137
|
-
|
|
138
|
-
|
|
213
|
+
ticketResults.success > 0
|
|
214
|
+
? NotificationStatus.PARTIAL_SUCCESS
|
|
215
|
+
: NotificationStatus.FAILED,
|
|
216
|
+
errorSummary
|
|
139
217
|
);
|
|
140
|
-
return
|
|
218
|
+
return ticketResults.success > 0;
|
|
141
219
|
}
|
|
142
220
|
|
|
221
|
+
Logger.info(
|
|
222
|
+
`[NotificationsAdmin] Successfully sent notification ${notification.id} to all recipients`
|
|
223
|
+
);
|
|
143
224
|
await this.updateNotificationStatus(
|
|
144
225
|
notification.id!,
|
|
145
226
|
NotificationStatus.SENT
|
|
@@ -148,7 +229,10 @@ export class NotificationsAdmin {
|
|
|
148
229
|
} catch (error) {
|
|
149
230
|
const errorMessage =
|
|
150
231
|
error instanceof Error ? error.message : "Unknown error";
|
|
151
|
-
|
|
232
|
+
Logger.error(
|
|
233
|
+
`[NotificationsAdmin] Critical error sending notification ${notification.id}:`,
|
|
234
|
+
error
|
|
235
|
+
);
|
|
152
236
|
await this.updateNotificationStatus(
|
|
153
237
|
notification.id!,
|
|
154
238
|
NotificationStatus.FAILED,
|
|
@@ -164,6 +248,10 @@ export class NotificationsAdmin {
|
|
|
164
248
|
async processPendingNotifications(batchSize: number = 100): Promise<void> {
|
|
165
249
|
const now = admin.firestore.Timestamp.now();
|
|
166
250
|
|
|
251
|
+
Logger.info(
|
|
252
|
+
`[NotificationsAdmin] Starting to process pending notifications with batch size ${batchSize}`
|
|
253
|
+
);
|
|
254
|
+
|
|
167
255
|
const pendingNotifications = await this.db
|
|
168
256
|
.collection("notifications")
|
|
169
257
|
.where("status", "==", NotificationStatus.PENDING)
|
|
@@ -171,12 +259,27 @@ export class NotificationsAdmin {
|
|
|
171
259
|
.limit(batchSize)
|
|
172
260
|
.get();
|
|
173
261
|
|
|
262
|
+
Logger.info(
|
|
263
|
+
`[NotificationsAdmin] Found ${pendingNotifications.size} pending notifications to process`
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
if (pendingNotifications.empty) {
|
|
267
|
+
Logger.info(
|
|
268
|
+
"[NotificationsAdmin] No pending notifications found to process"
|
|
269
|
+
);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
174
273
|
const results = await Promise.allSettled(
|
|
175
274
|
pendingNotifications.docs.map(async (doc) => {
|
|
176
275
|
const notification = {
|
|
177
276
|
id: doc.id,
|
|
178
277
|
...doc.data(),
|
|
179
278
|
} as Notification;
|
|
279
|
+
|
|
280
|
+
Logger.info(
|
|
281
|
+
`[NotificationsAdmin] Processing notification ${notification.id} of type ${notification.notificationType}`
|
|
282
|
+
);
|
|
180
283
|
return this.sendPushNotification(notification);
|
|
181
284
|
})
|
|
182
285
|
);
|
|
@@ -189,8 +292,8 @@ export class NotificationsAdmin {
|
|
|
189
292
|
(r) => r.status === "rejected" || (r.status === "fulfilled" && !r.value)
|
|
190
293
|
).length;
|
|
191
294
|
|
|
192
|
-
|
|
193
|
-
`Processed ${results.length} notifications: ${successful} successful, ${failed} failed`
|
|
295
|
+
Logger.info(
|
|
296
|
+
`[NotificationsAdmin] Processed ${results.length} notifications: ${successful} successful, ${failed} failed`
|
|
194
297
|
);
|
|
195
298
|
}
|
|
196
299
|
|
|
@@ -204,6 +307,11 @@ export class NotificationsAdmin {
|
|
|
204
307
|
const cutoffDate = new Date();
|
|
205
308
|
cutoffDate.setDate(cutoffDate.getDate() - daysOld);
|
|
206
309
|
|
|
310
|
+
Logger.info(
|
|
311
|
+
`[NotificationsAdmin] Starting cleanup of notifications older than ${daysOld} days`
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
let totalDeleted = 0;
|
|
207
315
|
while (true) {
|
|
208
316
|
const oldNotifications = await this.db
|
|
209
317
|
.collection("notifications")
|
|
@@ -216,6 +324,9 @@ export class NotificationsAdmin {
|
|
|
216
324
|
.get();
|
|
217
325
|
|
|
218
326
|
if (oldNotifications.empty) {
|
|
327
|
+
Logger.info(
|
|
328
|
+
`[NotificationsAdmin] No more old notifications to delete. Total deleted: ${totalDeleted}`
|
|
329
|
+
);
|
|
219
330
|
break;
|
|
220
331
|
}
|
|
221
332
|
|
|
@@ -225,8 +336,9 @@ export class NotificationsAdmin {
|
|
|
225
336
|
});
|
|
226
337
|
|
|
227
338
|
await batch.commit();
|
|
228
|
-
|
|
229
|
-
|
|
339
|
+
totalDeleted += oldNotifications.size;
|
|
340
|
+
Logger.info(
|
|
341
|
+
`[NotificationsAdmin] Deleted batch of ${oldNotifications.size} old notifications. Running total: ${totalDeleted}`
|
|
230
342
|
);
|
|
231
343
|
}
|
|
232
344
|
}
|