@timardex/cluemart-server-shared 1.0.208 → 1.0.211
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/{chunk-3BUXU7KR.mjs → chunk-7C3KPJ33.mjs} +39 -9
- package/dist/chunk-7C3KPJ33.mjs.map +1 -0
- package/dist/index.cjs +145 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +13 -7
- package/dist/index.d.ts +13 -7
- package/dist/index.mjs +142 -41
- package/dist/index.mjs.map +1 -1
- package/dist/mongoose/index.cjs +38 -8
- package/dist/mongoose/index.cjs.map +1 -1
- package/dist/mongoose/index.mjs +1 -1
- package/dist/service/index.cjs +143 -41
- package/dist/service/index.cjs.map +1 -1
- package/dist/service/index.d.mts +14 -8
- package/dist/service/index.d.ts +14 -8
- package/dist/service/index.mjs +105 -34
- package/dist/service/index.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-3BUXU7KR.mjs.map +0 -1
package/dist/service/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { f as SchemaCreateBulkNotificationInput, O as ObjectId } from '../Chat-DYkhie3G.mjs';
|
|
2
|
-
import { EnumUserLicence,
|
|
2
|
+
import { EnumUserLicence, DateTimeType, EventListItemType, DateTimeWithPriceType } from '@timardex/cluemart-shared';
|
|
3
|
+
import dayjs from 'dayjs';
|
|
3
4
|
import { DateTimeType as DateTimeType$1 } from '@timardex/cluemart-shared/types';
|
|
4
5
|
import { S as SchemaRelationType } from '../Relation-BjYghDE9.mjs';
|
|
5
6
|
import 'mongoose';
|
|
@@ -38,6 +39,17 @@ declare function updateVendorBasedOnUserLicense(userId: ObjectId, licenceType: E
|
|
|
38
39
|
*/
|
|
39
40
|
declare function convertObjectIdsToStrings(obj: any): any;
|
|
40
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Updates the dateStatus field for a single DateTimeType object based on the current date/time
|
|
44
|
+
* @param dateTime The date-time object to update
|
|
45
|
+
* @returns A new object with updated dateStatus value
|
|
46
|
+
*/
|
|
47
|
+
declare function updateSingleDateTimeStatus<T extends DateTimeType>(dateTime: T, now?: dayjs.Dayjs): T;
|
|
48
|
+
/**
|
|
49
|
+
* Recomputes dateStatus for every dateTime slot on events and google imported markets.
|
|
50
|
+
*/
|
|
51
|
+
declare function updateAllEventDateTimeStatuses(): Promise<void>;
|
|
52
|
+
|
|
41
53
|
type EventOrMarket = Pick<EventListItemType, "_id" | "name"> | null;
|
|
42
54
|
/**
|
|
43
55
|
* This function attempts to find an Event or a Google Imported Market by the given resource ID.
|
|
@@ -48,12 +60,6 @@ type EventOrMarket = Pick<EventListItemType, "_id" | "name"> | null;
|
|
|
48
60
|
* @returns A promise that resolves to either an Event or a Google Imported Market object containing _id and name, or null if not found.
|
|
49
61
|
*/
|
|
50
62
|
declare function findEventOrImportedMarketById(resourceId: ObjectId | string | null | undefined): Promise<EventOrMarket>;
|
|
51
|
-
/**
|
|
52
|
-
* Updates the dateStatus field for a single DateTimeType object based on the current date/time
|
|
53
|
-
* @param dateTime The date-time object to update
|
|
54
|
-
* @returns A new object with updated dateStatus value
|
|
55
|
-
*/
|
|
56
|
-
declare function updateSingleDateTimeStatus<T extends DateTimeType>(dateTime: T): T;
|
|
57
63
|
|
|
58
64
|
type EventDateSlot = Pick<DateTimeType$1, "startDate" | "startTime">;
|
|
59
65
|
/**
|
|
@@ -67,4 +73,4 @@ declare function didRemoveAnyEventDates(previousDateTime: EventDateSlot[] | unde
|
|
|
67
73
|
*/
|
|
68
74
|
declare function updateRelationDatesToUnavailable(relationDates: SchemaRelationType["relationDates"], eventDateTime: DateTimeWithPriceType[] | undefined): SchemaRelationType["relationDates"];
|
|
69
75
|
|
|
70
|
-
export { connectToDatabase, convertObjectIdsToStrings, didRemoveAnyEventDates, findEventOrImportedMarketById, saveNotificationsInDb, sendPushNotifications, updateAdStatuses, updateRelationDatesToUnavailable, updateSingleDateTimeStatus, updateVendorBasedOnUserLicense };
|
|
76
|
+
export { connectToDatabase, convertObjectIdsToStrings, didRemoveAnyEventDates, findEventOrImportedMarketById, saveNotificationsInDb, sendPushNotifications, updateAdStatuses, updateAllEventDateTimeStatuses, updateRelationDatesToUnavailable, updateSingleDateTimeStatus, updateVendorBasedOnUserLicense };
|
package/dist/service/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { f as SchemaCreateBulkNotificationInput, O as ObjectId } from '../Chat-DYkhie3G.js';
|
|
2
|
-
import { EnumUserLicence,
|
|
2
|
+
import { EnumUserLicence, DateTimeType, EventListItemType, DateTimeWithPriceType } from '@timardex/cluemart-shared';
|
|
3
|
+
import dayjs from 'dayjs';
|
|
3
4
|
import { DateTimeType as DateTimeType$1 } from '@timardex/cluemart-shared/types';
|
|
4
5
|
import { S as SchemaRelationType } from '../Relation-6t3Gn4pM.js';
|
|
5
6
|
import 'mongoose';
|
|
@@ -38,6 +39,17 @@ declare function updateVendorBasedOnUserLicense(userId: ObjectId, licenceType: E
|
|
|
38
39
|
*/
|
|
39
40
|
declare function convertObjectIdsToStrings(obj: any): any;
|
|
40
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Updates the dateStatus field for a single DateTimeType object based on the current date/time
|
|
44
|
+
* @param dateTime The date-time object to update
|
|
45
|
+
* @returns A new object with updated dateStatus value
|
|
46
|
+
*/
|
|
47
|
+
declare function updateSingleDateTimeStatus<T extends DateTimeType>(dateTime: T, now?: dayjs.Dayjs): T;
|
|
48
|
+
/**
|
|
49
|
+
* Recomputes dateStatus for every dateTime slot on events and google imported markets.
|
|
50
|
+
*/
|
|
51
|
+
declare function updateAllEventDateTimeStatuses(): Promise<void>;
|
|
52
|
+
|
|
41
53
|
type EventOrMarket = Pick<EventListItemType, "_id" | "name"> | null;
|
|
42
54
|
/**
|
|
43
55
|
* This function attempts to find an Event or a Google Imported Market by the given resource ID.
|
|
@@ -48,12 +60,6 @@ type EventOrMarket = Pick<EventListItemType, "_id" | "name"> | null;
|
|
|
48
60
|
* @returns A promise that resolves to either an Event or a Google Imported Market object containing _id and name, or null if not found.
|
|
49
61
|
*/
|
|
50
62
|
declare function findEventOrImportedMarketById(resourceId: ObjectId | string | null | undefined): Promise<EventOrMarket>;
|
|
51
|
-
/**
|
|
52
|
-
* Updates the dateStatus field for a single DateTimeType object based on the current date/time
|
|
53
|
-
* @param dateTime The date-time object to update
|
|
54
|
-
* @returns A new object with updated dateStatus value
|
|
55
|
-
*/
|
|
56
|
-
declare function updateSingleDateTimeStatus<T extends DateTimeType>(dateTime: T): T;
|
|
57
63
|
|
|
58
64
|
type EventDateSlot = Pick<DateTimeType$1, "startDate" | "startTime">;
|
|
59
65
|
/**
|
|
@@ -67,4 +73,4 @@ declare function didRemoveAnyEventDates(previousDateTime: EventDateSlot[] | unde
|
|
|
67
73
|
*/
|
|
68
74
|
declare function updateRelationDatesToUnavailable(relationDates: SchemaRelationType["relationDates"], eventDateTime: DateTimeWithPriceType[] | undefined): SchemaRelationType["relationDates"];
|
|
69
75
|
|
|
70
|
-
export { connectToDatabase, convertObjectIdsToStrings, didRemoveAnyEventDates, findEventOrImportedMarketById, saveNotificationsInDb, sendPushNotifications, updateAdStatuses, updateRelationDatesToUnavailable, updateSingleDateTimeStatus, updateVendorBasedOnUserLicense };
|
|
76
|
+
export { connectToDatabase, convertObjectIdsToStrings, didRemoveAnyEventDates, findEventOrImportedMarketById, saveNotificationsInDb, sendPushNotifications, updateAdStatuses, updateAllEventDateTimeStatuses, updateRelationDatesToUnavailable, updateSingleDateTimeStatus, updateVendorBasedOnUserLicense };
|
package/dist/service/index.mjs
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
VendorModel,
|
|
16
16
|
dateFormat,
|
|
17
17
|
timeFormat
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-7C3KPJ33.mjs";
|
|
19
19
|
|
|
20
20
|
// src/service/database.ts
|
|
21
21
|
import mongoose from "mongoose";
|
|
@@ -386,32 +386,21 @@ function convertObjectIdsToStrings(obj) {
|
|
|
386
386
|
return obj;
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
-
// src/service/event.ts
|
|
389
|
+
// src/service/event/updateAllEventDateTimeStatuses.ts
|
|
390
390
|
import dayjs from "dayjs";
|
|
391
391
|
import customParseFormat from "dayjs/plugin/customParseFormat";
|
|
392
392
|
import isoWeek from "dayjs/plugin/isoWeek";
|
|
393
|
-
import isToday from "dayjs/plugin/isToday";
|
|
394
|
-
import isTomorrow from "dayjs/plugin/isTomorrow";
|
|
395
393
|
dayjs.extend(customParseFormat);
|
|
396
|
-
dayjs.extend(isToday);
|
|
397
|
-
dayjs.extend(isTomorrow);
|
|
398
394
|
dayjs.extend(isoWeek);
|
|
399
|
-
async function findEventOrImportedMarketById(resourceId) {
|
|
400
|
-
if (!resourceId) {
|
|
401
|
-
return null;
|
|
402
|
-
}
|
|
403
|
-
const normalizedId = convertObjectIdsToStrings(resourceId);
|
|
404
|
-
const [eventDoc, googleImportedDoc] = await Promise.all([
|
|
405
|
-
EventModel.findById(normalizedId).select("_id name").lean().exec(),
|
|
406
|
-
GoogleImportedMarketModel.findById(normalizedId).select("_id name").lean().exec()
|
|
407
|
-
]);
|
|
408
|
-
return eventDoc ?? googleImportedDoc;
|
|
409
|
-
}
|
|
410
395
|
function getFutureEventStatus(startDateTime, now) {
|
|
411
|
-
|
|
396
|
+
const hoursUntilStart = startDateTime.diff(now, "hour", true);
|
|
397
|
+
if (hoursUntilStart > 0 && hoursUntilStart <= 4) {
|
|
398
|
+
return EnumEventDateStatus.STARTING_SOON;
|
|
399
|
+
}
|
|
400
|
+
if (startDateTime.isSame(now, "day")) {
|
|
412
401
|
return EnumEventDateStatus.TODAY;
|
|
413
402
|
}
|
|
414
|
-
if (startDateTime.
|
|
403
|
+
if (startDateTime.isSame(now.add(1, "day"), "day")) {
|
|
415
404
|
return EnumEventDateStatus.TOMORROW;
|
|
416
405
|
}
|
|
417
406
|
if (startDateTime.isSame(now, "isoWeek")) {
|
|
@@ -420,41 +409,122 @@ function getFutureEventStatus(startDateTime, now) {
|
|
|
420
409
|
if (startDateTime.isSame(now.add(1, "week"), "isoWeek")) {
|
|
421
410
|
return EnumEventDateStatus.NEXT_WEEK;
|
|
422
411
|
}
|
|
423
|
-
const hoursUntilStart = startDateTime.diff(now, "hour", true);
|
|
424
|
-
if (hoursUntilStart > 0 && hoursUntilStart <= 4) {
|
|
425
|
-
return EnumEventDateStatus.STARTING_SOON;
|
|
426
|
-
}
|
|
427
412
|
return EnumEventDateStatus.UPCOMING;
|
|
428
413
|
}
|
|
429
|
-
function updateSingleDateTimeStatus(dateTime) {
|
|
430
|
-
const
|
|
414
|
+
function updateSingleDateTimeStatus(dateTime, now = dayjs()) {
|
|
415
|
+
const dateTimeFormat = `${dateFormat} ${timeFormat}`;
|
|
431
416
|
const startDateTime = dayjs(
|
|
432
417
|
`${dateTime.startDate} ${dateTime.startTime}`,
|
|
433
|
-
|
|
418
|
+
dateTimeFormat,
|
|
419
|
+
true
|
|
434
420
|
);
|
|
435
421
|
const endDateTime = dayjs(
|
|
436
422
|
`${dateTime.endDate} ${dateTime.endTime}`,
|
|
437
|
-
|
|
423
|
+
dateTimeFormat,
|
|
424
|
+
true
|
|
438
425
|
);
|
|
439
426
|
if (!startDateTime.isValid() || !endDateTime.isValid()) {
|
|
440
427
|
return {
|
|
441
428
|
...dateTime,
|
|
442
|
-
dateStatus:
|
|
429
|
+
dateStatus: EnumEventDateStatus.INVALID
|
|
443
430
|
};
|
|
444
431
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
432
|
+
if (endDateTime.isBefore(startDateTime)) {
|
|
433
|
+
return {
|
|
434
|
+
...dateTime,
|
|
435
|
+
dateStatus: EnumEventDateStatus.INVALID
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
let dateStatus;
|
|
439
|
+
if (endDateTime.isAfter(now)) {
|
|
440
|
+
if (startDateTime.isAfter(now)) {
|
|
441
|
+
dateStatus = getFutureEventStatus(startDateTime, now);
|
|
442
|
+
} else {
|
|
443
|
+
dateStatus = EnumEventDateStatus.STARTED;
|
|
444
|
+
}
|
|
450
445
|
} else {
|
|
451
|
-
dateStatus =
|
|
446
|
+
dateStatus = EnumEventDateStatus.ENDED;
|
|
452
447
|
}
|
|
453
448
|
return {
|
|
454
449
|
...dateTime,
|
|
455
450
|
dateStatus
|
|
456
451
|
};
|
|
457
452
|
}
|
|
453
|
+
var dateTimeStatusFilter = {
|
|
454
|
+
dateTime: { $ne: [], $type: "array" },
|
|
455
|
+
deletedAt: null
|
|
456
|
+
};
|
|
457
|
+
var CURSOR_BATCH_SIZE = 50;
|
|
458
|
+
function hasDateTimeStatusChanges(stored, updated) {
|
|
459
|
+
if (stored.length !== updated.length) {
|
|
460
|
+
return true;
|
|
461
|
+
}
|
|
462
|
+
return stored.some(
|
|
463
|
+
(slot, index) => slot.dateStatus !== updated[index].dateStatus
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
async function updateModelDateTimeStatuses(model, now) {
|
|
467
|
+
let updated = 0;
|
|
468
|
+
const cursor = model.find(dateTimeStatusFilter).select({ _id: 1, dateTime: 1 }).lean().cursor({ batchSize: CURSOR_BATCH_SIZE });
|
|
469
|
+
let bulkOps = [];
|
|
470
|
+
const flushBulkWrites = async () => {
|
|
471
|
+
if (!bulkOps.length) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
await model.bulkWrite(bulkOps);
|
|
475
|
+
updated += bulkOps.length;
|
|
476
|
+
bulkOps = [];
|
|
477
|
+
};
|
|
478
|
+
try {
|
|
479
|
+
for await (const doc of cursor) {
|
|
480
|
+
const dateTime = doc.dateTime.map(
|
|
481
|
+
(slot) => updateSingleDateTimeStatus(slot, now)
|
|
482
|
+
);
|
|
483
|
+
if (!hasDateTimeStatusChanges(doc.dateTime, dateTime)) {
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
bulkOps.push({
|
|
487
|
+
updateOne: {
|
|
488
|
+
filter: { _id: doc._id },
|
|
489
|
+
update: { $set: { dateTime } }
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
if (bulkOps.length >= CURSOR_BATCH_SIZE) {
|
|
493
|
+
await flushBulkWrites();
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
await flushBulkWrites();
|
|
497
|
+
} finally {
|
|
498
|
+
await cursor.close().catch(() => void 0);
|
|
499
|
+
}
|
|
500
|
+
return updated;
|
|
501
|
+
}
|
|
502
|
+
async function updateAllEventDateTimeStatuses() {
|
|
503
|
+
const now = dayjs();
|
|
504
|
+
const [eventCount, marketCount] = await Promise.all([
|
|
505
|
+
updateModelDateTimeStatuses(EventModel, now),
|
|
506
|
+
updateModelDateTimeStatuses(
|
|
507
|
+
GoogleImportedMarketModel,
|
|
508
|
+
now
|
|
509
|
+
)
|
|
510
|
+
]);
|
|
511
|
+
console.log(
|
|
512
|
+
`\u2705 Event dateTime statuses updated: events=${eventCount} changed, google imported markets=${marketCount} changed`
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// src/service/event/findEventOrImportedMarketById.ts
|
|
517
|
+
async function findEventOrImportedMarketById(resourceId) {
|
|
518
|
+
if (!resourceId) {
|
|
519
|
+
return null;
|
|
520
|
+
}
|
|
521
|
+
const normalizedId = convertObjectIdsToStrings(resourceId);
|
|
522
|
+
const [eventDoc, googleImportedDoc] = await Promise.all([
|
|
523
|
+
EventModel.findById(normalizedId).select("_id name").lean().exec(),
|
|
524
|
+
GoogleImportedMarketModel.findById(normalizedId).select("_id name").lean().exec()
|
|
525
|
+
]);
|
|
526
|
+
return eventDoc ?? googleImportedDoc;
|
|
527
|
+
}
|
|
458
528
|
|
|
459
529
|
// src/service/relations.ts
|
|
460
530
|
function didRemoveAnyEventDates(previousDateTime, nextDateTime) {
|
|
@@ -486,6 +556,7 @@ export {
|
|
|
486
556
|
saveNotificationsInDb,
|
|
487
557
|
sendPushNotifications,
|
|
488
558
|
updateAdStatuses,
|
|
559
|
+
updateAllEventDateTimeStatuses,
|
|
489
560
|
updateRelationDatesToUnavailable,
|
|
490
561
|
updateSingleDateTimeStatus,
|
|
491
562
|
updateVendorBasedOnUserLicense
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/service/database.ts","../../src/service/saveNotificationsInDb.ts","../../src/service/sendPushNotifications.ts","../../src/service/updateAdStatus.ts","../../src/service/associate.ts","../../src/service/vendor.ts","../../src/service/objectIdToString.ts","../../src/service/event.ts","../../src/service/relations.ts"],"sourcesContent":["import mongoose from \"mongoose\";\n\n/**\n * Connect to MongoDB using Mongoose.\n * Supports both local MongoDB (via MONGODB_URI) and MongoDB Atlas (via individual env vars).\n */\nexport const connectToDatabase = async ({\n appName,\n dbName,\n dbPassword,\n dbUser,\n mongodbUri,\n}: {\n appName: string;\n dbName: string;\n dbPassword: string;\n dbUser: string;\n mongodbUri: string;\n}) => {\n try {\n // Check if MONGODB_URI is provided (for local Docker MongoDB)\n const mongoUri = mongodbUri\n ? mongodbUri\n : // Fallback to MongoDB Atlas connection string\n `mongodb+srv://${dbUser}:${dbPassword}@${dbName}.mongodb.net/?retryWrites=true&w=majority&appName=${appName}`;\n\n await mongoose.connect(mongoUri);\n\n const connectionType = mongodbUri ? \"Local MongoDB\" : \"MongoDB Atlas\";\n console.log(\n `${connectionType} connected from server/src/service/database.ts`,\n );\n } catch (err) {\n console.error(\"Error connecting to MongoDB:\", err);\n throw err; // You can throw the error if you want to stop the server in case of connection failure\n }\n};\n","import {\n SchemaCreateBulkNotificationInput,\n NotificationModel,\n} from \"src/mongoose/Notification\";\nimport { ObjectId } from \"src/types\";\n\n/**\n * Create notifications in the database for multiple users\n * This is typically called when sending push notifications\n */\nexport async function saveNotificationsInDb(\n payload: SchemaCreateBulkNotificationInput,\n): Promise<ObjectId[]> {\n const { data, message, title, type, userIds } = payload;\n console.log('NOTIFICATION DATA', JSON.stringify(payload, null, 2));\n try {\n const notifications = userIds.map((userId) => ({\n data,\n isRead: false,\n message,\n title,\n type,\n userId,\n }));\n\n // Save notifications to database\n await NotificationModel.insertMany(notifications);\n console.log(\n `Created ${notifications.length} notifications for ${userIds.length} users`,\n );\n\n return [...new Set(userIds)];\n } catch (error) {\n console.error(\"Failed to create notifications:\", error);\n return [];\n //throw new Error(`Failed to create notifications: ${error}`);\n }\n}\n","import { NotificationDataType } from \"@timardex/cluemart-shared\";\nimport { Expo, ExpoPushMessage, ExpoPushTicket } from \"expo-server-sdk\";\n\nimport { SchemaCreateBulkNotificationInput } from \"src/mongoose/Notification\";\nimport { PushTokenModel } from \"src/mongoose/PushToken\";\n\nconst expo = new Expo();\n\n/**\n * Safely extract tokens from ExpoPushMessage handling both string and array cases\n */\nfunction extractTokensFromMessage(message: ExpoPushMessage): string[] {\n return Array.isArray(message.to) ? message.to : [message.to];\n}\n\ninterface CreatePushMessagesOptions {\n tokens: string[];\n message: string;\n title: string;\n data: NotificationDataType;\n}\n\n/**\n * Create push messages from valid tokens\n */\nfunction createPushMessages({\n tokens,\n message,\n title,\n data,\n}: CreatePushMessagesOptions): {\n messages: ExpoPushMessage[];\n invalidTokens: string[];\n} {\n const messages: ExpoPushMessage[] = [];\n const invalidTokens: string[] = [];\n\n for (const token of tokens) {\n if (!Expo.isExpoPushToken(token)) {\n invalidTokens.push(token);\n continue;\n }\n\n messages.push({\n body: message,\n data: { ...data },\n sound: \"default\",\n title,\n to: token,\n });\n }\n\n return { invalidTokens, messages };\n}\n\n/**\n * Process chunk results and extract failed tokens\n */\nfunction processChunkResults(\n tickets: ExpoPushTicket[],\n chunk: ExpoPushMessage[],\n): { successCount: number; failedTokens: string[] } {\n let successCount = 0;\n const failedTokens: string[] = [];\n\n for (const [ticketIndex, ticket] of tickets.entries()) {\n if (ticket.status === \"error\") {\n const message = chunk[ticketIndex];\n if (message) {\n const tokens = extractTokensFromMessage(message);\n if (ticket.details?.error === \"DeviceNotRegistered\") {\n failedTokens.push(...tokens);\n }\n console.log(\"Push notification error\", {\n error: ticket.details?.error,\n tokens,\n });\n }\n } else {\n successCount++;\n }\n }\n\n return { failedTokens, successCount };\n}\n\n/**\n * Send a single chunk of push notifications\n */\nasync function sendChunk(\n chunk: ExpoPushMessage[],\n chunkIndex: number,\n): Promise<{ successCount: number; failedTokens: string[] }> {\n try {\n const tickets = await expo.sendPushNotificationsAsync(chunk);\n const { successCount, failedTokens } = processChunkResults(tickets, chunk);\n\n console.log(\n `Chunk ${chunkIndex + 1}: Sent ${successCount}/${chunk.length} notifications successfully`,\n );\n\n return { failedTokens, successCount };\n } catch (error) {\n console.log(\"Error sending Expo push notification chunk\", {\n chunkIndex,\n chunkSize: chunk.length,\n error: error instanceof Error ? error.message : String(error),\n });\n return { failedTokens: [], successCount: 0 };\n }\n}\n\nexport async function sendPushNotifications({\n data,\n message,\n title,\n userIds,\n}: SchemaCreateBulkNotificationInput) {\n const pushTokens = await PushTokenModel.find({ userId: { $in: userIds } });\n const expoTokens = pushTokens.map((token) => token.token);\n\n if (!data) return;\n\n const { messages, invalidTokens } = createPushMessages({\n data,\n message,\n title,\n tokens: expoTokens,\n });\n\n // Log invalid tokens\n if (invalidTokens.length > 0) {\n console.log(`Found ${invalidTokens.length} invalid push tokens`);\n }\n\n if (messages.length === 0) {\n console.log(\"No valid messages to send after filtering tokens\");\n return;\n }\n\n // Send notifications in chunks\n const chunks = expo.chunkPushNotifications(messages);\n let totalSuccessCount = 0;\n const allFailedTokens: string[] = [];\n\n for (const [chunkIndex, chunk] of chunks.entries()) {\n const { successCount, failedTokens } = await sendChunk(\n chunk,\n chunkIndex + 1,\n );\n totalSuccessCount += successCount;\n allFailedTokens.push(...failedTokens);\n }\n\n // Log final results\n console.log(\n `Sent push notification to ${totalSuccessCount}/${messages.length} tokens across ${chunks.length} chunks`,\n );\n\n if (allFailedTokens.length > 0) {\n console.log(`Found ${allFailedTokens.length} failed push tokens`);\n }\n}\n","import { EnumAdStatus } from \"@timardex/cluemart-shared\";\n\nimport { AdModel } from \"src/mongoose\";\n\n/**\n * Updates ad statuses based on start/end dates and validity\n */\nexport async function updateAdStatuses(): Promise<void> {\n const now = new Date();\n\n // invalid\n const invalidResult = await AdModel.updateMany(\n {\n $or: [\n { start: { $exists: false } },\n { end: { $exists: false } },\n { $expr: { $gt: [\"$start\", \"$end\"] } },\n ],\n status: { $ne: EnumAdStatus.PAUSED },\n },\n { $set: { status: EnumAdStatus.PAUSED } },\n );\n\n // expired\n const expiredResult = await AdModel.updateMany(\n { end: { $lte: now }, status: { $ne: EnumAdStatus.EXPIRED } },\n { $set: { status: EnumAdStatus.EXPIRED } },\n );\n\n // active\n const activeResult = await AdModel.updateMany(\n {\n end: { $gt: now },\n start: { $lte: now },\n status: { $ne: EnumAdStatus.ACTIVE },\n },\n { $set: { status: EnumAdStatus.ACTIVE } },\n );\n\n // paused\n const pausedResult = await AdModel.updateMany(\n { start: { $gt: now }, status: { $ne: EnumAdStatus.PAUSED } },\n { $set: { status: EnumAdStatus.PAUSED } },\n );\n\n console.log(\n `✅ Ad statuses updated: invalid=${invalidResult.modifiedCount}, expired=${expiredResult.modifiedCount}, active=${activeResult.modifiedCount}, paused=${pausedResult.modifiedCount}`,\n );\n}\n","import { EnumChatType, EnumResourceType } from \"@timardex/cluemart-shared\";\nimport mongoose from \"mongoose\";\n\nimport { ChatModel, UserModel } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\ninterface RemoveAssociateFromResourceParams {\n resourceId: string | ObjectId;\n resourceOwnerId: string | ObjectId;\n resourceType: EnumResourceType;\n}\n\ninterface ResourceAssociateScope {\n normalizedResourceId: string;\n resourceType: EnumResourceType;\n}\n\nfunction normalizeObjectId(id: string | ObjectId): ObjectId {\n return typeof id === \"string\" ? new mongoose.Types.ObjectId(id) : id;\n}\n\nasync function getAssociateEmailsForResource({\n normalizedResourceId,\n resourceType,\n}: ResourceAssociateScope): Promise<string[]> {\n const usersWithAssociates = await UserModel.find(\n {\n associates: {\n $elemMatch: {\n resourceId: normalizedResourceId,\n resourceType,\n },\n },\n },\n {\n associates: 1,\n },\n ).lean();\n\n return [\n ...new Set(\n usersWithAssociates.flatMap((user) =>\n (user.associates ?? [])\n .filter(\n (associate) =>\n associate.resourceId === normalizedResourceId &&\n associate.resourceType === resourceType,\n )\n .map((associate) => associate.email),\n ),\n ),\n ];\n}\n\nasync function pullAssociatesFromUsers({\n normalizedResourceId,\n resourceType,\n}: ResourceAssociateScope): Promise<void> {\n await UserModel.updateMany(\n {\n associates: {\n $elemMatch: {\n resourceId: normalizedResourceId,\n resourceType,\n },\n },\n },\n {\n $pull: {\n associates: {\n resourceId: normalizedResourceId,\n resourceType,\n },\n },\n },\n );\n}\n\nasync function pullAssociateParticipantsFromChats(\n resourceOwnerId: ObjectId,\n associateEmails: string[],\n): Promise<void> {\n await ChatModel.updateMany(\n {\n active: true,\n chatType: EnumChatType.RELATION,\n deletedAt: null,\n participants: {\n $elemMatch: {\n userId: resourceOwnerId,\n },\n },\n },\n {\n $pull: {\n participants: {\n isAssociate: true,\n userEmail: {\n $in: associateEmails,\n },\n },\n },\n },\n );\n}\n\n/**\n * Removes all associates linked to a resource\n * and removes related associate chat participants.\n */\nexport async function removeAssociateFromResource({\n resourceId,\n resourceOwnerId,\n resourceType,\n}: RemoveAssociateFromResourceParams): Promise<void> {\n try {\n const scope: ResourceAssociateScope = {\n normalizedResourceId: resourceId.toString(),\n resourceType,\n };\n\n const associateEmails = await getAssociateEmailsForResource(scope);\n\n if (associateEmails.length === 0) {\n return;\n }\n\n await pullAssociatesFromUsers(scope);\n await pullAssociateParticipantsFromChats(\n normalizeObjectId(resourceOwnerId),\n associateEmails,\n );\n } catch (error) {\n console.error(\n `[removeAssociateFromResource] Failed for resourceId=${resourceId}, resourceType=${resourceType}`,\n error,\n );\n }\n}\n","import { EnumResourceType, EnumUserLicence } from \"@timardex/cluemart-shared\";\n\nimport { UserModel, VendorModel, SchemaVendorType } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\nimport { removeAssociateFromResource } from \"./associate\";\n\nexport async function updateVendorBasedOnUserLicense(\n userId: ObjectId,\n licenceType: EnumUserLicence,\n): Promise<void> {\n try {\n /**\n * Fetch user vendor reference\n */\n const user = await UserModel.findById(userId)\n .select(\"vendor\")\n .lean()\n .exec();\n\n if (!user?.vendor) {\n console.warn(`[updateVendor] No vendor found for userId=${userId}`);\n return;\n }\n\n /**\n * Fetch vendor\n */\n const vendor = await VendorModel.findById(user.vendor)\n .lean<SchemaVendorType>()\n .exec();\n\n if (!vendor) {\n console.warn(`[updateVendor] Vendor not found for id=${user.vendor}`);\n return;\n }\n\n /**\n * Build vendor update payload\n */\n const updateData: Partial<SchemaVendorType> = {};\n\n const isStandardVendor = licenceType === EnumUserLicence.STANDARD_VENDOR;\n\n if (isStandardVendor) {\n updateData.associates = [];\n\n updateData.availability = {\n corporate: false,\n private: false,\n school: false,\n };\n\n updateData.products = {\n active: false,\n productsList: vendor.products?.productsList ?? [],\n };\n\n updateData.calendar = {\n active: false,\n calendarData: vendor.calendar?.calendarData ?? [],\n };\n }\n\n /**\n * Image rules\n * STANDARD_VENDOR => only first 6 active\n * PRO_VENDOR => all active\n */\n updateData.images = (vendor.images ?? []).map((image, index) => ({\n ...image,\n active: isStandardVendor ? index < 6 : true,\n }));\n\n /**\n * Persist vendor updates\n */\n await VendorModel.updateOne({ _id: vendor._id }, { $set: updateData });\n\n /**\n * Cleanup associates for STANDARD licence\n */\n if (isStandardVendor) {\n await removeAssociateFromResource({\n resourceId: vendor._id,\n resourceOwnerId: vendor.owner.userId,\n resourceType: EnumResourceType.VENDOR,\n });\n }\n } catch (error) {\n console.error(\"[updateVendorBasedOnUserLicense] Failed:\", error);\n }\n}\n","import mongoose from \"mongoose\";\n\n/**\n * Recursively converts all ObjectId fields to strings in an object\n * This is needed because GraphQL expects string IDs, not ObjectIds\n */\nexport function convertObjectIdsToStrings(obj: any): any {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (obj instanceof mongoose.Types.ObjectId) {\n return obj.toString();\n }\n\n if (Array.isArray(obj)) {\n return obj.map(convertObjectIdsToStrings);\n }\n\n if (typeof obj === \"object\") {\n const converted: any = {};\n for (const [key, value] of Object.entries(obj)) {\n converted[key] = convertObjectIdsToStrings(value);\n }\n return converted;\n }\n\n return obj;\n}\n","import {\n dateFormat,\n DateTimeType,\n EnumEventDateStatus,\n EventListItemType,\n timeFormat,\n} from \"@timardex/cluemart-shared\";\nimport dayjs from \"dayjs\";\nimport customParseFormat from \"dayjs/plugin/customParseFormat\";\nimport isoWeek from \"dayjs/plugin/isoWeek\";\nimport isToday from \"dayjs/plugin/isToday\";\nimport isTomorrow from \"dayjs/plugin/isTomorrow\";\n\nimport { EventModel, GoogleImportedMarketModel } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\nimport { convertObjectIdsToStrings } from \"./objectIdToString\";\n\n// Enable custom parse format plugin\ndayjs.extend(customParseFormat);\ndayjs.extend(isToday);\ndayjs.extend(isTomorrow);\ndayjs.extend(isoWeek);\n\ntype EventOrMarket = Pick<EventListItemType, \"_id\" | \"name\"> | null;\n\n/**\n * This function attempts to find an Event or a Google Imported Market by the given resource ID.\n * It first normalizes the resource ID to a string format, then performs parallel queries to both collections.\n * If an Event is found, it returns that; otherwise, it checks for a Google Imported Market and returns it if found.\n * If neither is found, it returns null.\n * @param resourceId - The ID of the resource to find, which can be an ObjectId, string, null, or undefined.\n * @returns A promise that resolves to either an Event or a Google Imported Market object containing _id and name, or null if not found.\n */\n\nexport async function findEventOrImportedMarketById(\n resourceId: ObjectId | string | null | undefined,\n): Promise<EventOrMarket> {\n if (!resourceId) {\n return null;\n }\n\n const normalizedId = convertObjectIdsToStrings(resourceId) as string;\n\n const [eventDoc, googleImportedDoc] = await Promise.all([\n EventModel.findById(normalizedId)\n .select(\"_id name\")\n .lean<Pick<EventListItemType, \"_id\" | \"name\">>()\n .exec(),\n GoogleImportedMarketModel.findById(normalizedId)\n .select(\"_id name\")\n .lean<Pick<EventListItemType, \"_id\" | \"name\">>()\n .exec(),\n ]);\n\n return eventDoc ?? googleImportedDoc;\n}\n\n/**\n * Determines the dateStatus for a future event date\n * @param startDateTime The start date-time of the event\n * @param now The current date-time\n * @returns The appropriate EnumEventDateStatus\n */\nfunction getFutureEventStatus(\n startDateTime: dayjs.Dayjs,\n now: dayjs.Dayjs,\n): EnumEventDateStatus {\n if (startDateTime.isToday()) {\n return EnumEventDateStatus.TODAY;\n }\n\n if (startDateTime.isTomorrow()) {\n return EnumEventDateStatus.TOMORROW;\n }\n\n if (startDateTime.isSame(now, \"isoWeek\")) {\n return EnumEventDateStatus.THIS_WEEK;\n }\n\n if (startDateTime.isSame(now.add(1, \"week\"), \"isoWeek\")) {\n return EnumEventDateStatus.NEXT_WEEK;\n }\n\n const hoursUntilStart = startDateTime.diff(now, \"hour\", true);\n if (hoursUntilStart > 0 && hoursUntilStart <= 4) {\n return EnumEventDateStatus.STARTING_SOON;\n }\n\n return EnumEventDateStatus.UPCOMING;\n}\n\n/**\n * Updates the dateStatus field for a single DateTimeType object based on the current date/time\n * @param dateTime The date-time object to update\n * @returns A new object with updated dateStatus value\n */\nexport function updateSingleDateTimeStatus<T extends DateTimeType>(\n dateTime: T,\n): T {\n const now = dayjs();\n\n // Parse start and end date-time\n const startDateTime = dayjs(\n `${dateTime.startDate} ${dateTime.startTime}`,\n `${dateFormat} ${timeFormat}`,\n );\n const endDateTime = dayjs(\n `${dateTime.endDate} ${dateTime.endTime}`,\n `${dateFormat} ${timeFormat}`,\n );\n\n // Skip if dates are invalid\n if (!startDateTime.isValid() || !endDateTime.isValid()) {\n return {\n ...dateTime,\n dateStatus: null,\n };\n }\n\n let dateStatus: EnumEventDateStatus | null = null;\n\n // Check if event has ended\n if (endDateTime.isBefore(now)) {\n dateStatus = EnumEventDateStatus.ENDED;\n } else if (startDateTime.isBefore(now) && endDateTime.isAfter(now)) {\n // Event has started but not ended\n dateStatus = EnumEventDateStatus.STARTED;\n } else {\n // Event is in the future\n dateStatus = getFutureEventStatus(startDateTime, now);\n }\n\n return {\n ...dateTime,\n dateStatus,\n };\n}\n","import {\n DateTimeWithPriceType,\n EnumInviteStatus,\n} from \"@timardex/cluemart-shared\";\nimport { DateTimeType } from \"@timardex/cluemart-shared/types\";\n\nimport { SchemaRelationType } from \"src/mongoose/Relation\";\n\ntype EventDateSlot = Pick<DateTimeType, \"startDate\" | \"startTime\">;\n\n/**\n * Returns true when at least one startDate/startTime slot from the previous\n * schedule is absent from the next schedule (i.e. a date was removed).\n */\nexport function didRemoveAnyEventDates(\n previousDateTime: EventDateSlot[] | undefined,\n nextDateTime: EventDateSlot[] | undefined,\n): boolean {\n if (!previousDateTime?.length) {\n return false;\n }\n\n return previousDateTime.some(\n (prev) =>\n !nextDateTime?.some(\n (next) =>\n next.startDate === prev.startDate &&\n next.startTime === prev.startTime,\n ),\n );\n}\n\n/**\n * Helper: Update relationDates based on event's dateTime\n * Marks dates as UNAVAILABLE if they no longer exist in the event's dateTime.\n */\nexport function updateRelationDatesToUnavailable(\n relationDates: SchemaRelationType[\"relationDates\"],\n eventDateTime: DateTimeWithPriceType[] | undefined,\n): SchemaRelationType[\"relationDates\"] {\n return relationDates.map((relationDate) => {\n // Check if this relationDate exists in the event's dateTime\n const existsInEvent =\n eventDateTime?.some(\n (dt) =>\n dt.startDate === relationDate.dateTime.startDate &&\n dt.startTime === relationDate.dateTime.startTime,\n ) ?? false;\n\n return {\n ...relationDate,\n status: existsInEvent\n ? relationDate.status\n : EnumInviteStatus.UNAVAILABLE,\n };\n });\n}\n"],"mappings":"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","names":["mongoose","mongoose","mongoose"]}
|
|
1
|
+
{"version":3,"sources":["../../src/service/database.ts","../../src/service/saveNotificationsInDb.ts","../../src/service/sendPushNotifications.ts","../../src/service/updateAdStatus.ts","../../src/service/associate.ts","../../src/service/vendor.ts","../../src/service/objectIdToString.ts","../../src/service/event/updateAllEventDateTimeStatuses.ts","../../src/service/event/findEventOrImportedMarketById.ts","../../src/service/relations.ts"],"sourcesContent":["import mongoose from \"mongoose\";\n\n/**\n * Connect to MongoDB using Mongoose.\n * Supports both local MongoDB (via MONGODB_URI) and MongoDB Atlas (via individual env vars).\n */\nexport const connectToDatabase = async ({\n appName,\n dbName,\n dbPassword,\n dbUser,\n mongodbUri,\n}: {\n appName: string;\n dbName: string;\n dbPassword: string;\n dbUser: string;\n mongodbUri: string;\n}) => {\n try {\n // Check if MONGODB_URI is provided (for local Docker MongoDB)\n const mongoUri = mongodbUri\n ? mongodbUri\n : // Fallback to MongoDB Atlas connection string\n `mongodb+srv://${dbUser}:${dbPassword}@${dbName}.mongodb.net/?retryWrites=true&w=majority&appName=${appName}`;\n\n await mongoose.connect(mongoUri);\n\n const connectionType = mongodbUri ? \"Local MongoDB\" : \"MongoDB Atlas\";\n console.log(\n `${connectionType} connected from server/src/service/database.ts`,\n );\n } catch (err) {\n console.error(\"Error connecting to MongoDB:\", err);\n throw err; // You can throw the error if you want to stop the server in case of connection failure\n }\n};\n","import {\n SchemaCreateBulkNotificationInput,\n NotificationModel,\n} from \"src/mongoose/Notification\";\nimport { ObjectId } from \"src/types\";\n\n/**\n * Create notifications in the database for multiple users\n * This is typically called when sending push notifications\n */\nexport async function saveNotificationsInDb(\n payload: SchemaCreateBulkNotificationInput,\n): Promise<ObjectId[]> {\n const { data, message, title, type, userIds } = payload;\n console.log('NOTIFICATION DATA', JSON.stringify(payload, null, 2));\n try {\n const notifications = userIds.map((userId) => ({\n data,\n isRead: false,\n message,\n title,\n type,\n userId,\n }));\n\n // Save notifications to database\n await NotificationModel.insertMany(notifications);\n console.log(\n `Created ${notifications.length} notifications for ${userIds.length} users`,\n );\n\n return [...new Set(userIds)];\n } catch (error) {\n console.error(\"Failed to create notifications:\", error);\n return [];\n //throw new Error(`Failed to create notifications: ${error}`);\n }\n}\n","import { NotificationDataType } from \"@timardex/cluemart-shared\";\nimport { Expo, ExpoPushMessage, ExpoPushTicket } from \"expo-server-sdk\";\n\nimport { SchemaCreateBulkNotificationInput } from \"src/mongoose/Notification\";\nimport { PushTokenModel } from \"src/mongoose/PushToken\";\n\nconst expo = new Expo();\n\n/**\n * Safely extract tokens from ExpoPushMessage handling both string and array cases\n */\nfunction extractTokensFromMessage(message: ExpoPushMessage): string[] {\n return Array.isArray(message.to) ? message.to : [message.to];\n}\n\ninterface CreatePushMessagesOptions {\n tokens: string[];\n message: string;\n title: string;\n data: NotificationDataType;\n}\n\n/**\n * Create push messages from valid tokens\n */\nfunction createPushMessages({\n tokens,\n message,\n title,\n data,\n}: CreatePushMessagesOptions): {\n messages: ExpoPushMessage[];\n invalidTokens: string[];\n} {\n const messages: ExpoPushMessage[] = [];\n const invalidTokens: string[] = [];\n\n for (const token of tokens) {\n if (!Expo.isExpoPushToken(token)) {\n invalidTokens.push(token);\n continue;\n }\n\n messages.push({\n body: message,\n data: { ...data },\n sound: \"default\",\n title,\n to: token,\n });\n }\n\n return { invalidTokens, messages };\n}\n\n/**\n * Process chunk results and extract failed tokens\n */\nfunction processChunkResults(\n tickets: ExpoPushTicket[],\n chunk: ExpoPushMessage[],\n): { successCount: number; failedTokens: string[] } {\n let successCount = 0;\n const failedTokens: string[] = [];\n\n for (const [ticketIndex, ticket] of tickets.entries()) {\n if (ticket.status === \"error\") {\n const message = chunk[ticketIndex];\n if (message) {\n const tokens = extractTokensFromMessage(message);\n if (ticket.details?.error === \"DeviceNotRegistered\") {\n failedTokens.push(...tokens);\n }\n console.log(\"Push notification error\", {\n error: ticket.details?.error,\n tokens,\n });\n }\n } else {\n successCount++;\n }\n }\n\n return { failedTokens, successCount };\n}\n\n/**\n * Send a single chunk of push notifications\n */\nasync function sendChunk(\n chunk: ExpoPushMessage[],\n chunkIndex: number,\n): Promise<{ successCount: number; failedTokens: string[] }> {\n try {\n const tickets = await expo.sendPushNotificationsAsync(chunk);\n const { successCount, failedTokens } = processChunkResults(tickets, chunk);\n\n console.log(\n `Chunk ${chunkIndex + 1}: Sent ${successCount}/${chunk.length} notifications successfully`,\n );\n\n return { failedTokens, successCount };\n } catch (error) {\n console.log(\"Error sending Expo push notification chunk\", {\n chunkIndex,\n chunkSize: chunk.length,\n error: error instanceof Error ? error.message : String(error),\n });\n return { failedTokens: [], successCount: 0 };\n }\n}\n\nexport async function sendPushNotifications({\n data,\n message,\n title,\n userIds,\n}: SchemaCreateBulkNotificationInput) {\n const pushTokens = await PushTokenModel.find({ userId: { $in: userIds } });\n const expoTokens = pushTokens.map((token) => token.token);\n\n if (!data) return;\n\n const { messages, invalidTokens } = createPushMessages({\n data,\n message,\n title,\n tokens: expoTokens,\n });\n\n // Log invalid tokens\n if (invalidTokens.length > 0) {\n console.log(`Found ${invalidTokens.length} invalid push tokens`);\n }\n\n if (messages.length === 0) {\n console.log(\"No valid messages to send after filtering tokens\");\n return;\n }\n\n // Send notifications in chunks\n const chunks = expo.chunkPushNotifications(messages);\n let totalSuccessCount = 0;\n const allFailedTokens: string[] = [];\n\n for (const [chunkIndex, chunk] of chunks.entries()) {\n const { successCount, failedTokens } = await sendChunk(\n chunk,\n chunkIndex + 1,\n );\n totalSuccessCount += successCount;\n allFailedTokens.push(...failedTokens);\n }\n\n // Log final results\n console.log(\n `Sent push notification to ${totalSuccessCount}/${messages.length} tokens across ${chunks.length} chunks`,\n );\n\n if (allFailedTokens.length > 0) {\n console.log(`Found ${allFailedTokens.length} failed push tokens`);\n }\n}\n","import { EnumAdStatus } from \"@timardex/cluemart-shared\";\n\nimport { AdModel } from \"src/mongoose\";\n\n/**\n * Updates ad statuses based on start/end dates and validity\n */\nexport async function updateAdStatuses(): Promise<void> {\n const now = new Date();\n\n // invalid\n const invalidResult = await AdModel.updateMany(\n {\n $or: [\n { start: { $exists: false } },\n { end: { $exists: false } },\n { $expr: { $gt: [\"$start\", \"$end\"] } },\n ],\n status: { $ne: EnumAdStatus.PAUSED },\n },\n { $set: { status: EnumAdStatus.PAUSED } },\n );\n\n // expired\n const expiredResult = await AdModel.updateMany(\n { end: { $lte: now }, status: { $ne: EnumAdStatus.EXPIRED } },\n { $set: { status: EnumAdStatus.EXPIRED } },\n );\n\n // active\n const activeResult = await AdModel.updateMany(\n {\n end: { $gt: now },\n start: { $lte: now },\n status: { $ne: EnumAdStatus.ACTIVE },\n },\n { $set: { status: EnumAdStatus.ACTIVE } },\n );\n\n // paused\n const pausedResult = await AdModel.updateMany(\n { start: { $gt: now }, status: { $ne: EnumAdStatus.PAUSED } },\n { $set: { status: EnumAdStatus.PAUSED } },\n );\n\n console.log(\n `✅ Ad statuses updated: invalid=${invalidResult.modifiedCount}, expired=${expiredResult.modifiedCount}, active=${activeResult.modifiedCount}, paused=${pausedResult.modifiedCount}`,\n );\n}\n","import { EnumChatType, EnumResourceType } from \"@timardex/cluemart-shared\";\nimport mongoose from \"mongoose\";\n\nimport { ChatModel, UserModel } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\ninterface RemoveAssociateFromResourceParams {\n resourceId: string | ObjectId;\n resourceOwnerId: string | ObjectId;\n resourceType: EnumResourceType;\n}\n\ninterface ResourceAssociateScope {\n normalizedResourceId: string;\n resourceType: EnumResourceType;\n}\n\nfunction normalizeObjectId(id: string | ObjectId): ObjectId {\n return typeof id === \"string\" ? new mongoose.Types.ObjectId(id) : id;\n}\n\nasync function getAssociateEmailsForResource({\n normalizedResourceId,\n resourceType,\n}: ResourceAssociateScope): Promise<string[]> {\n const usersWithAssociates = await UserModel.find(\n {\n associates: {\n $elemMatch: {\n resourceId: normalizedResourceId,\n resourceType,\n },\n },\n },\n {\n associates: 1,\n },\n ).lean();\n\n return [\n ...new Set(\n usersWithAssociates.flatMap((user) =>\n (user.associates ?? [])\n .filter(\n (associate) =>\n associate.resourceId === normalizedResourceId &&\n associate.resourceType === resourceType,\n )\n .map((associate) => associate.email),\n ),\n ),\n ];\n}\n\nasync function pullAssociatesFromUsers({\n normalizedResourceId,\n resourceType,\n}: ResourceAssociateScope): Promise<void> {\n await UserModel.updateMany(\n {\n associates: {\n $elemMatch: {\n resourceId: normalizedResourceId,\n resourceType,\n },\n },\n },\n {\n $pull: {\n associates: {\n resourceId: normalizedResourceId,\n resourceType,\n },\n },\n },\n );\n}\n\nasync function pullAssociateParticipantsFromChats(\n resourceOwnerId: ObjectId,\n associateEmails: string[],\n): Promise<void> {\n await ChatModel.updateMany(\n {\n active: true,\n chatType: EnumChatType.RELATION,\n deletedAt: null,\n participants: {\n $elemMatch: {\n userId: resourceOwnerId,\n },\n },\n },\n {\n $pull: {\n participants: {\n isAssociate: true,\n userEmail: {\n $in: associateEmails,\n },\n },\n },\n },\n );\n}\n\n/**\n * Removes all associates linked to a resource\n * and removes related associate chat participants.\n */\nexport async function removeAssociateFromResource({\n resourceId,\n resourceOwnerId,\n resourceType,\n}: RemoveAssociateFromResourceParams): Promise<void> {\n try {\n const scope: ResourceAssociateScope = {\n normalizedResourceId: resourceId.toString(),\n resourceType,\n };\n\n const associateEmails = await getAssociateEmailsForResource(scope);\n\n if (associateEmails.length === 0) {\n return;\n }\n\n await pullAssociatesFromUsers(scope);\n await pullAssociateParticipantsFromChats(\n normalizeObjectId(resourceOwnerId),\n associateEmails,\n );\n } catch (error) {\n console.error(\n `[removeAssociateFromResource] Failed for resourceId=${resourceId}, resourceType=${resourceType}`,\n error,\n );\n }\n}\n","import { EnumResourceType, EnumUserLicence } from \"@timardex/cluemart-shared\";\n\nimport { UserModel, VendorModel, SchemaVendorType } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\nimport { removeAssociateFromResource } from \"./associate\";\n\nexport async function updateVendorBasedOnUserLicense(\n userId: ObjectId,\n licenceType: EnumUserLicence,\n): Promise<void> {\n try {\n /**\n * Fetch user vendor reference\n */\n const user = await UserModel.findById(userId)\n .select(\"vendor\")\n .lean()\n .exec();\n\n if (!user?.vendor) {\n console.warn(`[updateVendor] No vendor found for userId=${userId}`);\n return;\n }\n\n /**\n * Fetch vendor\n */\n const vendor = await VendorModel.findById(user.vendor)\n .lean<SchemaVendorType>()\n .exec();\n\n if (!vendor) {\n console.warn(`[updateVendor] Vendor not found for id=${user.vendor}`);\n return;\n }\n\n /**\n * Build vendor update payload\n */\n const updateData: Partial<SchemaVendorType> = {};\n\n const isStandardVendor = licenceType === EnumUserLicence.STANDARD_VENDOR;\n\n if (isStandardVendor) {\n updateData.associates = [];\n\n updateData.availability = {\n corporate: false,\n private: false,\n school: false,\n };\n\n updateData.products = {\n active: false,\n productsList: vendor.products?.productsList ?? [],\n };\n\n updateData.calendar = {\n active: false,\n calendarData: vendor.calendar?.calendarData ?? [],\n };\n }\n\n /**\n * Image rules\n * STANDARD_VENDOR => only first 6 active\n * PRO_VENDOR => all active\n */\n updateData.images = (vendor.images ?? []).map((image, index) => ({\n ...image,\n active: isStandardVendor ? index < 6 : true,\n }));\n\n /**\n * Persist vendor updates\n */\n await VendorModel.updateOne({ _id: vendor._id }, { $set: updateData });\n\n /**\n * Cleanup associates for STANDARD licence\n */\n if (isStandardVendor) {\n await removeAssociateFromResource({\n resourceId: vendor._id,\n resourceOwnerId: vendor.owner.userId,\n resourceType: EnumResourceType.VENDOR,\n });\n }\n } catch (error) {\n console.error(\"[updateVendorBasedOnUserLicense] Failed:\", error);\n }\n}\n","import mongoose from \"mongoose\";\n\n/**\n * Recursively converts all ObjectId fields to strings in an object\n * This is needed because GraphQL expects string IDs, not ObjectIds\n */\nexport function convertObjectIdsToStrings(obj: any): any {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (obj instanceof mongoose.Types.ObjectId) {\n return obj.toString();\n }\n\n if (Array.isArray(obj)) {\n return obj.map(convertObjectIdsToStrings);\n }\n\n if (typeof obj === \"object\") {\n const converted: any = {};\n for (const [key, value] of Object.entries(obj)) {\n converted[key] = convertObjectIdsToStrings(value);\n }\n return converted;\n }\n\n return obj;\n}\n","import {\n dateFormat,\n DateTimeType,\n EnumEventDateStatus,\n timeFormat,\n} from \"@timardex/cluemart-shared\";\nimport dayjs from \"dayjs\";\nimport customParseFormat from \"dayjs/plugin/customParseFormat\";\nimport isoWeek from \"dayjs/plugin/isoWeek\";\n\nimport { EventModel, GoogleImportedMarketModel } from \"src/mongoose\";\n\n// Enable dayjs plugins used by event date parsing/status logic\ndayjs.extend(customParseFormat);\ndayjs.extend(isoWeek);\n\n/**\n * Determines the dateStatus for a future event date\n * @param startDateTime The start date-time of the event\n * @param now The current date-time\n * @returns The appropriate EnumEventDateStatus\n */\nexport function getFutureEventStatus(\n startDateTime: dayjs.Dayjs,\n now: dayjs.Dayjs,\n): EnumEventDateStatus {\n const hoursUntilStart = startDateTime.diff(now, \"hour\", true);\n if (hoursUntilStart > 0 && hoursUntilStart <= 4) {\n return EnumEventDateStatus.STARTING_SOON;\n }\n\n if (startDateTime.isSame(now, \"day\")) {\n return EnumEventDateStatus.TODAY;\n }\n\n if (startDateTime.isSame(now.add(1, \"day\"), \"day\")) {\n return EnumEventDateStatus.TOMORROW;\n }\n\n if (startDateTime.isSame(now, \"isoWeek\")) {\n return EnumEventDateStatus.THIS_WEEK;\n }\n\n if (startDateTime.isSame(now.add(1, \"week\"), \"isoWeek\")) {\n return EnumEventDateStatus.NEXT_WEEK;\n }\n\n return EnumEventDateStatus.UPCOMING;\n}\n\n/**\n * Updates the dateStatus field for a single DateTimeType object based on the current date/time\n * @param dateTime The date-time object to update\n * @returns A new object with updated dateStatus value\n */\nexport function updateSingleDateTimeStatus<T extends DateTimeType>(\n dateTime: T,\n now: dayjs.Dayjs = dayjs(),\n): T {\n // Parse start and end date-time\n const dateTimeFormat = `${dateFormat} ${timeFormat}`;\n const startDateTime = dayjs(\n `${dateTime.startDate} ${dateTime.startTime}`,\n dateTimeFormat,\n true,\n );\n const endDateTime = dayjs(\n `${dateTime.endDate} ${dateTime.endTime}`,\n dateTimeFormat,\n true,\n );\n\n // Skip if dates are invalid\n if (!startDateTime.isValid() || !endDateTime.isValid()) {\n return {\n ...dateTime,\n dateStatus: EnumEventDateStatus.INVALID,\n };\n }\n\n if (endDateTime.isBefore(startDateTime)) {\n return {\n ...dateTime,\n dateStatus: EnumEventDateStatus.INVALID,\n };\n }\n\n let dateStatus: EnumEventDateStatus;\n\n if (endDateTime.isAfter(now)) {\n if (startDateTime.isAfter(now)) {\n // Event has not started yet\n dateStatus = getFutureEventStatus(startDateTime, now);\n } else {\n // Event is in progress\n dateStatus = EnumEventDateStatus.STARTED;\n }\n } else {\n // Event has ended\n dateStatus = EnumEventDateStatus.ENDED;\n }\n\n return {\n ...dateTime,\n dateStatus,\n };\n}\n\nconst dateTimeStatusFilter = {\n dateTime: { $ne: [], $type: \"array\" },\n deletedAt: null,\n} as const;\n\nconst CURSOR_BATCH_SIZE = 50;\n\ntype DocWithDateTime = {\n _id: unknown;\n dateTime: DateTimeType[];\n};\n\ntype DateTimeBulkWriteOp = {\n updateOne: {\n filter: { _id: unknown };\n update: { $set: { dateTime: DateTimeType[] } };\n };\n};\n\ntype DateTimeCursor = AsyncIterable<DocWithDateTime> & {\n close: () => Promise<unknown>;\n};\n\ntype DateTimeUpdatableModel = {\n bulkWrite: (ops: DateTimeBulkWriteOp[]) => Promise<unknown>;\n find: (filter: typeof dateTimeStatusFilter) => {\n select: (fields: { _id: 1; dateTime: 1 }) => {\n lean: () => {\n cursor: (opts: { batchSize: number }) => DateTimeCursor;\n };\n };\n };\n};\n\nfunction hasDateTimeStatusChanges(\n stored: DateTimeType[],\n updated: DateTimeType[],\n): boolean {\n if (stored.length !== updated.length) {\n return true;\n }\n\n return stored.some(\n (slot, index) => slot.dateStatus !== updated[index].dateStatus,\n );\n}\n\nasync function updateModelDateTimeStatuses(\n model: DateTimeUpdatableModel,\n now: dayjs.Dayjs,\n): Promise<number> {\n let updated = 0;\n const cursor = model\n .find(dateTimeStatusFilter)\n .select({ _id: 1, dateTime: 1 })\n .lean()\n .cursor({ batchSize: CURSOR_BATCH_SIZE });\n\n let bulkOps: DateTimeBulkWriteOp[] = [];\n\n const flushBulkWrites = async (): Promise<void> => {\n if (!bulkOps.length) {\n return;\n }\n\n await model.bulkWrite(bulkOps);\n updated += bulkOps.length;\n bulkOps = [];\n };\n\n try {\n for await (const doc of cursor) {\n const dateTime = doc.dateTime.map((slot) =>\n updateSingleDateTimeStatus(slot, now),\n );\n\n if (!hasDateTimeStatusChanges(doc.dateTime, dateTime)) {\n continue;\n }\n\n bulkOps.push({\n updateOne: {\n filter: { _id: doc._id },\n update: { $set: { dateTime } },\n },\n });\n\n if (bulkOps.length >= CURSOR_BATCH_SIZE) {\n await flushBulkWrites();\n }\n }\n\n await flushBulkWrites();\n } finally {\n await cursor.close().catch(() => undefined);\n }\n\n return updated;\n}\n\n/**\n * Recomputes dateStatus for every dateTime slot on events and google imported markets.\n */\nexport async function updateAllEventDateTimeStatuses(): Promise<void> {\n const now = dayjs();\n const [eventCount, marketCount] = await Promise.all([\n updateModelDateTimeStatuses(EventModel as DateTimeUpdatableModel, now),\n updateModelDateTimeStatuses(\n GoogleImportedMarketModel as DateTimeUpdatableModel,\n now,\n ),\n ]);\n\n console.log(\n `✅ Event dateTime statuses updated: events=${eventCount} changed, google imported markets=${marketCount} changed`,\n );\n}\n","import { EventListItemType } from \"@timardex/cluemart-shared\";\n\nimport { EventModel, GoogleImportedMarketModel } from \"src/mongoose\";\nimport { ObjectId } from \"src/types\";\n\nimport { convertObjectIdsToStrings } from \"../objectIdToString\";\n\ntype EventOrMarket = Pick<EventListItemType, \"_id\" | \"name\"> | null;\n\n/**\n * This function attempts to find an Event or a Google Imported Market by the given resource ID.\n * It first normalizes the resource ID to a string format, then performs parallel queries to both collections.\n * If an Event is found, it returns that; otherwise, it checks for a Google Imported Market and returns it if found.\n * If neither is found, it returns null.\n * @param resourceId - The ID of the resource to find, which can be an ObjectId, string, null, or undefined.\n * @returns A promise that resolves to either an Event or a Google Imported Market object containing _id and name, or null if not found.\n */\n\nexport async function findEventOrImportedMarketById(\n resourceId: ObjectId | string | null | undefined,\n): Promise<EventOrMarket> {\n if (!resourceId) {\n return null;\n }\n\n const normalizedId = convertObjectIdsToStrings(resourceId) as string;\n\n const [eventDoc, googleImportedDoc] = await Promise.all([\n EventModel.findById(normalizedId)\n .select(\"_id name\")\n .lean<Pick<EventListItemType, \"_id\" | \"name\">>()\n .exec(),\n GoogleImportedMarketModel.findById(normalizedId)\n .select(\"_id name\")\n .lean<Pick<EventListItemType, \"_id\" | \"name\">>()\n .exec(),\n ]);\n\n return eventDoc ?? googleImportedDoc;\n}\n","import {\n DateTimeWithPriceType,\n EnumInviteStatus,\n} from \"@timardex/cluemart-shared\";\nimport { DateTimeType } from \"@timardex/cluemart-shared/types\";\n\nimport { SchemaRelationType } from \"src/mongoose/Relation\";\n\ntype EventDateSlot = Pick<DateTimeType, \"startDate\" | \"startTime\">;\n\n/**\n * Returns true when at least one startDate/startTime slot from the previous\n * schedule is absent from the next schedule (i.e. a date was removed).\n */\nexport function didRemoveAnyEventDates(\n previousDateTime: EventDateSlot[] | undefined,\n nextDateTime: EventDateSlot[] | undefined,\n): boolean {\n if (!previousDateTime?.length) {\n return false;\n }\n\n return previousDateTime.some(\n (prev) =>\n !nextDateTime?.some(\n (next) =>\n next.startDate === prev.startDate &&\n next.startTime === prev.startTime,\n ),\n );\n}\n\n/**\n * Helper: Update relationDates based on event's dateTime\n * Marks dates as UNAVAILABLE if they no longer exist in the event's dateTime.\n */\nexport function updateRelationDatesToUnavailable(\n relationDates: SchemaRelationType[\"relationDates\"],\n eventDateTime: DateTimeWithPriceType[] | undefined,\n): SchemaRelationType[\"relationDates\"] {\n return relationDates.map((relationDate) => {\n // Check if this relationDate exists in the event's dateTime\n const existsInEvent =\n eventDateTime?.some(\n (dt) =>\n dt.startDate === relationDate.dateTime.startDate &&\n dt.startTime === relationDate.dateTime.startTime,\n ) ?? false;\n\n return {\n ...relationDate,\n status: existsInEvent\n ? relationDate.status\n : EnumInviteStatus.UNAVAILABLE,\n };\n });\n}\n"],"mappings":"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","names":["mongoose","mongoose","mongoose"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timardex/cluemart-server-shared",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.211",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"author": "Csaba Timár",
|
|
45
45
|
"license": "ISC",
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@timardex/cluemart-shared": "^1.5.
|
|
47
|
+
"@timardex/cluemart-shared": "^1.5.722",
|
|
48
48
|
"@types/express": "^5.0.5",
|
|
49
49
|
"@types/node": "^22.13.4",
|
|
50
50
|
"@typescript-eslint/eslint-plugin": "^8.20.0",
|