@antelopejs/dms-mailing 0.3.3 → 0.4.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 (705) hide show
  1. package/README.md +232 -22
  2. package/dist/automation/email-event-trigger.js +2 -2
  3. package/dist/automation/email-event-trigger.js.map +1 -1
  4. package/dist/automation/send-template-action.js +2 -2
  5. package/dist/automation/send-template-action.js.map +1 -1
  6. package/dist/config.js +3 -1
  7. package/dist/config.js.map +1 -1
  8. package/dist/constants.d.ts +10 -1
  9. package/dist/constants.js +15 -3
  10. package/dist/constants.js.map +1 -1
  11. package/dist/crons/attention.d.ts +3 -0
  12. package/dist/crons/attention.js +19 -0
  13. package/dist/crons/attention.js.map +1 -0
  14. package/dist/crons/index.d.ts +2 -0
  15. package/dist/crons/index.js +2 -0
  16. package/dist/crons/index.js.map +1 -1
  17. package/dist/crons/jobs.d.ts +12 -0
  18. package/dist/crons/jobs.js +27 -0
  19. package/dist/crons/jobs.js.map +1 -0
  20. package/dist/crons/retention.d.ts +2 -4
  21. package/dist/crons/retention.js +7 -22
  22. package/dist/crons/retention.js.map +1 -1
  23. package/dist/data/displays.d.ts +5 -0
  24. package/dist/data/displays.js +23 -0
  25. package/dist/data/displays.js.map +1 -0
  26. package/dist/data/index.d.ts +1 -0
  27. package/dist/data/index.js +1 -0
  28. package/dist/data/index.js.map +1 -1
  29. package/dist/data/locale-fallback.d.ts +3 -0
  30. package/dist/data/locale-fallback.js +20 -0
  31. package/dist/data/locale-fallback.js.map +1 -0
  32. package/dist/data/read-only-routes.d.ts +7 -0
  33. package/dist/data/read-only-routes.js +13 -0
  34. package/dist/data/read-only-routes.js.map +1 -0
  35. package/dist/data/sends-table.d.ts +19 -5
  36. package/dist/data/sends-table.js +185 -17
  37. package/dist/data/sends-table.js.map +1 -1
  38. package/dist/data/suppressions-table.d.ts +24 -0
  39. package/dist/data/suppressions-table.js +120 -0
  40. package/dist/data/suppressions-table.js.map +1 -0
  41. package/dist/data/templates-table.d.ts +20 -2
  42. package/dist/data/templates-table.js +188 -31
  43. package/dist/data/templates-table.js.map +1 -1
  44. package/dist/data-types/categories-type.d.ts +11 -13
  45. package/dist/data-types/categories-type.js +3 -3
  46. package/dist/data-types/categories-type.js.map +1 -1
  47. package/dist/data-types/category-type.js +1 -1
  48. package/dist/data-types/category-type.js.map +1 -1
  49. package/dist/db/models/index.d.ts +3 -0
  50. package/dist/db/models/index.js +3 -0
  51. package/dist/db/models/index.js.map +1 -1
  52. package/dist/db/models/sends.model.d.ts +12 -1
  53. package/dist/db/models/sends.model.js +64 -0
  54. package/dist/db/models/sends.model.js.map +1 -1
  55. package/dist/db/models/settings.model.d.ts +0 -1
  56. package/dist/db/models/settings.model.js +0 -7
  57. package/dist/db/models/settings.model.js.map +1 -1
  58. package/dist/db/models/suppressions.model.d.ts +28 -0
  59. package/dist/db/models/suppressions.model.js +46 -0
  60. package/dist/db/models/suppressions.model.js.map +1 -0
  61. package/dist/db/models/template-versions.model.d.ts +24 -0
  62. package/dist/db/models/template-versions.model.js +17 -0
  63. package/dist/db/models/template-versions.model.js.map +1 -0
  64. package/dist/db/models/templates.model.d.ts +2 -0
  65. package/dist/db/models/templates.model.js +3 -0
  66. package/dist/db/models/templates.model.js.map +1 -1
  67. package/dist/db/models/webhook-status.model.d.ts +24 -0
  68. package/dist/db/models/webhook-status.model.js +21 -0
  69. package/dist/db/models/webhook-status.model.js.map +1 -0
  70. package/dist/db/tables/index.d.ts +3 -0
  71. package/dist/db/tables/index.js +3 -0
  72. package/dist/db/tables/index.js.map +1 -1
  73. package/dist/db/tables/send-events.table.d.ts +2 -2
  74. package/dist/db/tables/send-events.table.js.map +1 -1
  75. package/dist/db/tables/sends.table.d.ts +10 -2
  76. package/dist/db/tables/sends.table.js +34 -1
  77. package/dist/db/tables/sends.table.js.map +1 -1
  78. package/dist/db/tables/suppressions.table.d.ts +12 -0
  79. package/dist/db/tables/suppressions.table.js +53 -0
  80. package/dist/db/tables/suppressions.table.js.map +1 -0
  81. package/dist/db/tables/template-versions.table.d.ts +13 -0
  82. package/dist/db/tables/template-versions.table.js +59 -0
  83. package/dist/db/tables/template-versions.table.js.map +1 -0
  84. package/dist/db/tables/templates.table.d.ts +11 -0
  85. package/dist/db/tables/templates.table.js +45 -0
  86. package/dist/db/tables/templates.table.js.map +1 -1
  87. package/dist/db/tables/webhook-status.table.d.ts +14 -0
  88. package/dist/db/tables/webhook-status.table.js +58 -0
  89. package/dist/db/tables/webhook-status.table.js.map +1 -0
  90. package/dist/engine/changes.d.ts +12 -0
  91. package/dist/engine/changes.js +107 -0
  92. package/dist/engine/changes.js.map +1 -0
  93. package/dist/engine/conditions.js +0 -2
  94. package/dist/engine/conditions.js.map +1 -1
  95. package/dist/engine/coverage.d.ts +1 -0
  96. package/dist/engine/coverage.js +6 -2
  97. package/dist/engine/coverage.js.map +1 -1
  98. package/dist/engine/fallback-html.d.ts +1 -1
  99. package/dist/engine/fallback-html.js +51 -34
  100. package/dist/engine/fallback-html.js.map +1 -1
  101. package/dist/engine/index.d.ts +3 -0
  102. package/dist/engine/index.js +3 -0
  103. package/dist/engine/index.js.map +1 -1
  104. package/dist/engine/plain-text.d.ts +3 -0
  105. package/dist/engine/plain-text.js +60 -0
  106. package/dist/engine/plain-text.js.map +1 -0
  107. package/dist/engine/resolve.d.ts +2 -1
  108. package/dist/engine/resolve.js +17 -9
  109. package/dist/engine/resolve.js.map +1 -1
  110. package/dist/engine/system-variables.d.ts +10 -0
  111. package/dist/engine/system-variables.js +70 -0
  112. package/dist/engine/system-variables.js.map +1 -0
  113. package/dist/engine/tokens.d.ts +2 -1
  114. package/dist/engine/tokens.js +6 -2
  115. package/dist/engine/tokens.js.map +1 -1
  116. package/dist/hooks/tenant-export.js +13 -1
  117. package/dist/hooks/tenant-export.js.map +1 -1
  118. package/dist/implementations/dms-mailing/index.d.ts +1 -1
  119. package/dist/implementations/dms-mailing/index.js +2 -2
  120. package/dist/implementations/dms-mailing/index.js.map +1 -1
  121. package/dist/index.js +13 -11
  122. package/dist/index.js.map +1 -1
  123. package/dist/pages/editor.js +9 -2
  124. package/dist/pages/editor.js.map +1 -1
  125. package/dist/pages/index.d.ts +1 -0
  126. package/dist/pages/index.js +1 -0
  127. package/dist/pages/index.js.map +1 -1
  128. package/dist/pages/module.d.ts +2 -0
  129. package/dist/pages/module.js +26 -2
  130. package/dist/pages/module.js.map +1 -1
  131. package/dist/pages/overview.d.ts +2 -6
  132. package/dist/pages/overview.js +109 -52
  133. package/dist/pages/overview.js.map +1 -1
  134. package/dist/pages/sends.d.ts +3 -4
  135. package/dist/pages/sends.js +197 -60
  136. package/dist/pages/sends.js.map +1 -1
  137. package/dist/pages/settings/form.js +114 -53
  138. package/dist/pages/settings/form.js.map +1 -1
  139. package/dist/pages/settings/page.d.ts +0 -1
  140. package/dist/pages/settings/page.js +8 -11
  141. package/dist/pages/settings/page.js.map +1 -1
  142. package/dist/pages/suppressions.d.ts +9 -0
  143. package/dist/pages/suppressions.js +151 -0
  144. package/dist/pages/suppressions.js.map +1 -0
  145. package/dist/pages/templates.d.ts +0 -1
  146. package/dist/pages/templates.js +114 -40
  147. package/dist/pages/templates.js.map +1 -1
  148. package/dist/permissions.js +2 -2
  149. package/dist/permissions.js.map +1 -1
  150. package/dist/quick-actions.js +7 -4
  151. package/dist/quick-actions.js.map +1 -1
  152. package/dist/routes/events.d.ts +8 -5
  153. package/dist/routes/events.js +55 -24
  154. package/dist/routes/events.js.map +1 -1
  155. package/dist/routes/index.d.ts +2 -0
  156. package/dist/routes/index.js +2 -0
  157. package/dist/routes/index.js.map +1 -1
  158. package/dist/routes/metrics.d.ts +60 -23
  159. package/dist/routes/metrics.js +231 -83
  160. package/dist/routes/metrics.js.map +1 -1
  161. package/dist/routes/period.d.ts +2 -1
  162. package/dist/routes/period.js +9 -3
  163. package/dist/routes/period.js.map +1 -1
  164. package/dist/routes/sends.d.ts +49 -8
  165. package/dist/routes/sends.js +239 -24
  166. package/dist/routes/sends.js.map +1 -1
  167. package/dist/routes/settings.d.ts +44 -5
  168. package/dist/routes/settings.js +190 -15
  169. package/dist/routes/settings.js.map +1 -1
  170. package/dist/routes/suppressions.d.ts +16 -0
  171. package/dist/routes/suppressions.js +92 -0
  172. package/dist/routes/suppressions.js.map +1 -0
  173. package/dist/routes/template-versions.d.ts +28 -0
  174. package/dist/routes/template-versions.js +87 -0
  175. package/dist/routes/template-versions.js.map +1 -0
  176. package/dist/routes/templates.d.ts +60 -6
  177. package/dist/routes/templates.js +204 -35
  178. package/dist/routes/templates.js.map +1 -1
  179. package/dist/services/attention.d.ts +19 -6
  180. package/dist/services/attention.js +177 -12
  181. package/dist/services/attention.js.map +1 -1
  182. package/dist/services/catalog.d.ts +3 -0
  183. package/dist/services/catalog.js +25 -0
  184. package/dist/services/catalog.js.map +1 -0
  185. package/dist/services/categories.d.ts +8 -32
  186. package/dist/services/categories.js +14 -25
  187. package/dist/services/categories.js.map +1 -1
  188. package/dist/services/checked-send.d.ts +9 -0
  189. package/dist/services/checked-send.js +54 -0
  190. package/dist/services/checked-send.js.map +1 -0
  191. package/dist/services/events.d.ts +5 -0
  192. package/dist/services/events.js +102 -9
  193. package/dist/services/events.js.map +1 -1
  194. package/dist/services/metrics.d.ts +17 -6
  195. package/dist/services/metrics.js +57 -18
  196. package/dist/services/metrics.js.map +1 -1
  197. package/dist/services/notify.d.ts +18 -10
  198. package/dist/services/notify.js +82 -37
  199. package/dist/services/notify.js.map +1 -1
  200. package/dist/services/provider-banner.d.ts +14 -0
  201. package/dist/services/provider-banner.js +115 -0
  202. package/dist/services/provider-banner.js.map +1 -0
  203. package/dist/services/render.js.map +1 -1
  204. package/dist/services/send-stat-items.d.ts +7 -0
  205. package/dist/services/send-stat-items.js +127 -0
  206. package/dist/services/send-stat-items.js.map +1 -0
  207. package/dist/services/send-stats.d.ts +23 -0
  208. package/dist/services/send-stats.js +63 -0
  209. package/dist/services/send-stats.js.map +1 -0
  210. package/dist/services/send.d.ts +18 -3
  211. package/dist/services/send.js +81 -17
  212. package/dist/services/send.js.map +1 -1
  213. package/dist/services/settings.d.ts +5 -0
  214. package/dist/services/settings.js +28 -7
  215. package/dist/services/settings.js.map +1 -1
  216. package/dist/services/starters.d.ts +15 -0
  217. package/dist/services/starters.js +264 -0
  218. package/dist/services/starters.js.map +1 -0
  219. package/dist/services/suppressions.d.ts +20 -0
  220. package/dist/services/suppressions.js +53 -0
  221. package/dist/services/suppressions.js.map +1 -0
  222. package/dist/services/template-attention.d.ts +4 -0
  223. package/dist/services/template-attention.js +43 -0
  224. package/dist/services/template-attention.js.map +1 -0
  225. package/dist/services/template-stats.d.ts +27 -0
  226. package/dist/services/template-stats.js +59 -0
  227. package/dist/services/template-stats.js.map +1 -0
  228. package/dist/services/templates.d.ts +31 -4
  229. package/dist/services/templates.js +240 -21
  230. package/dist/services/templates.js.map +1 -1
  231. package/dist/services/webhook-status.d.ts +27 -0
  232. package/dist/services/webhook-status.js +134 -0
  233. package/dist/services/webhook-status.js.map +1 -0
  234. package/dist/types/blocks.d.ts +1 -0
  235. package/dist/types/index.d.ts +2 -0
  236. package/dist/types/index.js +2 -0
  237. package/dist/types/index.js.map +1 -1
  238. package/dist/types/sends.d.ts +10 -1
  239. package/dist/types/sends.js +35 -2
  240. package/dist/types/sends.js.map +1 -1
  241. package/dist/types/suppressions.d.ts +9 -0
  242. package/dist/types/suppressions.js +10 -0
  243. package/dist/types/suppressions.js.map +1 -0
  244. package/dist/types/webhook.d.ts +17 -0
  245. package/dist/types/webhook.js +3 -0
  246. package/dist/types/webhook.js.map +1 -0
  247. package/dist/validation/settings.schema.d.ts +144 -9
  248. package/dist/validation/settings.schema.js +113 -16
  249. package/dist/validation/settings.schema.js.map +1 -1
  250. package/dist/validation/templates.schema.d.ts +137 -10
  251. package/dist/validation/templates.schema.js +28 -2
  252. package/dist/validation/templates.schema.js.map +1 -1
  253. package/frontend-vue/app/build/components/FormFieldRow.vue +90 -0
  254. package/frontend-vue/app/build/components/FormRows.vue +26 -0
  255. package/frontend-vue/app/build/components/RequiredLegend.vue +11 -0
  256. package/frontend-vue/app/components/CategoriesInput.vue +323 -77
  257. package/frontend-vue/app/components/CategoryInput.vue +13 -14
  258. package/frontend-vue/app/components/CategoryLabel.vue +34 -0
  259. package/frontend-vue/app/components/DuplicateModal.vue +201 -0
  260. package/frontend-vue/app/components/Editor.vue +55 -20
  261. package/frontend-vue/app/components/FixAddressModal.vue +133 -0
  262. package/frontend-vue/app/components/FunnelCard.vue +146 -43
  263. package/frontend-vue/app/components/LocaleSelect.vue +98 -0
  264. package/frontend-vue/app/components/NewTemplateModal.vue +388 -102
  265. package/frontend-vue/app/components/NewTemplateSourceTile.vue +70 -0
  266. package/frontend-vue/app/components/OverviewGate.vue +220 -0
  267. package/frontend-vue/app/components/PageHeader.vue +98 -0
  268. package/frontend-vue/app/components/RealSendModal.vue +555 -0
  269. package/frontend-vue/app/components/RecipientsField.vue +41 -0
  270. package/frontend-vue/app/components/RenderingModal.vue +189 -0
  271. package/frontend-vue/app/components/RetentionInput.vue +212 -0
  272. package/frontend-vue/app/components/SendDrawer.vue +542 -209
  273. package/frontend-vue/app/components/StarterGallery.vue +153 -0
  274. package/frontend-vue/app/components/SystemVariables.vue +63 -0
  275. package/frontend-vue/app/components/TemplateCard.vue +218 -57
  276. package/frontend-vue/app/components/TemplateDrawer.vue +785 -274
  277. package/frontend-vue/app/components/TemplateGallery.vue +312 -56
  278. package/frontend-vue/app/components/TemplatePreviewFrame.vue +112 -22
  279. package/frontend-vue/app/components/TestSendModal.vue +266 -95
  280. package/frontend-vue/app/components/TokenText.vue +61 -10
  281. package/frontend-vue/app/components/VariablePath.vue +20 -0
  282. package/frontend-vue/app/components/VersionHistory.vue +196 -0
  283. package/frontend-vue/app/components/VersionPreview.vue +164 -0
  284. package/frontend-vue/app/components/WebhookStatus.vue +130 -0
  285. package/frontend-vue/app/components/blocks/Button.vue +1 -1
  286. package/frontend-vue/app/components/blocks/Code.vue +1 -1
  287. package/frontend-vue/app/components/blocks/Footer.vue +56 -7
  288. package/frontend-vue/app/components/blocks/Heading.vue +1 -1
  289. package/frontend-vue/app/components/blocks/Hero.vue +13 -7
  290. package/frontend-vue/app/components/blocks/List.vue +50 -6
  291. package/frontend-vue/app/components/blocks/Paragraph.vue +1 -1
  292. package/frontend-vue/app/components/blocks/Total.vue +3 -3
  293. package/frontend-vue/app/components/editor/EditorAutocompleteMenu.vue +50 -0
  294. package/frontend-vue/app/components/editor/EditorBlock.vue +37 -90
  295. package/frontend-vue/app/components/editor/EditorBlockFields.vue +140 -0
  296. package/frontend-vue/app/components/editor/EditorBlockInspector.vue +92 -0
  297. package/frontend-vue/app/components/editor/EditorBlockList.vue +32 -25
  298. package/frontend-vue/app/components/editor/EditorBlockPicker.vue +58 -0
  299. package/frontend-vue/app/components/editor/EditorBlockTools.vue +71 -0
  300. package/frontend-vue/app/components/editor/EditorCanvas.vue +105 -70
  301. package/frontend-vue/app/components/editor/EditorCompare.vue +211 -0
  302. package/frontend-vue/app/components/editor/EditorConditionFields.vue +56 -46
  303. package/frontend-vue/app/components/editor/EditorConditionInspector.vue +54 -0
  304. package/frontend-vue/app/components/editor/EditorEnvelope.vue +77 -0
  305. package/frontend-vue/app/components/editor/EditorIfBlock.vue +36 -86
  306. package/frontend-vue/app/components/editor/EditorInsertPoint.vue +64 -0
  307. package/frontend-vue/app/components/editor/EditorInspector.vue +80 -0
  308. package/frontend-vue/app/components/editor/EditorLeftPane.vue +103 -0
  309. package/frontend-vue/app/components/editor/EditorLifecycle.vue +67 -0
  310. package/frontend-vue/app/components/editor/EditorLoading.vue +23 -0
  311. package/frontend-vue/app/components/editor/EditorLocaleSwitch.vue +61 -0
  312. package/frontend-vue/app/components/editor/EditorMissingLocale.vue +72 -48
  313. package/frontend-vue/app/components/editor/EditorMissingPolicy.vue +42 -0
  314. package/frontend-vue/app/components/editor/EditorNotice.vue +127 -0
  315. package/frontend-vue/app/components/editor/EditorOutline.vue +65 -0
  316. package/frontend-vue/app/components/editor/EditorPalette.vue +95 -42
  317. package/frontend-vue/app/components/editor/EditorPaletteGroup.vue +66 -0
  318. package/frontend-vue/app/components/editor/EditorPublishReview.vue +102 -0
  319. package/frontend-vue/app/components/editor/EditorSaveState.vue +88 -0
  320. package/frontend-vue/app/components/editor/EditorShortcutHint.vue +17 -0
  321. package/frontend-vue/app/components/editor/EditorSimChip.vue +51 -0
  322. package/frontend-vue/app/components/editor/EditorTemplatePane.vue +131 -0
  323. package/frontend-vue/app/components/editor/EditorTestDataPane.vue +98 -0
  324. package/frontend-vue/app/components/editor/EditorTitle.vue +82 -0
  325. package/frontend-vue/app/components/editor/EditorTokenField.vue +224 -0
  326. package/frontend-vue/app/components/editor/EditorToolbar.vue +34 -134
  327. package/frontend-vue/app/components/editor/EditorVariableForm.vue +100 -0
  328. package/frontend-vue/app/components/editor/EditorVariableRow.vue +87 -0
  329. package/frontend-vue/app/components/editor/EditorVariablesPane.vue +161 -0
  330. package/frontend-vue/app/components/editor/EditorViewSwitches.vue +76 -0
  331. package/frontend-vue/app/components/editor/EditorVisibility.vue +101 -0
  332. package/frontend-vue/app/components/editor/EditorWorkspace.vue +62 -149
  333. package/frontend-vue/app/composables/useBlockContext.ts +16 -0
  334. package/frontend-vue/app/composables/useEditorActions.ts +381 -0
  335. package/frontend-vue/app/composables/useEditorAnnouncements.ts +51 -0
  336. package/frontend-vue/app/composables/useEditorContext.ts +30 -23
  337. package/frontend-vue/app/composables/useEditorSession.ts +299 -0
  338. package/frontend-vue/app/composables/useEditorShortcuts.ts +81 -0
  339. package/frontend-vue/app/composables/useLocalizedDefaults.ts +17 -0
  340. package/frontend-vue/app/composables/useMailingApi.ts +142 -27
  341. package/frontend-vue/app/composables/useOverviewSetup.ts +13 -0
  342. package/frontend-vue/app/composables/useReplayToast.ts +72 -0
  343. package/frontend-vue/app/composables/useTemplateCategories.ts +35 -0
  344. package/frontend-vue/app/composables/useTemplateDrawer.ts +196 -62
  345. package/frontend-vue/app/composables/useTemplateEditor.ts +318 -86
  346. package/frontend-vue/app/emails/EmailMailingTemplate.vue +16 -4
  347. package/frontend-vue/app/emails/components/MailingBlocks.vue +96 -38
  348. package/frontend-vue/app/emails/components/MailingTextLines.vue +20 -0
  349. package/frontend-vue/app/plugins/column-displays.ts +65 -0
  350. package/frontend-vue/app/plugins/{template-gallery-display.client.ts → template-gallery-display.ts} +1 -1
  351. package/frontend-vue/app/types/mailing.ts +193 -18
  352. package/frontend-vue/app/utils/api-error.ts +33 -0
  353. package/frontend-vue/app/utils/autocomplete.ts +120 -0
  354. package/frontend-vue/app/utils/blocks/components.ts +10 -10
  355. package/frontend-vue/app/utils/blocks/dnd.ts +7 -3
  356. package/frontend-vue/app/utils/blocks/factory.ts +199 -38
  357. package/frontend-vue/app/utils/blocks/fields.ts +39 -19
  358. package/frontend-vue/app/utils/blocks/index.ts +1 -0
  359. package/frontend-vue/app/utils/blocks/outline.ts +91 -0
  360. package/frontend-vue/app/utils/blocks/tree.ts +114 -2
  361. package/frontend-vue/app/utils/categories.ts +201 -15
  362. package/frontend-vue/app/utils/changes.ts +152 -0
  363. package/frontend-vue/app/utils/conditions.ts +25 -19
  364. package/frontend-vue/app/utils/editor-checks.ts +266 -0
  365. package/frontend-vue/app/utils/editor-route.ts +43 -4
  366. package/frontend-vue/app/utils/funnel.ts +74 -0
  367. package/frontend-vue/app/utils/gallery.ts +179 -1
  368. package/frontend-vue/app/utils/history.ts +66 -0
  369. package/frontend-vue/app/utils/lifecycle.ts +185 -0
  370. package/frontend-vue/app/utils/locales.ts +107 -2
  371. package/frontend-vue/app/utils/overview-setup.ts +83 -0
  372. package/frontend-vue/app/utils/pages.ts +5 -0
  373. package/frontend-vue/app/utils/paths.ts +51 -15
  374. package/frontend-vue/app/utils/period.ts +62 -22
  375. package/frontend-vue/app/utils/problems.ts +181 -0
  376. package/frontend-vue/app/utils/recipients.ts +49 -0
  377. package/frontend-vue/app/utils/rendering-title.ts +23 -0
  378. package/frontend-vue/app/utils/send-actions.ts +207 -0
  379. package/frontend-vue/app/utils/send-link.ts +28 -0
  380. package/frontend-vue/app/utils/send-snippet.ts +97 -0
  381. package/frontend-vue/app/utils/send-stats.ts +24 -0
  382. package/frontend-vue/app/utils/send-values.ts +156 -0
  383. package/frontend-vue/app/utils/shortcuts.ts +113 -0
  384. package/frontend-vue/app/utils/slug.ts +82 -0
  385. package/frontend-vue/app/utils/starters.ts +23 -0
  386. package/frontend-vue/app/utils/suppression.ts +112 -0
  387. package/frontend-vue/app/utils/system-variables.ts +165 -0
  388. package/frontend-vue/app/utils/template-attention.ts +104 -0
  389. package/frontend-vue/app/utils/timeline.ts +221 -19
  390. package/frontend-vue/app/utils/tokens.ts +115 -13
  391. package/frontend-vue/app/utils/variable-types.ts +23 -0
  392. package/frontend-vue/app/utils/variables.ts +208 -1
  393. package/frontend-vue/app/utils/version-history.ts +53 -0
  394. package/frontend-vue/app/utils/webhook-status.ts +170 -0
  395. package/frontend-vue/dms.frontend.ts +19 -11
  396. package/frontend-vue/i18n/locales/mailing-en-GB.json +1173 -161
  397. package/frontend-vue/i18n/locales/mailing-fr-FR.json +1220 -208
  398. package/frontend-vue/package.json +4 -1
  399. package/frontend-vue/pnpm-lock.yaml +46 -161
  400. package/frontend-vue/tests/api-error.test.ts +27 -0
  401. package/frontend-vue/tests/autocomplete.test.ts +84 -0
  402. package/frontend-vue/tests/block-components.test.ts +1 -1
  403. package/frontend-vue/tests/block-fields.test.ts +12 -2
  404. package/frontend-vue/tests/blocks-factory.test.ts +46 -0
  405. package/frontend-vue/tests/blocks-outline.test.ts +102 -0
  406. package/frontend-vue/tests/blocks-tree.test.ts +28 -1
  407. package/frontend-vue/tests/categories-input.test.ts +139 -0
  408. package/frontend-vue/tests/categories.test.ts +148 -15
  409. package/frontend-vue/tests/changes.test.ts +136 -0
  410. package/frontend-vue/tests/column-displays.test.ts +73 -0
  411. package/frontend-vue/tests/conditions.test.ts +49 -19
  412. package/frontend-vue/tests/dnd.test.ts +10 -0
  413. package/frontend-vue/tests/editor-block-list.test.ts +24 -2
  414. package/frontend-vue/tests/editor-checks.test.ts +178 -0
  415. package/frontend-vue/tests/editor-route.test.ts +37 -9
  416. package/frontend-vue/tests/editor-session.test.ts +206 -0
  417. package/frontend-vue/tests/footer-block.test.ts +88 -0
  418. package/frontend-vue/tests/funnel-card.test.ts +116 -0
  419. package/frontend-vue/tests/funnel.test.ts +81 -0
  420. package/frontend-vue/tests/gallery.test.ts +124 -2
  421. package/frontend-vue/tests/helpers/nuxt-globals.ts +232 -0
  422. package/frontend-vue/tests/history.test.ts +48 -0
  423. package/frontend-vue/tests/i18n-editor.test.ts +38 -0
  424. package/frontend-vue/tests/i18n.test.ts +55 -0
  425. package/frontend-vue/tests/lifecycle.test.ts +145 -0
  426. package/frontend-vue/tests/locales.test.ts +60 -0
  427. package/frontend-vue/tests/localized-defaults.test.ts +54 -0
  428. package/frontend-vue/tests/new-template-modal.test.ts +210 -0
  429. package/frontend-vue/tests/overview-gate.test.ts +146 -0
  430. package/frontend-vue/tests/overview-setup.test.ts +78 -0
  431. package/frontend-vue/tests/paths.test.ts +23 -0
  432. package/frontend-vue/tests/period.test.ts +59 -10
  433. package/frontend-vue/tests/problems.test.ts +153 -0
  434. package/frontend-vue/tests/recipients.test.ts +47 -0
  435. package/frontend-vue/tests/rendering-title.test.ts +24 -0
  436. package/frontend-vue/tests/replay-toast.test.ts +67 -0
  437. package/frontend-vue/tests/retention-input.test.ts +129 -0
  438. package/frontend-vue/tests/send-actions.test.ts +128 -0
  439. package/frontend-vue/tests/send-modals.test.ts +415 -0
  440. package/frontend-vue/tests/send-snippet.test.ts +51 -0
  441. package/frontend-vue/tests/send-stats.test.ts +12 -0
  442. package/frontend-vue/tests/send-values.test.ts +119 -0
  443. package/frontend-vue/tests/shortcuts.test.ts +75 -0
  444. package/frontend-vue/tests/slug.test.ts +88 -0
  445. package/frontend-vue/tests/suppression.test.ts +159 -0
  446. package/frontend-vue/tests/system-variables.test.ts +133 -0
  447. package/frontend-vue/tests/template-attention.test.ts +123 -0
  448. package/frontend-vue/tests/template-drawer.test.ts +449 -0
  449. package/frontend-vue/tests/template-editor.test.ts +218 -9
  450. package/frontend-vue/tests/template-gallery-display.test.ts +32 -0
  451. package/frontend-vue/tests/template-gallery.test.ts +370 -0
  452. package/frontend-vue/tests/template-overlays.test.ts +125 -0
  453. package/frontend-vue/tests/timeline.test.ts +175 -20
  454. package/frontend-vue/tests/tokens.test.ts +79 -1
  455. package/frontend-vue/tests/variable-path.test.ts +22 -0
  456. package/frontend-vue/tests/variable-types.test.ts +20 -0
  457. package/frontend-vue/tests/variables.test.ts +90 -2
  458. package/frontend-vue/tests/version-history.test.ts +41 -0
  459. package/frontend-vue/tests/webhook-status.test.ts +108 -0
  460. package/package.json +11 -9
  461. package/src/automation/email-event-trigger.ts +3 -3
  462. package/src/automation/send-template-action.ts +7 -5
  463. package/src/config.ts +3 -1
  464. package/src/constants.ts +18 -2
  465. package/src/crons/attention.ts +21 -0
  466. package/src/crons/index.ts +2 -0
  467. package/src/crons/jobs.ts +35 -0
  468. package/src/crons/retention.ts +7 -22
  469. package/src/data/displays.ts +18 -0
  470. package/src/data/index.ts +1 -0
  471. package/src/data/locale-fallback.ts +26 -0
  472. package/src/data/read-only-routes.ts +14 -0
  473. package/src/data/sends-table.ts +204 -19
  474. package/src/data/suppressions-table.ts +127 -0
  475. package/src/data/templates-table.ts +295 -63
  476. package/src/data-types/categories-type.ts +4 -5
  477. package/src/data-types/category-type.ts +1 -1
  478. package/src/db/models/index.ts +3 -0
  479. package/src/db/models/sends.model.ts +102 -1
  480. package/src/db/models/settings.model.ts +2 -12
  481. package/src/db/models/suppressions.model.ts +53 -0
  482. package/src/db/models/template-versions.model.ts +23 -0
  483. package/src/db/models/templates.model.ts +17 -0
  484. package/src/db/models/webhook-status.model.ts +25 -0
  485. package/src/db/tables/index.ts +3 -0
  486. package/src/db/tables/send-events.table.ts +6 -2
  487. package/src/db/tables/sends.table.ts +37 -2
  488. package/src/db/tables/suppressions.table.ts +46 -0
  489. package/src/db/tables/template-versions.table.ts +44 -0
  490. package/src/db/tables/templates.table.ts +67 -5
  491. package/src/db/tables/webhook-status.table.ts +44 -0
  492. package/src/engine/changes.ts +198 -0
  493. package/src/engine/conditions.ts +1 -7
  494. package/src/engine/coverage.ts +7 -2
  495. package/src/engine/fallback-html.ts +80 -42
  496. package/src/engine/index.ts +3 -0
  497. package/src/engine/plain-text.ts +86 -0
  498. package/src/engine/resolve.ts +49 -15
  499. package/src/engine/system-variables.ts +124 -0
  500. package/src/engine/tokens.ts +13 -1
  501. package/src/hooks/tenant-export.ts +21 -2
  502. package/src/implementations/dms-mailing/index.ts +1 -1
  503. package/src/index.ts +29 -13
  504. package/src/pages/editor.ts +13 -2
  505. package/src/pages/index.ts +6 -3
  506. package/src/pages/module.ts +31 -2
  507. package/src/pages/overview.ts +187 -128
  508. package/src/pages/sends.ts +271 -112
  509. package/src/pages/settings/form.ts +144 -54
  510. package/src/pages/settings/page.ts +9 -17
  511. package/src/pages/suppressions.ts +157 -0
  512. package/src/pages/templates.ts +139 -42
  513. package/src/permissions.ts +6 -4
  514. package/src/quick-actions.ts +12 -5
  515. package/src/routes/events.ts +110 -33
  516. package/src/routes/index.ts +2 -0
  517. package/src/routes/metrics.ts +348 -98
  518. package/src/routes/period.ts +23 -6
  519. package/src/routes/sends.ts +413 -41
  520. package/src/routes/settings.ts +291 -26
  521. package/src/routes/suppressions.ts +87 -0
  522. package/src/routes/template-versions.ts +116 -0
  523. package/src/routes/templates.ts +334 -48
  524. package/src/services/attention.ts +283 -30
  525. package/src/services/catalog.ts +28 -0
  526. package/src/services/categories.ts +28 -27
  527. package/src/services/checked-send.ts +123 -0
  528. package/src/services/events.ts +174 -20
  529. package/src/services/metrics.ts +137 -28
  530. package/src/services/notify.ts +126 -44
  531. package/src/services/provider-banner.ts +165 -0
  532. package/src/services/render.ts +1 -0
  533. package/src/services/send-stat-items.ts +160 -0
  534. package/src/services/send-stats.ts +122 -0
  535. package/src/services/send.ts +193 -31
  536. package/src/services/settings.ts +52 -8
  537. package/src/services/starters.ts +383 -0
  538. package/src/services/suppressions.ts +116 -0
  539. package/src/services/template-attention.ts +82 -0
  540. package/src/services/template-stats.ts +97 -0
  541. package/src/services/templates.ts +400 -37
  542. package/src/services/webhook-status.ts +202 -0
  543. package/src/types/blocks.ts +6 -0
  544. package/src/types/index.ts +2 -0
  545. package/src/types/sends.ts +64 -2
  546. package/src/types/suppressions.ts +27 -0
  547. package/src/types/webhook.ts +29 -0
  548. package/src/validation/settings.schema.ts +173 -17
  549. package/src/validation/templates.schema.ts +53 -1
  550. package/dist/antelope-modules.d.ts +0 -32
  551. package/dist/antelope-modules.js +0 -36
  552. package/dist/antelope-modules.js.map +0 -1
  553. package/dist/test/antelope.test.d.ts +0 -2
  554. package/dist/test/antelope.test.js +0 -180
  555. package/dist/test/antelope.test.js.map +0 -1
  556. package/dist/test/helpers/http.d.ts +0 -4
  557. package/dist/test/helpers/http.js +0 -28
  558. package/dist/test/helpers/http.js.map +0 -1
  559. package/dist/test/helpers/owner.d.ts +0 -5
  560. package/dist/test/helpers/owner.js +0 -30
  561. package/dist/test/helpers/owner.js.map +0 -1
  562. package/dist/test/integration/events.test.d.ts +0 -1
  563. package/dist/test/integration/events.test.js +0 -143
  564. package/dist/test/integration/events.test.js.map +0 -1
  565. package/dist/test/integration/retention.test.d.ts +0 -1
  566. package/dist/test/integration/retention.test.js +0 -291
  567. package/dist/test/integration/retention.test.js.map +0 -1
  568. package/dist/test/integration/sends.test.d.ts +0 -1
  569. package/dist/test/integration/sends.test.js +0 -210
  570. package/dist/test/integration/sends.test.js.map +0 -1
  571. package/dist/test/integration/settings.test.d.ts +0 -1
  572. package/dist/test/integration/settings.test.js +0 -137
  573. package/dist/test/integration/settings.test.js.map +0 -1
  574. package/dist/test/integration/setup.test.d.ts +0 -1
  575. package/dist/test/integration/setup.test.js +0 -32
  576. package/dist/test/integration/setup.test.js.map +0 -1
  577. package/dist/test/integration/templates.test.d.ts +0 -1
  578. package/dist/test/integration/templates.test.js +0 -233
  579. package/dist/test/integration/templates.test.js.map +0 -1
  580. package/dist/test/integration/tenant-export.test.d.ts +0 -1
  581. package/dist/test/integration/tenant-export.test.js +0 -85
  582. package/dist/test/integration/tenant-export.test.js.map +0 -1
  583. package/dist/test/unit/attention.test.d.ts +0 -1
  584. package/dist/test/unit/attention.test.js +0 -109
  585. package/dist/test/unit/attention.test.js.map +0 -1
  586. package/dist/test/unit/automation.test.d.ts +0 -1
  587. package/dist/test/unit/automation.test.js +0 -104
  588. package/dist/test/unit/automation.test.js.map +0 -1
  589. package/dist/test/unit/categories.test.d.ts +0 -1
  590. package/dist/test/unit/categories.test.js +0 -38
  591. package/dist/test/unit/categories.test.js.map +0 -1
  592. package/dist/test/unit/engine/conditions.test.d.ts +0 -1
  593. package/dist/test/unit/engine/conditions.test.js +0 -23
  594. package/dist/test/unit/engine/conditions.test.js.map +0 -1
  595. package/dist/test/unit/engine/coverage.test.d.ts +0 -1
  596. package/dist/test/unit/engine/coverage.test.js +0 -106
  597. package/dist/test/unit/engine/coverage.test.js.map +0 -1
  598. package/dist/test/unit/engine/fallback-html.test.d.ts +0 -1
  599. package/dist/test/unit/engine/fallback-html.test.js +0 -78
  600. package/dist/test/unit/engine/fallback-html.test.js.map +0 -1
  601. package/dist/test/unit/engine/paths.test.d.ts +0 -1
  602. package/dist/test/unit/engine/paths.test.js +0 -33
  603. package/dist/test/unit/engine/paths.test.js.map +0 -1
  604. package/dist/test/unit/engine/resolve.test.d.ts +0 -1
  605. package/dist/test/unit/engine/resolve.test.js +0 -157
  606. package/dist/test/unit/engine/resolve.test.js.map +0 -1
  607. package/dist/test/unit/engine/tokens.test.d.ts +0 -1
  608. package/dist/test/unit/engine/tokens.test.js +0 -26
  609. package/dist/test/unit/engine/tokens.test.js.map +0 -1
  610. package/dist/test/unit/events.test.d.ts +0 -1
  611. package/dist/test/unit/events.test.js +0 -13
  612. package/dist/test/unit/events.test.js.map +0 -1
  613. package/dist/test/unit/metrics.test.d.ts +0 -1
  614. package/dist/test/unit/metrics.test.js +0 -108
  615. package/dist/test/unit/metrics.test.js.map +0 -1
  616. package/dist/test/unit/notify.test.d.ts +0 -1
  617. package/dist/test/unit/notify.test.js +0 -49
  618. package/dist/test/unit/notify.test.js.map +0 -1
  619. package/dist/test/unit/period.test.d.ts +0 -1
  620. package/dist/test/unit/period.test.js +0 -61
  621. package/dist/test/unit/period.test.js.map +0 -1
  622. package/dist/test/unit/permissions.test.d.ts +0 -1
  623. package/dist/test/unit/permissions.test.js +0 -27
  624. package/dist/test/unit/permissions.test.js.map +0 -1
  625. package/dist/test/unit/provider.test.d.ts +0 -1
  626. package/dist/test/unit/provider.test.js +0 -47
  627. package/dist/test/unit/provider.test.js.map +0 -1
  628. package/dist/test/unit/realtime.test.d.ts +0 -1
  629. package/dist/test/unit/realtime.test.js +0 -13
  630. package/dist/test/unit/realtime.test.js.map +0 -1
  631. package/dist/test/unit/render.test.d.ts +0 -1
  632. package/dist/test/unit/render.test.js +0 -23
  633. package/dist/test/unit/render.test.js.map +0 -1
  634. package/dist/test/unit/retention.test.d.ts +0 -1
  635. package/dist/test/unit/retention.test.js +0 -66
  636. package/dist/test/unit/retention.test.js.map +0 -1
  637. package/dist/test/unit/send-batch.test.d.ts +0 -1
  638. package/dist/test/unit/send-batch.test.js +0 -46
  639. package/dist/test/unit/send-batch.test.js.map +0 -1
  640. package/dist/test/unit/send.test.d.ts +0 -1
  641. package/dist/test/unit/send.test.js +0 -120
  642. package/dist/test/unit/send.test.js.map +0 -1
  643. package/dist/test/unit/smoke.test.d.ts +0 -1
  644. package/dist/test/unit/smoke.test.js +0 -10
  645. package/dist/test/unit/smoke.test.js.map +0 -1
  646. package/dist/test/unit/status.test.d.ts +0 -1
  647. package/dist/test/unit/status.test.js +0 -16
  648. package/dist/test/unit/status.test.js.map +0 -1
  649. package/dist/test/unit/templates.test.d.ts +0 -1
  650. package/dist/test/unit/templates.test.js +0 -48
  651. package/dist/test/unit/templates.test.js.map +0 -1
  652. package/dist/test/unit/tenant-export.test.d.ts +0 -1
  653. package/dist/test/unit/tenant-export.test.js +0 -59
  654. package/dist/test/unit/tenant-export.test.js.map +0 -1
  655. package/dist/test/unit/webhook-secret.test.d.ts +0 -1
  656. package/dist/test/unit/webhook-secret.test.js +0 -43
  657. package/dist/test/unit/webhook-secret.test.js.map +0 -1
  658. package/frontend-vue/app/components/AttentionCard.vue +0 -78
  659. package/frontend-vue/app/components/HtmlPreviewModal.vue +0 -20
  660. package/frontend-vue/app/components/ProviderChip.vue +0 -39
  661. package/frontend-vue/app/components/editor/EditorBlockSettings.vue +0 -186
  662. package/frontend-vue/app/components/editor/EditorDataPanel.vue +0 -130
  663. package/frontend-vue/app/components/editor/EditorDraftBar.vue +0 -35
  664. package/frontend-vue/app/components/editor/EditorRail.vue +0 -58
  665. package/frontend-vue/app/components/editor/EditorSubjectSettings.vue +0 -37
  666. package/frontend-vue/app/components/editor/EditorTemplateSettings.vue +0 -87
  667. package/frontend-vue/app/components/editor/EditorTestSendModal.vue +0 -66
  668. package/frontend-vue/app/components/editor/EditorVariables.vue +0 -163
  669. package/frontend-vue/app/composables/useMailingPeriodData.ts +0 -39
  670. package/src/antelope-modules.ts +0 -48
  671. package/src/test/antelope.test.ts +0 -190
  672. package/src/test/helpers/http.ts +0 -23
  673. package/src/test/helpers/owner.ts +0 -37
  674. package/src/test/integration/events.test.ts +0 -159
  675. package/src/test/integration/retention.test.ts +0 -363
  676. package/src/test/integration/sends.test.ts +0 -233
  677. package/src/test/integration/settings.test.ts +0 -128
  678. package/src/test/integration/setup.test.ts +0 -35
  679. package/src/test/integration/templates.test.ts +0 -272
  680. package/src/test/integration/tenant-export.test.ts +0 -125
  681. package/src/test/unit/attention.test.ts +0 -129
  682. package/src/test/unit/automation.test.ts +0 -130
  683. package/src/test/unit/categories.test.ts +0 -51
  684. package/src/test/unit/engine/conditions.test.ts +0 -35
  685. package/src/test/unit/engine/coverage.test.ts +0 -118
  686. package/src/test/unit/engine/fallback-html.test.ts +0 -86
  687. package/src/test/unit/engine/paths.test.ts +0 -39
  688. package/src/test/unit/engine/resolve.test.ts +0 -176
  689. package/src/test/unit/engine/tokens.test.ts +0 -26
  690. package/src/test/unit/events.test.ts +0 -19
  691. package/src/test/unit/metrics.test.ts +0 -170
  692. package/src/test/unit/notify.test.ts +0 -71
  693. package/src/test/unit/period.test.ts +0 -91
  694. package/src/test/unit/permissions.test.ts +0 -30
  695. package/src/test/unit/provider.test.ts +0 -57
  696. package/src/test/unit/realtime.test.ts +0 -11
  697. package/src/test/unit/render.test.ts +0 -23
  698. package/src/test/unit/retention.test.ts +0 -91
  699. package/src/test/unit/send-batch.test.ts +0 -72
  700. package/src/test/unit/send.test.ts +0 -161
  701. package/src/test/unit/smoke.test.ts +0 -8
  702. package/src/test/unit/status.test.ts +0 -14
  703. package/src/test/unit/templates.test.ts +0 -52
  704. package/src/test/unit/tenant-export.test.ts +0 -88
  705. package/src/test/unit/webhook-secret.test.ts +0 -51
package/README.md CHANGED
@@ -7,25 +7,60 @@
7
7
  </div>
8
8
 
9
9
  Mailing module for the AntelopeJS DMS: a template library with a block-based
10
- e-mail editor, a send log, an overview dashboard and
11
- settings. It owns the data (tenant-scoped Mongo tables), renders e-mails
12
- through the DMS html-render chain and sends them through
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
13
  `@antelopejs/interface-email`.
14
14
 
15
+ The module targets `@antelopejs/dms` 0.7 (0.7.21 or later) and `@antelopejs/dms-frontend` 0.5 (0.5.5 or later).
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
+
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
+
15
50
  ## Layout
16
51
 
17
52
  | Path | What it holds |
18
53
  | --- | --- |
19
- | `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 retention cron. |
20
- | `src/pages/` | The DMS pages: `overview`, `templates`, `editor`, `sends` and the settings form. |
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. |
21
56
  | `src/data/` | The `TableView` data controllers behind `/api/mailing/tables/*`. |
22
- | `src/routes/` | The HTTP API under `/api/mailing` (templates, sends, events, metrics, settings, provider). |
57
+ | `src/routes/` | The HTTP API under `/api/mailing` (templates, sends, events, metrics, settings, provider, suppressions). |
23
58
  | `src/engine/` | The pure-TS rendering engine: block tree + variables → resolved e-mail. |
24
59
  | `../interface-dms-mailing/` | The separately published public AntelopeJS interface (see below). |
25
60
  | `src/automation/` | The `dms-automation` action and trigger. |
26
- | `src/crons/` | The daily, replay-safe send-log retention job. |
61
+ | `src/crons/` | The daily, replay-safe send-log retention job and the hourly refresh of the templates needing attention. |
27
62
  | `src/hooks/` | The tenant data export contributor. |
28
- | `frontend-vue/` | Vue Inertia module: gallery display, detail drawers, block editor, `dms.email.ts` server template entry and the `mailing-*.json` i18n catalogs. |
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. |
29
64
  | `playground/` | Standalone AntelopeJS project wiring this module to the DMS, Mongo, the API server and the mailer, for local development. |
30
65
 
31
66
  ## Public interface
@@ -62,25 +97,199 @@ once and issues a single `SendBatch`; otherwise it loops `Send`. Either way one
62
97
  row per recipient lands in the send log, and the returned
63
98
  `SendTemplateResult` describes the first one.
64
99
 
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.
105
+
106
+ ## What a recipient receives
107
+
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.
114
+
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:
121
+
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
+ });
131
+ ```
132
+
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.
155
+
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`:
168
+
169
+ ```ts
170
+ config: {
171
+ // false renders with the module's own fallback HTML, not the DMS chain.
172
+ useHtmlRender: true,
173
+ },
174
+ ```
175
+
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
+
65
186
  ## Webhook contract
66
187
 
67
- Provider events are posted to `POST /api/mailing/events/:provider`, guarded by
68
- the `x-mailing-webhook-secret` header (the secret lives in the mailing
69
- settings, per tenant). The endpoint never creates those settings: until a
70
- tenant's settings exist (any mailing page or send creates them), its events are
71
- refused with `403`.
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:
72
201
 
73
202
  ```sh
74
- curl -X POST http://localhost:5010/api/mailing/events/brevo \
203
+ curl -X POST https://dms.example.com/api/mailing/events/postmark/<tenantId> \
75
204
  -H "Content-Type: application/json" \
76
- -H "x-mailing-webhook-secret: <settings.webhookSecret>" \
77
- -d '{"messageId":"<provider message id>","type":"bounced","at":"2026-09-09T10:00:00.000Z","details":{"reason":"mailbox full"}}'
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:
252
+
253
+ ```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
+ };
262
+
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
+ }
78
286
  ```
79
287
 
80
- `type` is one of `queued`, `sent`, `delivered`, `opened`, `clicked`,
81
- `bounced`, `spam`, `failed`, `unsubscribed`. The event is appended to the
82
- send's timeline, the send status only ever moves forward, and a `bounced`,
83
- `spam` or `failed` event notifies the tenant owners in the DMS bell.
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.
84
293
 
85
294
  ## Retention
86
295
 
@@ -133,7 +342,8 @@ pnpm frontend:dev # the DMS front-end, in another terminal
133
342
 
134
343
  The backend listens on `http://localhost:5010` and needs a MongoDB on
135
344
  `mongodb://localhost:27017` (database `playground_dms_mailing`); set
136
- `MONGO_URL` to point the playground at another instance.
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.
137
347
 
138
348
  Both packages are public on npm, published under the `@antelopejs` scope with
139
349
  npm trusted publishing and provenance. The interface package must be released
@@ -143,7 +353,7 @@ DMS mailing module` publishes this package and refuses to run until the
143
353
  interface version its dependency range is floored at resolves on npm. Inside
144
354
  the workspace that same range resolves to the sibling package, through
145
355
  `link-workspace-packages`. The module implements the interface, so that range
146
- is capped below the next minor (`>=0.5.0 <0.6.0`): a breaking interface minor
356
+ is capped below the next minor (`>=0.7.0 <0.8.0`): a breaking interface minor
147
357
  never reaches a module that does not implement it, and the release workflow
148
358
  refuses any other shape.
149
359
 
@@ -11,7 +11,7 @@ const CONFIG_SCHEMA = {
11
11
  properties: {
12
12
  types: {
13
13
  type: "array",
14
- items: { type: "string", enum: types_1.SEND_STATUSES },
14
+ items: { type: "string", enum: types_1.SEND_EVENT_TYPES },
15
15
  description: "Event types the trigger fires on. Leave empty to fire on every event.",
16
16
  },
17
17
  },
@@ -22,7 +22,7 @@ const OUTPUT_SCHEMA = {
22
22
  tenantId: { type: "string" },
23
23
  sendId: { type: "string" },
24
24
  templateSlug: { type: "string" },
25
- type: { type: "string", enum: types_1.SEND_STATUSES },
25
+ type: { type: "string", enum: types_1.SEND_EVENT_TYPES },
26
26
  recipientEmail: { type: "string" },
27
27
  },
28
28
  };
@@ -1 +1 @@
1
- {"version":3,"file":"email-event-trigger.js","sourceRoot":"","sources":["../../src/automation/email-event-trigger.ts"],"names":[],"mappings":";;;AA8EA,wCAIC;AAGD,oEAEC;AAvFD,gEAA6D;AAK7D,oCAA6D;AAmBhD,QAAA,sBAAsB,GAAG,qBAAqB,CAAC;AAE5D,MAAM,aAAa,GAAe;IAChC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,KAAK,EAAE;YACL,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,qBAAa,EAAE;YAC9C,WAAW,EACT,uEAAuE;SAC1E;KACF;CACF,CAAC;AAEF,MAAM,aAAa,GAAe;IAChC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC5B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC1B,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAChC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,qBAAa,EAAE;QAC7C,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KACnC;CACF,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAEnC,MAAM,2BAA2B,GAAG,yCAAyC,CAAC;AAE9E,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkC,CAAC;AAEhE,IAAI,qBAAqB,GAAG,wBAAwB,CAAC;AAErD,MAAM,OAAO,GAAG,CACd,YAAoC,EACpC,OAA0B,EACjB,EAAE,CACX,YAAY,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE/E,SAAS,OAAO,CACd,MAAc,EACd,YAAoC,EACpC,OAA0B;IAE1B,IAAI,CAAC;QACH,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,iBAAO,CAAC,IAAI,CACV,GAAG,2BAA2B,KAAK,MAAM,kBAAkB,OAAO,CAAC,IAAI,UAAU,EACjF,KAAK,CACN,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,cAAc,CAAC,OAA0B;IACvD,KAAK,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,aAAa,EAAE,CAAC;QACnD,IAAI,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC;YAAE,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAGD,SAAgB,4BAA4B;IAC1C,aAAa,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC;AAEY,QAAA,iBAAiB,GAG1B;IACF,EAAE,EAAE,8BAAsB;IAC1B,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,kEAAkE;IACpE,IAAI,EAAE,mBAAmB;IACzB,OAAO,EAAE,YAAY;IACrB,YAAY,EAAE,aAAa;IAC3B,YAAY,EAAE,aAAa;IAC3B,QAAQ,CAAC,MAAM,EAAE,IAAI;QACnB,MAAM,MAAM,GAAG,GAAG,8BAAsB,IAAI,qBAAqB,EAAE,CAAC;QACpE,qBAAqB,IAAI,CAAC,CAAC;QAC3B,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IACD,UAAU,CAAC,MAAM;QACf,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACrC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"email-event-trigger.js","sourceRoot":"","sources":["../../src/automation/email-event-trigger.ts"],"names":[],"mappings":";;;AA8EA,wCAIC;AAGD,oEAEC;AAvFD,gEAA6D;AAK7D,oCAAgE;AAmBnD,QAAA,sBAAsB,GAAG,qBAAqB,CAAC;AAE5D,MAAM,aAAa,GAAe;IAChC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,KAAK,EAAE;YACL,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,wBAAgB,EAAE;YACjD,WAAW,EACT,uEAAuE;SAC1E;KACF;CACF,CAAC;AAEF,MAAM,aAAa,GAAe;IAChC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC5B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC1B,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAChC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,wBAAgB,EAAE;QAChD,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KACnC;CACF,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAEnC,MAAM,2BAA2B,GAAG,yCAAyC,CAAC;AAE9E,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkC,CAAC;AAEhE,IAAI,qBAAqB,GAAG,wBAAwB,CAAC;AAErD,MAAM,OAAO,GAAG,CACd,YAAoC,EACpC,OAA0B,EACjB,EAAE,CACX,YAAY,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE/E,SAAS,OAAO,CACd,MAAc,EACd,YAAoC,EACpC,OAA0B;IAE1B,IAAI,CAAC;QACH,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,iBAAO,CAAC,IAAI,CACV,GAAG,2BAA2B,KAAK,MAAM,kBAAkB,OAAO,CAAC,IAAI,UAAU,EACjF,KAAK,CACN,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,cAAc,CAAC,OAA0B;IACvD,KAAK,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,aAAa,EAAE,CAAC;QACnD,IAAI,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC;YAAE,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAGD,SAAgB,4BAA4B;IAC1C,aAAa,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC;AAEY,QAAA,iBAAiB,GAG1B;IACF,EAAE,EAAE,8BAAsB;IAC1B,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,kEAAkE;IACpE,IAAI,EAAE,mBAAmB;IACzB,OAAO,EAAE,YAAY;IACrB,YAAY,EAAE,aAAa;IAC3B,YAAY,EAAE,aAAa;IAC3B,QAAQ,CAAC,MAAM,EAAE,IAAI;QACnB,MAAM,MAAM,GAAG,GAAG,8BAAsB,IAAI,qBAAqB,EAAE,CAAC;QACpE,qBAAqB,IAAI,CAAC,CAAC;QAC3B,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IACD,UAAU,CAAC,MAAM;QACf,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACrC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF,CAAC"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.sendTemplateAction = exports.SEND_TEMPLATE_ACTION_ID = void 0;
4
- const send_1 = require("../services/send");
4
+ const checked_send_1 = require("../services/checked-send");
5
5
  const types_1 = require("../types");
6
6
  exports.SEND_TEMPLATE_ACTION_ID = "mailing.send-template";
7
7
  const AUTOMATION_SOURCE_PREFIX = "automation:";
@@ -49,7 +49,7 @@ exports.sendTemplateAction = {
49
49
  async execute(input, ctx) {
50
50
  const source = input.source ?? `${AUTOMATION_SOURCE_PREFIX}${ctx.procedureId}`;
51
51
  try {
52
- const result = await (0, send_1.sendTemplate)(input.slug, {
52
+ const result = await (0, checked_send_1.sendUnlessSuppressed)(input.slug, {
53
53
  tenantId: input.tenantId,
54
54
  to: input.to,
55
55
  locale: input.locale,
@@ -1 +1 @@
1
- {"version":3,"file":"send-template-action.js","sourceRoot":"","sources":["../../src/automation/send-template-action.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"send-template-action.js","sourceRoot":"","sources":["../../src/automation/send-template-action.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -2,7 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setConfig = setConfig;
4
4
  exports.getConfig = getConfig;
5
- const DEFAULTS = { useHtmlRender: true };
5
+ const DEFAULTS = {
6
+ useHtmlRender: true,
7
+ };
6
8
  let current = DEFAULTS;
7
9
  function setConfig(config) {
8
10
  current = { ...DEFAULTS, ...config };
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAQA,8BAEC;AAED,8BAEC;AAVD,MAAM,QAAQ,GAA+B,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AAErE,IAAI,OAAO,GAA+B,QAAQ,CAAC;AAEnD,SAAgB,SAAS,CAAC,MAAwB;IAChD,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;AACvC,CAAC;AAED,SAAgB,SAAS;IACvB,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAUA,8BAEC;AAED,8BAEC;AAZD,MAAM,QAAQ,GAA+B;IAC3C,aAAa,EAAE,IAAI;CACpB,CAAC;AAEF,IAAI,OAAO,GAA+B,QAAQ,CAAC;AAEnD,SAAgB,SAAS,CAAC,MAAwB;IAChD,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;AACvC,CAAC;AAED,SAAgB,SAAS;IACvB,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1,13 +1,19 @@
1
1
  export declare const MODULE_ID = "mailing";
2
2
  export declare const API_BASE_PATH = "/api/mailing";
3
3
  export declare const TABLES_BASE_PATH = "/api/mailing/tables";
4
+ export declare const MODULE_BASE_PATH = "/modules/mailing";
5
+ export declare const TEMPLATES_PATH = "/modules/mailing/templates";
6
+ export declare const SENDS_PATH = "/modules/mailing/sends";
7
+ export declare const SETTINGS_PATH = "/modules/mailing/settings";
8
+ export declare const NEW_TEMPLATE_BUTTON_ID = "create";
9
+ export declare const NEW_TEMPLATE_ACTION_ID = "mailing.new-template";
4
10
  export declare const FRONTEND_MODULE_NAME = "@antelopejs/dms-mailing-frontend-vue";
5
11
  export declare const EMAIL_TEMPLATE_NAME = "EmailMailingTemplate";
6
12
  export declare const MAILING_SEND_PERMISSION = "mailing.send";
7
13
  export declare const OVERVIEW_PERIOD_SCOPE = "mailing-overview";
8
14
  export declare const SENDS_PERIOD_SCOPE = "mailing-sends";
9
15
  export declare const MAILING_SENDS_TOPIC = "mailing:sends";
10
- export declare const GALLERY_DISPLAY_ID = "gallery";
16
+ export declare const GALLERY_DISPLAY_ID = "mailing:gallery";
11
17
  export declare const TEMPLATE_CATEGORIES_TYPE_ID = "mailing_template_categories";
12
18
  export declare const TEMPLATE_CATEGORY_TYPE_ID = "mailing_template_category";
13
19
  export declare const DEFAULT_FALLBACK_LOCALE = "en";
@@ -21,5 +27,8 @@ export declare const HTTP_NOT_FOUND = 404;
21
27
  export declare const HTTP_CONFLICT = 409;
22
28
  export declare const HTTP_UNPROCESSABLE = 422;
23
29
  export declare const LOCALE_LIST_SEPARATOR = ",";
30
+ export declare const ARCHIVED_STATUS = "archived";
31
+ export declare const UNSUBSCRIBE_URL_PATH = "unsubscribeUrl";
32
+ export declare const PREFERENCES_URL_PATH = "preferencesUrl";
24
33
  export declare const SYSTEM_VARIABLE_PATHS: string[];
25
34
  export declare const MAX_WINDOW_DAYS = 400;
package/dist/constants.js CHANGED
@@ -1,16 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MAX_WINDOW_DAYS = exports.SYSTEM_VARIABLE_PATHS = exports.LOCALE_LIST_SEPARATOR = exports.HTTP_UNPROCESSABLE = exports.HTTP_CONFLICT = exports.HTTP_NOT_FOUND = exports.HTTP_FORBIDDEN = exports.HTTP_BAD_REQUEST = exports.SLUG_PATTERN = exports.MAX_NAME_LENGTH = exports.MAX_SLUG_LENGTH = exports.DEFAULT_LOG_RETENTION_DAYS = exports.DEFAULT_FALLBACK_LOCALE = exports.TEMPLATE_CATEGORY_TYPE_ID = exports.TEMPLATE_CATEGORIES_TYPE_ID = exports.GALLERY_DISPLAY_ID = exports.MAILING_SENDS_TOPIC = exports.SENDS_PERIOD_SCOPE = exports.OVERVIEW_PERIOD_SCOPE = exports.MAILING_SEND_PERMISSION = exports.EMAIL_TEMPLATE_NAME = exports.FRONTEND_MODULE_NAME = exports.TABLES_BASE_PATH = exports.API_BASE_PATH = exports.MODULE_ID = void 0;
3
+ exports.MAX_WINDOW_DAYS = exports.SYSTEM_VARIABLE_PATHS = exports.PREFERENCES_URL_PATH = exports.UNSUBSCRIBE_URL_PATH = exports.ARCHIVED_STATUS = exports.LOCALE_LIST_SEPARATOR = exports.HTTP_UNPROCESSABLE = exports.HTTP_CONFLICT = exports.HTTP_NOT_FOUND = exports.HTTP_FORBIDDEN = exports.HTTP_BAD_REQUEST = exports.SLUG_PATTERN = exports.MAX_NAME_LENGTH = exports.MAX_SLUG_LENGTH = exports.DEFAULT_LOG_RETENTION_DAYS = exports.DEFAULT_FALLBACK_LOCALE = exports.TEMPLATE_CATEGORY_TYPE_ID = exports.TEMPLATE_CATEGORIES_TYPE_ID = exports.GALLERY_DISPLAY_ID = exports.MAILING_SENDS_TOPIC = exports.SENDS_PERIOD_SCOPE = exports.OVERVIEW_PERIOD_SCOPE = exports.MAILING_SEND_PERMISSION = exports.EMAIL_TEMPLATE_NAME = exports.FRONTEND_MODULE_NAME = exports.NEW_TEMPLATE_ACTION_ID = exports.NEW_TEMPLATE_BUTTON_ID = exports.SETTINGS_PATH = exports.SENDS_PATH = exports.TEMPLATES_PATH = exports.MODULE_BASE_PATH = exports.TABLES_BASE_PATH = exports.API_BASE_PATH = exports.MODULE_ID = void 0;
4
4
  exports.MODULE_ID = "mailing";
5
5
  exports.API_BASE_PATH = "/api/mailing";
6
6
  exports.TABLES_BASE_PATH = `${exports.API_BASE_PATH}/tables`;
7
+ exports.MODULE_BASE_PATH = `/modules/${exports.MODULE_ID}`;
8
+ exports.TEMPLATES_PATH = `${exports.MODULE_BASE_PATH}/templates`;
9
+ exports.SENDS_PATH = `${exports.MODULE_BASE_PATH}/sends`;
10
+ exports.SETTINGS_PATH = `${exports.MODULE_BASE_PATH}/settings`;
11
+ exports.NEW_TEMPLATE_BUTTON_ID = "create";
12
+ exports.NEW_TEMPLATE_ACTION_ID = "mailing.new-template";
7
13
  exports.FRONTEND_MODULE_NAME = "@antelopejs/dms-mailing-frontend-vue";
8
14
  exports.EMAIL_TEMPLATE_NAME = "EmailMailingTemplate";
9
15
  exports.MAILING_SEND_PERMISSION = "mailing.send";
10
16
  exports.OVERVIEW_PERIOD_SCOPE = "mailing-overview";
11
17
  exports.SENDS_PERIOD_SCOPE = "mailing-sends";
12
18
  exports.MAILING_SENDS_TOPIC = "mailing:sends";
13
- exports.GALLERY_DISPLAY_ID = "gallery";
19
+ exports.GALLERY_DISPLAY_ID = `${exports.MODULE_ID}:gallery`;
14
20
  exports.TEMPLATE_CATEGORIES_TYPE_ID = "mailing_template_categories";
15
21
  exports.TEMPLATE_CATEGORY_TYPE_ID = "mailing_template_category";
16
22
  exports.DEFAULT_FALLBACK_LOCALE = "en";
@@ -24,6 +30,12 @@ exports.HTTP_NOT_FOUND = 404;
24
30
  exports.HTTP_CONFLICT = 409;
25
31
  exports.HTTP_UNPROCESSABLE = 422;
26
32
  exports.LOCALE_LIST_SEPARATOR = ",";
27
- exports.SYSTEM_VARIABLE_PATHS = ["unsubscribeUrl", "preferencesUrl"];
33
+ exports.ARCHIVED_STATUS = "archived";
34
+ exports.UNSUBSCRIBE_URL_PATH = "unsubscribeUrl";
35
+ exports.PREFERENCES_URL_PATH = "preferencesUrl";
36
+ exports.SYSTEM_VARIABLE_PATHS = [
37
+ exports.UNSUBSCRIBE_URL_PATH,
38
+ exports.PREFERENCES_URL_PATH,
39
+ ];
28
40
  exports.MAX_WINDOW_DAYS = 400;
29
41
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,SAAS,GAAG,SAAS,CAAC;AACtB,QAAA,aAAa,GAAG,cAAc,CAAC;AAC/B,QAAA,gBAAgB,GAAG,GAAG,qBAAa,SAAS,CAAC;AAC7C,QAAA,oBAAoB,GAAG,sCAAsC,CAAC;AAC9D,QAAA,mBAAmB,GAAG,sBAAsB,CAAC;AAE7C,QAAA,uBAAuB,GAAG,cAAc,CAAC;AAEzC,QAAA,qBAAqB,GAAG,kBAAkB,CAAC;AAC3C,QAAA,kBAAkB,GAAG,eAAe,CAAC;AAErC,QAAA,mBAAmB,GAAG,eAAe,CAAC;AAEtC,QAAA,kBAAkB,GAAG,SAAS,CAAC;AAC/B,QAAA,2BAA2B,GAAG,6BAA6B,CAAC;AAC5D,QAAA,yBAAyB,GAAG,2BAA2B,CAAC;AAExD,QAAA,uBAAuB,GAAG,IAAI,CAAC;AAC/B,QAAA,0BAA0B,GAAG,EAAE,CAAC;AAChC,QAAA,eAAe,GAAG,EAAE,CAAC;AACrB,QAAA,eAAe,GAAG,GAAG,CAAC;AACtB,QAAA,YAAY,GAAG,sBAAsB,CAAC;AAEtC,QAAA,gBAAgB,GAAG,GAAG,CAAC;AACvB,QAAA,cAAc,GAAG,GAAG,CAAC;AACrB,QAAA,cAAc,GAAG,GAAG,CAAC;AACrB,QAAA,aAAa,GAAG,GAAG,CAAC;AACpB,QAAA,kBAAkB,GAAG,GAAG,CAAC;AAEzB,QAAA,qBAAqB,GAAG,GAAG,CAAC;AAE5B,QAAA,qBAAqB,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;AAO7D,QAAA,eAAe,GAAG,GAAG,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,SAAS,GAAG,SAAS,CAAC;AACtB,QAAA,aAAa,GAAG,cAAc,CAAC;AAC/B,QAAA,gBAAgB,GAAG,GAAG,qBAAa,SAAS,CAAC;AAC7C,QAAA,gBAAgB,GAAG,YAAY,iBAAS,EAAE,CAAC;AAC3C,QAAA,cAAc,GAAG,GAAG,wBAAgB,YAAY,CAAC;AACjD,QAAA,UAAU,GAAG,GAAG,wBAAgB,QAAQ,CAAC;AACzC,QAAA,aAAa,GAAG,GAAG,wBAAgB,WAAW,CAAC;AAC/C,QAAA,sBAAsB,GAAG,QAAQ,CAAC;AAClC,QAAA,sBAAsB,GAAG,sBAAsB,CAAC;AAChD,QAAA,oBAAoB,GAAG,sCAAsC,CAAC;AAC9D,QAAA,mBAAmB,GAAG,sBAAsB,CAAC;AAE7C,QAAA,uBAAuB,GAAG,cAAc,CAAC;AAEzC,QAAA,qBAAqB,GAAG,kBAAkB,CAAC;AAC3C,QAAA,kBAAkB,GAAG,eAAe,CAAC;AAErC,QAAA,mBAAmB,GAAG,eAAe,CAAC;AAEtC,QAAA,kBAAkB,GAAG,GAAG,iBAAS,UAAU,CAAC;AAC5C,QAAA,2BAA2B,GAAG,6BAA6B,CAAC;AAC5D,QAAA,yBAAyB,GAAG,2BAA2B,CAAC;AAExD,QAAA,uBAAuB,GAAG,IAAI,CAAC;AAC/B,QAAA,0BAA0B,GAAG,EAAE,CAAC;AAChC,QAAA,eAAe,GAAG,EAAE,CAAC;AACrB,QAAA,eAAe,GAAG,GAAG,CAAC;AACtB,QAAA,YAAY,GAAG,sBAAsB,CAAC;AAEtC,QAAA,gBAAgB,GAAG,GAAG,CAAC;AACvB,QAAA,cAAc,GAAG,GAAG,CAAC;AACrB,QAAA,cAAc,GAAG,GAAG,CAAC;AACrB,QAAA,aAAa,GAAG,GAAG,CAAC;AACpB,QAAA,kBAAkB,GAAG,GAAG,CAAC;AAEzB,QAAA,qBAAqB,GAAG,GAAG,CAAC;AAG5B,QAAA,eAAe,GAAG,UAAU,CAAC;AAE7B,QAAA,oBAAoB,GAAG,gBAAgB,CAAC;AACxC,QAAA,oBAAoB,GAAG,gBAAgB,CAAC;AAGxC,QAAA,qBAAqB,GAAG;IACnC,4BAAoB;IACpB,4BAAoB;CACrB,CAAC;AAOW,QAAA,eAAe,GAAG,GAAG,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CronJob } from "./jobs";
2
+ export declare function runAttentionRefresh(): Promise<void>;
3
+ export declare const ATTENTION_JOB: CronJob;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ATTENTION_JOB = void 0;
4
+ exports.runAttentionRefresh = runAttentionRefresh;
5
+ const interface_database_decorators_1 = require("@antelopejs/interface-database-decorators");
6
+ const db_1 = require("@antelopejs/interface-dms/db");
7
+ const template_attention_1 = require("../services/template-attention");
8
+ const ATTENTION_SCHEDULE = "5 * * * *";
9
+ async function runAttentionRefresh() {
10
+ const tenants = await (0, interface_database_decorators_1.GetModel)(db_1.TenantModel).getAll();
11
+ for (const tenant of tenants)
12
+ await (0, template_attention_1.refreshTemplateAttention)(tenant._id);
13
+ }
14
+ exports.ATTENTION_JOB = {
15
+ name: "mailing-attention",
16
+ schedule: ATTENTION_SCHEDULE,
17
+ run: runAttentionRefresh,
18
+ };
19
+ //# sourceMappingURL=attention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attention.js","sourceRoot":"","sources":["../../src/crons/attention.ts"],"names":[],"mappings":";;;AAWA,kDAGC;AAdD,6FAAqE;AACrE,qDAA2D;AAC3D,uEAA0E;AAO1E,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAEhC,KAAK,UAAU,mBAAmB;IACvC,MAAM,OAAO,GAAG,MAAM,IAAA,wCAAQ,EAAC,gBAAW,CAAC,CAAC,MAAM,EAAE,CAAC;IACrD,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,MAAM,IAAA,6CAAwB,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC3E,CAAC;AAEY,QAAA,aAAa,GAAY;IACpC,IAAI,EAAE,mBAAmB;IACzB,QAAQ,EAAE,kBAAkB;IAC5B,GAAG,EAAE,mBAAmB;CACzB,CAAC"}
@@ -1 +1,3 @@
1
+ export * from "./attention";
2
+ export * from "./jobs";
1
3
  export * from "./retention";
@@ -14,5 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./attention"), exports);
18
+ __exportStar(require("./jobs"), exports);
17
19
  __exportStar(require("./retention"), exports);
18
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/crons/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/crons/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,yCAAuB;AACvB,8CAA4B"}
@@ -0,0 +1,12 @@
1
+ import { type ScheduledTask } from "node-cron";
2
+ export interface CronJob {
3
+ name: string;
4
+ schedule: string;
5
+ run: () => Promise<unknown>;
6
+ }
7
+ export interface ScheduledJob {
8
+ name: string;
9
+ task: ScheduledTask;
10
+ }
11
+ export declare function scheduleJob(job: CronJob): ScheduledJob;
12
+ export declare function stopJob(job: ScheduledJob): Promise<void>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.scheduleJob = scheduleJob;
7
+ exports.stopJob = stopJob;
8
+ const logging_1 = require("@antelopejs/interface-core/logging");
9
+ const node_cron_1 = __importDefault(require("node-cron"));
10
+ function scheduleJob(job) {
11
+ const task = node_cron_1.default.schedule(job.schedule, () => {
12
+ void job.run().catch((error) => {
13
+ logging_1.Logging.Error(`Cron '${job.name}' failed:`, error);
14
+ });
15
+ });
16
+ return { name: job.name, task };
17
+ }
18
+ async function stopJob(job) {
19
+ try {
20
+ await job.task.stop();
21
+ await job.task.destroy();
22
+ }
23
+ catch (error) {
24
+ logging_1.Logging.Error(`Cron '${job.name}' failed to stop:`, error);
25
+ }
26
+ }
27
+ //# sourceMappingURL=jobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/crons/jobs.ts"],"names":[],"mappings":";;;;;AAiBA,kCAOC;AAGD,0BAOC;AAlCD,gEAA6D;AAC7D,0DAAqD;AAgBrD,SAAgB,WAAW,CAAC,GAAY;IACtC,MAAM,IAAI,GAAG,mBAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE;QAC5C,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACtC,iBAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,IAAI,WAAW,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC;AAGM,KAAK,UAAU,OAAO,CAAC,GAAiB;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,iBAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,IAAI,mBAAmB,EAAE,KAAK,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC"}
@@ -1,5 +1,4 @@
1
- import { type ScheduledTask } from "node-cron";
2
- export declare const RETENTION_CRON_NAME = "mailing-retention";
1
+ import type { CronJob } from "./jobs";
3
2
  export interface RetentionLimits {
4
3
  pageSize: number;
5
4
  maxRows: number;
@@ -14,5 +13,4 @@ export declare function purgeInPages(pass: RetentionPass, limits?: RetentionLimi
14
13
  export declare function purgeSend(tenantId: string, sendId: string, limit: Date): Promise<number>;
15
14
  export declare function purgeOrphanEvents(tenantId: string, pageSize?: number): Promise<void>;
16
15
  export declare function runRetention(now?: Date): Promise<number>;
17
- export declare function stopRetention(task: ScheduledTask | undefined): Promise<void>;
18
- export declare function scheduleRetention(): ScheduledTask;
16
+ export declare const RETENTION_JOB: CronJob;
@@ -1,22 +1,15 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.RETENTION_LIMITS = exports.RETENTION_CRON_NAME = void 0;
3
+ exports.RETENTION_JOB = exports.RETENTION_LIMITS = void 0;
7
4
  exports.retentionLimit = retentionLimit;
8
5
  exports.purgeInPages = purgeInPages;
9
6
  exports.purgeSend = purgeSend;
10
7
  exports.purgeOrphanEvents = purgeOrphanEvents;
11
8
  exports.runRetention = runRetention;
12
- exports.stopRetention = stopRetention;
13
- exports.scheduleRetention = scheduleRetention;
14
9
  const logging_1 = require("@antelopejs/interface-core/logging");
15
10
  const interface_database_decorators_1 = require("@antelopejs/interface-database-decorators");
16
11
  const db_1 = require("@antelopejs/interface-dms/db");
17
- const node_cron_1 = __importDefault(require("node-cron"));
18
12
  const db_2 = require("../db");
19
- exports.RETENTION_CRON_NAME = "mailing-retention";
20
13
  exports.RETENTION_LIMITS = {
21
14
  pageSize: 500,
22
15
  maxRows: 20_000,
@@ -75,7 +68,7 @@ async function purgeOrphanEvents(tenantId, pageSize = exports.RETENTION_LIMITS.p
75
68
  }
76
69
  }
77
70
  async function purgeTenant(tenantId, now) {
78
- const settings = await (0, interface_database_decorators_1.GetModel)(db_2.SettingsModel, tenantId).getSingleton(tenantId);
71
+ const settings = await (0, interface_database_decorators_1.GetModel)(db_2.SettingsModel, tenantId).get(tenantId);
79
72
  if (!settings || settings.logRetentionDays < MIN_RETENTION_DAYS)
80
73
  return 0;
81
74
  const limit = retentionLimit(settings.logRetentionDays, now);
@@ -91,17 +84,9 @@ async function runRetention(now = new Date()) {
91
84
  logging_1.Logging.Info(`[dms-mailing] Retention purged ${purged} sends`);
92
85
  return purged;
93
86
  }
94
- async function stopRetention(task) {
95
- if (!task)
96
- return;
97
- await task.stop();
98
- await task.destroy();
99
- }
100
- function scheduleRetention() {
101
- return node_cron_1.default.schedule(RETENTION_SCHEDULE, () => {
102
- void runRetention().catch((error) => {
103
- logging_1.Logging.Error(`Cron '${exports.RETENTION_CRON_NAME}' failed:`, error);
104
- });
105
- });
106
- }
87
+ exports.RETENTION_JOB = {
88
+ name: "mailing-retention",
89
+ schedule: RETENTION_SCHEDULE,
90
+ run: runRetention,
91
+ };
107
92
  //# sourceMappingURL=retention.js.map