@burdenoff/be-sdk 2026.516.1 → 2026.516.3

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 (115) hide show
  1. package/dist/EventQueueFactory-6UJ3UIP4.js +6 -0
  2. package/dist/{EventQueueFactory-DGHBOV7I.js.map → EventQueueFactory-6UJ3UIP4.js.map} +1 -1
  3. package/dist/auth/index.d.ts +2 -2
  4. package/dist/auth/index.js +3 -3
  5. package/dist/cache/index.d.ts +2 -2
  6. package/dist/cache/index.js +2 -2
  7. package/dist/{chunk-6U2P4ANJ.js → chunk-5M3YVBTH.js} +5 -5
  8. package/dist/{chunk-6U2P4ANJ.js.map → chunk-5M3YVBTH.js.map} +1 -1
  9. package/dist/{chunk-RVB5QFZ4.js → chunk-6WYNQ26B.js} +4 -4
  10. package/dist/{chunk-RVB5QFZ4.js.map → chunk-6WYNQ26B.js.map} +1 -1
  11. package/dist/{chunk-5CAA3JST.js → chunk-CPO7ZXUQ.js} +3 -3
  12. package/dist/{chunk-5CAA3JST.js.map → chunk-CPO7ZXUQ.js.map} +1 -1
  13. package/dist/{chunk-24VR7PF3.js → chunk-HF3EFD7G.js} +2 -2
  14. package/dist/{chunk-24VR7PF3.js.map → chunk-HF3EFD7G.js.map} +1 -1
  15. package/dist/{chunk-CCV2AVAI.js → chunk-IFES3AQS.js} +3 -3
  16. package/dist/{chunk-CCV2AVAI.js.map → chunk-IFES3AQS.js.map} +1 -1
  17. package/dist/{chunk-SNW4BLF2.js → chunk-IPKUQS7K.js} +3 -3
  18. package/dist/{chunk-SNW4BLF2.js.map → chunk-IPKUQS7K.js.map} +1 -1
  19. package/dist/{chunk-Q6N74R6S.js → chunk-JO6XUKZ5.js} +3 -3
  20. package/dist/{chunk-Q6N74R6S.js.map → chunk-JO6XUKZ5.js.map} +1 -1
  21. package/dist/{chunk-N52W3RQA.js → chunk-MVHOP4IG.js} +3 -174
  22. package/dist/chunk-MVHOP4IG.js.map +1 -0
  23. package/dist/{chunk-M3PYLAPT.js → chunk-NGA6NTFG.js} +5 -5
  24. package/dist/{chunk-M3PYLAPT.js.map → chunk-NGA6NTFG.js.map} +1 -1
  25. package/dist/{chunk-RTQIRGVB.js → chunk-O6RHB2YP.js} +2 -2
  26. package/dist/chunk-O6RHB2YP.js.map +1 -0
  27. package/dist/{chunk-Z4IRLBWO.js → chunk-R3XPCYHM.js} +3 -3
  28. package/dist/{chunk-Z4IRLBWO.js.map → chunk-R3XPCYHM.js.map} +1 -1
  29. package/dist/{chunk-AQTNM2EY.js → chunk-RMDKB5O7.js} +3 -3
  30. package/dist/{chunk-AQTNM2EY.js.map → chunk-RMDKB5O7.js.map} +1 -1
  31. package/dist/chunk-RRFNSBDZ.js +181 -0
  32. package/dist/chunk-RRFNSBDZ.js.map +1 -0
  33. package/dist/{chunk-KLYAIEAX.js → chunk-SO57HNXV.js} +14 -30
  34. package/dist/chunk-SO57HNXV.js.map +1 -0
  35. package/dist/chunk-TM5RQ6P2.js +925 -0
  36. package/dist/chunk-TM5RQ6P2.js.map +1 -0
  37. package/dist/{chunk-U455UF4O.js → chunk-TXW7ZKA2.js} +5 -5
  38. package/dist/{chunk-U455UF4O.js.map → chunk-TXW7ZKA2.js.map} +1 -1
  39. package/dist/chunk-U2GLUZAO.js +241 -0
  40. package/dist/chunk-U2GLUZAO.js.map +1 -0
  41. package/dist/{chunk-HIWTWIGQ.js → chunk-UIJWXPOQ.js} +7 -7
  42. package/dist/chunk-UIJWXPOQ.js.map +1 -0
  43. package/dist/{chunk-WBWM7UY7.js → chunk-UNPJMENC.js} +3 -3
  44. package/dist/{chunk-WBWM7UY7.js.map → chunk-UNPJMENC.js.map} +1 -1
  45. package/dist/{chunk-FSTWNBRX.js → chunk-WCBKW3CL.js} +13 -41
  46. package/dist/chunk-WCBKW3CL.js.map +1 -0
  47. package/dist/{chunk-NGMEI42S.js → chunk-ZA3IGCDJ.js} +4 -4
  48. package/dist/chunk-ZA3IGCDJ.js.map +1 -0
  49. package/dist/database/index.js +3 -3
  50. package/dist/event-queue/index.d.ts +5 -5
  51. package/dist/event-queue/index.js +4 -6
  52. package/dist/export/index.d.ts +2 -2
  53. package/dist/export/index.js +5 -5
  54. package/dist/gateway/index.d.ts +2 -2
  55. package/dist/gateway/index.js +4 -4
  56. package/dist/gateway/security/index.js +1 -1
  57. package/dist/graph/index.d.ts +4 -4
  58. package/dist/graph/index.js +7 -8
  59. package/dist/{graph-emitter-Bk0FqD53.d.ts → graph-emitter-r5TylDBm.d.ts} +2 -2
  60. package/dist/graphql/index.d.ts +1 -1
  61. package/dist/graphql/index.js +2 -2
  62. package/dist/{graphql-0_hoaeUf.d.ts → graphql-DH3L5Hj7.d.ts} +1 -1
  63. package/dist/{index-DlFDFyWD.d.ts → index-BVjR9llq.d.ts} +2 -2
  64. package/dist/{index-DJq060D-.d.ts → index-BZPEyVOl.d.ts} +3 -3
  65. package/dist/{index-XY9x2I6b.d.ts → index-BqSh1K8I.d.ts} +4 -23
  66. package/dist/{index-syMAjErz.d.ts → index-C7T0Xx19.d.ts} +11 -90
  67. package/dist/{index-CSPbpywb.d.ts → index-Caqvetqq.d.ts} +5 -10
  68. package/dist/{index-DZO2nvC9.d.ts → index-CygU_fXS.d.ts} +4 -4
  69. package/dist/{index-DYEts1R8.d.ts → index-DLyc5o_K.d.ts} +1 -1
  70. package/dist/{index-BMq3lFjj.d.ts → index-Dg4kH1VJ.d.ts} +1 -1
  71. package/dist/{index-zzKCairW.d.ts → index-DohaJRZP.d.ts} +2 -2
  72. package/dist/{index-RU_M5c74.d.ts → index-KA3gg4es.d.ts} +1 -1
  73. package/dist/{index-B6IwtUb1.d.ts → index-cnFnfIjk.d.ts} +1 -1
  74. package/dist/{index-TKcu5LDR.d.ts → index-fhOvuvlv.d.ts} +1 -1
  75. package/dist/index-joONjwLt.d.ts +33 -0
  76. package/dist/index.d.ts +28 -28
  77. package/dist/index.js +89 -90
  78. package/dist/index.js.map +1 -1
  79. package/dist/init/index.d.ts +2 -2
  80. package/dist/init/index.js +5 -8
  81. package/dist/instrumentation/index.d.ts +3 -3
  82. package/dist/layer/index.d.ts +2 -2
  83. package/dist/layer/index.js +2 -2
  84. package/dist/{layer-DDip18KY.d.ts → layer-CUu_cZ7d.d.ts} +1 -1
  85. package/dist/logger/index.d.ts +2 -2
  86. package/dist/notifications/index.d.ts +3 -3
  87. package/dist/notifications/index.js +3 -3
  88. package/dist/prisma/index.js +4 -6
  89. package/dist/rbac/index.d.ts +3 -3
  90. package/dist/rbac/index.js +3 -3
  91. package/dist/telemetry/index.d.ts +6 -6
  92. package/dist/telemetry/index.js.map +1 -1
  93. package/dist/temporal/index.d.ts +1 -1
  94. package/dist/temporal/index.js +2 -2
  95. package/dist/tracker/index.d.ts +4 -4
  96. package/dist/tracker/index.js +5 -5
  97. package/package.json +1 -6
  98. package/dist/EventQueueFactory-DGHBOV7I.js +0 -8
  99. package/dist/chunk-462GJL5K.js +0 -478
  100. package/dist/chunk-462GJL5K.js.map +0 -1
  101. package/dist/chunk-7V6GUNGP.js +0 -438
  102. package/dist/chunk-7V6GUNGP.js.map +0 -1
  103. package/dist/chunk-FSTWNBRX.js.map +0 -1
  104. package/dist/chunk-HIWTWIGQ.js.map +0 -1
  105. package/dist/chunk-KLYAIEAX.js.map +0 -1
  106. package/dist/chunk-LRGXT37B.js +0 -1966
  107. package/dist/chunk-LRGXT37B.js.map +0 -1
  108. package/dist/chunk-N52W3RQA.js.map +0 -1
  109. package/dist/chunk-NGMEI42S.js.map +0 -1
  110. package/dist/chunk-RTQIRGVB.js.map +0 -1
  111. package/dist/chunk-UVYDP6P6.js +0 -13
  112. package/dist/chunk-UVYDP6P6.js.map +0 -1
  113. package/dist/config-QVYSAUMT.js +0 -4
  114. package/dist/config-QVYSAUMT.js.map +0 -1
  115. package/dist/index-CDFQRL-h.d.ts +0 -66
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/notifications/tenant-notifications.ts","../src/notifications/index.ts"],"names":["NotificationChannel","NotificationPriority","NotificationType","TenantNotificationsModule","client","context","send","input","validateSendInput","logger","info","channel","type","priority","mutation","variables","recipient","subject","body","htmlBody","data","metadata","scheduledFor","toISOString","expiresAt","trackOpens","trackClicks","response","tenantQuery","notificationId","sendNotification","sendWithTemplate","templateSlug","trim","length","ValidationError","Object","keys","email","userId","channelId","platform","timezone","result","triggerNotificationWithTemplate","firstNotification","notifications","totalTriggered","totalRequested","totalFailed","id","status","sendBatch","count","batchSize","map","n","delayBetweenBatches","batchId","sendBatchNotifications","queued","totalQueued","failed","getNotification","query","notification","getNotifications","filter","startDate","endDate","undefined","limit","offset","getTemplate","slug","locale","notificationTemplate","getTemplates","notificationTemplates","getStats","notificationStats","markAsRead","notificationIds","markAllAsRead","deleteNotifications","deleteAllReadNotifications","phoneNumber","pushToken","NotificationsModule","options","title","message","userIds","userCount","redirectUrl","appName","sms","successCount","createNotification","failureCount","errors","sendToUser","debug","search","markMultipleAsRead","markNotificationsAsRead","markAllMyNotificationsAsRead","deleteNotification","deleteMultiple","getUnreadCount","unreadCount","sendChannelNotification","recipients","includeInApp","recipientCount","inAppUserCount","results","Promise","allSettled","forEach","index","value","push","triggerNotification","reason","Error","error","sendTemplateNotification"],"mappings":"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","file":"chunk-AQTNM2EY.js","sourcesContent":["/**\n * Tenant-Backend Notifications Module\n * Comprehensive notification system supporting 10+ channels via tenant-backend\n */\n\nimport type { BurdenoffGraphQLClient } from '../client/graphql.js';\nimport type { SDKContext } from '../types/index.js';\nimport { ValidationError } from '../types/index.js';\nimport { logger } from '../logger/index.js';\n\n// ========================================\n// Enums\n// ========================================\n\nexport enum NotificationChannel {\n EMAIL = 'EMAIL',\n SMS = 'SMS',\n PUSH = 'PUSH',\n IN_APP = 'IN_APP',\n WEBHOOK = 'WEBHOOK',\n WHATSAPP = 'WHATSAPP',\n TEAMS = 'TEAMS',\n SLACK = 'SLACK',\n TELEGRAM = 'TELEGRAM',\n DISCORD = 'DISCORD',\n}\n\nexport enum NotificationPriority {\n LOW = 'LOW',\n MEDIUM = 'MEDIUM',\n HIGH = 'HIGH',\n URGENT = 'URGENT',\n}\n\nexport enum NotificationType {\n TRANSACTIONAL = 'TRANSACTIONAL',\n MARKETING = 'MARKETING',\n SYSTEM = 'SYSTEM',\n ALERT = 'ALERT',\n}\n\n// ========================================\n// Types & Interfaces\n// ========================================\n\nexport interface RecipientInput {\n userId?: string;\n email?: string;\n phoneNumber?: string;\n pushToken?: string;\n whatsappNumber?: string;\n teamsUserId?: string;\n slackUserId?: string;\n webhookUrl?: string;\n name?: string;\n locale?: string;\n timezone?: string;\n}\n\nexport interface SendNotificationInput {\n recipient: RecipientInput;\n channel: NotificationChannel;\n type?: NotificationType;\n priority?: NotificationPriority;\n subject?: string;\n body: string;\n htmlBody?: string;\n data?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n scheduledFor?: Date;\n expiresAt?: Date;\n trackOpens?: boolean;\n trackClicks?: boolean;\n}\n\nexport interface SendWithTemplateInput {\n templateSlug: string;\n variables: Record<string, unknown>;\n recipient: RecipientInput;\n priority?: NotificationPriority;\n scheduledFor?: Date;\n expiresAt?: Date;\n trackOpens?: boolean;\n trackClicks?: boolean;\n /** Specific channel instance ID from channel service (takes precedence) */\n channelId?: string;\n /** Platform type for auto-failover (EMAIL, SMS, etc.) - used if channelId not provided */\n platform?: NotificationChannel;\n /** Timezone for scheduling */\n timezone?: string;\n}\n\nexport interface BatchNotificationInput {\n notifications: SendNotificationInput[];\n batchSize?: number;\n delayBetweenBatches?: number;\n priority?: NotificationPriority;\n}\n\nexport interface Notification {\n id: string;\n userId: string;\n channel: NotificationChannel;\n type: NotificationType;\n priority: NotificationPriority;\n status: string;\n deliveryStatus?: string;\n title: string;\n message: string;\n htmlMessage?: string;\n subject?: string;\n recipientEmail?: string;\n recipientPhone?: string;\n trackOpens: boolean;\n trackClicks: boolean;\n openedAt?: string;\n clickedAt?: string;\n sentAt?: string;\n deliveredAt?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface NotificationTemplate {\n id: string;\n name: string;\n slug: string;\n description?: string;\n channel: NotificationChannel;\n type: NotificationType;\n locale: string;\n subject?: string;\n bodyTemplate: string;\n htmlTemplate?: string;\n variables: Array<{\n name: string;\n type: string;\n required: boolean;\n defaultValue?: unknown;\n description?: string;\n example?: unknown;\n }>;\n enabled: boolean;\n version: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface NotificationStats {\n total: number;\n pending: number;\n queued: number;\n processing: number;\n sent: number;\n delivered: number;\n failed: number;\n byChannel: Record<string, number>;\n byType: Record<string, number>;\n}\n\n// ========================================\n// Tenant Notifications Module\n// ========================================\n\n/**\n * Tenant-Backend Notifications Module\n * Provides access to the centralized notification system\n */\nexport class TenantNotificationsModule {\n constructor(\n private client: BurdenoffGraphQLClient,\n private context: SDKContext\n ) {}\n\n /**\n * Send a single notification\n */\n public async send(input: SendNotificationInput): Promise<string> {\n // Validate inputs\n this.validateSendInput(input);\n\n logger.info('[TenantNotifications] Sending notification', {\n channel: input.channel,\n type: input.type || NotificationType.TRANSACTIONAL,\n priority: input.priority || NotificationPriority.MEDIUM,\n });\n\n const mutation = `\n mutation SendNotification($input: SendNotificationInput!) {\n sendNotification(input: $input)\n }\n `;\n\n const variables = {\n input: {\n recipient: input.recipient,\n channel: input.channel,\n type: input.type || NotificationType.TRANSACTIONAL,\n priority: input.priority || NotificationPriority.MEDIUM,\n subject: input.subject,\n body: input.body,\n htmlBody: input.htmlBody,\n data: input.data,\n metadata: input.metadata,\n scheduledFor: input.scheduledFor?.toISOString(),\n expiresAt: input.expiresAt?.toISOString(),\n trackOpens: input.trackOpens,\n trackClicks: input.trackClicks,\n },\n };\n\n const response = await this.client.tenantQuery<{\n sendNotification: string;\n }>(mutation, variables, this.context);\n\n logger.info('[TenantNotifications] Notification sent', {\n notificationId: response.sendNotification,\n });\n\n return response.sendNotification;\n }\n\n /**\n * Send notification using a template\n */\n public async sendWithTemplate(input: SendWithTemplateInput): Promise<string> {\n // Validate inputs\n if (!input.templateSlug || input.templateSlug.trim().length === 0) {\n throw new ValidationError('Template slug is required');\n }\n\n if (!input.variables || Object.keys(input.variables).length === 0) {\n throw new ValidationError('Template variables are required');\n }\n\n if (!input.recipient || (!input.recipient.email && !input.recipient.userId)) {\n throw new ValidationError('Recipient email or userId is required');\n }\n\n logger.info('[TenantNotifications] Sending notification with template', {\n templateSlug: input.templateSlug,\n priority: input.priority || NotificationPriority.MEDIUM,\n });\n\n const mutation = `\n mutation TriggerNotificationWithTemplate($input: TriggerNotificationWithTemplateInput!) {\n triggerNotificationWithTemplate(input: $input) {\n totalRequested\n totalTriggered\n totalFailed\n notifications {\n id\n status\n deliveryStatus\n }\n }\n }\n `;\n\n const variables = {\n input: {\n templateSlug: input.templateSlug,\n variables: input.variables,\n recipient: input.recipient,\n priority: input.priority || NotificationPriority.MEDIUM,\n scheduledFor: input.scheduledFor?.toISOString(),\n expiresAt: input.expiresAt?.toISOString(),\n trackOpens: input.trackOpens,\n trackClicks: input.trackClicks,\n // Platform is required for notification delivery routing\n // If channelId is specified, it takes precedence; otherwise platform determines delivery\n channelId: input.channelId,\n platform: input.platform || NotificationChannel.EMAIL,\n timezone: input.timezone,\n },\n };\n\n const response = await this.client.tenantQuery<{\n triggerNotificationWithTemplate: {\n totalRequested: number;\n totalTriggered: number;\n totalFailed: number;\n notifications: Array<{ id: string; status: string; deliveryStatus?: string }>;\n };\n }>(mutation, variables, this.context);\n\n const result = response.triggerNotificationWithTemplate;\n const firstNotification = result.notifications[0];\n\n if (result.totalTriggered === 0 || !firstNotification) {\n throw new ValidationError(\n `Notification trigger failed: requested=${result.totalRequested}, triggered=${result.totalTriggered}, failed=${result.totalFailed}`\n );\n }\n\n logger.info('[TenantNotifications] Notification sent with template', {\n notificationId: firstNotification.id,\n status: firstNotification.status,\n totalTriggered: result.totalTriggered,\n totalFailed: result.totalFailed,\n });\n\n return firstNotification.id;\n }\n\n /**\n * Send batch notifications\n */\n public async sendBatch(input: BatchNotificationInput): Promise<{\n totalRequested: number;\n totalQueued: number;\n totalFailed: number;\n batchId: string;\n }> {\n if (!input.notifications || input.notifications.length === 0) {\n throw new ValidationError('At least one notification is required');\n }\n\n logger.info('[TenantNotifications] Sending batch notifications', {\n count: input.notifications.length,\n batchSize: input.batchSize,\n });\n\n const mutation = `\n mutation SendBatchNotifications($input: BatchNotificationInput!) {\n sendBatchNotifications(input: $input) {\n totalRequested\n totalQueued\n totalFailed\n batchId\n }\n }\n `;\n\n const variables = {\n input: {\n notifications: input.notifications.map((n) => ({\n recipient: n.recipient,\n channel: n.channel,\n type: n.type || NotificationType.TRANSACTIONAL,\n priority: n.priority || NotificationPriority.MEDIUM,\n subject: n.subject,\n body: n.body,\n htmlBody: n.htmlBody,\n data: n.data,\n metadata: n.metadata,\n scheduledFor: n.scheduledFor?.toISOString(),\n expiresAt: n.expiresAt?.toISOString(),\n trackOpens: n.trackOpens,\n trackClicks: n.trackClicks,\n })),\n batchSize: input.batchSize,\n delayBetweenBatches: input.delayBetweenBatches,\n priority: input.priority,\n },\n };\n\n const response = await this.client.tenantQuery<{\n sendBatchNotifications: {\n totalRequested: number;\n totalQueued: number;\n totalFailed: number;\n batchId: string;\n };\n }>(mutation, variables, this.context);\n\n logger.info('[TenantNotifications] Batch notifications sent', {\n batchId: response.sendBatchNotifications.batchId,\n queued: response.sendBatchNotifications.totalQueued,\n failed: response.sendBatchNotifications.totalFailed,\n });\n\n return response.sendBatchNotifications;\n }\n\n /**\n * Get a notification by ID\n */\n public async getNotification(id: string): Promise<Notification | null> {\n const query = `\n query GetNotification($id: ID!) {\n notification(id: $id) {\n id\n userId\n channel\n type\n priority\n status\n deliveryStatus\n title\n message\n htmlMessage\n subject\n recipientEmail\n recipientPhone\n trackOpens\n trackClicks\n openedAt\n clickedAt\n sentAt\n deliveredAt\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notification: Notification | null;\n }>(query, { id }, this.context);\n\n return response.notification;\n }\n\n /**\n * Get notifications with filters\n */\n public async getNotifications(filter?: {\n userId?: string;\n channel?: NotificationChannel;\n type?: NotificationType;\n status?: string;\n priority?: NotificationPriority;\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n }): Promise<Notification[]> {\n const query = `\n query GetNotifications($filter: NotificationFilterInput, $limit: Int, $offset: Int) {\n notifications(filter: $filter, limit: $limit, offset: $offset) {\n id\n userId\n channel\n type\n priority\n status\n deliveryStatus\n title\n message\n subject\n recipientEmail\n trackOpens\n trackClicks\n openedAt\n clickedAt\n sentAt\n deliveredAt\n createdAt\n updatedAt\n }\n }\n `;\n\n const variables = {\n filter: filter\n ? {\n userId: filter.userId,\n channel: filter.channel,\n type: filter.type,\n status: filter.status,\n priority: filter.priority,\n startDate: filter.startDate?.toISOString(),\n endDate: filter.endDate?.toISOString(),\n }\n : undefined,\n limit: filter?.limit || 50,\n offset: filter?.offset || 0,\n };\n\n const response = await this.client.tenantQuery<{\n notifications: Notification[];\n }>(query, variables, this.context);\n\n return response.notifications;\n }\n\n /**\n * Get notification template\n */\n public async getTemplate(slug: string, locale?: string): Promise<NotificationTemplate | null> {\n const query = `\n query GetNotificationTemplate($slug: String!, $locale: String) {\n notificationTemplate(slug: $slug, locale: $locale) {\n id\n name\n slug\n description\n channel\n type\n locale\n subject\n bodyTemplate\n htmlTemplate\n variables\n enabled\n version\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notificationTemplate: NotificationTemplate | null;\n }>(query, { slug, locale }, this.context);\n\n return response.notificationTemplate;\n }\n\n /**\n * Get all notification templates\n */\n public async getTemplates(filter?: {\n channel?: NotificationChannel;\n type?: NotificationType;\n enabled?: boolean;\n }): Promise<NotificationTemplate[]> {\n const query = `\n query GetNotificationTemplates($filter: TemplateFilterInput) {\n notificationTemplates(filter: $filter) {\n id\n name\n slug\n description\n channel\n type\n locale\n subject\n bodyTemplate\n htmlTemplate\n variables\n enabled\n version\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notificationTemplates: NotificationTemplate[];\n }>(query, { filter }, this.context);\n\n return response.notificationTemplates;\n }\n\n /**\n * Get notification statistics\n */\n public async getStats(filter?: { userId?: string; startDate?: Date; endDate?: Date }): Promise<NotificationStats> {\n const query = `\n query GetNotificationStats($filter: NotificationFilterInput) {\n notificationStats(filter: $filter) {\n total\n pending\n queued\n processing\n sent\n delivered\n failed\n byChannel\n byType\n }\n }\n `;\n\n const variables = {\n filter: filter\n ? {\n userId: filter.userId,\n startDate: filter.startDate?.toISOString(),\n endDate: filter.endDate?.toISOString(),\n }\n : undefined,\n };\n\n const response = await this.client.tenantQuery<{\n notificationStats: NotificationStats;\n }>(query, variables, this.context);\n\n return response.notificationStats;\n }\n\n /**\n * Mark notifications as read\n */\n public async markAsRead(notificationIds: string[]): Promise<boolean> {\n const mutation = `\n mutation MarkNotificationsAsRead($notificationIds: [ID!]!) {\n markNotificationsAsRead(notificationIds: $notificationIds)\n }\n `;\n\n await this.client.tenantQuery(mutation, { notificationIds }, this.context);\n\n logger.info('[TenantNotifications] Notifications marked as read', {\n count: notificationIds.length,\n });\n\n return true;\n }\n\n /**\n * Mark all notifications as read for the current user\n */\n public async markAllAsRead(): Promise<boolean> {\n const mutation = `\n mutation MarkAllMyNotificationsAsRead {\n markAllMyNotificationsAsRead\n }\n `;\n\n await this.client.tenantQuery(mutation, {}, this.context);\n\n logger.info('[TenantNotifications] All notifications marked as read');\n\n return true;\n }\n\n /**\n * Delete notifications\n */\n public async deleteNotifications(notificationIds: string[]): Promise<boolean> {\n const mutation = `\n mutation DeleteNotifications($notificationIds: [ID!]!) {\n deleteNotifications(notificationIds: $notificationIds)\n }\n `;\n\n await this.client.tenantQuery(mutation, { notificationIds }, this.context);\n\n logger.info('[TenantNotifications] Notifications deleted', {\n count: notificationIds.length,\n });\n\n return true;\n }\n\n /**\n * Delete all read notifications for the current user\n */\n public async deleteAllReadNotifications(): Promise<boolean> {\n const mutation = `\n mutation DeleteMyReadNotifications {\n deleteMyReadNotifications\n }\n `;\n\n await this.client.tenantQuery(mutation, {}, this.context);\n\n logger.info('[TenantNotifications] All read notifications deleted');\n\n return true;\n }\n\n /**\n * Validate send notification input\n */\n private validateSendInput(input: SendNotificationInput): void {\n if (!input.recipient || (!input.recipient.email && !input.recipient.userId && !input.recipient.phoneNumber)) {\n throw new ValidationError('Recipient email, userId, or phoneNumber is required');\n }\n\n if (!input.channel) {\n throw new ValidationError('Notification channel is required');\n }\n\n if (!input.body || input.body.trim().length === 0) {\n throw new ValidationError('Notification body is required');\n }\n\n // Channel-specific validation\n if (input.channel === NotificationChannel.EMAIL && !input.recipient.email) {\n throw new ValidationError('Recipient email is required for EMAIL channel');\n }\n\n if (input.channel === NotificationChannel.SMS && !input.recipient.phoneNumber) {\n throw new ValidationError('Recipient phone number is required for SMS channel');\n }\n\n if (input.channel === NotificationChannel.PUSH && !input.recipient.pushToken && !input.recipient.userId) {\n throw new ValidationError('Recipient push token or userId is required for PUSH channel');\n }\n }\n}\n","/**\n * Notifications Module\n * Send in-app, email, SMS, and push notifications via workspaces-backend\n */\n\nimport type { BurdenoffGraphQLClient } from '../client/graphql.js';\nimport type { SDKContext } from '../types/index.js';\nimport { ValidationError } from '../types/index.js';\nimport { logger } from '../logger/index.js';\n\nexport enum NotificationType {\n INFO = 'info',\n SUCCESS = 'success',\n WARNING = 'warning',\n ERROR = 'error',\n}\n\nexport enum NotificationChannel {\n EMAIL = 'EMAIL',\n SMS = 'SMS',\n WHATSAPP = 'WHATSAPP',\n PUSH = 'PUSH',\n SLACK = 'SLACK',\n TEAMS = 'TEAMS',\n WEBHOOK = 'WEBHOOK',\n}\n\n// Re-export from tenant-notifications\nexport { NotificationPriority, TenantNotificationsModule } from './tenant-notifications.js';\n\nexport interface SendNotificationOptions {\n /** Notification title */\n title: string;\n /** Notification message */\n message: string;\n /** Notification type */\n type?: NotificationType;\n /** Target user IDs */\n userIds: string[];\n /** Optional redirect URL */\n redirectUrl?: string;\n /** Application name */\n appName?: string;\n /** Send email notification */\n email?: boolean;\n /** Send SMS notification */\n sms?: boolean;\n}\n\nexport interface NotificationResponse {\n /** Number of successful notifications */\n successCount: number;\n /** Number of failed notifications */\n failureCount: number;\n /** Error messages if any */\n errors: string[];\n /** Created notification IDs */\n notificationIds?: string[];\n}\n\nexport interface GetNotificationsOptions {\n /** User ID to get notifications for */\n userId: string;\n /** Filter by status */\n status?: 'unread' | 'read' | 'all';\n /** Filter by type */\n type?: NotificationType;\n /** Filter by app name */\n appName?: string;\n /** Search term */\n search?: string;\n /** Limit number of results */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n}\n\nexport interface Notification {\n id: string;\n userId: string;\n title: string;\n message: string;\n type: NotificationType;\n status: 'unread' | 'read';\n redirectUrl?: string;\n appName?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface RecipientInput {\n email?: string;\n locale?: string;\n name?: string;\n phoneNumber?: string;\n pushToken?: string;\n slackUserId?: string;\n teamsUserId?: string;\n timezone?: string;\n userId?: string;\n webhookUrl?: string;\n whatsappNumber?: string;\n}\n\nexport interface SendChannelNotificationOptions {\n /** Primary delivery channel (EMAIL, SMS, WHATSAPP, etc.) */\n platform: NotificationChannel;\n /** Recipient information for primary channel */\n recipient: RecipientInput;\n /** Multiple recipients for bulk delivery */\n recipients?: RecipientInput[];\n /** Notification subject (for EMAIL) */\n subject?: string;\n /** Notification body/message */\n body: string;\n /** HTML body (for EMAIL) */\n htmlBody?: string;\n /** Notification type */\n type?: NotificationType;\n /** Application name */\n appName?: string;\n /** Redirect URL */\n redirectUrl?: string;\n /** Also send as in-app notification */\n includeInApp?: boolean;\n /** User IDs for in-app notifications (required when includeInApp is true) */\n userIds?: string[];\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n /** Track email opens */\n trackOpens?: boolean;\n /** Track link clicks */\n trackClicks?: boolean;\n /** Expiration time */\n expiresAt?: Date;\n /** Specific channel instance ID (overrides platform) */\n channelId?: string;\n}\n\nexport interface SendTemplateNotificationOptions {\n /** Primary delivery channel (EMAIL, SMS, WHATSAPP, etc.) */\n platform: NotificationChannel;\n /** Template slug to use */\n templateSlug: string;\n /** Template variables */\n variables: Record<string, unknown>;\n /** Recipient information for primary channel */\n recipient?: RecipientInput;\n /** Multiple recipients for bulk delivery */\n recipients?: RecipientInput[];\n /** Also send as in-app notification */\n includeInApp?: boolean;\n /** User IDs for in-app notifications (required when includeInApp is true) */\n userIds?: string[];\n /** Application name */\n appName?: string;\n /** Track email opens */\n trackOpens?: boolean;\n /** Track link clicks */\n trackClicks?: boolean;\n /** Expiration time */\n expiresAt?: Date;\n /** Scheduled delivery time */\n scheduledFor?: Date;\n /** Timezone for scheduling */\n timezone?: string;\n /** Specific channel instance ID (overrides platform) */\n channelId?: string;\n}\n\n/**\n * Notifications Module\n */\nexport class NotificationsModule {\n constructor(\n private client: BurdenoffGraphQLClient,\n private context: SDKContext\n ) {}\n\n /**\n * Send notification to users\n */\n public async send(options: SendNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.title || options.title.trim().length === 0) {\n throw new ValidationError('Notification title is required');\n }\n\n if (!options.message || options.message.trim().length === 0) {\n throw new ValidationError('Notification message is required');\n }\n\n if (!options.userIds || options.userIds.length === 0) {\n throw new ValidationError('At least one user ID is required');\n }\n\n logger.info('[Notifications] Sending notification', {\n title: options.title,\n userCount: options.userIds.length,\n type: options.type || NotificationType.INFO,\n });\n\n const mutation = `\n mutation CreateNotification($input: CreateNotificationInput!) {\n createNotification(input: $input) {\n successCount\n failureCount\n errors\n notifications {\n id\n }\n }\n }\n `;\n\n const variables = {\n input: {\n title: options.title,\n message: options.message,\n type: options.type || NotificationType.INFO,\n userIds: options.userIds,\n redirectUrl: options.redirectUrl || '',\n appName: options.appName,\n email: options.email || false,\n sms: options.sms || false,\n },\n };\n\n const response = await this.client.query<{\n createNotification: NotificationResponse & { notifications: Array<{ id: string }> };\n }>(mutation, variables, this.context);\n\n const result = {\n successCount: response.createNotification.successCount,\n failureCount: response.createNotification.failureCount,\n errors: response.createNotification.errors,\n notificationIds: response.createNotification.notifications.map((n) => n.id),\n };\n\n logger.info('[Notifications] Notification sent', {\n successCount: result.successCount,\n failureCount: result.failureCount,\n });\n\n return result;\n }\n\n /**\n * Send notification to a single user (convenience method)\n */\n public async sendToUser(\n userId: string,\n title: string,\n message: string,\n options?: Omit<SendNotificationOptions, 'userIds' | 'title' | 'message'>\n ): Promise<NotificationResponse> {\n return this.send({\n title,\n message,\n userIds: [userId],\n ...options,\n });\n }\n\n /**\n * Get notifications for a user\n */\n public async getNotifications(options: GetNotificationsOptions): Promise<{\n notifications: Notification[];\n total: number;\n unreadCount: number;\n }> {\n logger.debug('[Notifications] Getting notifications', { userId: options.userId });\n\n const query = `\n query GetNotifications(\n $userId: ID!\n $status: NotificationStatus\n $type: NotificationType\n $appName: String\n $search: String\n $limit: Int\n $offset: Int\n ) {\n getNotifications(\n userId: $userId\n status: $status\n type: $type\n appName: $appName\n search: $search\n limit: $limit\n offset: $offset\n ) {\n notifications {\n id\n userId\n title\n message\n type\n status\n redirectUrl\n appName\n createdAt\n updatedAt\n }\n total\n unreadCount\n }\n }\n `;\n\n const variables = {\n userId: options.userId,\n status: options.status,\n type: options.type,\n appName: options.appName,\n search: options.search,\n limit: options.limit || 20,\n offset: options.offset || 0,\n };\n\n const response = await this.client.query<{\n getNotifications: {\n notifications: Notification[];\n total: number;\n unreadCount: number;\n };\n }>(query, variables, this.context);\n\n return response.getNotifications;\n }\n\n /**\n * Mark notification as read\n */\n public async markAsRead(notificationId: string): Promise<boolean> {\n logger.debug('[Notifications] Marking notification as read', { notificationId });\n\n const mutation = `\n mutation MarkNotificationAsRead($notificationId: ID!) {\n markNotificationAsRead(notificationId: $notificationId) {\n id\n status\n }\n }\n `;\n\n await this.client.query(mutation, { notificationId }, this.context);\n\n logger.info('[Notifications] Notification marked as read', { notificationId });\n\n return true;\n }\n\n /**\n * Mark multiple notifications as read\n */\n public async markMultipleAsRead(notificationIds: string[]): Promise<number> {\n logger.debug('[Notifications] Marking multiple notifications as read', {\n count: notificationIds.length,\n });\n\n const mutation = `\n mutation MarkNotificationsAsRead($notificationIds: [ID!]!) {\n markNotificationsAsRead(notificationIds: $notificationIds) {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n markNotificationsAsRead: { count: number };\n }>(mutation, { notificationIds }, this.context);\n\n logger.info('[Notifications] Notifications marked as read', {\n count: response.markNotificationsAsRead.count,\n });\n\n return response.markNotificationsAsRead.count;\n }\n\n /**\n * Mark all notifications as read for the current user\n */\n public async markAllAsRead(): Promise<number> {\n logger.debug('[Notifications] Marking all notifications as read');\n\n const mutation = `\n mutation MarkAllMyNotificationsAsRead {\n markAllMyNotificationsAsRead {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n markAllMyNotificationsAsRead: { count: number };\n }>(mutation, {}, this.context);\n\n logger.info('[Notifications] All notifications marked as read', {\n count: response.markAllMyNotificationsAsRead.count,\n });\n\n return response.markAllMyNotificationsAsRead.count;\n }\n\n /**\n * Delete notification\n */\n public async deleteNotification(notificationId: string): Promise<boolean> {\n logger.debug('[Notifications] Deleting notification', { notificationId });\n\n const mutation = `\n mutation DeleteNotification($notificationId: ID!) {\n deleteNotification(notificationId: $notificationId) {\n success\n }\n }\n `;\n\n await this.client.query(mutation, { notificationId }, this.context);\n\n logger.info('[Notifications] Notification deleted', { notificationId });\n\n return true;\n }\n\n /**\n * Delete multiple notifications\n */\n public async deleteMultiple(notificationIds: string[]): Promise<number> {\n logger.debug('[Notifications] Deleting multiple notifications', {\n count: notificationIds.length,\n });\n\n const mutation = `\n mutation DeleteNotifications($notificationIds: [ID!]!) {\n deleteNotifications(notificationIds: $notificationIds) {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n deleteNotifications: { count: number };\n }>(mutation, { notificationIds }, this.context);\n\n logger.info('[Notifications] Notifications deleted', {\n count: response.deleteNotifications.count,\n });\n\n return response.deleteNotifications.count;\n }\n\n /**\n * Get unread notification count for a user\n */\n public async getUnreadCount(userId: string): Promise<number> {\n const result = await this.getNotifications({\n userId,\n status: 'unread',\n limit: 0,\n });\n\n return result.unreadCount;\n }\n\n /**\n * Send notification via specific channel (EMAIL, SMS, WHATSAPP, etc.)\n * with optional in-app notification\n */\n public async sendChannelNotification(options: SendChannelNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.body || options.body.trim().length === 0) {\n throw new ValidationError('Notification body is required');\n }\n\n if (!options.recipient && !options.recipients) {\n throw new ValidationError('At least one recipient is required');\n }\n\n if (options.includeInApp && (!options.userIds || options.userIds.length === 0)) {\n throw new ValidationError('User IDs are required when includeInApp is true');\n }\n\n logger.info('[Notifications] Sending channel notification', {\n platform: options.platform,\n recipientCount: options.recipients ? options.recipients.length : 1,\n includeInApp: options.includeInApp,\n inAppUserCount: options.userIds ? options.userIds.length : 0,\n });\n\n const mutation = `\n mutation TriggerNotification($input: TriggerNotificationInput!) {\n triggerNotification(input: $input) {\n id\n status\n deliveryStatus\n }\n }\n `;\n\n const variables = {\n input: {\n platform: options.platform,\n channelId: options.channelId,\n includeInApp: options.includeInApp || false,\n userIds: options.userIds || [],\n notification: {\n subject: options.subject || '',\n body: options.body,\n htmlBody: options.htmlBody || '',\n channel: options.platform,\n type: options.type || NotificationType.INFO,\n recipient: options.recipient,\n appName: options.appName,\n redirectUrl: options.redirectUrl || '',\n metadata: options.metadata || {},\n trackOpens: options.trackOpens || false,\n trackClicks: options.trackClicks || false,\n expiresAt: options.expiresAt?.toISOString(),\n },\n },\n };\n\n // Handle bulk recipients\n if (options.recipients && options.recipients.length > 1) {\n const results = await Promise.allSettled(\n options.recipients.map((recipient) =>\n this.client.query(\n mutation,\n {\n input: {\n ...variables.input,\n notification: {\n ...variables.input.notification,\n recipient,\n },\n },\n },\n this.context\n )\n )\n );\n\n let successCount = 0;\n let failureCount = 0;\n const errors: string[] = [];\n const notificationIds: string[] = [];\n\n results.forEach((result, index) => {\n if (result.status === 'fulfilled') {\n successCount++;\n const response = result.value as { triggerNotification: { id: string } };\n notificationIds.push(response.triggerNotification.id);\n } else {\n failureCount++;\n errors.push(\n `Recipient ${index + 1}: ${result.reason instanceof Error ? result.reason.message : 'Unknown error'}`\n );\n }\n });\n\n const response: NotificationResponse = {\n successCount,\n failureCount,\n errors,\n notificationIds,\n };\n\n logger.info('[Notifications] Channel notification sent (bulk)', {\n successCount,\n failureCount,\n });\n\n return response;\n } else {\n // Single recipient\n try {\n const response = await this.client.query<{\n triggerNotification: { id: string; status: string; deliveryStatus: string };\n }>(mutation, variables, this.context);\n\n const result: NotificationResponse = {\n successCount: 1,\n failureCount: 0,\n errors: [],\n notificationIds: [response.triggerNotification.id],\n };\n\n logger.info('[Notifications] Channel notification sent', {\n notificationId: response.triggerNotification.id,\n status: response.triggerNotification.status,\n });\n\n return result;\n } catch (error) {\n logger.error('[Notifications] Failed to send channel notification', { error });\n\n return {\n successCount: 0,\n failureCount: 1,\n errors: [error instanceof Error ? error.message : 'Unknown error'],\n notificationIds: [],\n };\n }\n }\n }\n\n /**\n * Send notification using a template with optional in-app notification\n */\n public async sendTemplateNotification(options: SendTemplateNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.templateSlug || options.templateSlug.trim().length === 0) {\n throw new ValidationError('Template slug is required');\n }\n\n if (!options.variables || typeof options.variables !== 'object') {\n throw new ValidationError('Template variables are required');\n }\n\n if (!options.recipient && !options.recipients) {\n throw new ValidationError('At least one recipient is required');\n }\n\n if (options.includeInApp && (!options.userIds || options.userIds.length === 0)) {\n throw new ValidationError('User IDs are required when includeInApp is true');\n }\n\n logger.info('[Notifications] Sending template notification', {\n templateSlug: options.templateSlug,\n platform: options.platform,\n recipientCount: options.recipients ? options.recipients.length : 1,\n includeInApp: options.includeInApp,\n inAppUserCount: options.userIds ? options.userIds.length : 0,\n });\n\n const mutation = `\n mutation TriggerNotificationWithTemplate($input: TriggerNotificationWithTemplateInput!) {\n triggerNotificationWithTemplate(input: $input) {\n totalRequested\n totalTriggered\n totalFailed\n notifications {\n id\n status\n deliveryStatus\n }\n }\n }\n `;\n\n const variables = {\n input: {\n platform: options.platform,\n channelId: options.channelId,\n includeInApp: options.includeInApp || false,\n userIds: options.userIds || [],\n templateSlug: options.templateSlug,\n variables: options.variables,\n recipient: options.recipient,\n recipients: options.recipients,\n trackOpens: options.trackOpens || false,\n trackClicks: options.trackClicks || false,\n expiresAt: options.expiresAt?.toISOString(),\n scheduledFor: options.scheduledFor?.toISOString(),\n timezone: options.timezone,\n },\n };\n\n try {\n const response = await this.client.query<{\n triggerNotificationWithTemplate: {\n totalRequested: number;\n totalTriggered: number;\n totalFailed: number;\n notifications: Array<{ id: string; status: string; deliveryStatus?: string }>;\n };\n }>(mutation, variables, this.context);\n\n const data = response.triggerNotificationWithTemplate;\n\n const result: NotificationResponse = {\n successCount: data.totalTriggered,\n failureCount: data.totalFailed,\n errors: [],\n notificationIds: data.notifications.map((n) => n.id),\n };\n\n logger.info('[Notifications] Template notification sent', {\n templateSlug: options.templateSlug,\n totalTriggered: data.totalTriggered,\n totalFailed: data.totalFailed,\n notificationIds: result.notificationIds,\n });\n\n return result;\n } catch (error) {\n logger.error('[Notifications] Failed to send template notification', { error });\n\n return {\n successCount: 0,\n failureCount: 1,\n errors: [error instanceof Error ? error.message : 'Unknown error'],\n notificationIds: [],\n };\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/notifications/tenant-notifications.ts","../src/notifications/index.ts"],"names":["NotificationChannel","NotificationPriority","NotificationType","TenantNotificationsModule","client","context","send","input","validateSendInput","logger","info","channel","type","priority","mutation","variables","recipient","subject","body","htmlBody","data","metadata","scheduledFor","toISOString","expiresAt","trackOpens","trackClicks","response","tenantQuery","notificationId","sendNotification","sendWithTemplate","templateSlug","trim","length","ValidationError","Object","keys","email","userId","channelId","platform","timezone","result","triggerNotificationWithTemplate","firstNotification","notifications","totalTriggered","totalRequested","totalFailed","id","status","sendBatch","count","batchSize","map","n","delayBetweenBatches","batchId","sendBatchNotifications","queued","totalQueued","failed","getNotification","query","notification","getNotifications","filter","startDate","endDate","undefined","limit","offset","getTemplate","slug","locale","notificationTemplate","getTemplates","notificationTemplates","getStats","notificationStats","markAsRead","notificationIds","markAllAsRead","deleteNotifications","deleteAllReadNotifications","phoneNumber","pushToken","NotificationsModule","options","title","message","userIds","userCount","redirectUrl","appName","sms","successCount","createNotification","failureCount","errors","sendToUser","debug","search","markMultipleAsRead","markNotificationsAsRead","markAllMyNotificationsAsRead","deleteNotification","deleteMultiple","getUnreadCount","unreadCount","sendChannelNotification","recipients","includeInApp","recipientCount","inAppUserCount","results","Promise","allSettled","forEach","index","value","push","triggerNotification","reason","Error","error","sendTemplateNotification"],"mappings":"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","file":"chunk-RMDKB5O7.js","sourcesContent":["/**\n * Tenant-Backend Notifications Module\n * Comprehensive notification system supporting 10+ channels via tenant-backend\n */\n\nimport type { BurdenoffGraphQLClient } from '../client/graphql.js';\nimport type { SDKContext } from '../types/index.js';\nimport { ValidationError } from '../types/index.js';\nimport { logger } from '../logger/index.js';\n\n// ========================================\n// Enums\n// ========================================\n\nexport enum NotificationChannel {\n EMAIL = 'EMAIL',\n SMS = 'SMS',\n PUSH = 'PUSH',\n IN_APP = 'IN_APP',\n WEBHOOK = 'WEBHOOK',\n WHATSAPP = 'WHATSAPP',\n TEAMS = 'TEAMS',\n SLACK = 'SLACK',\n TELEGRAM = 'TELEGRAM',\n DISCORD = 'DISCORD',\n}\n\nexport enum NotificationPriority {\n LOW = 'LOW',\n MEDIUM = 'MEDIUM',\n HIGH = 'HIGH',\n URGENT = 'URGENT',\n}\n\nexport enum NotificationType {\n TRANSACTIONAL = 'TRANSACTIONAL',\n MARKETING = 'MARKETING',\n SYSTEM = 'SYSTEM',\n ALERT = 'ALERT',\n}\n\n// ========================================\n// Types & Interfaces\n// ========================================\n\nexport interface RecipientInput {\n userId?: string;\n email?: string;\n phoneNumber?: string;\n pushToken?: string;\n whatsappNumber?: string;\n teamsUserId?: string;\n slackUserId?: string;\n webhookUrl?: string;\n name?: string;\n locale?: string;\n timezone?: string;\n}\n\nexport interface SendNotificationInput {\n recipient: RecipientInput;\n channel: NotificationChannel;\n type?: NotificationType;\n priority?: NotificationPriority;\n subject?: string;\n body: string;\n htmlBody?: string;\n data?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n scheduledFor?: Date;\n expiresAt?: Date;\n trackOpens?: boolean;\n trackClicks?: boolean;\n}\n\nexport interface SendWithTemplateInput {\n templateSlug: string;\n variables: Record<string, unknown>;\n recipient: RecipientInput;\n priority?: NotificationPriority;\n scheduledFor?: Date;\n expiresAt?: Date;\n trackOpens?: boolean;\n trackClicks?: boolean;\n /** Specific channel instance ID from channel service (takes precedence) */\n channelId?: string;\n /** Platform type for auto-failover (EMAIL, SMS, etc.) - used if channelId not provided */\n platform?: NotificationChannel;\n /** Timezone for scheduling */\n timezone?: string;\n}\n\nexport interface BatchNotificationInput {\n notifications: SendNotificationInput[];\n batchSize?: number;\n delayBetweenBatches?: number;\n priority?: NotificationPriority;\n}\n\nexport interface Notification {\n id: string;\n userId: string;\n channel: NotificationChannel;\n type: NotificationType;\n priority: NotificationPriority;\n status: string;\n deliveryStatus?: string;\n title: string;\n message: string;\n htmlMessage?: string;\n subject?: string;\n recipientEmail?: string;\n recipientPhone?: string;\n trackOpens: boolean;\n trackClicks: boolean;\n openedAt?: string;\n clickedAt?: string;\n sentAt?: string;\n deliveredAt?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface NotificationTemplate {\n id: string;\n name: string;\n slug: string;\n description?: string;\n channel: NotificationChannel;\n type: NotificationType;\n locale: string;\n subject?: string;\n bodyTemplate: string;\n htmlTemplate?: string;\n variables: Array<{\n name: string;\n type: string;\n required: boolean;\n defaultValue?: unknown;\n description?: string;\n example?: unknown;\n }>;\n enabled: boolean;\n version: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface NotificationStats {\n total: number;\n pending: number;\n queued: number;\n processing: number;\n sent: number;\n delivered: number;\n failed: number;\n byChannel: Record<string, number>;\n byType: Record<string, number>;\n}\n\n// ========================================\n// Tenant Notifications Module\n// ========================================\n\n/**\n * Tenant-Backend Notifications Module\n * Provides access to the centralized notification system\n */\nexport class TenantNotificationsModule {\n constructor(\n private client: BurdenoffGraphQLClient,\n private context: SDKContext\n ) {}\n\n /**\n * Send a single notification\n */\n public async send(input: SendNotificationInput): Promise<string> {\n // Validate inputs\n this.validateSendInput(input);\n\n logger.info('[TenantNotifications] Sending notification', {\n channel: input.channel,\n type: input.type || NotificationType.TRANSACTIONAL,\n priority: input.priority || NotificationPriority.MEDIUM,\n });\n\n const mutation = `\n mutation SendNotification($input: SendNotificationInput!) {\n sendNotification(input: $input)\n }\n `;\n\n const variables = {\n input: {\n recipient: input.recipient,\n channel: input.channel,\n type: input.type || NotificationType.TRANSACTIONAL,\n priority: input.priority || NotificationPriority.MEDIUM,\n subject: input.subject,\n body: input.body,\n htmlBody: input.htmlBody,\n data: input.data,\n metadata: input.metadata,\n scheduledFor: input.scheduledFor?.toISOString(),\n expiresAt: input.expiresAt?.toISOString(),\n trackOpens: input.trackOpens,\n trackClicks: input.trackClicks,\n },\n };\n\n const response = await this.client.tenantQuery<{\n sendNotification: string;\n }>(mutation, variables, this.context);\n\n logger.info('[TenantNotifications] Notification sent', {\n notificationId: response.sendNotification,\n });\n\n return response.sendNotification;\n }\n\n /**\n * Send notification using a template\n */\n public async sendWithTemplate(input: SendWithTemplateInput): Promise<string> {\n // Validate inputs\n if (!input.templateSlug || input.templateSlug.trim().length === 0) {\n throw new ValidationError('Template slug is required');\n }\n\n if (!input.variables || Object.keys(input.variables).length === 0) {\n throw new ValidationError('Template variables are required');\n }\n\n if (!input.recipient || (!input.recipient.email && !input.recipient.userId)) {\n throw new ValidationError('Recipient email or userId is required');\n }\n\n logger.info('[TenantNotifications] Sending notification with template', {\n templateSlug: input.templateSlug,\n priority: input.priority || NotificationPriority.MEDIUM,\n });\n\n const mutation = `\n mutation TriggerNotificationWithTemplate($input: TriggerNotificationWithTemplateInput!) {\n triggerNotificationWithTemplate(input: $input) {\n totalRequested\n totalTriggered\n totalFailed\n notifications {\n id\n status\n deliveryStatus\n }\n }\n }\n `;\n\n const variables = {\n input: {\n templateSlug: input.templateSlug,\n variables: input.variables,\n recipient: input.recipient,\n priority: input.priority || NotificationPriority.MEDIUM,\n scheduledFor: input.scheduledFor?.toISOString(),\n expiresAt: input.expiresAt?.toISOString(),\n trackOpens: input.trackOpens,\n trackClicks: input.trackClicks,\n // Platform is required for notification delivery routing\n // If channelId is specified, it takes precedence; otherwise platform determines delivery\n channelId: input.channelId,\n platform: input.platform || NotificationChannel.EMAIL,\n timezone: input.timezone,\n },\n };\n\n const response = await this.client.tenantQuery<{\n triggerNotificationWithTemplate: {\n totalRequested: number;\n totalTriggered: number;\n totalFailed: number;\n notifications: Array<{ id: string; status: string; deliveryStatus?: string }>;\n };\n }>(mutation, variables, this.context);\n\n const result = response.triggerNotificationWithTemplate;\n const firstNotification = result.notifications[0];\n\n if (result.totalTriggered === 0 || !firstNotification) {\n throw new ValidationError(\n `Notification trigger failed: requested=${result.totalRequested}, triggered=${result.totalTriggered}, failed=${result.totalFailed}`\n );\n }\n\n logger.info('[TenantNotifications] Notification sent with template', {\n notificationId: firstNotification.id,\n status: firstNotification.status,\n totalTriggered: result.totalTriggered,\n totalFailed: result.totalFailed,\n });\n\n return firstNotification.id;\n }\n\n /**\n * Send batch notifications\n */\n public async sendBatch(input: BatchNotificationInput): Promise<{\n totalRequested: number;\n totalQueued: number;\n totalFailed: number;\n batchId: string;\n }> {\n if (!input.notifications || input.notifications.length === 0) {\n throw new ValidationError('At least one notification is required');\n }\n\n logger.info('[TenantNotifications] Sending batch notifications', {\n count: input.notifications.length,\n batchSize: input.batchSize,\n });\n\n const mutation = `\n mutation SendBatchNotifications($input: BatchNotificationInput!) {\n sendBatchNotifications(input: $input) {\n totalRequested\n totalQueued\n totalFailed\n batchId\n }\n }\n `;\n\n const variables = {\n input: {\n notifications: input.notifications.map((n) => ({\n recipient: n.recipient,\n channel: n.channel,\n type: n.type || NotificationType.TRANSACTIONAL,\n priority: n.priority || NotificationPriority.MEDIUM,\n subject: n.subject,\n body: n.body,\n htmlBody: n.htmlBody,\n data: n.data,\n metadata: n.metadata,\n scheduledFor: n.scheduledFor?.toISOString(),\n expiresAt: n.expiresAt?.toISOString(),\n trackOpens: n.trackOpens,\n trackClicks: n.trackClicks,\n })),\n batchSize: input.batchSize,\n delayBetweenBatches: input.delayBetweenBatches,\n priority: input.priority,\n },\n };\n\n const response = await this.client.tenantQuery<{\n sendBatchNotifications: {\n totalRequested: number;\n totalQueued: number;\n totalFailed: number;\n batchId: string;\n };\n }>(mutation, variables, this.context);\n\n logger.info('[TenantNotifications] Batch notifications sent', {\n batchId: response.sendBatchNotifications.batchId,\n queued: response.sendBatchNotifications.totalQueued,\n failed: response.sendBatchNotifications.totalFailed,\n });\n\n return response.sendBatchNotifications;\n }\n\n /**\n * Get a notification by ID\n */\n public async getNotification(id: string): Promise<Notification | null> {\n const query = `\n query GetNotification($id: ID!) {\n notification(id: $id) {\n id\n userId\n channel\n type\n priority\n status\n deliveryStatus\n title\n message\n htmlMessage\n subject\n recipientEmail\n recipientPhone\n trackOpens\n trackClicks\n openedAt\n clickedAt\n sentAt\n deliveredAt\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notification: Notification | null;\n }>(query, { id }, this.context);\n\n return response.notification;\n }\n\n /**\n * Get notifications with filters\n */\n public async getNotifications(filter?: {\n userId?: string;\n channel?: NotificationChannel;\n type?: NotificationType;\n status?: string;\n priority?: NotificationPriority;\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n }): Promise<Notification[]> {\n const query = `\n query GetNotifications($filter: NotificationFilterInput, $limit: Int, $offset: Int) {\n notifications(filter: $filter, limit: $limit, offset: $offset) {\n id\n userId\n channel\n type\n priority\n status\n deliveryStatus\n title\n message\n subject\n recipientEmail\n trackOpens\n trackClicks\n openedAt\n clickedAt\n sentAt\n deliveredAt\n createdAt\n updatedAt\n }\n }\n `;\n\n const variables = {\n filter: filter\n ? {\n userId: filter.userId,\n channel: filter.channel,\n type: filter.type,\n status: filter.status,\n priority: filter.priority,\n startDate: filter.startDate?.toISOString(),\n endDate: filter.endDate?.toISOString(),\n }\n : undefined,\n limit: filter?.limit || 50,\n offset: filter?.offset || 0,\n };\n\n const response = await this.client.tenantQuery<{\n notifications: Notification[];\n }>(query, variables, this.context);\n\n return response.notifications;\n }\n\n /**\n * Get notification template\n */\n public async getTemplate(slug: string, locale?: string): Promise<NotificationTemplate | null> {\n const query = `\n query GetNotificationTemplate($slug: String!, $locale: String) {\n notificationTemplate(slug: $slug, locale: $locale) {\n id\n name\n slug\n description\n channel\n type\n locale\n subject\n bodyTemplate\n htmlTemplate\n variables\n enabled\n version\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notificationTemplate: NotificationTemplate | null;\n }>(query, { slug, locale }, this.context);\n\n return response.notificationTemplate;\n }\n\n /**\n * Get all notification templates\n */\n public async getTemplates(filter?: {\n channel?: NotificationChannel;\n type?: NotificationType;\n enabled?: boolean;\n }): Promise<NotificationTemplate[]> {\n const query = `\n query GetNotificationTemplates($filter: TemplateFilterInput) {\n notificationTemplates(filter: $filter) {\n id\n name\n slug\n description\n channel\n type\n locale\n subject\n bodyTemplate\n htmlTemplate\n variables\n enabled\n version\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notificationTemplates: NotificationTemplate[];\n }>(query, { filter }, this.context);\n\n return response.notificationTemplates;\n }\n\n /**\n * Get notification statistics\n */\n public async getStats(filter?: { userId?: string; startDate?: Date; endDate?: Date }): Promise<NotificationStats> {\n const query = `\n query GetNotificationStats($filter: NotificationFilterInput) {\n notificationStats(filter: $filter) {\n total\n pending\n queued\n processing\n sent\n delivered\n failed\n byChannel\n byType\n }\n }\n `;\n\n const variables = {\n filter: filter\n ? {\n userId: filter.userId,\n startDate: filter.startDate?.toISOString(),\n endDate: filter.endDate?.toISOString(),\n }\n : undefined,\n };\n\n const response = await this.client.tenantQuery<{\n notificationStats: NotificationStats;\n }>(query, variables, this.context);\n\n return response.notificationStats;\n }\n\n /**\n * Mark notifications as read\n */\n public async markAsRead(notificationIds: string[]): Promise<boolean> {\n const mutation = `\n mutation MarkNotificationsAsRead($notificationIds: [ID!]!) {\n markNotificationsAsRead(notificationIds: $notificationIds)\n }\n `;\n\n await this.client.tenantQuery(mutation, { notificationIds }, this.context);\n\n logger.info('[TenantNotifications] Notifications marked as read', {\n count: notificationIds.length,\n });\n\n return true;\n }\n\n /**\n * Mark all notifications as read for the current user\n */\n public async markAllAsRead(): Promise<boolean> {\n const mutation = `\n mutation MarkAllMyNotificationsAsRead {\n markAllMyNotificationsAsRead\n }\n `;\n\n await this.client.tenantQuery(mutation, {}, this.context);\n\n logger.info('[TenantNotifications] All notifications marked as read');\n\n return true;\n }\n\n /**\n * Delete notifications\n */\n public async deleteNotifications(notificationIds: string[]): Promise<boolean> {\n const mutation = `\n mutation DeleteNotifications($notificationIds: [ID!]!) {\n deleteNotifications(notificationIds: $notificationIds)\n }\n `;\n\n await this.client.tenantQuery(mutation, { notificationIds }, this.context);\n\n logger.info('[TenantNotifications] Notifications deleted', {\n count: notificationIds.length,\n });\n\n return true;\n }\n\n /**\n * Delete all read notifications for the current user\n */\n public async deleteAllReadNotifications(): Promise<boolean> {\n const mutation = `\n mutation DeleteMyReadNotifications {\n deleteMyReadNotifications\n }\n `;\n\n await this.client.tenantQuery(mutation, {}, this.context);\n\n logger.info('[TenantNotifications] All read notifications deleted');\n\n return true;\n }\n\n /**\n * Validate send notification input\n */\n private validateSendInput(input: SendNotificationInput): void {\n if (!input.recipient || (!input.recipient.email && !input.recipient.userId && !input.recipient.phoneNumber)) {\n throw new ValidationError('Recipient email, userId, or phoneNumber is required');\n }\n\n if (!input.channel) {\n throw new ValidationError('Notification channel is required');\n }\n\n if (!input.body || input.body.trim().length === 0) {\n throw new ValidationError('Notification body is required');\n }\n\n // Channel-specific validation\n if (input.channel === NotificationChannel.EMAIL && !input.recipient.email) {\n throw new ValidationError('Recipient email is required for EMAIL channel');\n }\n\n if (input.channel === NotificationChannel.SMS && !input.recipient.phoneNumber) {\n throw new ValidationError('Recipient phone number is required for SMS channel');\n }\n\n if (input.channel === NotificationChannel.PUSH && !input.recipient.pushToken && !input.recipient.userId) {\n throw new ValidationError('Recipient push token or userId is required for PUSH channel');\n }\n }\n}\n","/**\n * Notifications Module\n * Send in-app, email, SMS, and push notifications via workspaces-backend\n */\n\nimport type { BurdenoffGraphQLClient } from '../client/graphql.js';\nimport type { SDKContext } from '../types/index.js';\nimport { ValidationError } from '../types/index.js';\nimport { logger } from '../logger/index.js';\n\nexport enum NotificationType {\n INFO = 'info',\n SUCCESS = 'success',\n WARNING = 'warning',\n ERROR = 'error',\n}\n\nexport enum NotificationChannel {\n EMAIL = 'EMAIL',\n SMS = 'SMS',\n WHATSAPP = 'WHATSAPP',\n PUSH = 'PUSH',\n SLACK = 'SLACK',\n TEAMS = 'TEAMS',\n WEBHOOK = 'WEBHOOK',\n}\n\n// Re-export from tenant-notifications\nexport { NotificationPriority, TenantNotificationsModule } from './tenant-notifications.js';\n\nexport interface SendNotificationOptions {\n /** Notification title */\n title: string;\n /** Notification message */\n message: string;\n /** Notification type */\n type?: NotificationType;\n /** Target user IDs */\n userIds: string[];\n /** Optional redirect URL */\n redirectUrl?: string;\n /** Application name */\n appName?: string;\n /** Send email notification */\n email?: boolean;\n /** Send SMS notification */\n sms?: boolean;\n}\n\nexport interface NotificationResponse {\n /** Number of successful notifications */\n successCount: number;\n /** Number of failed notifications */\n failureCount: number;\n /** Error messages if any */\n errors: string[];\n /** Created notification IDs */\n notificationIds?: string[];\n}\n\nexport interface GetNotificationsOptions {\n /** User ID to get notifications for */\n userId: string;\n /** Filter by status */\n status?: 'unread' | 'read' | 'all';\n /** Filter by type */\n type?: NotificationType;\n /** Filter by app name */\n appName?: string;\n /** Search term */\n search?: string;\n /** Limit number of results */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n}\n\nexport interface Notification {\n id: string;\n userId: string;\n title: string;\n message: string;\n type: NotificationType;\n status: 'unread' | 'read';\n redirectUrl?: string;\n appName?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface RecipientInput {\n email?: string;\n locale?: string;\n name?: string;\n phoneNumber?: string;\n pushToken?: string;\n slackUserId?: string;\n teamsUserId?: string;\n timezone?: string;\n userId?: string;\n webhookUrl?: string;\n whatsappNumber?: string;\n}\n\nexport interface SendChannelNotificationOptions {\n /** Primary delivery channel (EMAIL, SMS, WHATSAPP, etc.) */\n platform: NotificationChannel;\n /** Recipient information for primary channel */\n recipient: RecipientInput;\n /** Multiple recipients for bulk delivery */\n recipients?: RecipientInput[];\n /** Notification subject (for EMAIL) */\n subject?: string;\n /** Notification body/message */\n body: string;\n /** HTML body (for EMAIL) */\n htmlBody?: string;\n /** Notification type */\n type?: NotificationType;\n /** Application name */\n appName?: string;\n /** Redirect URL */\n redirectUrl?: string;\n /** Also send as in-app notification */\n includeInApp?: boolean;\n /** User IDs for in-app notifications (required when includeInApp is true) */\n userIds?: string[];\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n /** Track email opens */\n trackOpens?: boolean;\n /** Track link clicks */\n trackClicks?: boolean;\n /** Expiration time */\n expiresAt?: Date;\n /** Specific channel instance ID (overrides platform) */\n channelId?: string;\n}\n\nexport interface SendTemplateNotificationOptions {\n /** Primary delivery channel (EMAIL, SMS, WHATSAPP, etc.) */\n platform: NotificationChannel;\n /** Template slug to use */\n templateSlug: string;\n /** Template variables */\n variables: Record<string, unknown>;\n /** Recipient information for primary channel */\n recipient?: RecipientInput;\n /** Multiple recipients for bulk delivery */\n recipients?: RecipientInput[];\n /** Also send as in-app notification */\n includeInApp?: boolean;\n /** User IDs for in-app notifications (required when includeInApp is true) */\n userIds?: string[];\n /** Application name */\n appName?: string;\n /** Track email opens */\n trackOpens?: boolean;\n /** Track link clicks */\n trackClicks?: boolean;\n /** Expiration time */\n expiresAt?: Date;\n /** Scheduled delivery time */\n scheduledFor?: Date;\n /** Timezone for scheduling */\n timezone?: string;\n /** Specific channel instance ID (overrides platform) */\n channelId?: string;\n}\n\n/**\n * Notifications Module\n */\nexport class NotificationsModule {\n constructor(\n private client: BurdenoffGraphQLClient,\n private context: SDKContext\n ) {}\n\n /**\n * Send notification to users\n */\n public async send(options: SendNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.title || options.title.trim().length === 0) {\n throw new ValidationError('Notification title is required');\n }\n\n if (!options.message || options.message.trim().length === 0) {\n throw new ValidationError('Notification message is required');\n }\n\n if (!options.userIds || options.userIds.length === 0) {\n throw new ValidationError('At least one user ID is required');\n }\n\n logger.info('[Notifications] Sending notification', {\n title: options.title,\n userCount: options.userIds.length,\n type: options.type || NotificationType.INFO,\n });\n\n const mutation = `\n mutation CreateNotification($input: CreateNotificationInput!) {\n createNotification(input: $input) {\n successCount\n failureCount\n errors\n notifications {\n id\n }\n }\n }\n `;\n\n const variables = {\n input: {\n title: options.title,\n message: options.message,\n type: options.type || NotificationType.INFO,\n userIds: options.userIds,\n redirectUrl: options.redirectUrl || '',\n appName: options.appName,\n email: options.email || false,\n sms: options.sms || false,\n },\n };\n\n const response = await this.client.query<{\n createNotification: NotificationResponse & { notifications: Array<{ id: string }> };\n }>(mutation, variables, this.context);\n\n const result = {\n successCount: response.createNotification.successCount,\n failureCount: response.createNotification.failureCount,\n errors: response.createNotification.errors,\n notificationIds: response.createNotification.notifications.map((n) => n.id),\n };\n\n logger.info('[Notifications] Notification sent', {\n successCount: result.successCount,\n failureCount: result.failureCount,\n });\n\n return result;\n }\n\n /**\n * Send notification to a single user (convenience method)\n */\n public async sendToUser(\n userId: string,\n title: string,\n message: string,\n options?: Omit<SendNotificationOptions, 'userIds' | 'title' | 'message'>\n ): Promise<NotificationResponse> {\n return this.send({\n title,\n message,\n userIds: [userId],\n ...options,\n });\n }\n\n /**\n * Get notifications for a user\n */\n public async getNotifications(options: GetNotificationsOptions): Promise<{\n notifications: Notification[];\n total: number;\n unreadCount: number;\n }> {\n logger.debug('[Notifications] Getting notifications', { userId: options.userId });\n\n const query = `\n query GetNotifications(\n $userId: ID!\n $status: NotificationStatus\n $type: NotificationType\n $appName: String\n $search: String\n $limit: Int\n $offset: Int\n ) {\n getNotifications(\n userId: $userId\n status: $status\n type: $type\n appName: $appName\n search: $search\n limit: $limit\n offset: $offset\n ) {\n notifications {\n id\n userId\n title\n message\n type\n status\n redirectUrl\n appName\n createdAt\n updatedAt\n }\n total\n unreadCount\n }\n }\n `;\n\n const variables = {\n userId: options.userId,\n status: options.status,\n type: options.type,\n appName: options.appName,\n search: options.search,\n limit: options.limit || 20,\n offset: options.offset || 0,\n };\n\n const response = await this.client.query<{\n getNotifications: {\n notifications: Notification[];\n total: number;\n unreadCount: number;\n };\n }>(query, variables, this.context);\n\n return response.getNotifications;\n }\n\n /**\n * Mark notification as read\n */\n public async markAsRead(notificationId: string): Promise<boolean> {\n logger.debug('[Notifications] Marking notification as read', { notificationId });\n\n const mutation = `\n mutation MarkNotificationAsRead($notificationId: ID!) {\n markNotificationAsRead(notificationId: $notificationId) {\n id\n status\n }\n }\n `;\n\n await this.client.query(mutation, { notificationId }, this.context);\n\n logger.info('[Notifications] Notification marked as read', { notificationId });\n\n return true;\n }\n\n /**\n * Mark multiple notifications as read\n */\n public async markMultipleAsRead(notificationIds: string[]): Promise<number> {\n logger.debug('[Notifications] Marking multiple notifications as read', {\n count: notificationIds.length,\n });\n\n const mutation = `\n mutation MarkNotificationsAsRead($notificationIds: [ID!]!) {\n markNotificationsAsRead(notificationIds: $notificationIds) {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n markNotificationsAsRead: { count: number };\n }>(mutation, { notificationIds }, this.context);\n\n logger.info('[Notifications] Notifications marked as read', {\n count: response.markNotificationsAsRead.count,\n });\n\n return response.markNotificationsAsRead.count;\n }\n\n /**\n * Mark all notifications as read for the current user\n */\n public async markAllAsRead(): Promise<number> {\n logger.debug('[Notifications] Marking all notifications as read');\n\n const mutation = `\n mutation MarkAllMyNotificationsAsRead {\n markAllMyNotificationsAsRead {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n markAllMyNotificationsAsRead: { count: number };\n }>(mutation, {}, this.context);\n\n logger.info('[Notifications] All notifications marked as read', {\n count: response.markAllMyNotificationsAsRead.count,\n });\n\n return response.markAllMyNotificationsAsRead.count;\n }\n\n /**\n * Delete notification\n */\n public async deleteNotification(notificationId: string): Promise<boolean> {\n logger.debug('[Notifications] Deleting notification', { notificationId });\n\n const mutation = `\n mutation DeleteNotification($notificationId: ID!) {\n deleteNotification(notificationId: $notificationId) {\n success\n }\n }\n `;\n\n await this.client.query(mutation, { notificationId }, this.context);\n\n logger.info('[Notifications] Notification deleted', { notificationId });\n\n return true;\n }\n\n /**\n * Delete multiple notifications\n */\n public async deleteMultiple(notificationIds: string[]): Promise<number> {\n logger.debug('[Notifications] Deleting multiple notifications', {\n count: notificationIds.length,\n });\n\n const mutation = `\n mutation DeleteNotifications($notificationIds: [ID!]!) {\n deleteNotifications(notificationIds: $notificationIds) {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n deleteNotifications: { count: number };\n }>(mutation, { notificationIds }, this.context);\n\n logger.info('[Notifications] Notifications deleted', {\n count: response.deleteNotifications.count,\n });\n\n return response.deleteNotifications.count;\n }\n\n /**\n * Get unread notification count for a user\n */\n public async getUnreadCount(userId: string): Promise<number> {\n const result = await this.getNotifications({\n userId,\n status: 'unread',\n limit: 0,\n });\n\n return result.unreadCount;\n }\n\n /**\n * Send notification via specific channel (EMAIL, SMS, WHATSAPP, etc.)\n * with optional in-app notification\n */\n public async sendChannelNotification(options: SendChannelNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.body || options.body.trim().length === 0) {\n throw new ValidationError('Notification body is required');\n }\n\n if (!options.recipient && !options.recipients) {\n throw new ValidationError('At least one recipient is required');\n }\n\n if (options.includeInApp && (!options.userIds || options.userIds.length === 0)) {\n throw new ValidationError('User IDs are required when includeInApp is true');\n }\n\n logger.info('[Notifications] Sending channel notification', {\n platform: options.platform,\n recipientCount: options.recipients ? options.recipients.length : 1,\n includeInApp: options.includeInApp,\n inAppUserCount: options.userIds ? options.userIds.length : 0,\n });\n\n const mutation = `\n mutation TriggerNotification($input: TriggerNotificationInput!) {\n triggerNotification(input: $input) {\n id\n status\n deliveryStatus\n }\n }\n `;\n\n const variables = {\n input: {\n platform: options.platform,\n channelId: options.channelId,\n includeInApp: options.includeInApp || false,\n userIds: options.userIds || [],\n notification: {\n subject: options.subject || '',\n body: options.body,\n htmlBody: options.htmlBody || '',\n channel: options.platform,\n type: options.type || NotificationType.INFO,\n recipient: options.recipient,\n appName: options.appName,\n redirectUrl: options.redirectUrl || '',\n metadata: options.metadata || {},\n trackOpens: options.trackOpens || false,\n trackClicks: options.trackClicks || false,\n expiresAt: options.expiresAt?.toISOString(),\n },\n },\n };\n\n // Handle bulk recipients\n if (options.recipients && options.recipients.length > 1) {\n const results = await Promise.allSettled(\n options.recipients.map((recipient) =>\n this.client.query(\n mutation,\n {\n input: {\n ...variables.input,\n notification: {\n ...variables.input.notification,\n recipient,\n },\n },\n },\n this.context\n )\n )\n );\n\n let successCount = 0;\n let failureCount = 0;\n const errors: string[] = [];\n const notificationIds: string[] = [];\n\n results.forEach((result, index) => {\n if (result.status === 'fulfilled') {\n successCount++;\n const response = result.value as { triggerNotification: { id: string } };\n notificationIds.push(response.triggerNotification.id);\n } else {\n failureCount++;\n errors.push(\n `Recipient ${index + 1}: ${result.reason instanceof Error ? result.reason.message : 'Unknown error'}`\n );\n }\n });\n\n const response: NotificationResponse = {\n successCount,\n failureCount,\n errors,\n notificationIds,\n };\n\n logger.info('[Notifications] Channel notification sent (bulk)', {\n successCount,\n failureCount,\n });\n\n return response;\n } else {\n // Single recipient\n try {\n const response = await this.client.query<{\n triggerNotification: { id: string; status: string; deliveryStatus: string };\n }>(mutation, variables, this.context);\n\n const result: NotificationResponse = {\n successCount: 1,\n failureCount: 0,\n errors: [],\n notificationIds: [response.triggerNotification.id],\n };\n\n logger.info('[Notifications] Channel notification sent', {\n notificationId: response.triggerNotification.id,\n status: response.triggerNotification.status,\n });\n\n return result;\n } catch (error) {\n logger.error('[Notifications] Failed to send channel notification', { error });\n\n return {\n successCount: 0,\n failureCount: 1,\n errors: [error instanceof Error ? error.message : 'Unknown error'],\n notificationIds: [],\n };\n }\n }\n }\n\n /**\n * Send notification using a template with optional in-app notification\n */\n public async sendTemplateNotification(options: SendTemplateNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.templateSlug || options.templateSlug.trim().length === 0) {\n throw new ValidationError('Template slug is required');\n }\n\n if (!options.variables || typeof options.variables !== 'object') {\n throw new ValidationError('Template variables are required');\n }\n\n if (!options.recipient && !options.recipients) {\n throw new ValidationError('At least one recipient is required');\n }\n\n if (options.includeInApp && (!options.userIds || options.userIds.length === 0)) {\n throw new ValidationError('User IDs are required when includeInApp is true');\n }\n\n logger.info('[Notifications] Sending template notification', {\n templateSlug: options.templateSlug,\n platform: options.platform,\n recipientCount: options.recipients ? options.recipients.length : 1,\n includeInApp: options.includeInApp,\n inAppUserCount: options.userIds ? options.userIds.length : 0,\n });\n\n const mutation = `\n mutation TriggerNotificationWithTemplate($input: TriggerNotificationWithTemplateInput!) {\n triggerNotificationWithTemplate(input: $input) {\n totalRequested\n totalTriggered\n totalFailed\n notifications {\n id\n status\n deliveryStatus\n }\n }\n }\n `;\n\n const variables = {\n input: {\n platform: options.platform,\n channelId: options.channelId,\n includeInApp: options.includeInApp || false,\n userIds: options.userIds || [],\n templateSlug: options.templateSlug,\n variables: options.variables,\n recipient: options.recipient,\n recipients: options.recipients,\n trackOpens: options.trackOpens || false,\n trackClicks: options.trackClicks || false,\n expiresAt: options.expiresAt?.toISOString(),\n scheduledFor: options.scheduledFor?.toISOString(),\n timezone: options.timezone,\n },\n };\n\n try {\n const response = await this.client.query<{\n triggerNotificationWithTemplate: {\n totalRequested: number;\n totalTriggered: number;\n totalFailed: number;\n notifications: Array<{ id: string; status: string; deliveryStatus?: string }>;\n };\n }>(mutation, variables, this.context);\n\n const data = response.triggerNotificationWithTemplate;\n\n const result: NotificationResponse = {\n successCount: data.totalTriggered,\n failureCount: data.totalFailed,\n errors: [],\n notificationIds: data.notifications.map((n) => n.id),\n };\n\n logger.info('[Notifications] Template notification sent', {\n templateSlug: options.templateSlug,\n totalTriggered: data.totalTriggered,\n totalFailed: data.totalFailed,\n notificationIds: result.notificationIds,\n });\n\n return result;\n } catch (error) {\n logger.error('[Notifications] Failed to send template notification', { error });\n\n return {\n successCount: 0,\n failureCount: 1,\n errors: [error instanceof Error ? error.message : 'Unknown error'],\n notificationIds: [],\n };\n }\n }\n}\n"]}
@@ -0,0 +1,181 @@
1
+ import { createDatabaseService, Logger } from './chunk-QLVKMWFA.js';
2
+ import { RedisStreamsConnection } from './chunk-MVHOP4IG.js';
3
+ import { logger } from './chunk-CBZNP6RF.js';
4
+ import { __export, __name } from './chunk-XE4OXN2W.js';
5
+
6
+ // src/graphql/index.ts
7
+ var graphql_exports = {};
8
+ __export(graphql_exports, {
9
+ Logger: () => Logger,
10
+ createDatabaseService: () => createDatabaseService,
11
+ createRedisStreamsEventTarget: () => createRedisStreamsEventTarget
12
+ });
13
+
14
+ // src/graphql/redis-streams-event-target.ts
15
+ async function createRedisStreamsEventTarget(options = {}) {
16
+ const url = options.redisUrl ?? process.env["REDIS_URL"];
17
+ if (!url) throw new Error("[RedisStreamsEventTarget] redisUrl or REDIS_URL is required");
18
+ const prefix = options.subjectPrefix ?? "graphql.pubsub";
19
+ const maxLen = options.maxLen ?? 1e3;
20
+ const serializer = options.serializer ?? {
21
+ stringify: /* @__PURE__ */ __name((d) => JSON.stringify(d), "stringify"),
22
+ parse: /* @__PURE__ */ __name((m) => JSON.parse(m), "parse")
23
+ };
24
+ const conn = new RedisStreamsConnection({
25
+ type: "redis-streams",
26
+ url,
27
+ password: options.password ?? process.env["REDIS_PASSWORD"],
28
+ name: "graphql-pubsub"
29
+ });
30
+ void conn.connect().then(() => logger.info("[RedisStreamsEventTarget] redis connected")).catch((err) => {
31
+ logger.warn("[RedisStreamsEventTarget] redis connect failed; pubsub will retry on demand", {
32
+ error: err instanceof Error ? err.message : String(err)
33
+ });
34
+ });
35
+ const streamKey = /* @__PURE__ */ __name((type) => `boff:pubsub:${prefix}:${type.replace(/\./g, ":")}`, "streamKey");
36
+ const listeners = /* @__PURE__ */ new Map();
37
+ const readers = /* @__PURE__ */ new Map();
38
+ let closed = false;
39
+ function startReader(type) {
40
+ if (readers.has(type) || closed) return;
41
+ let stopped = false;
42
+ const stream = streamKey(type);
43
+ const loop = /* @__PURE__ */ __name(async () => {
44
+ const blockingClient = await conn.makeBlockingClient();
45
+ let lastId = "$";
46
+ try {
47
+ while (!stopped && !closed) {
48
+ let raw = null;
49
+ try {
50
+ raw = await blockingClient.xreadgroup(
51
+ // pretend-arg pattern: we actually want XREAD, fall through
52
+ "COUNT",
53
+ 50,
54
+ "BLOCK",
55
+ 5e3,
56
+ "STREAMS",
57
+ stream,
58
+ lastId
59
+ );
60
+ } catch {
61
+ try {
62
+ raw = await blockingClient.call("XREAD", "COUNT", 50, "BLOCK", 5e3, "STREAMS", stream, lastId);
63
+ } catch (err) {
64
+ logger.debug("[RedisStreamsEventTarget] xread error", {
65
+ stream,
66
+ error: err instanceof Error ? err.message : String(err)
67
+ });
68
+ await new Promise((r) => setTimeout(r, 1e3));
69
+ continue;
70
+ }
71
+ }
72
+ if (!raw) continue;
73
+ for (const [, entries] of raw) {
74
+ for (const [id, rawFields] of entries) {
75
+ lastId = id;
76
+ const fields = {};
77
+ for (let i = 0; i + 1 < rawFields.length; i += 2) {
78
+ fields[rawFields[i]] = rawFields[i + 1];
79
+ }
80
+ const payload = await serializer.parse(fields["payload"] ?? "null");
81
+ const cbs = listeners.get(type);
82
+ if (!cbs) continue;
83
+ const ev = new CustomEvent(type, {
84
+ detail: payload
85
+ });
86
+ for (const cb of Array.from(cbs)) {
87
+ try {
88
+ cb(ev);
89
+ } catch (cbErr) {
90
+ logger.error("[RedisStreamsEventTarget] listener error", {
91
+ type,
92
+ error: cbErr instanceof Error ? cbErr.message : String(cbErr)
93
+ });
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ } finally {
100
+ try {
101
+ blockingClient.disconnect();
102
+ } catch {
103
+ }
104
+ }
105
+ }, "loop");
106
+ readers.set(type, {
107
+ stop: /* @__PURE__ */ __name(() => {
108
+ stopped = true;
109
+ }, "stop")
110
+ });
111
+ void loop().catch((err) => {
112
+ logger.error("[RedisStreamsEventTarget] reader crashed", {
113
+ type,
114
+ error: err instanceof Error ? err.message : String(err)
115
+ });
116
+ });
117
+ }
118
+ __name(startReader, "startReader");
119
+ function stopReader(type) {
120
+ const r = readers.get(type);
121
+ if (r) {
122
+ r.stop();
123
+ readers.delete(type);
124
+ }
125
+ }
126
+ __name(stopReader, "stopReader");
127
+ const target = {
128
+ addEventListener(type, listener) {
129
+ let set = listeners.get(type);
130
+ if (!set) {
131
+ set = /* @__PURE__ */ new Set();
132
+ listeners.set(type, set);
133
+ startReader(type);
134
+ }
135
+ set.add(listener);
136
+ },
137
+ removeEventListener(type, listener) {
138
+ const set = listeners.get(type);
139
+ if (!set) return;
140
+ set.delete(listener);
141
+ if (set.size === 0) {
142
+ listeners.delete(type);
143
+ stopReader(type);
144
+ }
145
+ },
146
+ dispatchEvent(event) {
147
+ const detail = "detail" in event ? event.detail : event;
148
+ void (async () => {
149
+ try {
150
+ const payload = await serializer.stringify(detail);
151
+ await conn.getClient().xadd(streamKey(event.type), "MAXLEN", "~", maxLen, "*", "payload", payload);
152
+ } catch (err) {
153
+ logger.error("[RedisStreamsEventTarget] dispatch failed", {
154
+ type: event.type,
155
+ error: err instanceof Error ? err.message : String(err)
156
+ });
157
+ }
158
+ })();
159
+ return true;
160
+ },
161
+ async close() {
162
+ closed = true;
163
+ for (const r of readers.values()) r.stop();
164
+ readers.clear();
165
+ listeners.clear();
166
+ await conn.disconnect();
167
+ },
168
+ isHealthy() {
169
+ return conn.isConnected();
170
+ }
171
+ };
172
+ logger.info("[RedisStreamsEventTarget] ready", {
173
+ prefix
174
+ });
175
+ return target;
176
+ }
177
+ __name(createRedisStreamsEventTarget, "createRedisStreamsEventTarget");
178
+
179
+ export { createRedisStreamsEventTarget, graphql_exports };
180
+ //# sourceMappingURL=chunk-RRFNSBDZ.js.map
181
+ //# sourceMappingURL=chunk-RRFNSBDZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/graphql/index.ts","../src/graphql/redis-streams-event-target.ts"],"names":["createRedisStreamsEventTarget","options","url","redisUrl","process","env","Error","prefix","subjectPrefix","maxLen","serializer","stringify","d","JSON","parse","m","conn","RedisStreamsConnection","type","password","name","connect","then","logger","info","catch","err","warn","error","message","String","streamKey","replace","listeners","Map","readers","closed","startReader","has","stopped","stream","loop","blockingClient","makeBlockingClient","lastId","raw","xreadgroup","call","debug","Promise","r","setTimeout","entries","id","rawFields","fields","i","length","payload","cbs","get","ev","CustomEvent","detail","cb","Array","from","cbErr","disconnect","set","stop","stopReader","delete","target","addEventListener","listener","Set","add","removeEventListener","size","dispatchEvent","event","getClient","xadd","close","values","clear","isHealthy","isConnected"],"mappings":"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","file":"chunk-RRFNSBDZ.js","sourcesContent":["/**\n * GraphQL Utilities Module\n *\n * Provides GraphQL-related utilities for Burdenoff products.\n *\n * @module graphql\n */\n\n// NATS event target was removed on 2026-05-16. Use\n// `createRedisStreamsEventTarget` from `./redis-streams-event-target.js`\n// for distributed GraphQL Yoga subscriptions.\n\nexport { createRedisStreamsEventTarget } from './redis-streams-event-target.js';\nexport type {\n RedisStreamsEventTarget,\n RedisStreamsEventTargetOptions,\n} from './redis-streams-event-target.js';\n\n// Injectable services for GraphQL Modules\nexport { Logger, createDatabaseService } from './services/index.js';\nexport type { DatabaseService, PrismaTransactionClient } from './services/index.js';\n","/**\n * Redis Streams-based EventTarget for graphql-yoga distributed PubSub.\n *\n * Each server tails a per-event-type stream with `XREAD BLOCK ... $` (no\n * consumer group) so every instance receives every dispatch — the fan-out\n * semantics GraphQL subscriptions require.\n *\n * For durable inter-svc events use `event-queue/createPublisher` instead.\n */\nimport { logger } from '../logger/index.js';\nimport { RedisStreamsConnection } from '../event-queue/implementations/redis-streams/RedisStreamsConnection.js';\n\nexport interface RedisStreamsEventTarget {\n addEventListener(type: string, listener: (event: Event) => void): void;\n removeEventListener(type: string, listener: (event: Event) => void): void;\n dispatchEvent(event: Event): boolean;\n close(): Promise<void>;\n isHealthy(): boolean;\n}\n\nexport interface RedisStreamsEventTargetOptions {\n /** Redis connection URL. Defaults to `REDIS_URL` env. */\n redisUrl?: string;\n /** Optional password override. */\n password?: string;\n /** Subject prefix; keys become `<prefix>.<type>` mapped via `:` separator. */\n subjectPrefix?: string;\n /** Approximate MAXLEN trim for each pubsub stream. Default 1000. */\n maxLen?: number;\n /** Per-event serialiser. */\n serializer?: {\n stringify: (data: unknown) => string | Promise<string>;\n parse: (msg: string) => unknown | Promise<unknown>;\n };\n}\n\nexport async function createRedisStreamsEventTarget(\n options: RedisStreamsEventTargetOptions = {}\n): Promise<RedisStreamsEventTarget> {\n const url = options.redisUrl ?? process.env['REDIS_URL'];\n if (!url) throw new Error('[RedisStreamsEventTarget] redisUrl or REDIS_URL is required');\n const prefix = options.subjectPrefix ?? 'graphql.pubsub';\n const maxLen = options.maxLen ?? 1000;\n const serializer = options.serializer ?? {\n stringify: (d: unknown): string => JSON.stringify(d),\n parse: (m: string): unknown => JSON.parse(m),\n };\n\n const conn = new RedisStreamsConnection({\n type: 'redis-streams',\n url,\n password: options.password ?? process.env['REDIS_PASSWORD'],\n name: 'graphql-pubsub',\n });\n // Connect in the background — don't block svc startup on Redis reachability.\n void conn\n .connect()\n .then(() => logger.info('[RedisStreamsEventTarget] redis connected'))\n .catch((err) => {\n logger.warn('[RedisStreamsEventTarget] redis connect failed; pubsub will retry on demand', {\n error: err instanceof Error ? err.message : String(err),\n });\n });\n\n const streamKey = (type: string): string => `boff:pubsub:${prefix}:${type.replace(/\\./g, ':')}`;\n\n const listeners = new Map<string, Set<(event: Event) => void>>();\n const readers = new Map<string, { stop: () => void }>();\n let closed = false;\n\n function startReader(type: string): void {\n if (readers.has(type) || closed) return;\n let stopped = false;\n const stream = streamKey(type);\n\n const loop = async (): Promise<void> => {\n const blockingClient = await conn.makeBlockingClient();\n let lastId = '$';\n try {\n while (!stopped && !closed) {\n let raw: Array<[string, Array<[string, string[]]>]> | null = null;\n try {\n raw = (await blockingClient.xreadgroup(\n // pretend-arg pattern: we actually want XREAD, fall through\n 'COUNT',\n 50,\n 'BLOCK',\n 5000,\n 'STREAMS',\n stream,\n lastId\n )) as Array<[string, Array<[string, string[]]>]> | null;\n } catch {\n // Some ioredis typings make xreadgroup the only signature; fall back to xread via raw command.\n try {\n raw = (await (blockingClient as unknown as {\n call: (...args: unknown[]) => Promise<unknown>;\n }).call('XREAD', 'COUNT', 50, 'BLOCK', 5000, 'STREAMS', stream, lastId)) as Array<\n [string, Array<[string, string[]]>]\n > | null;\n } catch (err) {\n logger.debug('[RedisStreamsEventTarget] xread error', {\n stream,\n error: err instanceof Error ? err.message : String(err),\n });\n await new Promise((r) => setTimeout(r, 1000));\n continue;\n }\n }\n if (!raw) continue;\n for (const [, entries] of raw) {\n for (const [id, rawFields] of entries) {\n lastId = id;\n const fields: Record<string, string> = {};\n for (let i = 0; i + 1 < rawFields.length; i += 2) {\n fields[rawFields[i]!] = rawFields[i + 1]!;\n }\n const payload = await serializer.parse(fields['payload'] ?? 'null');\n const cbs = listeners.get(type);\n if (!cbs) continue;\n const ev = new CustomEvent(type, { detail: payload });\n for (const cb of Array.from(cbs)) {\n try {\n cb(ev);\n } catch (cbErr) {\n logger.error('[RedisStreamsEventTarget] listener error', {\n type,\n error: cbErr instanceof Error ? cbErr.message : String(cbErr),\n });\n }\n }\n }\n }\n }\n } finally {\n try {\n blockingClient.disconnect();\n } catch {\n /* ignore */\n }\n }\n };\n\n readers.set(type, {\n stop: (): void => {\n stopped = true;\n },\n });\n void loop().catch((err) => {\n logger.error('[RedisStreamsEventTarget] reader crashed', {\n type,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n }\n\n function stopReader(type: string): void {\n const r = readers.get(type);\n if (r) {\n r.stop();\n readers.delete(type);\n }\n }\n\n const target: RedisStreamsEventTarget = {\n addEventListener(type, listener): void {\n let set = listeners.get(type);\n if (!set) {\n set = new Set();\n listeners.set(type, set);\n startReader(type);\n }\n set.add(listener);\n },\n removeEventListener(type, listener): void {\n const set = listeners.get(type);\n if (!set) return;\n set.delete(listener);\n if (set.size === 0) {\n listeners.delete(type);\n stopReader(type);\n }\n },\n dispatchEvent(event): boolean {\n const detail = 'detail' in event ? (event as CustomEvent).detail : event;\n void (async (): Promise<void> => {\n try {\n const payload = await serializer.stringify(detail);\n await conn.getClient().xadd(streamKey(event.type), 'MAXLEN', '~', maxLen, '*', 'payload', payload);\n } catch (err) {\n logger.error('[RedisStreamsEventTarget] dispatch failed', {\n type: event.type,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n })();\n return true;\n },\n async close(): Promise<void> {\n closed = true;\n for (const r of readers.values()) r.stop();\n readers.clear();\n listeners.clear();\n await conn.disconnect();\n },\n isHealthy(): boolean {\n return conn.isConnected();\n },\n };\n\n logger.info('[RedisStreamsEventTarget] ready', { prefix });\n return target;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { EventQueueFactory } from './chunk-LRGXT37B.js';
1
+ import { EventQueueFactory } from './chunk-TM5RQ6P2.js';
2
2
  import { logger } from './chunk-CBZNP6RF.js';
3
3
  import { __name } from './chunk-XE4OXN2W.js';
4
4
  import { randomUUID } from 'crypto';
@@ -457,36 +457,20 @@ __name(createGraphEventEmitter, "createGraphEventEmitter");
457
457
 
458
458
  // src/event-queue/graph-emitter.ts
459
459
  var uuidv4 = /* @__PURE__ */ __name(() => crypto.randomUUID(), "uuidv4");
460
- var NatsGraphEventEmitter = class {
460
+ var GraphEventEmitterImpl = class {
461
461
  static {
462
- __name(this, "NatsGraphEventEmitter");
462
+ __name(this, "GraphEventEmitterImpl");
463
463
  }
464
464
  publisher;
465
465
  connected = false;
466
466
  connecting = null;
467
467
  constructor() {
468
- const graphNatsUrl = process.env["GRAPH_NATS_URL"];
469
- const natsServers = graphNatsUrl || process.env["NATS_SERVERS"] || process.env["NATS_URL"];
470
- if (natsServers) {
471
- const originalNatsServers = process.env["NATS_SERVERS"];
472
- if (graphNatsUrl) {
473
- process.env["NATS_SERVERS"] = graphNatsUrl;
474
- logger.info("[NatsGraphEventEmitter] Using GRAPH_NATS_URL for graph events", {
475
- url: graphNatsUrl
476
- });
477
- } else if (!process.env["NATS_SERVERS"] && process.env["NATS_URL"]) {
478
- process.env["NATS_SERVERS"] = process.env["NATS_URL"];
479
- }
468
+ if (process.env["REDIS_URL"]) {
480
469
  this.publisher = EventQueueFactory.createPublisherFromEnv();
481
- if (graphNatsUrl && originalNatsServers !== void 0) {
482
- process.env["NATS_SERVERS"] = originalNatsServers;
483
- } else if (graphNatsUrl) {
484
- delete process.env["NATS_SERVERS"];
485
- }
486
- logger.info("[NatsGraphEventEmitter] Using NATS publisher");
470
+ logger.info("[GraphEventEmitter] Using Redis Streams publisher");
487
471
  } else {
488
472
  this.publisher = new MemoryEventPublisher();
489
- logger.info("[NatsGraphEventEmitter] Using in-memory publisher (NATS not configured)");
473
+ logger.info("[GraphEventEmitter] Using in-memory publisher (REDIS_URL not configured)");
490
474
  }
491
475
  }
492
476
  /**
@@ -503,7 +487,7 @@ var NatsGraphEventEmitter = class {
503
487
  this.connecting = this.publisher.connect().then(() => {
504
488
  this.connected = true;
505
489
  this.connecting = null;
506
- logger.info("[NatsGraphEventEmitter] Publisher connected");
490
+ logger.info("[GraphEventEmitterImpl] Publisher connected");
507
491
  });
508
492
  await this.connecting;
509
493
  }
@@ -521,7 +505,7 @@ var NatsGraphEventEmitter = class {
521
505
  const eventId = uuidv4();
522
506
  const action = eventType.split(".")[1];
523
507
  const subject = `graph.${context.productName}.${entity.type}.${action}`;
524
- logger.debug("[NatsGraphEventEmitter] Publishing entity event", {
508
+ logger.debug("[GraphEventEmitterImpl] Publishing entity event", {
525
509
  eventId,
526
510
  eventType,
527
511
  entityId: entity.id,
@@ -573,7 +557,7 @@ var NatsGraphEventEmitter = class {
573
557
  if (this.connected) {
574
558
  await this.publisher.disconnect();
575
559
  this.connected = false;
576
- logger.info("[NatsGraphEventEmitter] Publisher disconnected");
560
+ logger.info("[GraphEventEmitterImpl] Publisher disconnected");
577
561
  }
578
562
  }
579
563
  /**
@@ -591,13 +575,13 @@ var NatsGraphEventEmitter = class {
591
575
  var _graphEventEmitter = null;
592
576
  function getGraphEventEmitter() {
593
577
  if (!_graphEventEmitter) {
594
- _graphEventEmitter = new NatsGraphEventEmitter();
578
+ _graphEventEmitter = new GraphEventEmitterImpl();
595
579
  }
596
580
  return _graphEventEmitter;
597
581
  }
598
582
  __name(getGraphEventEmitter, "getGraphEventEmitter");
599
583
  function createGraphEventEmitter2() {
600
- return new NatsGraphEventEmitter();
584
+ return new GraphEventEmitterImpl();
601
585
  }
602
586
  __name(createGraphEventEmitter2, "createGraphEventEmitter");
603
587
  async function resetGraphEventEmitter() {
@@ -608,6 +592,6 @@ async function resetGraphEventEmitter() {
608
592
  }
609
593
  __name(resetGraphEventEmitter, "resetGraphEventEmitter");
610
594
 
611
- export { MemoryEventBus, MemoryEventConsumer, MemoryEventPublisher, MemoryEventQueue, NatsGraphEventEmitter, createGraphEventEmitter, createGraphEventEmitter2, createMemoryConsumer, createMemoryPublisher, getGraphEventEmitter, resetGraphEventEmitter };
612
- //# sourceMappingURL=chunk-KLYAIEAX.js.map
613
- //# sourceMappingURL=chunk-KLYAIEAX.js.map
595
+ export { GraphEventEmitterImpl, MemoryEventBus, MemoryEventConsumer, MemoryEventPublisher, MemoryEventQueue, createGraphEventEmitter, createGraphEventEmitter2, createMemoryConsumer, createMemoryPublisher, getGraphEventEmitter, resetGraphEventEmitter };
596
+ //# sourceMappingURL=chunk-SO57HNXV.js.map
597
+ //# sourceMappingURL=chunk-SO57HNXV.js.map