@ozdao/martyrs 0.2.511 → 0.2.513

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.
Files changed (156) hide show
  1. package/dist/{main-B1XN9Zjg.cjs → main-CVOBCkmD.cjs} +5 -5
  2. package/dist/{main-u7zgfMGL.js → main-CVRRj-vK.js} +259 -262
  3. package/dist/martyrs/src/components/Button/Button.vue2.cjs.map +1 -1
  4. package/dist/martyrs/src/components/Button/Button.vue2.js.map +1 -1
  5. package/dist/martyrs/src/components/Menu/{Menu.vue.cjs → Menu.vue2.cjs} +2 -2
  6. package/dist/martyrs/src/components/Menu/Menu.vue2.cjs.map +1 -0
  7. package/dist/martyrs/src/components/Menu/{Menu.vue.js → Menu.vue2.js} +2 -2
  8. package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +1 -0
  9. package/dist/martyrs/src/components/Menu/MenuItem.vue.cjs +2 -2
  10. package/dist/martyrs/src/components/Menu/MenuItem.vue.cjs.map +1 -1
  11. package/dist/martyrs/src/components/Menu/MenuItem.vue.js +2 -2
  12. package/dist/martyrs/src/components/Menu/MenuItem.vue.js.map +1 -1
  13. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +2 -2
  14. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs.map +1 -1
  15. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
  16. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js.map +1 -1
  17. package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.cjs +0 -2
  18. package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.cjs.map +1 -1
  19. package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.js +0 -2
  20. package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.js.map +1 -1
  21. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.cjs +3 -5
  22. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.cjs.map +1 -1
  23. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js +3 -5
  24. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js.map +1 -1
  25. package/dist/martyrs/src/modules/globals/globals.client.cjs +10 -1
  26. package/dist/martyrs/src/modules/globals/globals.client.cjs.map +1 -1
  27. package/dist/martyrs/src/modules/globals/globals.client.js +31 -22
  28. package/dist/martyrs/src/modules/globals/globals.client.js.map +1 -1
  29. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs.map +1 -1
  30. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js.map +1 -1
  31. package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.cjs +42 -46
  32. package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.cjs.map +1 -1
  33. package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.js +45 -49
  34. package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.js.map +1 -1
  35. package/dist/martyrs/src/modules/globals/views/components/sections/Walkthrough.vue.cjs +308 -0
  36. package/dist/martyrs/src/modules/globals/views/components/sections/Walkthrough.vue.cjs.map +1 -0
  37. package/dist/martyrs/src/modules/globals/views/components/sections/Walkthrough.vue.js +308 -0
  38. package/dist/martyrs/src/modules/globals/views/components/sections/Walkthrough.vue.js.map +1 -0
  39. package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.cjs +14 -16
  40. package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.cjs.map +1 -1
  41. package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.js +13 -15
  42. package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.js.map +1 -1
  43. package/dist/martyrs/src/modules/notifications/notifications.client.cjs +101 -32
  44. package/dist/martyrs/src/modules/notifications/notifications.client.cjs.map +1 -1
  45. package/dist/martyrs/src/modules/notifications/notifications.client.js +101 -32
  46. package/dist/martyrs/src/modules/notifications/notifications.client.js.map +1 -1
  47. package/dist/martyrs/src/modules/notifications/store/notifications.store.cjs +45 -12
  48. package/dist/martyrs/src/modules/notifications/store/notifications.store.cjs.map +1 -1
  49. package/dist/martyrs/src/modules/notifications/store/notifications.store.js +38 -5
  50. package/dist/martyrs/src/modules/notifications/store/notifications.store.js.map +1 -1
  51. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderItem.vue.cjs +19 -18
  52. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderItem.vue.cjs.map +1 -1
  53. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderItem.vue.js +19 -18
  54. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderItem.vue.js.map +1 -1
  55. package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.cjs +82 -61
  56. package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.cjs.map +1 -1
  57. package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.js +83 -62
  58. package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.js.map +1 -1
  59. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.cjs +3 -3
  60. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.cjs.map +1 -1
  61. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +3 -3
  62. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js.map +1 -1
  63. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.cjs +4 -2
  64. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.cjs.map +1 -1
  65. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js +4 -2
  66. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js.map +1 -1
  67. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs +2 -2
  68. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs.map +1 -1
  69. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +2 -2
  70. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js.map +1 -1
  71. package/dist/martyrs/src/modules/orders/orders.client.cjs +1 -0
  72. package/dist/martyrs/src/modules/orders/orders.client.cjs.map +1 -1
  73. package/dist/martyrs/src/modules/orders/orders.client.js +2 -0
  74. package/dist/martyrs/src/modules/orders/orders.client.js.map +1 -1
  75. package/dist/martyrs/src/modules/orders/store/shopcart.cjs +33 -23
  76. package/dist/martyrs/src/modules/orders/store/shopcart.cjs.map +1 -1
  77. package/dist/martyrs/src/modules/orders/store/shopcart.js +31 -21
  78. package/dist/martyrs/src/modules/orders/store/shopcart.js.map +1 -1
  79. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +1 -1
  80. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +1 -1
  81. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs +3 -18
  82. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs.map +1 -1
  83. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +4 -19
  84. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js.map +1 -1
  85. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.cjs +1 -1
  86. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
  87. package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.cjs +37 -43
  88. package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.cjs.map +1 -1
  89. package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.js +48 -54
  90. package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.js.map +1 -1
  91. package/dist/martyrs/src/modules/organizations/router/organizations.cjs +1 -1
  92. package/dist/martyrs/src/modules/organizations/router/organizations.js +1 -1
  93. package/dist/martyrs/src/modules/products/components/pages/Products.vue.cjs +11 -8
  94. package/dist/martyrs/src/modules/products/components/pages/Products.vue.cjs.map +1 -1
  95. package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +11 -8
  96. package/dist/martyrs/src/modules/products/components/pages/Products.vue.js.map +1 -1
  97. package/dist/martyrs.cjs.js +1 -1
  98. package/dist/martyrs.css +1 -1
  99. package/dist/martyrs.es.js +1 -1
  100. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.cjs +8 -0
  101. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.cjs.map +1 -0
  102. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.js +8 -0
  103. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.js.map +1 -0
  104. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.cjs +13 -0
  105. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.cjs.map +1 -0
  106. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.js +13 -0
  107. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.js.map +1 -0
  108. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.cjs +43 -0
  109. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.cjs.map +1 -0
  110. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js +43 -0
  111. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js.map +1 -0
  112. package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.cjs +43 -0
  113. package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.cjs.map +1 -0
  114. package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.js +43 -0
  115. package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.js.map +1 -0
  116. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.cjs +1630 -0
  117. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.cjs.map +1 -0
  118. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js +1630 -0
  119. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js.map +1 -0
  120. package/dist/notifications.server.cjs +205 -11
  121. package/dist/notifications.server.js +205 -11
  122. package/dist/style.css +258 -242
  123. package/dist/{web--8-wgr6b.js → web-BW449LVt.js} +1 -1
  124. package/dist/{web-BS6utuAZ.cjs → web-CO3tWG6J.cjs} +1 -1
  125. package/package.json +1 -1
  126. package/src/components/Button/Button.vue +2 -2
  127. package/src/components/Menu/MenuItem.vue +11 -6
  128. package/src/modules/auth/views/components/pages/Profile.vue +1 -1
  129. package/src/modules/chats/components/sections/ChatWindow.vue +1 -1
  130. package/src/modules/events/components/pages/EventsBackoffice.vue +0 -1
  131. package/src/modules/globals/globals.client.js +17 -0
  132. package/src/modules/globals/views/components/layouts/Client.vue +1 -0
  133. package/src/modules/globals/views/components/sections/Filters.vue +2 -4
  134. package/src/modules/globals/views/components/sections/Walkthrough.vue +245 -57
  135. package/src/modules/inventory/components/pages/Inventory.vue +0 -1
  136. package/src/modules/notifications/FIXES.md +1 -0
  137. package/src/modules/notifications/controllers/notifications.controller.js +147 -7
  138. package/src/modules/notifications/models/user-device.model.js +10 -2
  139. package/src/modules/notifications/notifications.client.js +127 -41
  140. package/src/modules/notifications/routes/notifications.routes.js +4 -0
  141. package/src/modules/notifications/services/notification.service.js +93 -0
  142. package/src/modules/notifications/store/notifications.store.js +47 -7
  143. package/src/modules/orders/components/blocks/CardOrderItem.vue +1 -1
  144. package/src/modules/orders/components/forms/FormCustomerDetails.vue +52 -35
  145. package/src/modules/orders/components/pages/OrderBackoffice.vue +2 -2
  146. package/src/modules/orders/components/pages/OrderCreate.vue +3 -1
  147. package/src/modules/orders/components/sections/FormDelivery.vue +2 -2
  148. package/src/modules/orders/orders.client.js +2 -0
  149. package/src/modules/orders/store/shopcart.js +34 -23
  150. package/src/modules/organizations/components/pages/Organization.vue +6 -2
  151. package/src/modules/organizations/configs/navigation.organization.config.js +36 -36
  152. package/src/modules/products/components/pages/Products.vue +11 -9
  153. package/src/modules/products/migrations/categories-to-materialized-path.js +0 -3
  154. package/src/styles/base/backgrounds.scss +1 -0
  155. package/dist/martyrs/src/components/Menu/Menu.vue.cjs.map +0 -1
  156. package/dist/martyrs/src/components/Menu/Menu.vue.js.map +0 -1
@@ -114,18 +114,45 @@ const NotificationsController = (db, wss, notificationService) => {
114
114
  };
115
115
  const registerDevice = async (req, res) => {
116
116
  try {
117
- const { userId, deviceId, deviceType, deviceToken } = req.body;
118
- const device = await db.userDevice.findOneAndUpdate(
119
- { userId, deviceId },
120
- {
117
+ const { userId, anonymousId, deviceId, deviceType, deviceToken } = req.body;
118
+ if (!userId && !anonymousId) {
119
+ return res.status(400).json({ message: "Either userId or anonymousId is required" });
120
+ }
121
+ const isAnonymous = !userId;
122
+ let query, updateData;
123
+ if (isAnonymous) {
124
+ query = { anonymousId, deviceId };
125
+ updateData = {
126
+ anonymousId,
127
+ deviceId,
128
+ deviceType,
129
+ deviceToken,
130
+ isActive: true,
131
+ isAnonymous: true,
132
+ lastActive: Date.now()
133
+ };
134
+ } else {
135
+ await db.userDevice.deleteMany({
136
+ $or: [
137
+ { deviceId, isAnonymous: true },
138
+ { deviceToken, isAnonymous: true }
139
+ ]
140
+ });
141
+ query = { userId, deviceId };
142
+ updateData = {
121
143
  userId,
122
144
  deviceId,
123
145
  deviceType,
124
146
  deviceToken,
125
147
  isActive: true,
148
+ isAnonymous: false,
126
149
  lastActive: Date.now()
127
- },
128
- { upsert: true, new: true }
150
+ };
151
+ }
152
+ const device = await db.userDevice.findOneAndUpdate(
153
+ query,
154
+ { $set: updateData },
155
+ { upsert: true, new: true, setDefaultsOnInsert: true }
129
156
  );
130
157
  return res.status(201).json(device);
131
158
  } catch (err) {
@@ -166,6 +193,87 @@ const NotificationsController = (db, wss, notificationService) => {
166
193
  return res.status(500).json({ message: err.message });
167
194
  }
168
195
  };
196
+ const sendToTokens = async (req, res) => {
197
+ try {
198
+ const { tokens, title, body, data = {} } = req.body;
199
+ if (!tokens || !Array.isArray(tokens) || tokens.length === 0) {
200
+ return res.status(400).json({ message: "tokens array is required" });
201
+ }
202
+ if (!title || !body) {
203
+ return res.status(400).json({ message: "title and body are required" });
204
+ }
205
+ const devices = await db.userDevice.find({
206
+ deviceToken: { $in: tokens },
207
+ isActive: true
208
+ });
209
+ const results = [];
210
+ for (const device of devices) {
211
+ try {
212
+ await notificationService.sendToDeviceToken({
213
+ deviceToken: device.deviceToken,
214
+ deviceType: device.deviceType,
215
+ title,
216
+ body,
217
+ data
218
+ });
219
+ results.push({ token: device.deviceToken, success: true });
220
+ } catch (error) {
221
+ results.push({ token: device.deviceToken, success: false, error: error.message });
222
+ }
223
+ }
224
+ return res.json({
225
+ message: "Notifications sent",
226
+ results,
227
+ total: tokens.length,
228
+ found: devices.length
229
+ });
230
+ } catch (err) {
231
+ return res.status(500).json({ message: err.message });
232
+ }
233
+ };
234
+ const sendToAnonymous = async (req, res) => {
235
+ try {
236
+ const { anonymousIds, title, body, data = {} } = req.body;
237
+ if (!title || !body) {
238
+ return res.status(400).json({ message: "title and body are required" });
239
+ }
240
+ let devices;
241
+ if (anonymousIds && Array.isArray(anonymousIds)) {
242
+ devices = await db.userDevice.find({
243
+ anonymousId: { $in: anonymousIds },
244
+ isAnonymous: true,
245
+ isActive: true
246
+ });
247
+ } else {
248
+ devices = await db.userDevice.find({
249
+ isAnonymous: true,
250
+ isActive: true
251
+ });
252
+ }
253
+ const results = [];
254
+ for (const device of devices) {
255
+ try {
256
+ await notificationService.sendToDeviceToken({
257
+ deviceToken: device.deviceToken,
258
+ deviceType: device.deviceType,
259
+ title,
260
+ body,
261
+ data
262
+ });
263
+ results.push({ anonymousId: device.anonymousId, deviceToken: device.deviceToken, success: true });
264
+ } catch (error) {
265
+ results.push({ anonymousId: device.anonymousId, deviceToken: device.deviceToken, success: false, error: error.message });
266
+ }
267
+ }
268
+ return res.json({
269
+ message: "Notifications sent to anonymous devices",
270
+ results,
271
+ devicesFound: devices.length
272
+ });
273
+ } catch (err) {
274
+ return res.status(500).json({ message: err.message });
275
+ }
276
+ };
169
277
  return {
170
278
  create,
171
279
  createBatch,
@@ -174,7 +282,9 @@ const NotificationsController = (db, wss, notificationService) => {
174
282
  registerDevice,
175
283
  updatePreferences,
176
284
  getUserPreferences,
177
- markAllAsRead
285
+ markAllAsRead,
286
+ sendToTokens,
287
+ sendToAnonymous
178
288
  };
179
289
  };
180
290
  const NotificationLogModel = (db, additionalFields = {}) => {
@@ -226,15 +336,22 @@ const NotificationModel = (db, additionalFields = {}) => {
226
336
  };
227
337
  const UserDeviceModel = (db, additionalFields = {}) => {
228
338
  const schema = new db.mongoose.Schema({
229
- userId: { type: db.mongoose.Schema.Types.ObjectId, ref: "User", required: true },
339
+ userId: { type: db.mongoose.Schema.Types.ObjectId, ref: "User", required: false },
340
+ anonymousId: { type: String, required: false },
341
+ // For anonymous users
230
342
  deviceId: { type: String, required: true },
231
343
  deviceType: { type: String, enum: ["ios", "android", "web"], required: true },
232
344
  deviceToken: { type: String, required: true },
233
345
  // Push token for mobile, or web token
234
346
  isActive: { type: Boolean, default: true },
235
- lastActive: { type: Date, default: Date.now }
347
+ lastActive: { type: Date, default: Date.now },
348
+ isAnonymous: { type: Boolean, default: false }
349
+ // Flag to identify anonymous devices
236
350
  });
237
- schema.index({ userId: 1, deviceId: 1 }, { unique: true });
351
+ schema.index({ userId: 1, deviceId: 1 }, { unique: true, sparse: true });
352
+ schema.index({ anonymousId: 1, deviceId: 1 }, { unique: true, sparse: true });
353
+ schema.index({ deviceToken: 1 }, { unique: true });
354
+ schema.index({ isAnonymous: 1, isActive: 1 });
238
355
  return db.mongoose.model("UserDevice", schema);
239
356
  };
240
357
  const notificationsRoutes = (app, db, wss, origins, publicPath, notificationService) => {
@@ -247,6 +364,8 @@ const notificationsRoutes = (app, db, wss, origins, publicPath, notificationServ
247
364
  app.post("/api/notifications/devices/register", controller.registerDevice);
248
365
  app.get("/api/notifications/preferences/:userId", controller.getUserPreferences);
249
366
  app.put("/api/notifications/preferences", controller.updatePreferences);
367
+ app.post("/api/notifications/send-to-tokens", controller.sendToTokens);
368
+ app.post("/api/notifications/send-to-anonymous", controller.sendToAnonymous);
250
369
  };
251
370
  let apnProvider = null;
252
371
  const getApnProvider = () => {
@@ -588,9 +707,84 @@ const NotificationService = function(db, wss) {
588
707
  await processNotification(notification);
589
708
  }
590
709
  };
710
+ const sendToDeviceToken = async ({ deviceToken, deviceType, title, body, data = {} }) => {
711
+ const pushService = getPushServiceByDeviceType(deviceType);
712
+ return pushService.send({
713
+ token: deviceToken,
714
+ title,
715
+ body,
716
+ data
717
+ });
718
+ };
719
+ const sendToDeviceTokens = async ({ tokens, title, body, data = {} }) => {
720
+ const results = [];
721
+ for (const token of tokens) {
722
+ try {
723
+ const device = await db.userDevice.findOne({ deviceToken: token, isActive: true });
724
+ if (!device) {
725
+ results.push({ token, success: false, error: "Device not found" });
726
+ continue;
727
+ }
728
+ await sendToDeviceToken({
729
+ deviceToken: token,
730
+ deviceType: device.deviceType,
731
+ title,
732
+ body,
733
+ data
734
+ });
735
+ results.push({ token, success: true });
736
+ } catch (error) {
737
+ results.push({ token, success: false, error: error.message });
738
+ }
739
+ }
740
+ return results;
741
+ };
742
+ const sendToAnonymousDevices = async ({ anonymousIds = null, title, body, data = {} }) => {
743
+ let devices;
744
+ if (anonymousIds && Array.isArray(anonymousIds)) {
745
+ devices = await db.userDevice.find({
746
+ anonymousId: { $in: anonymousIds },
747
+ isAnonymous: true,
748
+ isActive: true
749
+ });
750
+ } else {
751
+ devices = await db.userDevice.find({
752
+ isAnonymous: true,
753
+ isActive: true
754
+ });
755
+ }
756
+ const results = [];
757
+ for (const device of devices) {
758
+ try {
759
+ await sendToDeviceToken({
760
+ deviceToken: device.deviceToken,
761
+ deviceType: device.deviceType,
762
+ title,
763
+ body,
764
+ data
765
+ });
766
+ results.push({
767
+ anonymousId: device.anonymousId,
768
+ deviceToken: device.deviceToken,
769
+ success: true
770
+ });
771
+ } catch (error) {
772
+ results.push({
773
+ anonymousId: device.anonymousId,
774
+ deviceToken: device.deviceToken,
775
+ success: false,
776
+ error: error.message
777
+ });
778
+ }
779
+ }
780
+ return results;
781
+ };
591
782
  return {
592
783
  processNotification,
593
- processPendingNotifications
784
+ processPendingNotifications,
785
+ sendToDeviceToken,
786
+ sendToDeviceTokens,
787
+ sendToAnonymousDevices
594
788
  };
595
789
  };
596
790
  const { getInstance } = globalsabac;