@aglyn/shared-util-email 1.0.0-beta.270 → 1.0.0-beta.272

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.
@@ -0,0 +1,436 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /*==========================================
17
+ * SITE CARE, AS SYSTEM EMAILS (AGL-3959).
18
+ *
19
+ * A Site Care owner hears about their requests by email, because they do not
20
+ * use the console: that it arrived, that it is done (with what changed and
21
+ * the time it took), that a bigger job needs a quote, that they approved
22
+ * extra time, that a charge was corrected or reversed, and the month's
23
+ * statement on demand. Each is its own key so staff can redesign one
24
+ * without the rest. The merge tokens are what
25
+ * `@aglyn/tenant-data-admin/server/site-care-emails` fills.
26
+ *
27
+ * None answers a sender the intake does not recognize. Site Care mail
28
+ * arrives at the support address (AGL-3997), so such a message is ordinary
29
+ * support mail and the support inbox answers it.
30
+ *=========================================*/ export const SITE_CARE_REQUEST_RECEIVED_EMAIL_KEY = 'site-care-request-received';
31
+ export const SITE_CARE_REQUEST_DONE_EMAIL_KEY = 'site-care-request-done';
32
+ export const SITE_CARE_REQUEST_CORRECTED_EMAIL_KEY = 'site-care-request-corrected';
33
+ export const SITE_CARE_APPROVAL_EMAIL_KEY = 'site-care-approval-confirmation';
34
+ export const SITE_CARE_CHARGE_REVERSED_EMAIL_KEY = 'site-care-charge-reversed';
35
+ export const SITE_CARE_STATEMENT_EMAIL_KEY = 'site-care-statement';
36
+ export const SITE_CARE_QUOTE_EMAIL_KEY = 'site-care-quote';
37
+ const SOURCE = 'libs/tenant/data/admin/src/lib/server/site-care-emails.ts';
38
+ const ORG_NAME = {
39
+ name: 'org.name',
40
+ description: 'The workspace the request is for',
41
+ sample: 'Test Org'
42
+ };
43
+ const REQUEST_TITLE = {
44
+ name: 'request.title',
45
+ description: 'The request, as the owner titled it',
46
+ sample: 'Update our holiday hours'
47
+ };
48
+ const FOOTER = 'You’re receiving this because {{org.name}} has Site Care on {{brand.productName}}.';
49
+ export const SITE_CARE_SYSTEM_EMAIL_TEMPLATES = [
50
+ {
51
+ key: SITE_CARE_REQUEST_RECEIVED_EMAIL_KEY,
52
+ name: 'Site Care: request received',
53
+ description: 'Sent to the person who asked when a Site Care request arrives, by email or from the console.',
54
+ deliveredBy: 'resend',
55
+ defaultSubject: 'We have your request: {{request.title}}',
56
+ mergeTokens: [
57
+ ORG_NAME,
58
+ REQUEST_TITLE,
59
+ {
60
+ name: 'request.message',
61
+ description: 'What they asked for',
62
+ sample: 'Please change Saturday to 9 to 2 for December.'
63
+ },
64
+ {
65
+ name: 'request.due',
66
+ description: 'When it will be done at the latest',
67
+ sample: 'Wednesday, October 21'
68
+ }
69
+ ],
70
+ defaultBody: [
71
+ {
72
+ block: 'text',
73
+ text: 'Site Care · {{org.name}}',
74
+ variant: 'eyebrow'
75
+ },
76
+ {
77
+ block: 'text',
78
+ text: 'We have your request',
79
+ variant: 'heading'
80
+ },
81
+ {
82
+ block: 'text',
83
+ text: 'Thanks. We received “{{request.title}}” and will have it done by {{request.due}}. Reply to this email to add anything, and it joins the same request.',
84
+ variant: 'body'
85
+ },
86
+ {
87
+ block: 'text',
88
+ text: 'Request: {{request.title}}\nDone by: {{request.due}}',
89
+ variant: 'details'
90
+ },
91
+ {
92
+ block: 'text',
93
+ text: '{{request.message}}',
94
+ variant: 'body'
95
+ }
96
+ ],
97
+ footerReason: FOOTER,
98
+ source: SOURCE
99
+ },
100
+ {
101
+ key: SITE_CARE_REQUEST_DONE_EMAIL_KEY,
102
+ name: 'Site Care: request done',
103
+ description: 'Sent to the workspace owner when staff close a Site Care request: what changed, the time it took, the time left this month, or the extra time billed.',
104
+ deliveredBy: 'resend',
105
+ defaultSubject: 'Done: {{request.title}}',
106
+ mergeTokens: [
107
+ ORG_NAME,
108
+ REQUEST_TITLE,
109
+ {
110
+ name: 'request.changes',
111
+ description: 'What changed, from the request and the publish that shipped it',
112
+ sample: 'Published “Home” on Oct 19, 2026, 3:04 PM CDT'
113
+ },
114
+ {
115
+ name: 'request.minutes',
116
+ description: 'The time it took',
117
+ sample: '35 min'
118
+ },
119
+ {
120
+ name: 'month.minutesLeft',
121
+ description: 'Included time left this month',
122
+ sample: '25 min of this month’s included hour'
123
+ },
124
+ {
125
+ name: 'request.billing',
126
+ description: 'Whether anything bills, in one sentence',
127
+ sample: 'No extra charge: this fit in your included hour.'
128
+ }
129
+ ],
130
+ defaultBody: [
131
+ {
132
+ block: 'text',
133
+ text: 'Site Care · {{org.name}}',
134
+ variant: 'eyebrow'
135
+ },
136
+ {
137
+ block: 'text',
138
+ text: 'Done: {{request.title}}',
139
+ variant: 'heading'
140
+ },
141
+ {
142
+ block: 'text',
143
+ text: 'We finished your request. {{request.billing}}',
144
+ variant: 'body'
145
+ },
146
+ {
147
+ block: 'text',
148
+ text: 'What changed: {{request.changes}}\nTime: {{request.minutes}}\nLeft this month: {{month.minutesLeft}}',
149
+ variant: 'details'
150
+ },
151
+ {
152
+ block: 'text',
153
+ text: 'Something not right? Reply to this email and we will fix it.',
154
+ variant: 'caption'
155
+ }
156
+ ],
157
+ footerReason: FOOTER,
158
+ source: SOURCE
159
+ },
160
+ {
161
+ key: SITE_CARE_REQUEST_CORRECTED_EMAIL_KEY,
162
+ name: 'Site Care: time corrected',
163
+ description: 'Sent to the workspace owner when staff correct the minutes on a finished request, with the before and after.',
164
+ deliveredBy: 'resend',
165
+ defaultSubject: 'Corrected: the time on {{request.title}}',
166
+ mergeTokens: [
167
+ ORG_NAME,
168
+ REQUEST_TITLE,
169
+ {
170
+ name: 'correction.before',
171
+ description: 'The time before',
172
+ sample: '75 min'
173
+ },
174
+ {
175
+ name: 'correction.after',
176
+ description: 'The time now',
177
+ sample: '45 min'
178
+ },
179
+ {
180
+ name: 'correction.reason',
181
+ description: 'Why it changed',
182
+ sample: 'The timer ran while we waited for your photos.'
183
+ },
184
+ {
185
+ name: 'request.billing',
186
+ description: 'What bills now, in one sentence',
187
+ sample: 'No extra charge: this now fits in your included hour.'
188
+ },
189
+ {
190
+ name: 'month.minutesLeft',
191
+ description: 'Included time left this month',
192
+ sample: '15 min of this month’s included hour'
193
+ }
194
+ ],
195
+ defaultBody: [
196
+ {
197
+ block: 'text',
198
+ text: 'Site Care · {{org.name}}',
199
+ variant: 'eyebrow'
200
+ },
201
+ {
202
+ block: 'text',
203
+ text: 'We corrected the time on “{{request.title}}”',
204
+ variant: 'heading'
205
+ },
206
+ {
207
+ block: 'text',
208
+ text: '{{correction.reason}} {{request.billing}}',
209
+ variant: 'body'
210
+ },
211
+ {
212
+ block: 'text',
213
+ text: 'Before: {{correction.before}}\nNow: {{correction.after}}\nLeft this month: {{month.minutesLeft}}',
214
+ variant: 'details'
215
+ }
216
+ ],
217
+ footerReason: FOOTER,
218
+ source: SOURCE
219
+ },
220
+ {
221
+ key: SITE_CARE_APPROVAL_EMAIL_KEY,
222
+ name: 'Site Care: extra time approved',
223
+ description: 'Sent to the workspace owner the moment staff record their yes to extra time, and again, marked corrected, when the record is corrected. It is the written record of the approval.',
224
+ deliveredBy: 'resend',
225
+ defaultSubject: '{{approval.heading}}: extra time for {{request.title}}',
226
+ mergeTokens: [
227
+ ORG_NAME,
228
+ REQUEST_TITLE,
229
+ {
230
+ name: 'approval.heading',
231
+ description: '“You approved extra time”, or “Corrected” on a correction',
232
+ sample: 'You approved extra time'
233
+ },
234
+ {
235
+ name: 'approval.sentence',
236
+ description: 'What was approved, how and when',
237
+ sample: 'You approved up to 2 hours of extra time at $79 an hour for “Update our holiday hours”, by phone on Oct 19, 2026, 2:10 PM CDT.'
238
+ },
239
+ {
240
+ name: 'approval.correction',
241
+ description: 'What was corrected and why, on a correction; blank otherwise',
242
+ sample: 'Corrected from 1 hour to 2 hours: the owner asked for the gallery too.'
243
+ }
244
+ ],
245
+ defaultBody: [
246
+ {
247
+ block: 'text',
248
+ text: 'Site Care · {{org.name}}',
249
+ variant: 'eyebrow'
250
+ },
251
+ {
252
+ block: 'text',
253
+ text: '{{approval.heading}}',
254
+ variant: 'heading'
255
+ },
256
+ {
257
+ block: 'text',
258
+ text: '{{approval.sentence}} {{approval.correction}}',
259
+ variant: 'body'
260
+ },
261
+ {
262
+ block: 'text',
263
+ text: 'Extra time is billed in whole hours, rounded up, on your next invoice, and never more than you approved without asking you again. If this is not what you agreed to, reply to this email before we start.',
264
+ variant: 'caption'
265
+ }
266
+ ],
267
+ footerReason: FOOTER,
268
+ source: SOURCE
269
+ },
270
+ {
271
+ key: SITE_CARE_CHARGE_REVERSED_EMAIL_KEY,
272
+ name: 'Site Care: charge removed, credited or refunded',
273
+ description: 'Sent to the workspace owner when staff void, credit or refund an extra-time charge from the request.',
274
+ deliveredBy: 'resend',
275
+ defaultSubject: '{{charge.heading}}: {{request.title}}',
276
+ mergeTokens: [
277
+ ORG_NAME,
278
+ REQUEST_TITLE,
279
+ {
280
+ name: 'charge.heading',
281
+ description: '“Charge removed”, “Charge credited” or “Charge refunded”',
282
+ sample: 'Charge removed'
283
+ },
284
+ {
285
+ name: 'charge.sentence',
286
+ description: 'What happened to the money',
287
+ sample: 'The $79 for 1 hour of extra time will not be on your next invoice.'
288
+ },
289
+ {
290
+ name: 'charge.reason',
291
+ description: 'Why',
292
+ sample: 'We took longer than we should have on this one.'
293
+ }
294
+ ],
295
+ defaultBody: [
296
+ {
297
+ block: 'text',
298
+ text: 'Site Care · {{org.name}}',
299
+ variant: 'eyebrow'
300
+ },
301
+ {
302
+ block: 'text',
303
+ text: '{{charge.heading}}',
304
+ variant: 'heading'
305
+ },
306
+ {
307
+ block: 'text',
308
+ text: '{{charge.sentence}}',
309
+ variant: 'body'
310
+ },
311
+ {
312
+ block: 'text',
313
+ text: 'Request: {{request.title}}\nWhy: {{charge.reason}}',
314
+ variant: 'details'
315
+ }
316
+ ],
317
+ footerReason: FOOTER,
318
+ source: SOURCE
319
+ },
320
+ {
321
+ key: SITE_CARE_STATEMENT_EMAIL_KEY,
322
+ name: 'Site Care: monthly statement',
323
+ description: 'Sent to the workspace owner when staff press Send statement: every request of the month, the minutes, the extra time billed and every correction.',
324
+ deliveredBy: 'resend',
325
+ defaultSubject: 'Your Site Care statement for {{month.label}}',
326
+ mergeTokens: [
327
+ ORG_NAME,
328
+ {
329
+ name: 'month.label',
330
+ description: 'The month',
331
+ sample: 'October 2026'
332
+ },
333
+ {
334
+ name: 'statement.summary',
335
+ description: 'The month in one sentence',
336
+ sample: 'October 2026: 3 requests, 1 h 35 min of work, 60 of 60 included minutes used, 1 hour of extra time billed.'
337
+ },
338
+ {
339
+ name: 'statement.lines',
340
+ description: 'One line per request',
341
+ sample: 'Update our holiday hours: 35 min, included\nNew staff photo: 1 h, 1 hour billed ($79), on your next invoice'
342
+ },
343
+ {
344
+ name: 'statement.history',
345
+ description: 'Everything recorded this month, one dated line each',
346
+ sample: 'Oct 19, 2026, 3:04 PM CDT: Finished “Update our holiday hours”: 35 min.'
347
+ }
348
+ ],
349
+ defaultBody: [
350
+ {
351
+ block: 'text',
352
+ text: 'Site Care · {{org.name}}',
353
+ variant: 'eyebrow'
354
+ },
355
+ {
356
+ block: 'text',
357
+ text: 'Your statement for {{month.label}}',
358
+ variant: 'heading'
359
+ },
360
+ {
361
+ block: 'text',
362
+ text: '{{statement.summary}}',
363
+ variant: 'body'
364
+ },
365
+ {
366
+ block: 'text',
367
+ text: '{{statement.lines}}',
368
+ variant: 'details'
369
+ },
370
+ {
371
+ block: 'text',
372
+ text: 'Everything we recorded',
373
+ variant: 'subheading'
374
+ },
375
+ {
376
+ block: 'text',
377
+ text: '{{statement.history}}',
378
+ variant: 'body'
379
+ }
380
+ ],
381
+ footerReason: FOOTER,
382
+ source: SOURCE
383
+ },
384
+ {
385
+ key: SITE_CARE_QUOTE_EMAIL_KEY,
386
+ name: 'Site Care: bigger than Site Care covers',
387
+ description: 'Sent from a Site Care request by staff when the work adds something new (a page, a form, a design, a campaign): Site Care covers changes to what exists, so this is a flat quote.',
388
+ deliveredBy: 'resend',
389
+ defaultSubject: 'A quote for {{request.title}}',
390
+ mergeTokens: [
391
+ ORG_NAME,
392
+ REQUEST_TITLE,
393
+ {
394
+ name: 'quote.amount',
395
+ description: 'The flat price',
396
+ sample: '$249'
397
+ },
398
+ {
399
+ name: 'quote.scope',
400
+ description: 'What the price covers',
401
+ sample: 'A new landing page for the holiday sale, with a sign-up form.'
402
+ }
403
+ ],
404
+ defaultBody: [
405
+ {
406
+ block: 'text',
407
+ text: 'Site Care · {{org.name}}',
408
+ variant: 'eyebrow'
409
+ },
410
+ {
411
+ block: 'text',
412
+ text: 'This one is bigger than Site Care covers',
413
+ variant: 'heading'
414
+ },
415
+ {
416
+ block: 'text',
417
+ text: 'Site Care covers changes to what your site already has. “{{request.title}}” adds something new, so it is a project with one flat price, fixed once given.',
418
+ variant: 'body'
419
+ },
420
+ {
421
+ block: 'text',
422
+ text: 'Price: {{quote.amount}}\nWhat it covers: {{quote.scope}}',
423
+ variant: 'details'
424
+ },
425
+ {
426
+ block: 'text',
427
+ text: 'Reply to say yes and we will send the invoice to pay from your phone. Nothing is charged until you do.',
428
+ variant: 'caption'
429
+ }
430
+ ],
431
+ footerReason: FOOTER,
432
+ source: SOURCE
433
+ }
434
+ ];
435
+
436
+ //# sourceMappingURL=site-care-emails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/shared/util/email/src/lib/site-care-emails.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*==========================================\n * SITE CARE, AS SYSTEM EMAILS (AGL-3959).\n *\n * A Site Care owner hears about their requests by email, because they do not\n * use the console: that it arrived, that it is done (with what changed and\n * the time it took), that a bigger job needs a quote, that they approved\n * extra time, that a charge was corrected or reversed, and the month's\n * statement on demand. Each is its own key so staff can redesign one\n * without the rest. The merge tokens are what\n * `@aglyn/tenant-data-admin/server/site-care-emails` fills.\n *\n * None answers a sender the intake does not recognize. Site Care mail\n * arrives at the support address (AGL-3997), so such a message is ordinary\n * support mail and the support inbox answers it.\n *=========================================*/\n\nimport type {\n SystemEmailMergeToken,\n SystemEmailTemplateDefinition,\n} from './system-email-catalog'\n\nexport const SITE_CARE_REQUEST_RECEIVED_EMAIL_KEY = 'site-care-request-received'\nexport const SITE_CARE_REQUEST_DONE_EMAIL_KEY = 'site-care-request-done'\nexport const SITE_CARE_REQUEST_CORRECTED_EMAIL_KEY = 'site-care-request-corrected'\nexport const SITE_CARE_APPROVAL_EMAIL_KEY = 'site-care-approval-confirmation'\nexport const SITE_CARE_CHARGE_REVERSED_EMAIL_KEY = 'site-care-charge-reversed'\nexport const SITE_CARE_STATEMENT_EMAIL_KEY = 'site-care-statement'\nexport const SITE_CARE_QUOTE_EMAIL_KEY = 'site-care-quote'\n\nconst SOURCE = 'libs/tenant/data/admin/src/lib/server/site-care-emails.ts'\n\nconst ORG_NAME: SystemEmailMergeToken = {\n name: 'org.name',\n description: 'The workspace the request is for',\n sample: 'Test Org',\n}\nconst REQUEST_TITLE: SystemEmailMergeToken = {\n name: 'request.title',\n description: 'The request, as the owner titled it',\n sample: 'Update our holiday hours',\n}\n\nconst FOOTER =\n 'You’re receiving this because {{org.name}} has Site Care on {{brand.productName}}.'\n\nexport const SITE_CARE_SYSTEM_EMAIL_TEMPLATES: readonly SystemEmailTemplateDefinition[] = [\n {\n key: SITE_CARE_REQUEST_RECEIVED_EMAIL_KEY,\n name: 'Site Care: request received',\n description:\n 'Sent to the person who asked when a Site Care request arrives, by email or from the console.',\n deliveredBy: 'resend',\n defaultSubject: 'We have your request: {{request.title}}',\n mergeTokens: [\n ORG_NAME,\n REQUEST_TITLE,\n {\n name: 'request.message',\n description: 'What they asked for',\n sample: 'Please change Saturday to 9 to 2 for December.',\n },\n {\n name: 'request.due',\n description: 'When it will be done at the latest',\n sample: 'Wednesday, October 21',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Site Care · {{org.name}}', variant: 'eyebrow' },\n { block: 'text', text: 'We have your request', variant: 'heading' },\n {\n block: 'text',\n text: 'Thanks. We received “{{request.title}}” and will have it done by {{request.due}}. Reply to this email to add anything, and it joins the same request.',\n variant: 'body',\n },\n { block: 'text', text: 'Request: {{request.title}}\\nDone by: {{request.due}}', variant: 'details' },\n { block: 'text', text: '{{request.message}}', variant: 'body' },\n ],\n footerReason: FOOTER,\n source: SOURCE,\n },\n {\n key: SITE_CARE_REQUEST_DONE_EMAIL_KEY,\n name: 'Site Care: request done',\n description:\n 'Sent to the workspace owner when staff close a Site Care request: what changed, the time it took, the time left this month, or the extra time billed.',\n deliveredBy: 'resend',\n defaultSubject: 'Done: {{request.title}}',\n mergeTokens: [\n ORG_NAME,\n REQUEST_TITLE,\n {\n name: 'request.changes',\n description: 'What changed, from the request and the publish that shipped it',\n sample: 'Published “Home” on Oct 19, 2026, 3:04 PM CDT',\n },\n { name: 'request.minutes', description: 'The time it took', sample: '35 min' },\n {\n name: 'month.minutesLeft',\n description: 'Included time left this month',\n sample: '25 min of this month’s included hour',\n },\n {\n name: 'request.billing',\n description: 'Whether anything bills, in one sentence',\n sample: 'No extra charge: this fit in your included hour.',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Site Care · {{org.name}}', variant: 'eyebrow' },\n { block: 'text', text: 'Done: {{request.title}}', variant: 'heading' },\n { block: 'text', text: 'We finished your request. {{request.billing}}', variant: 'body' },\n {\n block: 'text',\n text: 'What changed: {{request.changes}}\\nTime: {{request.minutes}}\\nLeft this month: {{month.minutesLeft}}',\n variant: 'details',\n },\n {\n block: 'text',\n text: 'Something not right? Reply to this email and we will fix it.',\n variant: 'caption',\n },\n ],\n footerReason: FOOTER,\n source: SOURCE,\n },\n {\n key: SITE_CARE_REQUEST_CORRECTED_EMAIL_KEY,\n name: 'Site Care: time corrected',\n description:\n 'Sent to the workspace owner when staff correct the minutes on a finished request, with the before and after.',\n deliveredBy: 'resend',\n defaultSubject: 'Corrected: the time on {{request.title}}',\n mergeTokens: [\n ORG_NAME,\n REQUEST_TITLE,\n { name: 'correction.before', description: 'The time before', sample: '75 min' },\n { name: 'correction.after', description: 'The time now', sample: '45 min' },\n {\n name: 'correction.reason',\n description: 'Why it changed',\n sample: 'The timer ran while we waited for your photos.',\n },\n {\n name: 'request.billing',\n description: 'What bills now, in one sentence',\n sample: 'No extra charge: this now fits in your included hour.',\n },\n {\n name: 'month.minutesLeft',\n description: 'Included time left this month',\n sample: '15 min of this month’s included hour',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Site Care · {{org.name}}', variant: 'eyebrow' },\n { block: 'text', text: 'We corrected the time on “{{request.title}}”', variant: 'heading' },\n { block: 'text', text: '{{correction.reason}} {{request.billing}}', variant: 'body' },\n {\n block: 'text',\n text: 'Before: {{correction.before}}\\nNow: {{correction.after}}\\nLeft this month: {{month.minutesLeft}}',\n variant: 'details',\n },\n ],\n footerReason: FOOTER,\n source: SOURCE,\n },\n {\n key: SITE_CARE_APPROVAL_EMAIL_KEY,\n name: 'Site Care: extra time approved',\n description:\n 'Sent to the workspace owner the moment staff record their yes to extra time, and again, marked corrected, when the record is corrected. It is the written record of the approval.',\n deliveredBy: 'resend',\n defaultSubject: '{{approval.heading}}: extra time for {{request.title}}',\n mergeTokens: [\n ORG_NAME,\n REQUEST_TITLE,\n {\n name: 'approval.heading',\n description: '“You approved extra time”, or “Corrected” on a correction',\n sample: 'You approved extra time',\n },\n {\n name: 'approval.sentence',\n description: 'What was approved, how and when',\n sample:\n 'You approved up to 2 hours of extra time at $79 an hour for “Update our holiday hours”, by phone on Oct 19, 2026, 2:10 PM CDT.',\n },\n {\n name: 'approval.correction',\n description: 'What was corrected and why, on a correction; blank otherwise',\n sample: 'Corrected from 1 hour to 2 hours: the owner asked for the gallery too.',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Site Care · {{org.name}}', variant: 'eyebrow' },\n { block: 'text', text: '{{approval.heading}}', variant: 'heading' },\n { block: 'text', text: '{{approval.sentence}} {{approval.correction}}', variant: 'body' },\n {\n block: 'text',\n text: 'Extra time is billed in whole hours, rounded up, on your next invoice, and never more than you approved without asking you again. If this is not what you agreed to, reply to this email before we start.',\n variant: 'caption',\n },\n ],\n footerReason: FOOTER,\n source: SOURCE,\n },\n {\n key: SITE_CARE_CHARGE_REVERSED_EMAIL_KEY,\n name: 'Site Care: charge removed, credited or refunded',\n description:\n 'Sent to the workspace owner when staff void, credit or refund an extra-time charge from the request.',\n deliveredBy: 'resend',\n defaultSubject: '{{charge.heading}}: {{request.title}}',\n mergeTokens: [\n ORG_NAME,\n REQUEST_TITLE,\n {\n name: 'charge.heading',\n description: '“Charge removed”, “Charge credited” or “Charge refunded”',\n sample: 'Charge removed',\n },\n {\n name: 'charge.sentence',\n description: 'What happened to the money',\n sample: 'The $79 for 1 hour of extra time will not be on your next invoice.',\n },\n {\n name: 'charge.reason',\n description: 'Why',\n sample: 'We took longer than we should have on this one.',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Site Care · {{org.name}}', variant: 'eyebrow' },\n { block: 'text', text: '{{charge.heading}}', variant: 'heading' },\n { block: 'text', text: '{{charge.sentence}}', variant: 'body' },\n { block: 'text', text: 'Request: {{request.title}}\\nWhy: {{charge.reason}}', variant: 'details' },\n ],\n footerReason: FOOTER,\n source: SOURCE,\n },\n {\n key: SITE_CARE_STATEMENT_EMAIL_KEY,\n name: 'Site Care: monthly statement',\n description:\n 'Sent to the workspace owner when staff press Send statement: every request of the month, the minutes, the extra time billed and every correction.',\n deliveredBy: 'resend',\n defaultSubject: 'Your Site Care statement for {{month.label}}',\n mergeTokens: [\n ORG_NAME,\n { name: 'month.label', description: 'The month', sample: 'October 2026' },\n {\n name: 'statement.summary',\n description: 'The month in one sentence',\n sample: 'October 2026: 3 requests, 1 h 35 min of work, 60 of 60 included minutes used, 1 hour of extra time billed.',\n },\n {\n name: 'statement.lines',\n description: 'One line per request',\n sample:\n 'Update our holiday hours: 35 min, included\\nNew staff photo: 1 h, 1 hour billed ($79), on your next invoice',\n },\n {\n name: 'statement.history',\n description: 'Everything recorded this month, one dated line each',\n sample: 'Oct 19, 2026, 3:04 PM CDT: Finished “Update our holiday hours”: 35 min.',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Site Care · {{org.name}}', variant: 'eyebrow' },\n { block: 'text', text: 'Your statement for {{month.label}}', variant: 'heading' },\n { block: 'text', text: '{{statement.summary}}', variant: 'body' },\n { block: 'text', text: '{{statement.lines}}', variant: 'details' },\n { block: 'text', text: 'Everything we recorded', variant: 'subheading' },\n { block: 'text', text: '{{statement.history}}', variant: 'body' },\n ],\n footerReason: FOOTER,\n source: SOURCE,\n },\n {\n key: SITE_CARE_QUOTE_EMAIL_KEY,\n name: 'Site Care: bigger than Site Care covers',\n description:\n 'Sent from a Site Care request by staff when the work adds something new (a page, a form, a design, a campaign): Site Care covers changes to what exists, so this is a flat quote.',\n deliveredBy: 'resend',\n defaultSubject: 'A quote for {{request.title}}',\n mergeTokens: [\n ORG_NAME,\n REQUEST_TITLE,\n { name: 'quote.amount', description: 'The flat price', sample: '$249' },\n {\n name: 'quote.scope',\n description: 'What the price covers',\n sample: 'A new landing page for the holiday sale, with a sign-up form.',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Site Care · {{org.name}}', variant: 'eyebrow' },\n { block: 'text', text: 'This one is bigger than Site Care covers', variant: 'heading' },\n {\n block: 'text',\n text: 'Site Care covers changes to what your site already has. “{{request.title}}” adds something new, so it is a project with one flat price, fixed once given.',\n variant: 'body',\n },\n { block: 'text', text: 'Price: {{quote.amount}}\\nWhat it covers: {{quote.scope}}', variant: 'details' },\n {\n block: 'text',\n text: 'Reply to say yes and we will send the invoice to pay from your phone. Nothing is charged until you do.',\n variant: 'caption',\n },\n ],\n footerReason: FOOTER,\n source: SOURCE,\n },\n]\n"],"names":["SITE_CARE_REQUEST_RECEIVED_EMAIL_KEY","SITE_CARE_REQUEST_DONE_EMAIL_KEY","SITE_CARE_REQUEST_CORRECTED_EMAIL_KEY","SITE_CARE_APPROVAL_EMAIL_KEY","SITE_CARE_CHARGE_REVERSED_EMAIL_KEY","SITE_CARE_STATEMENT_EMAIL_KEY","SITE_CARE_QUOTE_EMAIL_KEY","SOURCE","ORG_NAME","name","description","sample","REQUEST_TITLE","FOOTER","SITE_CARE_SYSTEM_EMAIL_TEMPLATES","key","deliveredBy","defaultSubject","mergeTokens","defaultBody","block","text","variant","footerReason","source"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { SystemEmailTemplateDefinition } from './system-email-catalog';
18
+ export declare const SITE_CARE_PROJECT_ACCEPTANCE_EMAIL_KEY = "site-care-project-acceptance";
19
+ export declare const SITE_CARE_PROJECT_INVOICE_EMAIL_KEY = "site-care-project-invoice";
20
+ export declare const SITE_CARE_PROJECT_PAID_EMAIL_KEY = "site-care-project-paid";
21
+ export declare const SITE_CARE_PROJECT_REVERSED_EMAIL_KEY = "site-care-project-reversed";
22
+ export declare const SITE_CARE_PROJECT_SYSTEM_EMAIL_TEMPLATES: readonly SystemEmailTemplateDefinition[];