@soulbatical/tetra-core 0.1.39 → 0.1.41

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.

Potentially problematic release.


This version of @soulbatical/tetra-core might be problematic. Click here for more details.

Files changed (56) hide show
  1. package/dist/core/dualWriteProxy.d.ts +11 -0
  2. package/dist/core/dualWriteProxy.d.ts.map +1 -1
  3. package/dist/core/dualWriteProxy.js +142 -198
  4. package/dist/core/dualWriteProxy.js.map +1 -1
  5. package/dist/index.d.ts +4 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +3 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/shared/email/EmailService.d.ts +9 -1
  10. package/dist/shared/email/EmailService.d.ts.map +1 -1
  11. package/dist/shared/email/EmailService.js +83 -7
  12. package/dist/shared/email/EmailService.js.map +1 -1
  13. package/dist/shared/email/adminRoutes.d.ts +30 -0
  14. package/dist/shared/email/adminRoutes.d.ts.map +1 -0
  15. package/dist/shared/email/adminRoutes.js +227 -0
  16. package/dist/shared/email/adminRoutes.js.map +1 -0
  17. package/dist/shared/email/index.d.ts +3 -1
  18. package/dist/shared/email/index.d.ts.map +1 -1
  19. package/dist/shared/email/index.js +3 -0
  20. package/dist/shared/email/index.js.map +1 -1
  21. package/dist/shared/email/mailgun.d.ts +4 -1
  22. package/dist/shared/email/mailgun.d.ts.map +1 -1
  23. package/dist/shared/email/mailgun.js +41 -10
  24. package/dist/shared/email/mailgun.js.map +1 -1
  25. package/dist/shared/email/smtp.d.ts +4 -1
  26. package/dist/shared/email/smtp.d.ts.map +1 -1
  27. package/dist/shared/email/smtp.js +14 -2
  28. package/dist/shared/email/smtp.js.map +1 -1
  29. package/dist/shared/email/types.d.ts +23 -1
  30. package/dist/shared/email/types.d.ts.map +1 -1
  31. package/dist/shared/email/webhookRoutes.d.ts +29 -0
  32. package/dist/shared/email/webhookRoutes.d.ts.map +1 -0
  33. package/dist/shared/email/webhookRoutes.js +125 -0
  34. package/dist/shared/email/webhookRoutes.js.map +1 -0
  35. package/dist/shared/planner/GoogleCalendarService.d.ts +103 -0
  36. package/dist/shared/planner/GoogleCalendarService.d.ts.map +1 -0
  37. package/dist/shared/planner/GoogleCalendarService.js +365 -0
  38. package/dist/shared/planner/GoogleCalendarService.js.map +1 -0
  39. package/dist/shared/planner/PlannerService.d.ts +170 -0
  40. package/dist/shared/planner/PlannerService.d.ts.map +1 -0
  41. package/dist/shared/planner/PlannerService.js +860 -0
  42. package/dist/shared/planner/PlannerService.js.map +1 -0
  43. package/dist/shared/planner/index.d.ts +35 -0
  44. package/dist/shared/planner/index.d.ts.map +1 -0
  45. package/dist/shared/planner/index.js +34 -0
  46. package/dist/shared/planner/index.js.map +1 -0
  47. package/dist/shared/planner/routes.d.ts +67 -0
  48. package/dist/shared/planner/routes.d.ts.map +1 -0
  49. package/dist/shared/planner/routes.js +524 -0
  50. package/dist/shared/planner/routes.js.map +1 -0
  51. package/dist/shared/planner/types.d.ts +262 -0
  52. package/dist/shared/planner/types.d.ts.map +1 -0
  53. package/dist/shared/planner/types.js +9 -0
  54. package/dist/shared/planner/types.js.map +1 -0
  55. package/package.json +1 -1
  56. package/src/shared/email/migrations/004_add_email_logs_tracking_columns.sql +15 -0
@@ -1 +1 @@
1
- {"version":3,"file":"EmailService.d.ts","sourceRoot":"","sources":["../../../src/shared/email/EmailService.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAoC,MAAM,YAAY,CAAC;AAK/F,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;gBADN,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,WAAW;IAG7B;;;;;;;;OAQG;IACG,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAwC9E;;;OAGG;YACW,OAAO;IA+BrB;;OAEG;YACW,eAAe;IAgC7B,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;YACW,YAAY;IAgD1B;;;OAGG;IACH,OAAO,CAAC,MAAM;IAQd;;OAEG;YACW,SAAS;IAsCvB;;OAEG;YACW,SAAS;CAkBxB"}
1
+ {"version":3,"file":"EmailService.d.ts","sourceRoot":"","sources":["../../../src/shared/email/EmailService.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAqD,MAAM,YAAY,CAAC;AAahH,qBAAa,YAAY;IAIrB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IAJhB,OAAO,CAAC,aAAa,CAAiC;gBAG5C,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,WAAW;IAG7B;;;;;;;;OAQG;IACG,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAsD9E;;OAEG;IACH,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAa/B;;;OAGG;YACW,OAAO;IA6CrB;;OAEG;YACW,eAAe;IAmC7B,OAAO,CAAC,gBAAgB;IAOxB;;;OAGG;YACW,YAAY;IAqE1B,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,QAAQ;IAIhB;;;OAGG;IACH,OAAO,CAAC,MAAM;IAQd;;OAEG;YACW,SAAS;IA0CvB;;OAEG;YACW,SAAS;CAkBxB"}
@@ -2,7 +2,7 @@
2
2
  * EmailService — Core service for sending templated emails.
3
3
  *
4
4
  * Template lookup with language + org fallback, Handlebars rendering,
5
- * DB logging, and Mailgun delivery.
5
+ * DB logging, and multi-transport delivery (Gmail, SMTP, Mailgun).
6
6
  *
7
7
  * @module @soulbatical/tetra-core/email
8
8
  */
@@ -10,9 +10,11 @@ import Handlebars from 'handlebars';
10
10
  import { sendMailgunEmail } from './mailgun.js';
11
11
  import { sendSmtpEmail } from './smtp.js';
12
12
  import { getGmailClient } from './gmail.js';
13
+ const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
13
14
  export class EmailService {
14
15
  supabase;
15
16
  config;
17
+ templateCache = new Map();
16
18
  constructor(supabase, config) {
17
19
  this.supabase = supabase;
18
20
  this.config = config;
@@ -36,6 +38,9 @@ export class EmailService {
36
38
  const html = template
37
39
  ? this.render(template.body_html, opts.variables)
38
40
  : opts.fallbackHtml || `<p>${subject}</p>`;
41
+ const text = template?.body_text
42
+ ? this.render(template.body_text, opts.variables)
43
+ : opts.fallbackText || undefined;
39
44
  // 2. Create log entry (pending)
40
45
  const logId = await this.createLog({
41
46
  organizationId: opts.organizationId,
@@ -44,10 +49,20 @@ export class EmailService {
44
49
  subject,
45
50
  templateSlug: opts.templateSlug,
46
51
  variables: opts.variables,
52
+ emailType: opts.emailType,
53
+ metadata: opts.metadata,
47
54
  feedbackId: opts.feedbackId,
48
55
  });
49
56
  // 3. Send via configured transport
50
- const result = await this.deliver({ from: this.config.fromAddress, to: opts.to, subject, html });
57
+ const result = await this.deliver({
58
+ from: this.config.fromAddress,
59
+ to: opts.to,
60
+ subject,
61
+ html,
62
+ text,
63
+ replyTo: opts.replyTo,
64
+ attachments: opts.attachments,
65
+ });
51
66
  // 4. Update log
52
67
  if (logId) {
53
68
  await this.updateLog(logId, {
@@ -58,6 +73,22 @@ export class EmailService {
58
73
  }
59
74
  return { success: result.success, logId: logId || undefined };
60
75
  }
76
+ /**
77
+ * Clear template cache. Call after template is updated via admin UI.
78
+ */
79
+ clearCache(slug) {
80
+ if (slug) {
81
+ // Clear all cache keys that start with this slug (all language/org variants)
82
+ for (const key of this.templateCache.keys()) {
83
+ if (key.startsWith(`${slug}:`)) {
84
+ this.templateCache.delete(key);
85
+ }
86
+ }
87
+ }
88
+ else {
89
+ this.templateCache.clear();
90
+ }
91
+ }
61
92
  /**
62
93
  * Resolve transport and send email.
63
94
  * Priority: explicit config.transport > auto-detect (gmail > smtp > mailgun).
@@ -69,7 +100,13 @@ export class EmailService {
69
100
  }
70
101
  if (transport === 'smtp') {
71
102
  return sendSmtpEmail({
72
- ...params,
103
+ from: params.from,
104
+ to: params.to,
105
+ subject: params.subject,
106
+ html: params.html,
107
+ text: params.text,
108
+ replyTo: params.replyTo,
109
+ attachments: params.attachments,
73
110
  smtpHost: this.config.smtpHost,
74
111
  smtpPort: this.config.smtpPort ?? 587,
75
112
  smtpUser: this.config.smtpUser,
@@ -78,7 +115,12 @@ export class EmailService {
78
115
  });
79
116
  }
80
117
  return sendMailgunEmail({
81
- ...params,
118
+ from: params.from,
119
+ to: params.to,
120
+ subject: params.subject,
121
+ html: params.html,
122
+ text: params.text,
123
+ replyTo: params.replyTo,
82
124
  apiKey: this.config.mailgunApiKey,
83
125
  domain: this.config.mailgunDomain,
84
126
  endpoint: this.config.mailgunEndpoint,
@@ -122,10 +164,15 @@ export class EmailService {
122
164
  }
123
165
  /**
124
166
  * Template lookup with language + org fallback chain.
167
+ * Results are cached for 5 minutes.
125
168
  */
126
169
  async loadTemplate(slug, language, organizationId) {
127
170
  // Try: slug + language + org (if org provided)
128
171
  if (organizationId) {
172
+ const cacheKey = `${slug}:${language}:${organizationId}`;
173
+ const cached = this.getCached(cacheKey);
174
+ if (cached !== undefined)
175
+ return cached;
129
176
  const { data } = await this.supabase
130
177
  .from('email_templates')
131
178
  .select('*')
@@ -135,10 +182,16 @@ export class EmailService {
135
182
  .eq('is_active', true)
136
183
  .limit(1)
137
184
  .single();
138
- if (data)
185
+ if (data) {
186
+ this.setCache(cacheKey, data);
139
187
  return data;
188
+ }
140
189
  }
141
190
  // Try: slug + language + system default (org IS NULL)
191
+ const langKey = `${slug}:${language}:system`;
192
+ const cachedLang = this.getCached(langKey);
193
+ if (cachedLang !== undefined)
194
+ return cachedLang;
142
195
  const { data: langDefault } = await this.supabase
143
196
  .from('email_templates')
144
197
  .select('*')
@@ -148,10 +201,16 @@ export class EmailService {
148
201
  .eq('is_active', true)
149
202
  .limit(1)
150
203
  .single();
151
- if (langDefault)
204
+ if (langDefault) {
205
+ this.setCache(langKey, langDefault);
152
206
  return langDefault;
207
+ }
153
208
  // Try: slug + English fallback + system default
154
209
  if (language !== 'en') {
210
+ const enKey = `${slug}:en:system`;
211
+ const cachedEn = this.getCached(enKey);
212
+ if (cachedEn !== undefined)
213
+ return cachedEn;
155
214
  const { data: enDefault } = await this.supabase
156
215
  .from('email_templates')
157
216
  .select('*')
@@ -161,11 +220,26 @@ export class EmailService {
161
220
  .eq('is_active', true)
162
221
  .limit(1)
163
222
  .single();
164
- if (enDefault)
223
+ if (enDefault) {
224
+ this.setCache(enKey, enDefault);
165
225
  return enDefault;
226
+ }
166
227
  }
167
228
  return null;
168
229
  }
230
+ getCached(key) {
231
+ const entry = this.templateCache.get(key);
232
+ if (!entry)
233
+ return undefined;
234
+ if (Date.now() - entry.cachedAt > CACHE_TTL) {
235
+ this.templateCache.delete(key);
236
+ return undefined;
237
+ }
238
+ return entry.template;
239
+ }
240
+ setCache(key, template) {
241
+ this.templateCache.set(key, { template, cachedAt: Date.now() });
242
+ }
169
243
  /**
170
244
  * Render a Handlebars template string with variables.
171
245
  * Rejects templates with triple-brace {{{…}}} syntax to prevent escaping bypass.
@@ -188,6 +262,8 @@ export class EmailService {
188
262
  subject: opts.subject,
189
263
  template_slug: opts.templateSlug || null,
190
264
  variables_used: opts.variables || {},
265
+ email_type: opts.emailType || null,
266
+ metadata: opts.metadata || null,
191
267
  status: 'pending',
192
268
  };
193
269
  // feedbackId is app-specific — only include if the column exists
@@ -1 +1 @@
1
- {"version":3,"file":"EmailService.js","sourceRoot":"","sources":["../../../src/shared/email/EmailService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EmailService.js","sourceRoot":"","sources":["../../../src/shared/email/EmailService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Email Admin Routes — CRUD for email templates + send test email.
3
+ *
4
+ * Usage:
5
+ * import { addEmailAdminRoutes } from '@soulbatical/tetra-core';
6
+ * addEmailAdminRoutes(router, { supabase, emailService });
7
+ *
8
+ * Mounts:
9
+ * GET /email/templates — List all templates
10
+ * GET /email/templates/:id — Get single template
11
+ * POST /email/templates — Create template
12
+ * PUT /email/templates/:id — Update template
13
+ * DELETE /email/templates/:id — Soft-delete (set is_active=false)
14
+ * POST /email/templates/:id/test — Send test email
15
+ * GET /email/logs — List email logs
16
+ *
17
+ * @module @soulbatical/tetra-core/email
18
+ */
19
+ import { Router, Request } from 'express';
20
+ import type { SupabaseClient } from '@supabase/supabase-js';
21
+ import type { EmailService } from './EmailService.js';
22
+ interface EmailAdminRoutesConfig {
23
+ supabase: SupabaseClient;
24
+ emailService: EmailService;
25
+ /** Organization ID getter from request (for multi-tenant filtering). Optional. */
26
+ getOrganizationId?: (req: Request) => string | undefined;
27
+ }
28
+ export declare function addEmailAdminRoutes(router: Router, config: EmailAdminRoutesConfig): void;
29
+ export {};
30
+ //# sourceMappingURL=adminRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adminRoutes.d.ts","sourceRoot":"","sources":["../../../src/shared/email/adminRoutes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAY,MAAM,SAAS,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,cAAc,CAAC;IACzB,YAAY,EAAE,YAAY,CAAC;IAC3B,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;CAC1D;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI,CA2NxF"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Email Admin Routes — CRUD for email templates + send test email.
3
+ *
4
+ * Usage:
5
+ * import { addEmailAdminRoutes } from '@soulbatical/tetra-core';
6
+ * addEmailAdminRoutes(router, { supabase, emailService });
7
+ *
8
+ * Mounts:
9
+ * GET /email/templates — List all templates
10
+ * GET /email/templates/:id — Get single template
11
+ * POST /email/templates — Create template
12
+ * PUT /email/templates/:id — Update template
13
+ * DELETE /email/templates/:id — Soft-delete (set is_active=false)
14
+ * POST /email/templates/:id/test — Send test email
15
+ * GET /email/logs — List email logs
16
+ *
17
+ * @module @soulbatical/tetra-core/email
18
+ */
19
+ export function addEmailAdminRoutes(router, config) {
20
+ const { supabase, emailService } = config;
21
+ // GET /email/templates — List all templates
22
+ router.get('/email/templates', async (req, res) => {
23
+ try {
24
+ const orgId = config.getOrganizationId?.(req);
25
+ let query = supabase
26
+ .from('email_templates')
27
+ .select('id, slug, name, subject, language, category, is_active, organization_id, created_at, updated_at')
28
+ .order('slug', { ascending: true });
29
+ if (orgId) {
30
+ // Show system templates (org IS NULL) + org-specific ones
31
+ query = query.or(`organization_id.is.null,organization_id.eq.${orgId}`);
32
+ }
33
+ const { data, error } = await query;
34
+ if (error) {
35
+ res.status(500).json({ success: false, error: error.message });
36
+ return;
37
+ }
38
+ res.json({ success: true, data });
39
+ }
40
+ catch (error) {
41
+ res.status(500).json({ success: false, error: 'Internal error' });
42
+ }
43
+ });
44
+ // GET /email/templates/:id — Get single template with full body
45
+ router.get('/email/templates/:id', async (req, res) => {
46
+ try {
47
+ const { data, error } = await supabase
48
+ .from('email_templates')
49
+ .select('*')
50
+ .eq('id', req.params.id)
51
+ .single();
52
+ if (error || !data) {
53
+ res.status(404).json({ success: false, error: 'Template not found' });
54
+ return;
55
+ }
56
+ res.json({ success: true, data });
57
+ }
58
+ catch (error) {
59
+ res.status(500).json({ success: false, error: 'Internal error' });
60
+ }
61
+ });
62
+ // POST /email/templates — Create template
63
+ router.post('/email/templates', async (req, res) => {
64
+ try {
65
+ const { slug, name, subject, body_html, body_text, variables, language, category, organization_id } = req.body;
66
+ if (!slug || !name || !subject || !body_html) {
67
+ res.status(400).json({ success: false, error: 'slug, name, subject, and body_html are required' });
68
+ return;
69
+ }
70
+ const { data, error } = await supabase
71
+ .from('email_templates')
72
+ .insert({
73
+ slug,
74
+ name,
75
+ subject,
76
+ body_html,
77
+ body_text: body_text || null,
78
+ variables: variables || [],
79
+ language: language || 'nl',
80
+ category: category || 'transactional',
81
+ organization_id: organization_id || null,
82
+ is_active: true,
83
+ })
84
+ .select()
85
+ .single();
86
+ if (error) {
87
+ res.status(400).json({ success: false, error: error.message });
88
+ return;
89
+ }
90
+ emailService.clearCache(slug);
91
+ res.status(201).json({ success: true, data });
92
+ }
93
+ catch (error) {
94
+ res.status(500).json({ success: false, error: 'Internal error' });
95
+ }
96
+ });
97
+ // PUT /email/templates/:id — Update template
98
+ router.put('/email/templates/:id', async (req, res) => {
99
+ try {
100
+ const { slug, name, subject, body_html, body_text, variables, language, category, is_active } = req.body;
101
+ const updates = { updated_at: new Date().toISOString() };
102
+ if (slug !== undefined)
103
+ updates.slug = slug;
104
+ if (name !== undefined)
105
+ updates.name = name;
106
+ if (subject !== undefined)
107
+ updates.subject = subject;
108
+ if (body_html !== undefined)
109
+ updates.body_html = body_html;
110
+ if (body_text !== undefined)
111
+ updates.body_text = body_text;
112
+ if (variables !== undefined)
113
+ updates.variables = variables;
114
+ if (language !== undefined)
115
+ updates.language = language;
116
+ if (category !== undefined)
117
+ updates.category = category;
118
+ if (is_active !== undefined)
119
+ updates.is_active = is_active;
120
+ const { data, error } = await supabase
121
+ .from('email_templates')
122
+ .update(updates)
123
+ .eq('id', req.params.id)
124
+ .select()
125
+ .single();
126
+ if (error || !data) {
127
+ res.status(404).json({ success: false, error: error?.message || 'Template not found' });
128
+ return;
129
+ }
130
+ // Clear cache for both old and new slug
131
+ emailService.clearCache(data.slug);
132
+ if (slug && slug !== data.slug)
133
+ emailService.clearCache(slug);
134
+ res.json({ success: true, data });
135
+ }
136
+ catch (error) {
137
+ res.status(500).json({ success: false, error: 'Internal error' });
138
+ }
139
+ });
140
+ // DELETE /email/templates/:id — Soft delete (set is_active=false)
141
+ router.delete('/email/templates/:id', async (req, res) => {
142
+ try {
143
+ const { data, error } = await supabase
144
+ .from('email_templates')
145
+ .update({ is_active: false, updated_at: new Date().toISOString() })
146
+ .eq('id', req.params.id)
147
+ .select('slug')
148
+ .single();
149
+ if (error || !data) {
150
+ res.status(404).json({ success: false, error: 'Template not found' });
151
+ return;
152
+ }
153
+ emailService.clearCache(data.slug);
154
+ res.json({ success: true, message: 'Template deactivated' });
155
+ }
156
+ catch (error) {
157
+ res.status(500).json({ success: false, error: 'Internal error' });
158
+ }
159
+ });
160
+ // POST /email/templates/:id/test — Send test email
161
+ router.post('/email/templates/:id/test', async (req, res) => {
162
+ try {
163
+ const { to } = req.body;
164
+ if (!to) {
165
+ res.status(400).json({ success: false, error: 'to is required' });
166
+ return;
167
+ }
168
+ // Load template
169
+ const { data: template, error } = await supabase
170
+ .from('email_templates')
171
+ .select('*')
172
+ .eq('id', req.params.id)
173
+ .single();
174
+ if (error || !template) {
175
+ res.status(404).json({ success: false, error: 'Template not found' });
176
+ return;
177
+ }
178
+ // Create sample variables from template's variable list
179
+ const variables = {};
180
+ if (Array.isArray(template.variables)) {
181
+ for (const v of template.variables) {
182
+ const key = typeof v === 'string' ? v : v.key;
183
+ if (key)
184
+ variables[key] = `[${key}]`;
185
+ }
186
+ }
187
+ const result = await emailService.send({
188
+ to,
189
+ templateSlug: template.slug,
190
+ variables,
191
+ language: template.language,
192
+ organizationId: template.organization_id || undefined,
193
+ emailType: 'test',
194
+ });
195
+ res.json({ success: result.success, logId: result.logId });
196
+ }
197
+ catch (error) {
198
+ res.status(500).json({ success: false, error: 'Internal error' });
199
+ }
200
+ });
201
+ // GET /email/logs — List email logs with pagination
202
+ router.get('/email/logs', async (req, res) => {
203
+ try {
204
+ const limit = Math.min(parseInt(req.query.limit) || 50, 100);
205
+ const offset = parseInt(req.query.offset) || 0;
206
+ const orgId = config.getOrganizationId?.(req);
207
+ let query = supabase
208
+ .from('email_logs')
209
+ .select('id, to_email, subject, status, email_type, template_slug, sent_at, delivered_at, opened_at, clicked_at, error_message, created_at', { count: 'exact' })
210
+ .order('created_at', { ascending: false })
211
+ .range(offset, offset + limit - 1);
212
+ if (orgId) {
213
+ query = query.eq('organization_id', orgId);
214
+ }
215
+ const { data, error, count } = await query;
216
+ if (error) {
217
+ res.status(500).json({ success: false, error: error.message });
218
+ return;
219
+ }
220
+ res.json({ success: true, data, total: count, limit, offset });
221
+ }
222
+ catch (error) {
223
+ res.status(500).json({ success: false, error: 'Internal error' });
224
+ }
225
+ });
226
+ }
227
+ //# sourceMappingURL=adminRoutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adminRoutes.js","sourceRoot":"","sources":["../../../src/shared/email/adminRoutes.ts"],"names":[],"mappings":"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"}
@@ -6,8 +6,10 @@
6
6
  export { EmailService } from './EmailService.js';
7
7
  export { sendMailgunEmail } from './mailgun.js';
8
8
  export { sendSmtpEmail } from './smtp.js';
9
+ export { addEmailAdminRoutes } from './adminRoutes.js';
10
+ export { addMailgunWebhookRoutes } from './webhookRoutes.js';
9
11
  export { GmailClient, getGmailClient, listGmailAccounts, clearGmailClientCache, disconnectGmail, getGmailAuthUrl, startGmailOAuth, getGmailAuthServerStatus, resetGmailAuthServerState, exchangeGmailCode, addGmailOAuthRoutes, } from './gmail.js';
10
12
  export type { GmailTokens, GmailSendOptions, GmailSendResult, GmailSearchResult, GmailMessageSummary, GmailMessage, GmailMessagePart, GmailMessageHeader, GmailAttachmentInfo, GmailProfile, GmailOAuthConfig, GmailAuthServerStatus, GmailOAuthRoutesConfig, } from './gmail.js';
11
13
  export { escapeHtml } from './sanitize.js';
12
- export type { EmailConfig, SendEmailOpts, EmailTemplate, EmailLogEntry, MailgunResponse, SmtpResponse, EmailSendResponse, } from './types.js';
14
+ export type { EmailAttachment, EmailConfig, SendEmailOpts, EmailTemplate, EmailLogEntry, MailgunResponse, SmtpResponse, EmailSendResponse, } from './types.js';
13
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/email/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EACL,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,eAAe,EACf,wBAAwB,EACxB,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,YAAY,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/email/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAG7D,OAAO,EACL,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,eAAe,EACf,wBAAwB,EACxB,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,YAAY,EACV,eAAe,EACf,WAAW,EACX,aAAa,EACb,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
@@ -8,6 +8,9 @@ export { EmailService } from './EmailService.js';
8
8
  // Transport helpers
9
9
  export { sendMailgunEmail } from './mailgun.js';
10
10
  export { sendSmtpEmail } from './smtp.js';
11
+ // Route factories
12
+ export { addEmailAdminRoutes } from './adminRoutes.js';
13
+ export { addMailgunWebhookRoutes } from './webhookRoutes.js';
11
14
  // Gmail (OAuth2 API transport + client for read/search/attachments)
12
15
  export { GmailClient, getGmailClient, listGmailAccounts, clearGmailClientCache, disconnectGmail, getGmailAuthUrl, startGmailOAuth, getGmailAuthServerStatus, resetGmailAuthServerState, exchangeGmailCode, addGmailOAuthRoutes, } from './gmail.js';
13
16
  // Sanitization
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shared/email/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,UAAU;AACV,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,oBAAoB;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,oEAAoE;AACpE,OAAO,EACL,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,eAAe,EACf,wBAAwB,EACxB,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAiBpB,eAAe;AACf,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shared/email/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,UAAU;AACV,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,oBAAoB;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,kBAAkB;AAClB,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,oEAAoE;AACpE,OAAO,EACL,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,eAAe,EACf,wBAAwB,EACxB,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAiBpB,eAAe;AACf,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
@@ -2,12 +2,15 @@
2
2
  * Mailgun email helper — native fetch, no axios.
3
3
  * Graceful no-op when credentials are missing.
4
4
  */
5
- import type { MailgunResponse } from './types.js';
5
+ import type { MailgunResponse, EmailAttachment } from './types.js';
6
6
  export declare function sendMailgunEmail(params: {
7
7
  from: string;
8
8
  to: string;
9
9
  subject: string;
10
10
  html: string;
11
+ text?: string;
12
+ replyTo?: string;
13
+ attachments?: EmailAttachment[];
11
14
  apiKey?: string;
12
15
  domain?: string;
13
16
  endpoint?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"mailgun.d.ts","sourceRoot":"","sources":["../../../src/shared/email/mailgun.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,eAAe,CAAC,CA2C3B"}
1
+ {"version":3,"file":"mailgun.d.ts","sourceRoot":"","sources":["../../../src/shared/email/mailgun.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAInE,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,eAAe,CAAC,CAyE3B"}
@@ -10,19 +10,50 @@ export async function sendMailgunEmail(params) {
10
10
  return { success: false, message: 'Mailgun not configured' };
11
11
  }
12
12
  const baseUrl = params.endpoint || DEFAULT_EU_ENDPOINT;
13
- const formData = new URLSearchParams();
14
- formData.append('from', params.from);
15
- formData.append('to', params.to);
16
- formData.append('subject', params.subject);
17
- formData.append('html', params.html);
18
13
  try {
14
+ let body;
15
+ let contentType;
16
+ if (params.attachments?.length) {
17
+ // Use FormData for multipart (attachments)
18
+ const formData = new FormData();
19
+ formData.append('from', params.from);
20
+ formData.append('to', params.to);
21
+ formData.append('subject', params.subject);
22
+ formData.append('html', params.html);
23
+ if (params.text)
24
+ formData.append('text', params.text);
25
+ if (params.replyTo)
26
+ formData.append('h:Reply-To', params.replyTo);
27
+ for (const att of params.attachments) {
28
+ const blob = new Blob([att.data], { type: att.contentType || 'application/octet-stream' });
29
+ formData.append('attachment', blob, att.filename);
30
+ }
31
+ body = formData;
32
+ // Let fetch set the Content-Type with boundary
33
+ }
34
+ else {
35
+ // Simple URL-encoded form (no attachments)
36
+ const formData = new URLSearchParams();
37
+ formData.append('from', params.from);
38
+ formData.append('to', params.to);
39
+ formData.append('subject', params.subject);
40
+ formData.append('html', params.html);
41
+ if (params.text)
42
+ formData.append('text', params.text);
43
+ if (params.replyTo)
44
+ formData.append('h:Reply-To', params.replyTo);
45
+ body = formData.toString();
46
+ contentType = 'application/x-www-form-urlencoded';
47
+ }
48
+ const headers = {
49
+ Authorization: 'Basic ' + Buffer.from(`api:${apiKey}`).toString('base64'),
50
+ };
51
+ if (contentType)
52
+ headers['Content-Type'] = contentType;
19
53
  const resp = await fetch(`${baseUrl}/${domain}/messages`, {
20
54
  method: 'POST',
21
- headers: {
22
- Authorization: 'Basic ' + Buffer.from(`api:${apiKey}`).toString('base64'),
23
- 'Content-Type': 'application/x-www-form-urlencoded',
24
- },
25
- body: formData.toString(),
55
+ headers,
56
+ body,
26
57
  });
27
58
  if (!resp.ok) {
28
59
  const text = (await resp.text()).slice(0, 500);