@antelopejs/dms-mailing 0.5.0 → 0.6.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.
Files changed (106) hide show
  1. package/README.md +61 -339
  2. package/dist/data/templates-table.js +2 -10
  3. package/dist/data/templates-table.js.map +1 -1
  4. package/dist/db/models/index.d.ts +1 -0
  5. package/dist/db/models/index.js +1 -0
  6. package/dist/db/models/index.js.map +1 -1
  7. package/dist/db/models/send-events.model.d.ts +2 -0
  8. package/dist/db/models/send-events.model.js +11 -0
  9. package/dist/db/models/send-events.model.js.map +1 -1
  10. package/dist/db/models/sends.model.d.ts +3 -0
  11. package/dist/db/models/sends.model.js +13 -0
  12. package/dist/db/models/sends.model.js.map +1 -1
  13. package/dist/db/models/settings.model.d.ts +1 -0
  14. package/dist/db/models/suppressions.model.d.ts +1 -0
  15. package/dist/db/models/template-slugs.model.d.ts +27 -0
  16. package/dist/db/models/template-slugs.model.js +43 -0
  17. package/dist/db/models/template-slugs.model.js.map +1 -0
  18. package/dist/db/models/template-versions.model.d.ts +4 -1
  19. package/dist/db/models/template-versions.model.js +35 -2
  20. package/dist/db/models/template-versions.model.js.map +1 -1
  21. package/dist/db/models/templates.model.d.ts +2 -0
  22. package/dist/db/models/templates.model.js +22 -0
  23. package/dist/db/models/templates.model.js.map +1 -1
  24. package/dist/db/models/webhook-status.model.d.ts +1 -0
  25. package/dist/db/tables/index.d.ts +1 -0
  26. package/dist/db/tables/index.js +1 -0
  27. package/dist/db/tables/index.js.map +1 -1
  28. package/dist/db/tables/settings.table.d.ts +1 -0
  29. package/dist/db/tables/settings.table.js +4 -0
  30. package/dist/db/tables/settings.table.js.map +1 -1
  31. package/dist/db/tables/template-slugs.table.d.ts +7 -0
  32. package/dist/db/tables/template-slugs.table.js +35 -0
  33. package/dist/db/tables/template-slugs.table.js.map +1 -0
  34. package/dist/db/tables/templates.table.d.ts +5 -0
  35. package/dist/db/tables/templates.table.js +27 -0
  36. package/dist/db/tables/templates.table.js.map +1 -1
  37. package/dist/hooks/database-ready.d.ts +7 -0
  38. package/dist/hooks/database-ready.js +26 -0
  39. package/dist/hooks/database-ready.js.map +1 -0
  40. package/dist/hooks/index.d.ts +1 -0
  41. package/dist/hooks/index.js +1 -0
  42. package/dist/hooks/index.js.map +1 -1
  43. package/dist/implementations/dms-mailing/index.d.ts +3 -0
  44. package/dist/implementations/dms-mailing/index.js +7 -1
  45. package/dist/implementations/dms-mailing/index.js.map +1 -1
  46. package/dist/index.js +1 -0
  47. package/dist/index.js.map +1 -1
  48. package/dist/routes/templates.js +1 -0
  49. package/dist/routes/templates.js.map +1 -1
  50. package/dist/services/declaration-error.d.ts +6 -0
  51. package/dist/services/declaration-error.js +26 -0
  52. package/dist/services/declaration-error.js.map +1 -0
  53. package/dist/services/declarations.d.ts +3 -0
  54. package/dist/services/declarations.js +244 -0
  55. package/dist/services/declarations.js.map +1 -0
  56. package/dist/services/events.d.ts +4 -1
  57. package/dist/services/events.js.map +1 -1
  58. package/dist/services/fingerprint.d.ts +1 -0
  59. package/dist/services/fingerprint.js +20 -0
  60. package/dist/services/fingerprint.js.map +1 -0
  61. package/dist/services/send-import.d.ts +2 -0
  62. package/dist/services/send-import.js +136 -0
  63. package/dist/services/send-import.js.map +1 -0
  64. package/dist/services/templates.d.ts +3 -0
  65. package/dist/services/templates.js +75 -48
  66. package/dist/services/templates.js.map +1 -1
  67. package/dist/validation/declarations.schema.d.ts +299 -0
  68. package/dist/validation/declarations.schema.js +55 -0
  69. package/dist/validation/declarations.schema.js.map +1 -0
  70. package/frontend-vue/app/components/CategoriesInput.vue +12 -11
  71. package/frontend-vue/app/components/editor/EditorBlockList.vue +33 -30
  72. package/frontend-vue/app/components/editor/EditorPaletteGroup.vue +14 -14
  73. package/frontend-vue/app/composables/useSortableList.ts +159 -0
  74. package/frontend-vue/app/utils/blocks/dnd.ts +2 -0
  75. package/frontend-vue/i18n/locales/mailing-en-GB.json +1 -1
  76. package/frontend-vue/i18n/locales/mailing-fr-FR.json +1 -1
  77. package/frontend-vue/package.json +4 -3
  78. package/frontend-vue/pnpm-lock.yaml +6 -13
  79. package/frontend-vue/tests/editor-block-list.test.ts +46 -6
  80. package/frontend-vue/tests/sortable-list.test.ts +253 -0
  81. package/package.json +31 -14
  82. package/skills/dms-mailing/SKILL.md +101 -0
  83. package/src/data/templates-table.ts +7 -27
  84. package/src/db/models/index.ts +1 -0
  85. package/src/db/models/send-events.model.ts +13 -0
  86. package/src/db/models/sends.model.ts +22 -0
  87. package/src/db/models/template-slugs.model.ts +61 -0
  88. package/src/db/models/template-versions.model.ts +48 -2
  89. package/src/db/models/templates.model.ts +31 -0
  90. package/src/db/tables/index.ts +1 -0
  91. package/src/db/tables/settings.table.ts +8 -0
  92. package/src/db/tables/template-slugs.table.ts +29 -0
  93. package/src/db/tables/templates.table.ts +38 -0
  94. package/src/hooks/database-ready.ts +47 -0
  95. package/src/hooks/index.ts +1 -0
  96. package/src/implementations/dms-mailing/index.ts +17 -0
  97. package/src/index.ts +6 -1
  98. package/src/routes/templates.ts +2 -0
  99. package/src/services/declaration-error.ts +39 -0
  100. package/src/services/declarations.ts +450 -0
  101. package/src/services/events.ts +8 -2
  102. package/src/services/fingerprint.ts +22 -0
  103. package/src/services/send-import.ts +235 -0
  104. package/src/services/templates.ts +113 -72
  105. package/src/validation/declarations.schema.ts +77 -0
  106. package/frontend-vue/pnpm-workspace.yaml +0 -2
package/README.md CHANGED
@@ -1,374 +1,96 @@
1
- # @antelopejs/dms-mailing
2
-
3
1
  <div align="center">
4
- <a href="./LICENSE"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-blue?style=for-the-badge&labelColor=000000"></a>
5
- <a href="https://discord.gg/sjK28QHrA7"><img src="https://img.shields.io/badge/Discord-18181B?logo=discord&style=for-the-badge&color=000000" alt="Discord"></a>
6
- <a href="https://antelopejs.com"><img src="https://img.shields.io/badge/Docs-18181B?style=for-the-badge&color=000000" alt="Documentation"></a>
7
- </div>
8
-
9
- Mailing module for the AntelopeJS DMS: a template library with a block-based
10
- e-mail editor, drafts and published versions, a send log, an overview
11
- dashboard and settings. It owns the data (tenant-scoped Mongo tables), renders
12
- e-mails through the DMS html-render chain and sends them through
13
- `@antelopejs/interface-email`.
14
-
15
- The module targets `@antelopejs/dms` 0.9, `@antelopejs/interface-dms` 0.7 and `@antelopejs/dms-frontend` 0.6. Every read goes through the DMS's `useApiData`: what a page renders is read by the server render and handed to the browser; what a drawer, a dialog, a preview frame or the editor shows is read when it opens or asks (`immediate: false`, `useMailingReads`).
16
- Like every DMS module, its pages live in the module's own sidebar (Mailing:
17
- Overview, Templates, Sends; Configure: Settings, Suppression list) and are
18
- reserved to the platform owner. The design decisions behind the v2 screens are recorded in
19
- [`docs/design-v2-grill-me.md`](../../docs/design-v2-grill-me.md).
20
-
21
- ## Breaking changes since 0.3
22
-
23
- The v2 redesign neither reads what 0.3.x wrote nor takes its calls:
24
-
25
- - **Webhook URL.** `POST /api/mailing/events/<provider>`, with the tenant in
26
- the body, is gone. Copy the URL **Settings › Provider & webhook** shows
27
- (`/api/mailing/events/<provider>/<tenantId>`) into the provider again.
28
- - **Settings writes.** `POST /api/mailing/settings` is gone: send the changed
29
- fields with `PUT /api/mailing/settings`. A write carrying a read-only field
30
- (`webhookUrl`, `provider`) is refused.
31
- - **Categories.** The settings take `categories` as an array only, no longer
32
- as its JSON text, and always with the `marketing` category (it can be
33
- renamed, not removed: campaign rules depend on it).
34
- - **Interface.** The module implements `@antelopejs/interface-dms-mailing`
35
- 0.7, whose `SendStatus` adds `suppressed`.
36
- - **Data.** A 0.3.x database is not read any more (settings rows without the
37
- tenant key, templates without version numbers, sends without a stage):
38
- start the module on an empty database.
39
2
 
40
- ## Drafts and versions
41
-
42
- The editor never changes what customers receive. It saves a draft next to the
43
- published content; **Publish** turns the draft into the next version, keeps
44
- it in `mailing_template_versions` and makes it what `SendTemplate` sends.
45
- **Discard** drops the draft. Test sends use the draft (their subject starts
46
- with `[TEST]`), real sends always use the published version, and every send
47
- records the version it used and the locale the caller asked for, so the log
48
- can render exactly what went out and show `DE → EN` fallbacks.
49
-
50
- ## Layout
51
-
52
- | Path | What it holds |
53
- | --- | --- |
54
- | `src/index.ts` | Module lifecycle (`construct`/`start`/`stop`/`destroy`); registers the Vue frontend module, the automation nodes, the tenant-export contributor, the realtime topics and the crons. |
55
- | `src/pages/` | The DMS pages: `overview`, `templates`, the editor (`templates/:id`), `sends`, `settings` and `suppressions`, all inside the module sidebar. Every custom block carries a `.meta()` with i18n keys. |
56
- | `src/data/` | The `TableView` data controllers behind `/api/mailing/tables/*`. |
57
- | `src/routes/` | The HTTP API under `/api/mailing` (templates, sends, events, metrics, settings, provider, suppressions). |
58
- | `src/engine/` | The pure-TS rendering engine: block tree + variables → resolved e-mail. |
59
- | `../interface-dms-mailing/` | The separately published public AntelopeJS interface (see below). |
60
- | `src/automation/` | The `dms-automation` action and trigger. |
61
- | `src/crons/` | The daily, replay-safe send-log retention job and the hourly refresh of the templates needing attention. |
62
- | `src/hooks/` | The tenant data export contributor. |
63
- | `frontend-vue/` | Vue module registered under the `Mailing` component prefix: gallery display, template and send drawers, test / real send dialogs, the three-pane block editor, the overview and settings blocks, `dms.email.ts` server template entry and the `mailing-*.json` i18n catalogs. Its own composables and utils are imported by path, not auto-imported. |
64
- | `playground/` | Standalone AntelopeJS project wiring this module to the DMS, Mongo, the API server and the mailer, for local development. |
65
-
66
- ## Public interface
3
+ # @antelopejs/dms-mailing
67
4
 
68
- Published as `@antelopejs/interface-dms-mailing`.
5
+ <a href="https://www.npmjs.com/package/@antelopejs/dms-mailing"><img alt="npm" src="https://img.shields.io/npm/v/@antelopejs/dms-mailing?style=for-the-badge&labelColor=000000&color=000000"></a>
6
+ <a href="./LICENSE"><img alt="License" src="https://img.shields.io/npm/l/@antelopejs/dms-mailing?style=for-the-badge&labelColor=000000&color=000000"></a>
7
+ <a href="https://discord.gg/sjK28QHrA7"><img alt="Discord" src="https://img.shields.io/badge/Discord-18181B?logo=discord&style=for-the-badge&color=000000"></a>
8
+ <a href="https://dms.antelopejs.com/docs/modules/mailing"><img alt="Documentation" src="https://img.shields.io/badge/Docs-18181B?style=for-the-badge&color=000000"></a>
69
9
 
70
- ```ts
71
- import {
72
- RecordEmailEvent,
73
- SendTemplate,
74
- } from "@antelopejs/interface-dms-mailing";
10
+ E-mail templates, sends and delivery metrics for the AntelopeJS DMS.
75
11
 
76
- // Render a live template and send it.
77
- const result = await SendTemplate("order-confirmation", {
78
- tenantId,
79
- to: [{ email: "sofie@example.com", name: "Sofie" }],
80
- locale: "fr",
81
- variables: { order: { total: "48.00" } },
82
- source: "checkout",
83
- });
84
-
85
- // Report a provider event against the send it belongs to.
86
- await RecordEmailEvent(tenantId, {
87
- provider: "brevo",
88
- messageId,
89
- type: "bounced",
90
- details: { reason: "mailbox full" },
91
- });
92
- ```
12
+ </div>
93
13
 
94
- `SendTemplate` accepts one address or an array. With more than one recipient
95
- and a provider that advertises `features.batch`, the module renders the e-mail
96
- once and issues a single `SendBatch`; otherwise it loops `Send`. Either way one
97
- row per recipient lands in the send log, and the returned
98
- `SendTemplateResult` describes the first one.
14
+ ![The Mailing overview: reach, engagement and list health for the last 30 days](https://raw.githubusercontent.com/AntelopeJS/dms-mailing/main/packages/dms-mailing/docs/images/overview.png)
99
15
 
100
- A recipient on the [suppression list](#suppression-list) gets nothing: its
101
- row in the log and its entry in `results` have the status `suppressed`, and
102
- `error` names the reason as an i18n key
103
- (`$dms_mailing.errors.suppressed.hard_bounce`, `….complaint`,
104
- `….unsubscribe`, `….manual`). Do not retry such a send.
16
+ ## What it does
105
17
 
106
- ## What a recipient receives
18
+ - Designs e-mail templates in a block editor, with typed variables, conditions, lists and live test data.
19
+ - Keeps edits in draft and publishes them as versions, in several locales.
20
+ - Sends a template by its slug from your code, an automation or the dashboard, through any `@antelopejs/interface-email` provider.
21
+ - Logs every send with the provider's timeline, and turns delivery, open and click events into an overview.
22
+ - Protects your sender reputation with a suppression list fed by bounces, complaints and unsubscriptions.
107
23
 
108
- Every e-mail goes out as HTML and as a plain-text part generated from the
109
- same blocks (`multipart/alternative`), with a `viewport` meta. The header logo
110
- is the DMS branding's light logo (`branding.logo.default.light`) at an
111
- absolute public URL (the DMS `clientBaseUrl`): on a `localhost`, private-IP or
112
- `.local` address, or for an SVG (refused by Gmail and Outlook), it is left out
113
- rather than shown broken. The editor canvas draws the same header and footer.
24
+ ## Install
114
25
 
115
- **Footer links are system variables.** A footer whose unsubscribe or
116
- preferences label is filled (or a `{{unsubscribeUrl}}` / `{{preferencesUrl}}`
117
- token anywhere) declares `unsubscribeUrl` / `preferencesUrl` as variables of
118
- type `url`, required when the template is in the `marketing` category. The
119
- editor shows them in the Variables tab, the template drawer in its contract and
120
- its "Call it from code" snippet; pass them in `variables` at send time:
26
+ Run the AntelopeJS CLI from the root of a project that already loads `@antelopejs/dms`, and add an e-mail provider if the project has none:
121
27
 
122
- ```ts
123
- await SendTemplate("newsletter-october", {
124
- tenantId,
125
- to: "ana@example.com",
126
- variables: {
127
- unsubscribeUrl: `https://app.example.com/unsubscribe/${token}`,
128
- preferencesUrl: "https://app.example.com/preferences",
129
- },
130
- });
28
+ ```bash
29
+ ajs project modules add @antelopejs/dms-mailing
30
+ ajs project modules add @antelopejs/nodemailer
131
31
  ```
132
32
 
133
- A link whose URL is missing is dropped from the e-mail, and an empty label
134
- removes the link. For a marketing template, a missing required URL refuses a
135
- manual real send, and every send when "Missing variables" is set to refuse;
136
- a test send never waits for it. The starters and the templates of the other
137
- categories get a footer with a legal line and no unsubscribe link.
138
-
139
- ## Suppression list
140
-
141
- An address goes on the workspace's suppression list (`mailing_suppressions`)
142
- when the provider reports a permanent bounce (a `bounced` event that is not
143
- temporary: no `4xx` / `4.x.x` answer, no `soft` bounce type), a spam
144
- complaint (`spam`) or an unsubscription (`unsubscribed`), or when someone adds
145
- it by hand. A test send only adds its address on a permanent bounce: a spam
146
- report or an unsubscription on a test is the editor's own gesture.
147
-
148
- Every send path checks the list: `SendTemplate`, the automation action, the
149
- real send dialog, "Send again" and "Send to another address". A suppressed
150
- recipient is logged with the status `suppressed` (the Sends page has a tab for
151
- them, and the figures leave them out) and nothing is handed to the provider.
152
- A test send to the editor's own address still goes out, and the dialog warns
153
- that the address is suppressed; a test to any other suppressed address does
154
- not.
33
+ ## Quick start
155
34
 
156
- **Configure › Suppression list** lists the addresses with their reason and
157
- the send that caused it, searchable and filtered by reason. **Add an
158
- address** puts one on the list by hand (with an optional note); **Reactivate**
159
- lifts it, and the next send reaches it again. The same operations are
160
- `POST /api/mailing/suppressions` (`{ "email", "note"? }`, `409` when the
161
- address is already on the list) and `DELETE /api/mailing/suppressions/:id`.
162
- The tenant data export carries the list as `suppressions.json`.
163
-
164
- ## Configuration
165
-
166
- The module takes one option, in the `config` of its entry in the project's
167
- `antelope.config.ts`:
35
+ In development, send to a throwaway Ethereal inbox:
168
36
 
169
37
  ```ts
170
- config: {
171
- // false renders with the module's own fallback HTML, not the DMS chain.
172
- useHtmlRender: true,
38
+ // antelope.config.ts
39
+ nodemailer: {
40
+ source: { type: "package", package: "@antelopejs/nodemailer", version: ">=0.0.5 <1.0.0" },
41
+ config: { ethereal: true },
173
42
  },
174
43
  ```
175
44
 
176
- The webhook URL of **Settings › Provider & webhook** starts with the DMS
177
- `clientBaseUrl`, the dashboard's public origin (read through
178
- `GetClientBaseUrl`): set it in the `dms` module's config as soon as a real
179
- provider has to reach the webhook. The module declares the route a public
180
- endpoint of the dashboard, so the frontend server's proxy lets a provider's
181
- `POST` through without an `Origin`, never sends it a session and relays the
182
- `x-mailing-webhook-secret` header. The URL never follows the headers of the
183
- request that reads it. A provider already posting to the API origin
184
- (`apiBaseUrl`) keeps working: the path and the header are the same.
185
-
186
- ## Webhook contract
187
-
188
- The module has one generic event format. Provider events are posted to
189
-
190
- ```
191
- POST <clientBaseUrl>/api/mailing/events/<provider>/<tenantId>
192
- ```
193
-
194
- the URL **Settings › Provider & webhook** shows, ready to copy. `<provider>`
195
- is a free label recorded with the event (the settings use the configured
196
- e-mail provider's name); `<tenantId>` names the workspace.
197
-
198
- Every request carries the workspace's secret in the `x-mailing-webhook-secret`
199
- header (Settings › Provider & webhook; rotating it invalidates the old one at
200
- once). The body is JSON:
201
-
202
- ```sh
203
- curl -X POST https://dms.example.com/api/mailing/events/postmark/<tenantId> \
204
- -H "Content-Type: application/json" \
205
- -H "x-mailing-webhook-secret: <secret>" \
206
- -d '{"messageId":"<provider message id>","type":"bounced","at":"2026-09-09T10:00:00.000Z","details":{"reason":"550 5.1.1 No such user","bounceType":"hard","eventId":"<provider event id>"}}'
207
- ```
208
-
209
- | Field | Meaning |
210
- | --- | --- |
211
- | `messageId` | The id the provider returned when the e-mail was sent (the send's `providerMessageId`). Required. |
212
- | `type` | `queued`, `sent`, `delivered`, `opened`, `clicked`, `bounced`, `spam`, `failed` or `unsubscribed`. Required. |
213
- | `at` | When it happened (ISO date); now by default. |
214
- | `details.reason` | The provider's words (`550 5.1.1 …`), shown in the log. |
215
- | `details.bounceType` | `soft`/`transient`/`temporary` or `hard`/`permanent`; without it the SMTP class of `reason` decides. A permanent bounce suppresses the address. |
216
- | `details.eventId` | The provider's event id: a retried webhook with the same id is ignored. |
217
- | `details.url`, `details.userAgent` | Shown on the click and open steps. |
218
-
219
- The answer is `200 {"recorded": true}`, or `{"recorded": false}` when no send
220
- carries the message id (or the event was already recorded). The event is
221
- appended to the send's timeline, the status only ever moves forward (a
222
- delivery after a provider failure wins over it), a hard bounce, a spam report
223
- or an unsubscription puts the address on the suppression list, and repeated
224
- problems on a template notify the tenant owners in the DMS bell.
225
-
226
- A refused call gets a readable JSON body, for the relay's logs:
227
-
228
- | Status | `reason` | Why |
229
- | --- | --- | --- |
230
- | `403` | `missing_secret` | No `x-mailing-webhook-secret` header. |
231
- | `403` | `bad_secret` | The header does not match the workspace's secret, or the workspace has no mailing settings yet (any mailing page or send creates them). |
232
- | `400` | `invalid_event` | The secret is right but the body is not an event. |
233
-
234
- ```json
235
- { "error": "webhook_refused", "reason": "bad_secret", "message": "The x-mailing-webhook-secret header does not match …" }
236
- ```
237
-
238
- The secret is checked before the body, so a caller without it learns nothing
239
- of the format. **Settings › Provider & webhook › Webhook status** shows the
240
- last event received (when, its type, the provider label, whether it matched a
241
- send) and the last call refused (when, and why). **Send a test event** posts a
242
- test event to the URL shown, with the stored secret, from the backend: it
243
- proves the URL is reachable from the server, the secret and the format, and
244
- touches no send (its message id is `dms-mailing-webhook-test`).
245
-
246
- ### Relaying a provider
247
-
248
- Providers post their own format (Postmark, SES through SNS, Mailgun,
249
- SendGrid, Resend…) and most cannot add a custom header. Put a small relay
250
- between them and the module: it checks the provider's own signature,
251
- translates each event and forwards it with the secret. A sketch for Postmark:
45
+ Restart the backend, then the frontend, and open **Modules › Mailing** (`/modules/mailing/overview`). Create a template from a starter such as **Order confirmation**, publish it, then send it from any module through [`@antelopejs/interface-dms-mailing`](https://github.com/AntelopeJS/dms-mailing/tree/main/packages/interface-dms-mailing):
252
46
 
253
47
  ```ts
254
- const TYPES: Record<string, string> = {
255
- Delivery: "delivered",
256
- Open: "opened",
257
- Click: "clicked",
258
- Bounce: "bounced",
259
- SpamComplaint: "spam",
260
- SubscriptionChange: "unsubscribed",
261
- };
48
+ import { SendTemplate } from "@antelopejs/interface-dms-mailing";
262
49
 
263
- export async function relayPostmark(event: PostmarkEvent): Promise<void> {
264
- const type = TYPES[event.RecordType];
265
- if (!type) return;
266
- await fetch(MAILING_WEBHOOK_URL, {
267
- method: "POST",
268
- headers: {
269
- "content-type": "application/json",
270
- "x-mailing-webhook-secret": MAILING_WEBHOOK_SECRET,
271
- },
272
- body: JSON.stringify({
273
- messageId: event.MessageID,
274
- type,
275
- at: event.ReceivedAt ?? event.DeliveredAt ?? event.BouncedAt,
276
- details: {
277
- reason: event.Details ?? event.Description,
278
- bounceType: event.Type === "SoftBounce" ? "soft" : "hard",
279
- eventId: String(event.ID ?? ""),
280
- url: event.OriginalLink,
281
- userAgent: event.UserAgent,
282
- },
283
- }),
284
- });
285
- }
50
+ await SendTemplate("order-confirmation", {
51
+ tenantId,
52
+ to: "sofie@example.com",
53
+ variables: { order: { total: "48.00" } },
54
+ });
286
55
  ```
287
56
 
288
- A module of the same project can skip HTTP altogether and call
289
- `RecordEmailEvent(tenantId, event)` from the public interface. A provider or
290
- a relay posts through the dashboard's URL, as a public endpoint the module
291
- declares (`AddFrontendModule({ publicEndpoints })`), or straight to the API on
292
- `apiBaseUrl` when it is reachable: the path and the header are the same.
293
-
294
- ## Retention
295
-
296
- The daily sweep retires sends only when their creation time, latest event time
297
- and latest ingested activity all precede the tenant's retention cutoff. Queued
298
- sends remain active. Retirement irreversibly closes a send to provider events;
299
- the sweep then removes its events and finally the send. A failed cleanup leaves
300
- the retirement marker available for another sweep to resume.
57
+ ## Compatibility
301
58
 
302
- Concurrent sweeps require no shared cron lock. Send mutations use the database
303
- interface's `Table.atomicMutation` revision contract. Retirement rechecks the
304
- send's age and activity before comparing its revision; concurrent webhook
305
- activity advances that revision and invalidates the stale candidate. Known
306
- webhook conflicts reread and recompute counters, with a bounded retry limit.
307
- An unknown write outcome fails without retrying or reporting a deletion.
308
-
309
- This requires the atomic-mutation interface and adapter implementations; generic
310
- filtered updates and deletes are not an alternative. The dependency releases
311
- are prerequisites for rollout. Every send is inserted with a unique identity and
312
- revision, stored in the declared `revision` column.
313
-
314
- Each sweep inspects at most 20,000 send candidates per tenant and reports only
315
- actual send deletions. It also reconciles orphan events left by writers that
316
- crashed after inserting an event for an already-deleted send. That reconciliation
317
- scans the event table in keyset pages of 500 rows, with a parent lookup per
318
- distinct send in each page; its total work is not capped by the send limit.
319
- Event writes create the parent first and never reuse deleted send IDs. Neither
320
- retention path deletes templates or files. Disabled retention skips both passes.
321
-
322
- ## Automation nodes
323
-
324
- Registered against the optional `@antelopejs/interface-dms-automation`.
325
- They are inert no-ops when no module implements it.
59
+ | Package | Version |
60
+ | --- | --- |
61
+ | `@antelopejs/dms` | `>=0.9.0 <1.0.0` |
62
+ | `@antelopejs/interface-dms` | `>=0.7.1 <1.0.0` |
63
+ | `@antelopejs/dms-frontend` (renderer, playground range) | `>=0.6.1 <0.7.0` |
64
+ | `@antelopejs/interface-dms-mailing` | `>=0.8.0 <0.9.0` |
65
+ | E-mail provider | an `@antelopejs/interface-email` implementation, such as `@antelopejs/nodemailer` |
326
66
 
327
- | Node | Id | Purpose |
328
- | --- | --- | --- |
329
- | Action | `mailing.send-template` | Renders a live template and sends it. Inputs `tenantId`, `slug`, `to` (required), `locale`, `variables`, `source`. |
330
- | Trigger | `mailing.email-event` | Fires on provider events. Config `types` filters the event types; empty fires on every one. |
67
+ On DMS 0.8, use `@antelopejs/dms-mailing` 0.4.
331
68
 
332
- ## Development
69
+ ## Slugs
333
70
 
334
- ```sh
335
- pnpm install
336
- pnpm --dir frontend-vue install
337
- pnpm --dir playground install
71
+ Sends find a template by its slug, so a slug belongs to one template per
72
+ workspace. The database interface has no unique index, so the primary key of
73
+ `mailing_template_slugs` does that job: creating or duplicating a template
74
+ claims its slug there, and of two creations racing for one slug the second
75
+ gets `409 duplicate_slug` instead of a second template. Deleting a template
76
+ frees its slug. Templates created before the claims existed need no
77
+ migration: a new template still cannot take their slug.
338
78
 
339
- pnpm dev # backend + module, watching src/
340
- pnpm frontend:dev # the DMS front-end, in another terminal
341
- ```
79
+ ## Documentation
342
80
 
343
- The backend listens on `http://localhost:5010` and needs a MongoDB on
344
- `mongodb://localhost:27017` (database `playground_dms_mailing`); set
345
- `MONGO_URL` to point the playground at another instance. E-mails go to an
346
- Ethereal account, or to a local SMTP server when `SMTP_PORT` is set.
81
+ - [Introduction](https://dms.antelopejs.com/docs/modules/mailing/introduction)
82
+ - [Installation](https://dms.antelopejs.com/docs/modules/mailing/installation)
83
+ - [Configuration](https://dms.antelopejs.com/docs/modules/mailing/configuration)
84
+ - [Usage](https://dms.antelopejs.com/docs/modules/mailing/usage/overview)
85
+ - [Extending](https://dms.antelopejs.com/docs/modules/mailing/extending): sending from code, provider events and webhooks, automations
86
+ - [FAQ](https://dms.antelopejs.com/docs/modules/mailing/faq)
347
87
 
348
- Both packages are public on npm, published under the `@antelopejs` scope with
349
- npm trusted publishing and provenance. The interface package must be released
350
- before `@antelopejs/dms-mailing`. Each package has its own manual workflow:
351
- `Release DMS mailing interface` publishes `../interface-dms-mailing`, `Release
352
- DMS mailing module` publishes this package and refuses to run until the
353
- interface version its dependency range is floored at resolves on npm. Inside
354
- the workspace that same range resolves to the sibling package, through
355
- `link-workspace-packages`. The module implements the interface, so that range
356
- is capped below the next minor (`>=0.7.0 <0.8.0`): a breaking interface minor
357
- never reaches a module that does not implement it, and the release workflow
358
- refuses any other shape.
88
+ The guide's sources live in [`packages/dms-mailing/docs`](https://github.com/AntelopeJS/dms-mailing/tree/main/packages/dms-mailing/docs). The module ships the `dms-mailing` Claude Code skill in [`packages/dms-mailing/skills`](https://github.com/AntelopeJS/dms-mailing/tree/main/packages/dms-mailing/skills), declared under `antelopeJs.skills`.
359
89
 
360
- ## Conventions
90
+ ## Contributing
361
91
 
362
- Every backend-declared text uses the `$key` convention: a string starting with
363
- `$` is resolved against the i18n catalogs by the front-end. Add keys to
364
- `frontend-vue/i18n/locales/mailing-en-GB.json` and its French counterpart.
92
+ This package lives in the [`AntelopeJS/dms-mailing`](https://github.com/AntelopeJS/dms-mailing) pnpm workspace, next to `@antelopejs/interface-dms-mailing`. Read [CONTRIBUTING.md](https://github.com/AntelopeJS/dms-mailing/blob/main/CONTRIBUTING.md) and the [repository README](https://github.com/AntelopeJS/dms-mailing#contributing) for the development commands.
365
93
 
366
- ## Checks
94
+ ## License
367
95
 
368
- ```sh
369
- pnpm lint # oxlint + oxfmt + the layer's eslint
370
- pnpm typecheck # tsc --noEmit on tsconfig.json
371
- pnpm knip # unused dependencies
372
- pnpm build # tsconfig.json -> dist/
373
- pnpm test # backend (mocha through `ajs module test`) + layer (vitest)
374
- ```
96
+ [Apache-2.0](./LICENSE)
@@ -84,15 +84,6 @@ function assertKnownCategory(categories, category) {
84
84
  }
85
85
  throw new interface_api_1.HTTPResult(constants_1.HTTP_UNPROCESSABLE, UNKNOWN_CATEGORY);
86
86
  }
87
- const creationTime = (template) => new Date(template.createdAt).getTime();
88
- async function assertFirstOfSlug(model, slug, templateId) {
89
- const [first] = (await model.getBy("slug", slug)).sort((left, right) => creationTime(left) - creationTime(right) ||
90
- left._id.localeCompare(right._id));
91
- if (!first || first._id === templateId)
92
- return;
93
- await model.delete(templateId);
94
- throw new interface_api_1.HTTPResult(constants_1.HTTP_CONFLICT, DUPLICATE_SLUG);
95
- }
96
87
  function parseCreation(body) {
97
88
  const raw = (0, body_1.parseBody)(body);
98
89
  const seed = (0, interface_api_util_1.assertValidation)(raw, (value) => templates_schema_1.createTemplateSchema.parse(value), () => INVALID_TEMPLATE, constants_1.HTTP_BAD_REQUEST);
@@ -118,7 +109,7 @@ function withSeeding(base) {
118
109
  const fields = await seedFields(tenantId, seed, settings.fallbackLocale);
119
110
  const ids = (await base.func.call(this, ctx, params, normalized, ...rest));
120
111
  const templateId = ids[0];
121
- await assertFirstOfSlug(model, seed.slug, templateId);
112
+ await (0, templates_1.assertSlugClaimed)(tenantId, seed.slug, templateId);
122
113
  const user = await (0, guards_1.authenticateTenantRequest)(ctx);
123
114
  await (0, templates_1.initializeTemplate)(tenantId, templateId, (0, templates_1.displayName)(user), fields);
124
115
  return ids;
@@ -148,6 +139,7 @@ function afterDelete(tenantId, ids) {
148
139
  return async () => {
149
140
  const versions = (0, interface_database_decorators_1.GetModel)(db_1.TemplateVersionModel, tenantId).table;
150
141
  await Promise.all(ids.map((id) => versions.getAll(id, "templateId").delete().run()));
142
+ await (0, templates_1.releaseTemplateSlugs)(tenantId, ids);
151
143
  await (0, template_attention_1.refreshTemplateAttention)(tenantId);
152
144
  };
153
145
  }
@@ -1 +1 @@
1
- {"version":3,"file":"templates-table.js","sourceRoot":"","sources":["../../src/data/templates-table.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"templates-table.js","sourceRoot":"","sources":["../../src/data/templates-table.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ export * from "./send-events.model";
2
2
  export * from "./sends.model";
3
3
  export * from "./settings.model";
4
4
  export * from "./suppressions.model";
5
+ export * from "./template-slugs.model";
5
6
  export * from "./template-versions.model";
6
7
  export * from "./templates.model";
7
8
  export * from "./webhook-status.model";
@@ -18,6 +18,7 @@ __exportStar(require("./send-events.model"), exports);
18
18
  __exportStar(require("./sends.model"), exports);
19
19
  __exportStar(require("./settings.model"), exports);
20
20
  __exportStar(require("./suppressions.model"), exports);
21
+ __exportStar(require("./template-slugs.model"), exports);
21
22
  __exportStar(require("./template-versions.model"), exports);
22
23
  __exportStar(require("./templates.model"), exports);
23
24
  __exportStar(require("./webhook-status.model"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,gDAA8B;AAC9B,mDAAiC;AACjC,uDAAqC;AACrC,4DAA0C;AAC1C,oDAAkC;AAClC,yDAAuC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,gDAA8B;AAC9B,mDAAiC;AACjC,uDAAqC;AACrC,yDAAuC;AACvC,4DAA0C;AAC1C,oDAAkC;AAClC,yDAAuC"}
@@ -13,6 +13,7 @@ declare const SendEventModel_base: {
13
13
  delete(id: string): Promise<number>;
14
14
  };
15
15
  readonly schemaName: string;
16
+ readonly tableClass: import("@antelopejs/interface-database-decorators").Constructible<MailingSendEvent>;
16
17
  fromPlainData(obj: any): MailingSendEvent;
17
18
  fromDatabase(obj: any): MailingSendEvent | undefined;
18
19
  toDatabase(obj: any): Record<string, any>;
@@ -21,6 +22,7 @@ declare const SendEventModel_base: {
21
22
  export declare class SendEventModel extends SendEventModel_base {
22
23
  getBySend(sendId: string): Promise<MailingSendEvent[]>;
23
24
  insertForActiveSend(event: NewSendEvent): Promise<boolean>;
25
+ insertImported(event: MailingSendEvent): Promise<void>;
24
26
  listAfter(after: string, size: number): Promise<MailingSendEvent[]>;
25
27
  deleteBySend(sendId: string): Promise<number>;
26
28
  }
@@ -17,6 +17,17 @@ class SendEventModel extends (0, interface_database_decorators_1.BasicDataModel)
17
17
  await this.delete(id);
18
18
  return false;
19
19
  }
20
+ async insertImported(event) {
21
+ if (await this.get(event._id))
22
+ return;
23
+ try {
24
+ await this.insert(event);
25
+ }
26
+ catch (error) {
27
+ if (!(await this.get(event._id)))
28
+ throw error;
29
+ }
30
+ }
20
31
  listAfter(after, size) {
21
32
  return this.table
22
33
  .filter((row) => row.key("_id").gt(after))
@@ -1 +1 @@
1
- {"version":3,"file":"send-events.model.js","sourceRoot":"","sources":["../../../src/db/models/send-events.model.ts"],"names":[],"mappings":";;;AAAA,6FAA2E;AAC3E,sCAA6E;AAC7E,+CAA0C;AAI1C,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAE3B,MAAa,cAAe,SAAQ,IAAA,8CAAc,EAChD,yBAAgB,EAChB,uCAA8B,CAC/B;IACC,KAAK,CAAC,SAAS,CAAC,MAAc;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAGD,KAAK,CAAC,mBAAmB,CAAC,KAAmB;QAC3C,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,IAAI,uBAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAC1C,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IAGD,SAAS,CAAC,KAAa,EAAE,IAAY;QACnC,OAAO,IAAI,CAAC,KAAK;aACd,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;aACzC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;aACrB,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC;aAC7B,GAAG,EAAE,CAAC;IACX,CAAC;IAOD,YAAY,CAAC,MAAc;QACzB,OAAO,IAAI,CAAC,KAAK;aACd,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;aAC7C,MAAM,EAAE;aACR,GAAG,EAAE,CAAC;IACX,CAAC;CACF;AArCD,wCAqCC"}
1
+ {"version":3,"file":"send-events.model.js","sourceRoot":"","sources":["../../../src/db/models/send-events.model.ts"],"names":[],"mappings":";;;AAAA,6FAA2E;AAC3E,sCAA6E;AAC7E,+CAA0C;AAI1C,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAE3B,MAAa,cAAe,SAAQ,IAAA,8CAAc,EAChD,yBAAgB,EAChB,uCAA8B,CAC/B;IACC,KAAK,CAAC,SAAS,CAAC,MAAc;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAGD,KAAK,CAAC,mBAAmB,CAAC,KAAmB;QAC3C,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,IAAI,uBAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAC1C,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IAMD,KAAK,CAAC,cAAc,CAAC,KAAuB;QAC1C,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE,OAAO;QACtC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAAE,MAAM,KAAK,CAAC;QAChD,CAAC;IACH,CAAC;IAGD,SAAS,CAAC,KAAa,EAAE,IAAY;QACnC,OAAO,IAAI,CAAC,KAAK;aACd,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;aACzC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;aACrB,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC;aAC7B,GAAG,EAAE,CAAC;IACX,CAAC;IAOD,YAAY,CAAC,MAAc;QACzB,OAAO,IAAI,CAAC,KAAK;aACd,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;aAC7C,MAAM,EAAE;aACR,GAAG,EAAE,CAAC;IACX,CAAC;CACF;AAlDD,wCAkDC"}
@@ -1,5 +1,6 @@
1
1
  import { MailingSend } from "../tables";
2
2
  type NewSend = Omit<MailingSend, "_id" | "createdAt" | "revision" | "isRetiring" | "lastActivityAt">;
3
+ export type ImportedSendRow = Omit<MailingSend, "revision" | "isRetiring" | "lastActivityAt">;
3
4
  export type SendSummary = Omit<MailingSend, "json_variables">;
4
5
  type SendActivity = Pick<MailingSend, "status" | "opens" | "clicks" | "lastEventAt" | "provider" | "error" | "isSoftBounce">;
5
6
  export interface SendReplay {
@@ -19,6 +20,7 @@ declare const SendModel_base: {
19
20
  delete(id: string): Promise<number>;
20
21
  };
21
22
  readonly schemaName: string;
23
+ readonly tableClass: import("@antelopejs/interface-database-decorators").Constructible<MailingSend>;
22
24
  fromPlainData(obj: any): MailingSend;
23
25
  fromDatabase(obj: any): MailingSend | undefined;
24
26
  toDatabase(obj: any): Record<string, any>;
@@ -26,6 +28,7 @@ declare const SendModel_base: {
26
28
  };
27
29
  export declare class SendModel extends SendModel_base {
28
30
  insertSend(send: NewSend): Promise<string[]>;
31
+ insertImported(send: ImportedSendRow): Promise<boolean>;
29
32
  getSnapshot(sendId: string): Promise<MailingSend | undefined>;
30
33
  getByProviderMessageId(messageId: string): Promise<MailingSend | undefined>;
31
34
  listBetween(from: Date, to: Date): Promise<SendSummary[]>;
@@ -38,6 +38,19 @@ class SendModel extends (0, interface_database_decorators_1.BasicDataModel)(tabl
38
38
  })
39
39
  .run();
40
40
  }
41
+ async insertImported(send) {
42
+ if (await this.get(send._id))
43
+ return false;
44
+ try {
45
+ await this.table.insert({ ...send, revision: (0, node_crypto_1.randomUUID)() }).run();
46
+ return true;
47
+ }
48
+ catch (error) {
49
+ if (await this.get(send._id))
50
+ return false;
51
+ throw error;
52
+ }
53
+ }
41
54
  getSnapshot(sendId) {
42
55
  return this.table.get(sendId).run();
43
56
  }