@wopr-network/platform-core 1.54.0 → 1.56.0

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.
@@ -27,7 +27,7 @@ function layoutOpen(title: string): string {
27
27
  }
28
28
 
29
29
  const LAYOUT_CLOSE = ` </table>
30
- <p style="margin-top: 20px; color: #a0aec0; font-size: 12px;">&copy; ${YEAR} WOPR Network. All rights reserved.</p>
30
+ <p style="margin-top: 20px; color: #a0aec0; font-size: 12px;">&copy; ${YEAR} {{brandName}}. All rights reserved.</p>
31
31
  </td>
32
32
  </tr>
33
33
  </table>
@@ -70,7 +70,7 @@ function html(title: string, ...rows: string[]): string {
70
70
  return `${layoutOpen(title)}\n${rows.join("\n")}\n${LAYOUT_CLOSE}`;
71
71
  }
72
72
 
73
- const CR = `\n\n(c) ${YEAR} WOPR Network. All rights reserved.`;
73
+ const CR = `\n\n(c) ${YEAR} {{brandName}}. All rights reserved.`;
74
74
 
75
75
  // ---------------------------------------------------------------------------
76
76
  // Template definitions
@@ -89,19 +89,19 @@ export const DEFAULT_TEMPLATES: DefaultTemplate[] = [
89
89
  {
90
90
  name: "credits-depleted",
91
91
  description: "Sent when tenant credit balance reaches zero",
92
- subject: "Your WOPR credits are depleted \u2014 capabilities paused",
92
+ subject: "Your {{brandName}} credits are depleted \u2014 capabilities paused",
93
93
  htmlBody: html(
94
94
  "Credits Depleted",
95
- hd("Your WOPR Credits Are Depleted"),
95
+ hd("Your {{brandName}} Credits Are Depleted"),
96
96
  p(
97
- "<p>Your WOPR credit balance has reached $0. All agent capabilities have been paused.</p><p>Add credits now to resume service immediately.</p>",
97
+ "<p>Your {{brandName}} credit balance has reached $0. All agent capabilities have been paused.</p><p>Add credits now to resume service immediately.</p>",
98
98
  ),
99
99
  `{{#if creditsUrl}}${btn("{{creditsUrl}}", "Add Credits")}{{/if}}`,
100
100
  ft("Your data is preserved. Add credits to reactivate."),
101
101
  ),
102
- textBody: `Your WOPR Credits Are Depleted
102
+ textBody: `Your {{brandName}} Credits Are Depleted
103
103
 
104
- Your WOPR credit balance has reached $0. All agent capabilities have been paused.
104
+ Your {{brandName}} credit balance has reached $0. All agent capabilities have been paused.
105
105
 
106
106
  Add credits now to resume service immediately.
107
107
  {{#if creditsUrl}}
@@ -111,17 +111,17 @@ Add credits: {{creditsUrl}}
111
111
  {
112
112
  name: "grace-period-start",
113
113
  description: "Sent when a tenant enters the grace period after failed billing",
114
- subject: "Action needed: top up to keep your WOPRs running",
114
+ subject: "Action needed: top up to keep your {{brandName}} agents running",
115
115
  htmlBody: html(
116
116
  "Grace Period Started",
117
- hd("Action Needed: Top Up to Keep Your WOPRs Running"),
117
+ hd("Action Needed: Top Up to Keep Your {{brandName}} Agents Running"),
118
118
  p(
119
119
  "<p>Your current balance is <strong>{{balanceDollars}}</strong> and the monthly deduction could not be processed.</p><p>You have a <strong>{{graceDays}}-day grace period</strong> to add credits before your account is suspended.</p>",
120
120
  ),
121
121
  `{{#if creditsUrl}}${btn("{{creditsUrl}}", "Add Credits Now")}{{/if}}`,
122
122
  ft("This is a critical notification about your account status."),
123
123
  ),
124
- textBody: `Action Needed: Top Up to Keep Your WOPRs Running
124
+ textBody: `Action Needed: Top Up to Keep Your {{brandName}} Agents Running
125
125
 
126
126
  Your current balance is {{balanceDollars}} and the monthly deduction could not be processed.
127
127
 
@@ -133,17 +133,17 @@ Add credits: {{creditsUrl}}
133
133
  {
134
134
  name: "grace-period-warning",
135
135
  description: "Sent one day before grace period expires",
136
- subject: "Last chance: your WOPRs will be suspended tomorrow",
136
+ subject: "Last chance: your agents will be suspended tomorrow",
137
137
  htmlBody: html(
138
138
  "Grace Period Warning",
139
- hd("Last Chance: Your WOPRs Will Be Suspended Tomorrow"),
139
+ hd("Last Chance: Your Agents Will Be Suspended Tomorrow"),
140
140
  p(
141
141
  "<p>Your grace period expires tomorrow. If you do not add credits, your account will be suspended.</p><p>Add credits now to keep your agents running.</p>",
142
142
  ),
143
143
  `{{#if creditsUrl}}${btn("{{creditsUrl}}", "Add Credits Now", "#dc2626")}{{/if}}`,
144
144
  ft("This is a critical notification about your account status."),
145
145
  ),
146
- textBody: `Last Chance: Your WOPRs Will Be Suspended Tomorrow
146
+ textBody: `Last Chance: Your Agents Will Be Suspended Tomorrow
147
147
 
148
148
  Your grace period expires tomorrow. If you do not add credits, your account will be suspended.
149
149
  {{#if creditsUrl}}
@@ -158,7 +158,7 @@ Add credits: {{creditsUrl}}
158
158
  "Account Suspended",
159
159
  hd("Your Account Has Been Suspended"),
160
160
  p(
161
- "<p>Your WOPR account has been automatically suspended.</p><p><strong>Reason:</strong> {{reason}}</p><p>Add credits to reactivate your account immediately.</p>",
161
+ "<p>Your {{brandName}} account has been automatically suspended.</p><p><strong>Reason:</strong> {{reason}}</p><p>Add credits to reactivate your account immediately.</p>",
162
162
  ),
163
163
  `{{#if creditsUrl}}${btn("{{creditsUrl}}", "Add Credits to Reactivate")}{{/if}}`,
164
164
  ft("Your data is preserved for 30 days."),
@@ -205,7 +205,7 @@ View credits: {{creditsUrl}}
205
205
  "<p>Your auto top-up failed. We were unable to charge your payment method.</p><p>Please update your payment method or add credits manually to avoid service interruption.</p>",
206
206
  ),
207
207
  `{{#if creditsUrl}}${btn("{{creditsUrl}}", "Add Credits")}{{/if}}`,
208
- ft("If you need help, contact support@wopr.bot."),
208
+ ft("If you need help, contact {{supportEmail}}."),
209
209
  ),
210
210
  textBody: `Auto Top-Up Failed
211
211
 
@@ -226,7 +226,7 @@ Add credits: {{creditsUrl}}
226
226
  p(
227
227
  "<p>Your crypto payment has been confirmed. <strong>{{amountDollars}}</strong> in credits has been added to your account.</p><p>Your new balance is <strong>{{newBalanceDollars}}</strong>.</p>",
228
228
  ),
229
- ft("Thank you for supporting WOPR!"),
229
+ ft("Thank you for supporting {{brandName}}!"),
230
230
  ),
231
231
  textBody: `Crypto Payment Confirmed: {{amountDollars}} Credits Added
232
232
 
@@ -243,15 +243,15 @@ Your new balance is {{newBalanceDollars}}.${CR}`,
243
243
  "Account Suspended",
244
244
  hd("Your Account Has Been Suspended"),
245
245
  p(
246
- "<p>Your WOPR account has been suspended by an administrator.</p><p><strong>Reason:</strong> {{reason}}</p><p>If you believe this is an error, please contact support@wopr.bot.</p>",
246
+ "<p>Your {{brandName}} account has been suspended by an administrator.</p><p><strong>Reason:</strong> {{reason}}</p><p>If you believe this is an error, please contact {{supportEmail}}.</p>",
247
247
  ),
248
- ft("Contact support@wopr.bot if you have questions."),
248
+ ft("Contact {{supportEmail}} if you have questions."),
249
249
  ),
250
250
  textBody: `Your Account Has Been Suspended
251
251
 
252
252
  Reason: {{reason}}
253
253
 
254
- If you believe this is an error, please contact support@wopr.bot.${CR}`,
254
+ If you believe this is an error, please contact {{supportEmail}}.${CR}`,
255
255
  },
256
256
  {
257
257
  name: "admin-reactivated",
@@ -261,13 +261,13 @@ If you believe this is an error, please contact support@wopr.bot.${CR}`,
261
261
  "Account Reactivated",
262
262
  hd("Your Account Has Been Reactivated"),
263
263
  p(
264
- "<p>Your WOPR account has been reactivated. You now have full access to all services.</p><p>Your agents and channels are ready to use.</p>",
264
+ "<p>Your {{brandName}} account has been reactivated. You now have full access to all services.</p><p>Your agents and channels are ready to use.</p>",
265
265
  ),
266
266
  ft("Welcome back!"),
267
267
  ),
268
268
  textBody: `Your Account Has Been Reactivated
269
269
 
270
- Your WOPR account has been reactivated. You now have full access to all services.${CR}`,
270
+ Your {{brandName}} account has been reactivated. You now have full access to all services.${CR}`,
271
271
  },
272
272
  {
273
273
  name: "credits-granted",
@@ -277,9 +277,9 @@ Your WOPR account has been reactivated. You now have full access to all services
277
277
  "Credits Granted",
278
278
  hd("You Received {{amountDollars}} in Credits"),
279
279
  p(
280
- "<p><strong>{{amountDollars}}</strong> in credits has been added to your WOPR account.</p>{{#if reason}}<p><strong>Note:</strong> {{reason}}</p>{{/if}}",
280
+ "<p><strong>{{amountDollars}}</strong> in credits has been added to your {{brandName}} account.</p>{{#if reason}}<p><strong>Note:</strong> {{reason}}</p>{{/if}}",
281
281
  ),
282
- ft("Thank you for using WOPR!"),
282
+ ft("Thank you for using {{brandName}}!"),
283
283
  ),
284
284
  textBody: `You Received {{amountDollars}} in Credits
285
285
 
@@ -295,9 +295,9 @@ Note: {{reason}}{{/if}}${CR}`,
295
295
  "Role Changed",
296
296
  hd("Your Role Has Been Updated"),
297
297
  p(
298
- "<p>Your role on the WOPR platform has been updated to <strong>{{newRole}}</strong>.</p><p>Your new permissions are now active.</p>",
298
+ "<p>Your role on the {{brandName}} platform has been updated to <strong>{{newRole}}</strong>.</p><p>Your new permissions are now active.</p>",
299
299
  ),
300
- ft("If you did not expect this change, contact support@wopr.bot."),
300
+ ft("If you did not expect this change, contact {{supportEmail}}."),
301
301
  ),
302
302
  textBody: `Your Role Has Been Updated
303
303
 
@@ -311,7 +311,7 @@ Your role has been updated to {{newRole}}.${CR}`,
311
311
  "Team Invite",
312
312
  hd("You've Been Invited to Join {{tenantName}}"),
313
313
  p(
314
- "<p>You've been invited to join <strong>{{tenantName}}</strong> on the WOPR platform.</p><p>Click below to accept the invitation.</p>",
314
+ "<p>You've been invited to join <strong>{{tenantName}}</strong> on the {{brandName}} platform.</p><p>Click below to accept the invitation.</p>",
315
315
  ),
316
316
  `{{#if inviteUrl}}${btn("{{inviteUrl}}", "Accept Invitation")}{{/if}}`,
317
317
  ft("If you did not expect this invitation, you can ignore this email."),
@@ -325,16 +325,16 @@ Accept: {{inviteUrl}}
325
325
  {
326
326
  name: "agent-created",
327
327
  description: "Sent when a new agent is created",
328
- subject: "Your WOPR {{agentName}} is ready",
328
+ subject: "Your {{brandName}} {{agentName}} is ready",
329
329
  htmlBody: html(
330
330
  "Agent Created",
331
- hd("Your WOPR {{agentName}} Is Ready"),
331
+ hd("Your {{brandName}} {{agentName}} Is Ready"),
332
332
  p(
333
333
  "<p>Your new agent <strong>{{agentName}}</strong> has been created and is ready to use.</p><p>Connect it to a channel to start receiving and sending messages.</p>",
334
334
  ),
335
335
  ft("Happy building!"),
336
336
  ),
337
- textBody: `Your WOPR {{agentName}} Is Ready
337
+ textBody: `Your {{brandName}} {{agentName}} Is Ready
338
338
 
339
339
  Your new agent has been created and is ready to use.${CR}`,
340
340
  },
@@ -382,7 +382,7 @@ Reason: {{reason}}
382
382
  p(
383
383
  "<p>Your agent <strong>{{agentName}}</strong> has been paused.</p>{{#if reason}}<p><strong>Reason:</strong> {{reason}}</p>{{/if}}",
384
384
  ),
385
- ft("Contact support@wopr.bot if you have questions."),
385
+ ft("Contact {{supportEmail}} if you have questions."),
386
386
  ),
387
387
  textBody: `{{agentName}} Has Been Paused
388
388
  {{#if reason}}
@@ -393,21 +393,21 @@ Reason: {{reason}}
393
393
  {
394
394
  name: "account-deletion-requested",
395
395
  description: "Sent when a user requests account deletion",
396
- subject: "Your WOPR account deletion request",
396
+ subject: "Your {{brandName}} account deletion request",
397
397
  htmlBody: html(
398
398
  "Account Deletion Requested",
399
399
  hd("Account Deletion Requested"),
400
400
  p(
401
- "<p>Hi <strong>{{email}}</strong>,</p><p>We've received your request to delete your WOPR account and all associated data.</p><p>Your account will be permanently deleted on <strong>{{deleteAfterDate}}</strong>. Until then, you can cancel this request and keep your account.</p><p>After that date, all your data will be permanently and irreversibly removed, including bots, conversation history, credit records, and plugin configurations.</p>",
401
+ "<p>Hi <strong>{{email}}</strong>,</p><p>We've received your request to delete your {{brandName}} account and all associated data.</p><p>Your account will be permanently deleted on <strong>{{deleteAfterDate}}</strong>. Until then, you can cancel this request and keep your account.</p><p>After that date, all your data will be permanently and irreversibly removed, including bots, conversation history, credit records, and plugin configurations.</p>",
402
402
  ),
403
403
  `{{#if cancelUrl}}${btn("{{cancelUrl}}", "Cancel Deletion", "#22c55e")}{{/if}}`,
404
- ft("If you did not request this, please contact support@wopr.bot immediately."),
404
+ ft("If you did not request this, please contact {{supportEmail}} immediately."),
405
405
  ),
406
406
  textBody: `Account Deletion Requested
407
407
 
408
408
  Hi {{email}},
409
409
 
410
- We've received your request to delete your WOPR account and all associated data.
410
+ We've received your request to delete your {{brandName}} account and all associated data.
411
411
 
412
412
  Your account will be permanently deleted on {{deleteAfterDate}}. Until then, you can cancel this request.
413
413
 
@@ -415,19 +415,19 @@ After that date, all your data will be permanently and irreversibly removed.
415
415
  {{#if cancelUrl}}
416
416
  Cancel deletion: {{cancelUrl}}
417
417
  {{/if}}
418
- If you did not request this, please contact support@wopr.bot immediately.${CR}`,
418
+ If you did not request this, please contact {{supportEmail}} immediately.${CR}`,
419
419
  },
420
420
  {
421
421
  name: "account-deletion-cancelled",
422
422
  description: "Sent when account deletion is cancelled",
423
- subject: "Your WOPR account deletion has been cancelled",
423
+ subject: "Your {{brandName}} account deletion has been cancelled",
424
424
  htmlBody: html(
425
425
  "Account Deletion Cancelled",
426
426
  hd("Account Deletion Cancelled"),
427
427
  p(
428
428
  "<p>Hi <strong>{{email}}</strong>,</p><p>Your account deletion request has been cancelled. Your account and all data remain intact.</p><p>No further action is needed.</p>",
429
429
  ),
430
- ft("If you didn't cancel this, please contact support@wopr.bot."),
430
+ ft("If you didn't cancel this, please contact {{supportEmail}}."),
431
431
  ),
432
432
  textBody: `Account Deletion Cancelled
433
433
 
@@ -440,33 +440,33 @@ No further action is needed.${CR}`,
440
440
  {
441
441
  name: "account-deletion-completed",
442
442
  description: "Sent after account is permanently deleted",
443
- subject: "Your WOPR account has been deleted",
443
+ subject: "Your {{brandName}} account has been deleted",
444
444
  htmlBody: html(
445
445
  "Account Deleted",
446
446
  hd("Your Account Has Been Deleted"),
447
447
  p(
448
- "<p>Hi <strong>{{email}}</strong>,</p><p>Your WOPR account and all associated data have been permanently deleted as requested.</p><p>This includes all bots, conversation history, credit records, billing data, and plugin configurations.</p><p>If you'd like to use WOPR again in the future, you're welcome to create a new account.</p>",
448
+ "<p>Hi <strong>{{email}}</strong>,</p><p>Your {{brandName}} account and all associated data have been permanently deleted as requested.</p><p>This includes all bots, conversation history, credit records, billing data, and plugin configurations.</p><p>If you'd like to use {{brandName}} again in the future, you're welcome to create a new account.</p>",
449
449
  ),
450
- ft("Thank you for using WOPR. We're sorry to see you go."),
450
+ ft("Thank you for using {{brandName}}. We're sorry to see you go."),
451
451
  ),
452
452
  textBody: `Your Account Has Been Deleted
453
453
 
454
454
  Hi {{email}},
455
455
 
456
- Your WOPR account and all associated data have been permanently deleted as requested.
456
+ Your {{brandName}} account and all associated data have been permanently deleted as requested.
457
457
 
458
458
  This includes all bots, conversation history, credit records, billing data, and plugin configurations.
459
459
 
460
- If you'd like to use WOPR again in the future, you're welcome to create a new account.${CR}`,
460
+ If you'd like to use {{brandName}} again in the future, you're welcome to create a new account.${CR}`,
461
461
  },
462
462
  // -- Dividend & Affiliate --------------------------------------------------
463
463
  {
464
464
  name: "dividend-weekly-digest",
465
465
  description: "Weekly summary of dividend payouts",
466
- subject: "WOPR paid you {{weeklyTotalDollars}} this week",
466
+ subject: "{{brandName}} paid you {{weeklyTotalDollars}} this week",
467
467
  htmlBody: html(
468
468
  "Weekly Dividend Digest",
469
- hd("WOPR Paid You {{weeklyTotalDollars}} This Week"),
469
+ hd("{{brandName}} Paid You {{weeklyTotalDollars}} This Week"),
470
470
  p(
471
471
  `<p>Here's your weekly dividend summary for <strong>{{weekStartDate}} \u2013 {{weekEndDate}}</strong>.</p>` +
472
472
  `<table style="width: 100%; border-collapse: collapse; margin: 16px 0;">` +
@@ -482,7 +482,7 @@ If you'd like to use WOPR again in the future, you're welcome to create a new ac
482
482
  ft("Community dividends are distributed daily from platform revenue. Keep your credits active to stay eligible."),
483
483
  '{{#if unsubscribeUrl}}<tr><td style="padding: 0 40px 20px 40px; text-align: center; color: #a0aec0; font-size: 12px;"><a href="{{unsubscribeUrl}}" style="color: #a0aec0; text-decoration: underline;">Unsubscribe from dividend digests</a></td></tr>{{/if}}',
484
484
  ),
485
- textBody: `WOPR Paid You {{weeklyTotalDollars}} This Week
485
+ textBody: `{{brandName}} Paid You {{weeklyTotalDollars}} This Week
486
486
 
487
487
  Weekly summary for {{weekStartDate}} \u2013 {{weekEndDate}}:
488
488
 
@@ -509,7 +509,7 @@ Unsubscribe: {{unsubscribeUrl}}{{/if}}${CR}`,
509
509
  "<p>Great news! A user you referred just made their first purchase, and you've been credited <strong>{{amountDollars}}</strong>.</p>",
510
510
  ),
511
511
  `{{#if creditsUrl}}${btn("{{creditsUrl}}", "View Credit Balance")}{{/if}}`,
512
- ft("Thank you for spreading the word about WOPR!"),
512
+ ft("Thank you for spreading the word about {{brandName}}!"),
513
513
  ),
514
514
  textBody: `You Earned Affiliate Credits!
515
515
 
@@ -544,9 +544,9 @@ Review spending: {{creditsUrl}}
544
544
  subject: "{{subject}}",
545
545
  htmlBody: html(
546
546
  "{{subject}}",
547
- hd("Message from WOPR"),
547
+ hd("Message from {{brandName}}"),
548
548
  p("<p>{{{bodyTextHtml}}}</p>"),
549
- ft("This is an administrative message from WOPR Network."),
549
+ ft("This is an administrative message from {{brandName}}."),
550
550
  ),
551
551
  textBody: `{{bodyText}}${CR}`,
552
552
  },
@@ -554,15 +554,15 @@ Review spending: {{creditsUrl}}
554
554
  {
555
555
  name: "low-balance",
556
556
  description: "Sent when credit balance drops below threshold",
557
- subject: "Your WOPR credits are running low",
557
+ subject: "Your {{brandName}} credits are running low",
558
558
  htmlBody: html(
559
559
  "Low Balance",
560
- hd("Your WOPR Credits Are Running Low"),
560
+ hd("Your {{brandName}} Credits Are Running Low"),
561
561
  p("<p>Your balance is <strong>{{balanceDollars}}</strong>. Top up to keep your agents running.</p>"),
562
562
  `{{#if creditsUrl}}${btn("{{creditsUrl}}", "Buy Credits")}{{/if}}`,
563
563
  ft("This is an automated billing notification."),
564
564
  ),
565
- textBody: `Your WOPR Credits Are Running Low
565
+ textBody: `Your {{brandName}} Credits Are Running Low
566
566
 
567
567
  Balance: {{balanceDollars}}
568
568
  {{#if creditsUrl}}
@@ -579,7 +579,7 @@ Buy credits: {{creditsUrl}}
579
579
  p(
580
580
  "<p><strong>{{amountDollars}}</strong> in credits has been added.</p>{{#if newBalanceDollars}}<p>New balance: <strong>{{newBalanceDollars}}</strong></p>{{/if}}",
581
581
  ),
582
- ft("Thank you for supporting WOPR!"),
582
+ ft("Thank you for supporting {{brandName}}!"),
583
583
  ),
584
584
  textBody: `Credits Added
585
585
 
@@ -588,21 +588,21 @@ Buy credits: {{creditsUrl}}
588
588
  {
589
589
  name: "welcome",
590
590
  description: "Sent to new users after registration",
591
- subject: "Welcome to WOPR",
591
+ subject: "Welcome to {{brandName}}",
592
592
  htmlBody: html(
593
593
  "Welcome",
594
- hd("Welcome to WOPR!"),
594
+ hd("Welcome to {{brandName}}!"),
595
595
  p("<p>Your account is now active. Start building!</p>"),
596
596
  ft("Happy building!"),
597
597
  ),
598
- textBody: `Welcome to WOPR!
598
+ textBody: `Welcome to {{brandName}}!
599
599
 
600
600
  Your account is now active.${CR}`,
601
601
  },
602
602
  {
603
603
  name: "password-reset",
604
604
  description: "Sent when a user requests a password reset",
605
- subject: "Reset your WOPR password",
605
+ subject: "Reset your {{brandName}} password",
606
606
  htmlBody: html(
607
607
  "Reset Password",
608
608
  hd("Reset Your Password"),
@@ -92,6 +92,33 @@ export class DrizzleNotificationTemplateRepository implements INotificationTempl
92
92
  return result.length;
93
93
  }
94
94
 
95
+ /**
96
+ * Re-seed all templates using upsert — overwrites existing content
97
+ * while preserving row IDs and createdAt timestamps.
98
+ */
99
+ async reseedAll(
100
+ templates: Array<{
101
+ name: string;
102
+ description: string;
103
+ subject: string;
104
+ htmlBody: string;
105
+ textBody: string;
106
+ }>,
107
+ ): Promise<number> {
108
+ let count = 0;
109
+ for (const t of templates) {
110
+ await this.upsert(t.name, {
111
+ description: t.description,
112
+ subject: t.subject,
113
+ htmlBody: t.htmlBody,
114
+ textBody: t.textBody,
115
+ active: true,
116
+ });
117
+ count++;
118
+ }
119
+ return count;
120
+ }
121
+
95
122
  private toRow(r: typeof notificationTemplates.$inferSelect): NotificationTemplateRow {
96
123
  return {
97
124
  id: r.id,
@@ -30,6 +30,7 @@ describe("NotificationService", () => {
30
30
  balanceDollars: "$2.50",
31
31
  estimatedDaysRemaining: 5,
32
32
  creditsUrl: `${BASE_URL}/billing/credits`,
33
+ brandName: "WOPR",
33
34
  });
34
35
  });
35
36
  });
@@ -40,6 +41,7 @@ describe("NotificationService", () => {
40
41
  expect(queue.enqueue).toHaveBeenCalledWith("tenant-1", "credits-depleted", {
41
42
  email: "user@example.com",
42
43
  creditsUrl: `${BASE_URL}/billing/credits`,
44
+ brandName: "WOPR",
43
45
  });
44
46
  });
45
47
  });
@@ -52,6 +54,7 @@ describe("NotificationService", () => {
52
54
  balanceDollars: "$0.50",
53
55
  graceDays: 7,
54
56
  creditsUrl: `${BASE_URL}/billing/credits`,
57
+ brandName: "WOPR",
55
58
  });
56
59
  });
57
60
  });
@@ -62,6 +65,7 @@ describe("NotificationService", () => {
62
65
  expect(queue.enqueue).toHaveBeenCalledWith("tenant-1", "grace-period-warning", {
63
66
  email: "user@example.com",
64
67
  creditsUrl: `${BASE_URL}/billing/credits`,
68
+ brandName: "WOPR",
65
69
  });
66
70
  });
67
71
  });
@@ -73,6 +77,7 @@ describe("NotificationService", () => {
73
77
  email: "user@example.com",
74
78
  reason: "Grace period expired",
75
79
  creditsUrl: `${BASE_URL}/billing/credits`,
80
+ brandName: "WOPR",
76
81
  });
77
82
  });
78
83
  });
@@ -83,6 +88,7 @@ describe("NotificationService", () => {
83
88
  expect(queue.enqueue).toHaveBeenCalledWith("tenant-1", "admin-suspended", {
84
89
  email: "user@example.com",
85
90
  reason: "ToS violation",
91
+ brandName: "WOPR",
86
92
  });
87
93
  });
88
94
  });
@@ -92,6 +98,7 @@ describe("NotificationService", () => {
92
98
  service.notifyAdminReactivated("tenant-1", "user@example.com");
93
99
  expect(queue.enqueue).toHaveBeenCalledWith("tenant-1", "admin-reactivated", {
94
100
  email: "user@example.com",
101
+ brandName: "WOPR",
95
102
  });
96
103
  });
97
104
  });
@@ -103,6 +110,7 @@ describe("NotificationService", () => {
103
110
  email: "user@example.com",
104
111
  amountDollars: "$5.00",
105
112
  reason: "Support credit",
113
+ brandName: "WOPR",
106
114
  });
107
115
  });
108
116
  });
@@ -113,6 +121,7 @@ describe("NotificationService", () => {
113
121
  expect(queue.enqueue).toHaveBeenCalledWith("tenant-1", "role-changed", {
114
122
  email: "user@example.com",
115
123
  newRole: "tenant_admin",
124
+ brandName: "WOPR",
116
125
  });
117
126
  });
118
127
  });
@@ -124,6 +133,7 @@ describe("NotificationService", () => {
124
133
  email: "user@example.com",
125
134
  tenantName: "Acme Corp",
126
135
  inviteUrl: "https://app.wopr.bot/invite/abc",
136
+ brandName: "WOPR",
127
137
  });
128
138
  });
129
139
  });
@@ -136,6 +146,7 @@ describe("NotificationService", () => {
136
146
  channelName: "Discord",
137
147
  agentName: "MyBot",
138
148
  reason: "Token expired",
149
+ brandName: "WOPR",
139
150
  });
140
151
  });
141
152
  });
@@ -147,6 +158,7 @@ describe("NotificationService", () => {
147
158
  email: "user@example.com",
148
159
  subject: "Hello there",
149
160
  bodyText: "This is the body.",
161
+ brandName: "WOPR",
150
162
  });
151
163
  });
152
164
  });
@@ -160,6 +172,7 @@ describe("NotificationService", () => {
160
172
  amountDollars: "$50.00",
161
173
  reason: "fraudulent",
162
174
  creditsUrl: `${BASE_URL}/billing/credits`,
175
+ brandName: "WOPR",
163
176
  });
164
177
  });
165
178
  });
@@ -172,6 +185,7 @@ describe("NotificationService", () => {
172
185
  disputeId: "dp_123",
173
186
  amountDollars: "$50.00",
174
187
  creditsUrl: `${BASE_URL}/billing/credits`,
188
+ brandName: "WOPR",
175
189
  });
176
190
  });
177
191
  });