@cosmicdrift/kumiko-samples 0.361.0 → 0.363.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 (265) hide show
  1. package/package.json +1 -1
  2. package/packages/bundled-features/package.json +17 -6
  3. package/packages/bundled-features/src/admin-shell/changes.json +6 -0
  4. package/packages/bundled-features/src/admin-shell/feature.ts +8 -1
  5. package/packages/bundled-features/src/agent-tools/agent-manifest.ts +3 -4
  6. package/packages/bundled-features/src/agent-tools/filter-ops.ts +1 -3
  7. package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -3
  8. package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +2 -1
  9. package/packages/bundled-features/src/auth-email-password/changes.json +14 -0
  10. package/packages/bundled-features/src/auth-email-password/email-templates.ts +12 -138
  11. package/packages/bundled-features/src/auth-email-password/feature.ts +30 -9
  12. package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +4 -5
  13. package/packages/bundled-features/src/auth-email-password/handlers/request-account-unlock.write.ts +2 -5
  14. package/packages/bundled-features/src/auth-email-password/handlers/request-email-verification.write.ts +2 -5
  15. package/packages/bundled-features/src/auth-email-password/handlers/request-password-reset.write.ts +2 -5
  16. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +3 -4
  17. package/packages/bundled-features/src/auth-email-password/handlers/token-request-handler.ts +3 -12
  18. package/packages/bundled-features/src/auth-email-password/index.ts +2 -17
  19. package/packages/bundled-features/src/auth-email-password/magic-link-mail.ts +30 -22
  20. package/packages/bundled-features/src/auth-email-password/mail-notifications.ts +158 -0
  21. package/packages/bundled-features/src/auth-email-password/signup-activation.ts +2 -3
  22. package/packages/bundled-features/src/auth-foundation/types.ts +8 -18
  23. package/packages/bundled-features/src/auth-mfa/feature.ts +8 -10
  24. package/packages/bundled-features/src/auth-mfa/hmac-token-codec.ts +4 -4
  25. package/packages/bundled-features/src/auth-mfa/mfa-challenge-token.ts +3 -3
  26. package/packages/bundled-features/src/auth-mfa/mfa-preauth-setup-token.ts +3 -3
  27. package/packages/bundled-features/src/auth-mfa/mfa-setup-token.ts +8 -8
  28. package/packages/bundled-features/src/billing-foundation/changes.json +7 -0
  29. package/packages/bundled-features/src/billing-foundation/constants.ts +5 -4
  30. package/packages/bundled-features/src/billing-foundation/consumer-protection/confirmation-mail.ts +38 -44
  31. package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +3 -3
  32. package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +115 -0
  33. package/packages/bundled-features/src/billing-foundation/consumer-protection/register-consent.ts +2 -0
  34. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-mail.ts +30 -30
  35. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-notify.ts +2 -2
  36. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-pages.ts +1 -4
  37. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +2 -2
  38. package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +2 -2
  39. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +4 -9
  40. package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +1 -1
  41. package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +2 -2
  42. package/packages/bundled-features/src/billing-foundation/handlers/process-payment-event.write.ts +1 -1
  43. package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -6
  44. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +2 -1
  45. package/packages/bundled-features/src/cap-overview/web/cap-usage-cell.tsx +6 -4
  46. package/packages/bundled-features/src/channel-email/changes.json +19 -0
  47. package/packages/bundled-features/src/channel-email/email-channel.ts +122 -29
  48. package/packages/bundled-features/src/channel-email/feature.ts +6 -3
  49. package/packages/bundled-features/src/channel-email/index.ts +7 -1
  50. package/packages/bundled-features/src/channel-email/pii-guard.ts +13 -0
  51. package/packages/bundled-features/src/channel-email/smtp-transport.ts +15 -1
  52. package/packages/bundled-features/src/channel-email/types.ts +23 -0
  53. package/packages/bundled-features/src/channel-in-app/handlers/mark-read.write.ts +2 -2
  54. package/packages/bundled-features/src/config/handlers/set.write.ts +1 -5
  55. package/packages/bundled-features/src/custom-fields/db/queries/user-data-rights.ts +2 -2
  56. package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -11
  57. package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +7 -6
  58. package/packages/bundled-features/src/data-retention/changes.json +6 -0
  59. package/packages/bundled-features/src/data-retention/index.ts +1 -0
  60. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +8 -6
  61. package/packages/bundled-features/src/delivery/attachment-ref.ts +84 -0
  62. package/packages/bundled-features/src/delivery/changes.json +48 -0
  63. package/packages/bundled-features/src/delivery/channel-context.ts +129 -4
  64. package/packages/bundled-features/src/delivery/constants.ts +2 -0
  65. package/packages/bundled-features/src/delivery/delivery-service.ts +104 -26
  66. package/packages/bundled-features/src/delivery/feature.ts +1 -1
  67. package/packages/bundled-features/src/delivery/index.ts +17 -2
  68. package/packages/bundled-features/src/delivery/jobs.ts +48 -5
  69. package/packages/bundled-features/src/delivery/notify-factory.ts +14 -9
  70. package/packages/bundled-features/src/delivery/testing.ts +9 -1
  71. package/packages/bundled-features/src/delivery/types.ts +28 -18
  72. package/packages/bundled-features/src/delivery/unsubscribe.ts +5 -2
  73. package/packages/bundled-features/src/derivatives-sharp/render.ts +1 -22
  74. package/packages/bundled-features/src/document-ingest-foundation/aggregate-id.ts +10 -0
  75. package/packages/bundled-features/src/document-ingest-foundation/changes.json +6 -0
  76. package/packages/bundled-features/src/document-ingest-foundation/events.ts +3 -1
  77. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +5 -3
  78. package/packages/bundled-features/src/document-ingest-foundation/index.ts +1 -0
  79. package/packages/bundled-features/src/document-ingest-foundation/pages.ts +6 -3
  80. package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +4 -4
  81. package/packages/bundled-features/src/file-foundation/index.ts +7 -0
  82. package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +86 -0
  83. package/packages/bundled-features/src/folders/web/folder-manager.tsx +5 -2
  84. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +11 -11
  85. package/packages/bundled-features/src/form-draft/db/queries/draft-count.ts +2 -2
  86. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +2 -2
  87. package/packages/bundled-features/src/form-draft/release-file-refs.ts +3 -2
  88. package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +1 -1
  89. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +6 -6
  90. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +1 -1
  91. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +1 -1
  92. package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +2 -2
  93. package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +7 -7
  94. package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +2 -6
  95. package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +5 -13
  96. package/packages/bundled-features/src/inbound-mail-foundation/types.ts +4 -6
  97. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +40 -25
  98. package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +4 -3
  99. package/packages/bundled-features/src/jobs/handlers/catalog.query.ts +1 -1
  100. package/packages/bundled-features/src/ledger/recurring.ts +1 -3
  101. package/packages/bundled-features/src/managed-pages/branding.ts +33 -9
  102. package/packages/bundled-features/src/managed-pages/changes.json +6 -0
  103. package/packages/bundled-features/src/managed-pages/feature.ts +1 -0
  104. package/packages/bundled-features/src/managed-pages/i18n.ts +1 -0
  105. package/packages/bundled-features/src/managed-pages/screens/branding-screen.ts +8 -0
  106. package/packages/bundled-features/src/page-render/branding.ts +3 -0
  107. package/packages/bundled-features/src/page-render/markdown.ts +1 -1
  108. package/packages/bundled-features/src/personal-access-tokens/feature.ts +2 -4
  109. package/packages/bundled-features/src/personal-access-tokens/handlers/list.query.ts +2 -1
  110. package/packages/bundled-features/src/personal-access-tokens/index.ts +1 -1
  111. package/packages/bundled-features/src/personal-access-tokens/revoke-for-user.ts +2 -1
  112. package/packages/bundled-features/src/renderer-foundation/README.md +11 -10
  113. package/packages/bundled-features/src/renderer-foundation/api.ts +14 -14
  114. package/packages/bundled-features/src/renderer-foundation/changes.json +39 -0
  115. package/packages/bundled-features/src/renderer-foundation/constants.ts +6 -8
  116. package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
  117. package/packages/bundled-features/src/renderer-foundation/index.ts +13 -2
  118. package/packages/bundled-features/src/renderer-foundation/types.ts +132 -35
  119. package/packages/bundled-features/src/renderer-pdf/feature.ts +7 -1
  120. package/packages/bundled-features/src/sessions/db/queries/cleanup.ts +2 -2
  121. package/packages/bundled-features/src/sessions/feature.ts +2 -4
  122. package/packages/bundled-features/src/sessions/handlers/list.query.ts +2 -1
  123. package/packages/bundled-features/src/shared/attachment-file-name.ts +39 -0
  124. package/packages/bundled-features/src/shared/index.ts +6 -0
  125. package/packages/bundled-features/src/shared/is-tenant-db.ts +1 -1
  126. package/packages/bundled-features/src/shared/mail-template-body.ts +25 -0
  127. package/packages/bundled-features/src/shared/sharp-input-limits.ts +26 -0
  128. package/packages/bundled-features/src/shared/signup-handover.ts +4 -4
  129. package/packages/bundled-features/src/tags/handlers/assign-tag.write.ts +5 -1
  130. package/packages/bundled-features/src/tags/web/tag-chip.tsx +2 -1
  131. package/packages/bundled-features/src/template-resolver/README.md +63 -7
  132. package/packages/bundled-features/src/template-resolver/api.ts +83 -8
  133. package/packages/bundled-features/src/template-resolver/changes.json +118 -0
  134. package/packages/bundled-features/src/template-resolver/compile-document-body.ts +214 -0
  135. package/packages/bundled-features/src/template-resolver/constants.ts +39 -11
  136. package/packages/bundled-features/src/template-resolver/document-sanitizer.ts +335 -0
  137. package/packages/bundled-features/src/template-resolver/document-schema.ts +323 -0
  138. package/packages/bundled-features/src/template-resolver/feature.ts +56 -6
  139. package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +188 -0
  140. package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +30 -2
  141. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +142 -0
  142. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +72 -0
  143. package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +83 -0
  144. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +3 -3
  145. package/packages/bundled-features/src/template-resolver/handlers/import-bundle-system.write.ts +42 -0
  146. package/packages/bundled-features/src/template-resolver/handlers/import-bundle.write.ts +22 -0
  147. package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +108 -0
  148. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +5 -7
  149. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +250 -0
  150. package/packages/bundled-features/src/template-resolver/handlers/preview.query.ts +25 -0
  151. package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +58 -0
  152. package/packages/bundled-features/src/template-resolver/handlers/resource-link-pdf.write.ts +34 -0
  153. package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +50 -0
  154. package/packages/bundled-features/src/template-resolver/handlers/resource-shared.ts +24 -0
  155. package/packages/bundled-features/src/template-resolver/handlers/resource-upload.write.ts +135 -0
  156. package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +106 -0
  157. package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +32 -3
  158. package/packages/bundled-features/src/template-resolver/handlers/shared.ts +7 -2
  159. package/packages/bundled-features/src/template-resolver/handlers/template-gates.ts +184 -0
  160. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +183 -0
  161. package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +55 -0
  162. package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +57 -10
  163. package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +19 -71
  164. package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +15 -76
  165. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +17 -0
  166. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +116 -0
  167. package/packages/bundled-features/src/template-resolver/index.ts +100 -0
  168. package/packages/bundled-features/src/template-resolver/layout-regions.ts +206 -0
  169. package/packages/bundled-features/src/template-resolver/linked-resources.ts +102 -0
  170. package/packages/bundled-features/src/template-resolver/preview-display-html.ts +36 -0
  171. package/packages/bundled-features/src/template-resolver/print-document.ts +58 -0
  172. package/packages/bundled-features/src/template-resolver/qualified-names.ts +30 -0
  173. package/packages/bundled-features/src/template-resolver/record-mapping.ts +26 -0
  174. package/packages/bundled-features/src/template-resolver/resource-image.ts +47 -0
  175. package/packages/bundled-features/src/template-resolver/seeding.ts +147 -17
  176. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +416 -0
  177. package/packages/bundled-features/src/template-resolver/table.ts +14 -0
  178. package/packages/bundled-features/src/template-resolver/template-bundle.ts +79 -0
  179. package/packages/bundled-features/src/template-resolver/template-diff.ts +78 -0
  180. package/packages/bundled-features/src/template-resolver/template-meta.ts +129 -0
  181. package/packages/bundled-features/src/template-resolver/template-preview.ts +573 -0
  182. package/packages/bundled-features/src/template-resolver/template-resources.ts +74 -0
  183. package/packages/bundled-features/src/template-resolver/template-usage.ts +48 -0
  184. package/packages/bundled-features/src/template-resolver/template-validation.ts +229 -0
  185. package/packages/bundled-features/src/template-resolver/testing.ts +5 -5
  186. package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +9 -6
  187. package/packages/bundled-features/src/template-resolver/web/document-editor-extensions.ts +162 -0
  188. package/packages/bundled-features/src/template-resolver/web/document-editor.tsx +28 -0
  189. package/packages/bundled-features/src/template-resolver/web/document-tiptap-editor.tsx +850 -0
  190. package/packages/bundled-features/src/template-resolver/web/document-toolbar-blocks.ts +61 -0
  191. package/packages/bundled-features/src/template-resolver/web/editor-handle.ts +26 -0
  192. package/packages/bundled-features/src/template-resolver/web/i18n.ts +100 -0
  193. package/packages/bundled-features/src/template-resolver/web/index.ts +19 -0
  194. package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor-lazy.tsx +36 -0
  195. package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor.tsx +169 -0
  196. package/packages/bundled-features/src/template-resolver/web/placeholder-text.ts +37 -0
  197. package/packages/bundled-features/src/template-resolver/web/use-stable-by-key.ts +14 -0
  198. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +3 -2
  199. package/packages/bundled-features/src/tenant/seeding.ts +41 -7
  200. package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
  201. package/packages/bundled-features/src/tenant-lifecycle/handlers/cancel-destruction.write.ts +2 -1
  202. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +4 -4
  203. package/packages/bundled-features/src/user/handlers/detail.query.ts +3 -5
  204. package/packages/bundled-features/src/user/roles-input-schema.ts +2 -2
  205. package/packages/bundled-features/src/user-data-rights/changes.json +14 -0
  206. package/packages/bundled-features/src/user-data-rights/db/queries/forget-cleanup.ts +2 -2
  207. package/packages/bundled-features/src/user-data-rights/email-templates.ts +5 -149
  208. package/packages/bundled-features/src/user-data-rights/feature.ts +72 -35
  209. package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +2 -1
  210. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +5 -1
  211. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +13 -1
  212. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +5 -11
  213. package/packages/bundled-features/src/user-data-rights/index.ts +1 -0
  214. package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +134 -53
  215. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +2 -2
  216. package/packages/bundled-features/src/user-data-rights/mail-notifications.ts +157 -0
  217. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +1 -1
  218. package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +6 -12
  219. package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +2 -1
  220. package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +10 -1
  221. package/packages/bundled-features/src/user-data-rights-defaults/hooks/download-attempt.userdata-hook.ts +58 -0
  222. package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +2 -1
  223. package/packages/bundled-features/src/waitlist/changes.json +7 -0
  224. package/packages/bundled-features/src/waitlist/feature.ts +17 -0
  225. package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +4 -5
  226. package/packages/bundled-features/src/waitlist/mail.ts +69 -18
  227. package/packages/bundled-features/src/workflow-runner/event-trigger.ts +1 -2
  228. package/samples/apps/ui-walkthrough/package.json +2 -0
  229. package/samples/apps/ui-walkthrough/src/app/auth-constants.ts +9 -0
  230. package/samples/apps/ui-walkthrough/src/app/client.tsx +6 -0
  231. package/samples/apps/ui-walkthrough/src/app/seed-templates.ts +154 -0
  232. package/samples/apps/ui-walkthrough/src/app/server.ts +5 -1
  233. package/samples/apps/ui-walkthrough/src/app/shell.tsx +12 -1
  234. package/samples/apps/ui-walkthrough/src/app/template-seed-data.ts +354 -0
  235. package/samples/apps/ui-walkthrough/src/features/billing/feature.ts +68 -0
  236. package/samples/apps/ui-walkthrough/src/features/billing/i18n.ts +18 -0
  237. package/samples/apps/ui-walkthrough/src/features/billing/index.ts +2 -0
  238. package/samples/apps/ui-walkthrough/src/features/billing/web/index.ts +7 -0
  239. package/samples/apps/ui-walkthrough/src/features/rental/screens.ts +1 -1
  240. package/samples/apps/ui-walkthrough/src/run-config.ts +37 -1
  241. package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-features.ts +0 -2
  242. package/samples/apps/use-all-bundled/feature-manifest.json +123 -22
  243. package/samples/apps/use-all-bundled/kumiko/migrations/0044_download-attempt-ip-bidx.rebuild.json +4 -0
  244. package/samples/apps/use-all-bundled/kumiko/migrations/0045_template-resource-meta.rebuild.json +4 -0
  245. package/samples/apps/use-all-bundled/kumiko/migrations/0046_pdf-rendered.rebuild.json +4 -0
  246. package/samples/apps/use-all-bundled/package.json +2 -0
  247. package/samples/apps/use-all-bundled/playwright.config.ts +38 -3
  248. package/samples/apps/use-all-bundled/schema/generate.ts +13 -3
  249. package/samples/apps/use-all-bundled/schema/schema.generated.ts +3 -0
  250. package/samples/apps/use-all-bundled/scripts/check-coverage.ts +3 -0
  251. package/samples/apps/use-all-bundled/src/app/auth-constants.ts +3 -0
  252. package/samples/apps/use-all-bundled/src/app/client.tsx +4 -0
  253. package/samples/apps/use-all-bundled/src/app/seed-documents.ts +128 -0
  254. package/samples/apps/use-all-bundled/src/app/seed.ts +4 -0
  255. package/samples/apps/use-all-bundled/src/run-config.ts +11 -11
  256. package/samples/recipes/delivery-notifications/README.md +26 -25
  257. package/samples/recipes/delivery-notifications/package.json +2 -1
  258. package/samples/recipes/delivery-notifications/src/feature.ts +64 -58
  259. package/samples/recipes/seed-migration/README.md +1 -1
  260. package/packages/bundled-features/src/renderer-simple/changes.json +0 -27
  261. package/packages/bundled-features/src/renderer-simple/feature.ts +0 -66
  262. package/packages/bundled-features/src/renderer-simple/index.ts +0 -8
  263. package/packages/bundled-features/src/renderer-simple/mail-blocks.ts +0 -138
  264. package/packages/bundled-features/src/renderer-simple/resolve-variables.ts +0 -57
  265. package/packages/bundled-features/src/renderer-simple/simple-renderer.ts +0 -304
@@ -0,0 +1,354 @@
1
+ // Template content for the Nordlicht document-designer walkthrough. Pure data,
2
+ // no framework import: seed-templates.ts feeds it through the template write
3
+ // handlers, so every body here goes through the real sanitizer and placeholder
4
+ // validation.
5
+
6
+ export type SeedTemplate = {
7
+ readonly slug: string;
8
+ readonly kind: "mail" | "mail-layout" | "document-pdf" | "pdf-layout";
9
+ readonly locale: string;
10
+ readonly title?: string;
11
+ readonly content: string;
12
+ readonly meta?: Record<string, unknown>;
13
+ readonly variableSchema?: Record<string, unknown>;
14
+ };
15
+
16
+ // Document HTML marks a variable as an empty span; only link targets take {{name}}.
17
+ const v = (name: string): string => `<span data-variable="${name}"></span>`;
18
+
19
+ const AUTH_VARIABLE_SCHEMA = {
20
+ appName: { type: "text", required: true },
21
+ actionUrl: { type: "link", required: true },
22
+ validFor: { type: "text", required: true },
23
+ validUntil: { type: "text", required: true },
24
+ } as const;
25
+
26
+ const INVOICE_VARIABLE_SCHEMA = {
27
+ customerName: { type: "text", required: true },
28
+ invoiceNumber: { type: "text", required: true },
29
+ amount: { type: "money", required: true },
30
+ dueDate: { type: "date", required: true },
31
+ invoiceUrl: { type: "link", required: true },
32
+ } as const;
33
+
34
+ const DOCUMENT_LINES_SCHEMA = {
35
+ tenantName: { type: "text" },
36
+ customerName: { type: "text", required: true },
37
+ invoiceNumber: { type: "text", required: true },
38
+ invoiceDate: { type: "date", required: true },
39
+ total: { type: "money", required: true },
40
+ lines: {
41
+ type: "list",
42
+ required: true,
43
+ item: { description: { type: "text" }, amount: { type: "money" } },
44
+ },
45
+ } as const;
46
+
47
+ export const SYSTEM_PDF_LAYOUT: SeedTemplate = {
48
+ slug: "default",
49
+ kind: "pdf-layout",
50
+ locale: "en",
51
+ title: "Briefpapier",
52
+ content: [
53
+ `<div data-header><p><strong>${v("tenantName")}</strong></p></div>`,
54
+ "<div data-content></div>",
55
+ "<div data-signature></div>",
56
+ `<div data-footer><p>${v("tenantName")} · Seite ${v("page")} von ${v("pages")}</p></div>`,
57
+ ].join(""),
58
+ };
59
+
60
+ export const TENANT_MAIL_LAYOUT_VERSIONS: readonly string[] = [
61
+ [
62
+ `<div data-header><p><strong>${v("tenantName")}</strong></p></div>`,
63
+ "<div data-content></div>",
64
+ "<div data-signature><p>Mit freundlichen Grüßen</p></div>",
65
+ `<div data-footer><p>${v("tenantName")}</p></div>`,
66
+ ].join(""),
67
+ [
68
+ `<div data-header><p><strong>${v("tenantName")}</strong></p><p>Ihre Hausverwaltung in Kiel</p></div>`,
69
+ "<div data-content></div>",
70
+ `<div data-signature><p>Mit freundlichen Grüßen</p><p>${v("signature")}</p><p>${v("tenantName")}</p></div>`,
71
+ `<div data-footer><p>${v("imprint")}</p><p><a href="https://nordlicht-immobilien.de/datenschutz">Datenschutz</a> · <a href="{{unsubscribeUrl}}">Abmelden</a></p></div>`,
72
+ ].join(""),
73
+ ];
74
+
75
+ const LINES_TABLE = `<table><tbody><tr><th><p>Position</p></th><th><p>Betrag</p></th></tr><tr data-each="lines" data-repeat-header=""><td><p>${v("description")}</p></td><td><p>${v("amount")}</p></td></tr></tbody></table>`;
76
+
77
+ // The registry of the billing notifications declares the variables, so these
78
+ // templates carry no variableSchema of their own.
79
+ function invoiceIssuedBody(args: {
80
+ readonly intro: string;
81
+ readonly withDueDate: boolean;
82
+ }): string {
83
+ const due = args.withDueDate ? ` Bitte überweisen Sie den Betrag bis zum ${v("dueDate")}.` : "";
84
+ return [
85
+ "<h2>Ihre Rechnung ist da</h2>",
86
+ `<p>Guten Tag ${v("recipientName")},</p>`,
87
+ `<p>${args.intro} <strong>${v("invoiceNumber")}</strong> über <strong>${v("invoiceTotal")}</strong>.${due}</p>`,
88
+ '<a data-button href="{{invoiceUrl}}">Rechnung öffnen</a>',
89
+ LINES_TABLE,
90
+ "<hr>",
91
+ "<p>Mit freundlichen Grüßen</p>",
92
+ `<p>${v("tenantName")}</p>`,
93
+ ].join("");
94
+ }
95
+
96
+ const INVOICE_ISSUED_SLUG = "billing:notify:invoice-issued";
97
+ const INVOICE_CORRECTED_SLUG = "billing:notify:invoice-corrected";
98
+
99
+ const invoiceIssuedMeta = (subject: string) => ({
100
+ subject,
101
+ previewText: "Rechnung {{invoiceNumber}} über {{invoiceTotal}}, online abrufbar",
102
+ });
103
+
104
+ // The platform default has a due date; the tenant drafts below drop it, which
105
+ // is what blocks publishing in the walkthrough.
106
+ export const SYSTEM_INVOICE_ISSUED: SeedTemplate = {
107
+ slug: INVOICE_ISSUED_SLUG,
108
+ kind: "mail",
109
+ locale: "de",
110
+ title: "Rechnung versendet",
111
+ content: invoiceIssuedBody({ intro: "anbei senden wir Ihnen die Rechnung", withDueDate: true }),
112
+ meta: invoiceIssuedMeta("Rechnung {{invoiceNumber}} von {{tenantName}}"),
113
+ };
114
+
115
+ // Saved in order: each entry becomes the next version of the same draft.
116
+ export const INVOICE_ISSUED_DRAFT_VERSIONS: readonly SeedTemplate[] = [
117
+ {
118
+ slug: INVOICE_ISSUED_SLUG,
119
+ kind: "mail",
120
+ locale: "de",
121
+ title: "Rechnung versendet",
122
+ content: invoiceIssuedBody({
123
+ intro: "anbei senden wir Ihnen die Rechnung",
124
+ withDueDate: false,
125
+ }),
126
+ meta: invoiceIssuedMeta("Ihre Rechnung {{invoiceNumber}}"),
127
+ },
128
+ {
129
+ slug: INVOICE_ISSUED_SLUG,
130
+ kind: "mail",
131
+ locale: "de",
132
+ title: "Rechnung versendet",
133
+ content: invoiceIssuedBody({ intro: "anbei erhalten Sie die Rechnung", withDueDate: false }),
134
+ meta: invoiceIssuedMeta("Ihre Rechnung {{invoiceNumber}} von {{tenantName}}"),
135
+ },
136
+ ];
137
+
138
+ // Separate draft for the screenshot spec, so the mail-editor e2e can change
139
+ // "Rechnung versendet" without touching what the screenshots show.
140
+ export const INVOICE_CORRECTED_DRAFT: SeedTemplate = {
141
+ slug: INVOICE_CORRECTED_SLUG,
142
+ kind: "mail",
143
+ locale: "de",
144
+ title: "Korrigierte Rechnung",
145
+ content: invoiceIssuedBody({
146
+ intro: "anbei erhalten Sie die korrigierte Rechnung",
147
+ withDueDate: false,
148
+ }),
149
+ meta: invoiceIssuedMeta("Ihre Rechnung {{invoiceNumber}} von {{tenantName}}"),
150
+ };
151
+
152
+ export const PAYMENT_REMINDER_TEMPLATES: readonly SeedTemplate[] = [
153
+ {
154
+ slug: "billing:notify:payment-reminder",
155
+ kind: "mail",
156
+ locale: "de",
157
+ title: "Zahlungserinnerung",
158
+ content: [
159
+ `<p>Guten Tag ${v("customerName")},</p>`,
160
+ `<p>zu unserer Rechnung <strong>${v("invoiceNumber")}</strong> über <strong>${v("amount")}</strong> konnten wir bis heute keinen Zahlungseingang feststellen. Fällig war der Betrag am ${v("dueDate")}.</p>`,
161
+ `<p>Bitte überweisen Sie den offenen Betrag in den nächsten Tagen. Die Rechnung finden Sie hier: <a href="{{invoiceUrl}}">Rechnung öffnen</a></p>`,
162
+ "<p>Sollten Sie bereits gezahlt haben, betrachten Sie diese Nachricht bitte als gegenstandslos.</p>",
163
+ ].join(""),
164
+ meta: { subject: "Zahlungserinnerung zu Rechnung {{invoiceNumber}}" },
165
+ variableSchema: INVOICE_VARIABLE_SCHEMA,
166
+ },
167
+ {
168
+ slug: "billing:notify:payment-reminder",
169
+ kind: "mail",
170
+ locale: "en",
171
+ title: "Payment reminder",
172
+ content: [
173
+ `<p>Hello ${v("customerName")},</p>`,
174
+ `<p>we have not received a payment for invoice <strong>${v("invoiceNumber")}</strong> of <strong>${v("amount")}</strong>, which was due on ${v("dueDate")}.</p>`,
175
+ `<p>Please transfer the open amount in the next few days. You can find the invoice here: <a href="{{invoiceUrl}}">Open invoice</a></p>`,
176
+ "<p>If you have already paid, please disregard this message.</p>",
177
+ ].join(""),
178
+ meta: { subject: "Payment reminder for invoice {{invoiceNumber}}" },
179
+ variableSchema: INVOICE_VARIABLE_SCHEMA,
180
+ },
181
+ ];
182
+
183
+ function authMail(
184
+ notification: string,
185
+ locale: "de" | "en",
186
+ title: string,
187
+ subject: string,
188
+ paragraphs: readonly string[],
189
+ extraSchema: Record<string, unknown> = {},
190
+ ): SeedTemplate {
191
+ return {
192
+ slug: `auth-email-password:notify:${notification}`,
193
+ kind: "mail",
194
+ locale,
195
+ title,
196
+ content: paragraphs.join(""),
197
+ meta: { subject },
198
+ variableSchema: { ...AUTH_VARIABLE_SCHEMA, ...extraSchema },
199
+ };
200
+ }
201
+
202
+ export const SYSTEM_AUTH_MAILS: readonly SeedTemplate[] = [
203
+ authMail(
204
+ "password-reset",
205
+ "de",
206
+ "Passwort zurücksetzen",
207
+ "Passwort für {{appName}} zurücksetzen",
208
+ [
209
+ "<p>Hallo,</p>",
210
+ `<p>für Ihr Konto bei ${v("appName")} wurde ein neues Passwort angefordert. Über den folgenden Link können Sie es festlegen: <a href="{{actionUrl}}">Passwort zurücksetzen</a></p>`,
211
+ `<p>Der Link ist ${v("validFor")} gültig, bis ${v("validUntil")}. Haben Sie das nicht angefordert, können Sie diese Nachricht ignorieren.</p>`,
212
+ ],
213
+ ),
214
+ authMail("password-reset", "en", "Reset password", "Reset your {{appName}} password", [
215
+ "<p>Hello,</p>",
216
+ `<p>a new password was requested for your ${v("appName")} account. You can set it with this link: <a href="{{actionUrl}}">Reset password</a></p>`,
217
+ `<p>The link is valid for ${v("validFor")}, until ${v("validUntil")}. If you did not ask for this, you can ignore this message.</p>`,
218
+ ]),
219
+ authMail(
220
+ "invite",
221
+ "de",
222
+ "Einladung ins Team",
223
+ "Einladung zu {{appName}}",
224
+ [
225
+ "<p>Hallo,</p>",
226
+ `<p>Sie wurden zu ${v("appName")} eingeladen, mit der Rolle <strong>${v("role")}</strong>. Mit dem folgenden Link nehmen Sie die Einladung an: <a href="{{actionUrl}}">Einladung annehmen</a></p>`,
227
+ `<p>Die Einladung ist ${v("validFor")} gültig, bis ${v("validUntil")}.</p>`,
228
+ ],
229
+ { role: { type: "text", required: true } },
230
+ ),
231
+ authMail(
232
+ "invite",
233
+ "en",
234
+ "Team invitation",
235
+ "You are invited to {{appName}}",
236
+ [
237
+ "<p>Hello,</p>",
238
+ `<p>You have been invited to ${v("appName")} with the role <strong>${v("role")}</strong>. Accept the invitation with this link: <a href="{{actionUrl}}">Accept invitation</a></p>`,
239
+ `<p>The invitation is valid for ${v("validFor")}, until ${v("validUntil")}.</p>`,
240
+ ],
241
+ { role: { type: "text", required: true } },
242
+ ),
243
+ authMail(
244
+ "signup-activation",
245
+ "de",
246
+ "Registrierung bestätigen",
247
+ "Registrierung bei {{appName}} bestätigen",
248
+ [
249
+ "<p>Willkommen,</p>",
250
+ `<p>vielen Dank für Ihre Registrierung bei ${v("appName")}. Bitte bestätigen Sie Ihre E-Mail-Adresse: <a href="{{actionUrl}}">Registrierung bestätigen</a></p>`,
251
+ `<p>Der Link ist ${v("validFor")} gültig, bis ${v("validUntil")}.</p>`,
252
+ ],
253
+ ),
254
+ authMail(
255
+ "email-verification",
256
+ "de",
257
+ "E-Mail-Adresse bestätigen",
258
+ "E-Mail-Adresse für {{appName}} bestätigen",
259
+ [
260
+ "<p>Hallo,</p>",
261
+ `<p>bitte bestätigen Sie Ihre E-Mail-Adresse für ${v("appName")}: <a href="{{actionUrl}}">E-Mail-Adresse bestätigen</a></p>`,
262
+ `<p>Der Link ist ${v("validFor")} gültig, bis ${v("validUntil")}.</p>`,
263
+ ],
264
+ ),
265
+ authMail("email-verification", "en", "Confirm email address", "Confirm your {{appName}} email", [
266
+ "<p>Hello,</p>",
267
+ `<p>please confirm your email address for ${v("appName")}: <a href="{{actionUrl}}">Confirm email address</a></p>`,
268
+ `<p>The link is valid for ${v("validFor")}, until ${v("validUntil")}.</p>`,
269
+ ]),
270
+ authMail("account-unlock", "de", "Konto entsperren", "Ihr Konto bei {{appName}} entsperren", [
271
+ "<p>Hallo,</p>",
272
+ `<p>Ihr Konto bei ${v("appName")} wurde nach mehreren fehlgeschlagenen Anmeldungen gesperrt. Mit dem folgenden Link entsperren Sie es: <a href="{{actionUrl}}">Konto entsperren</a></p>`,
273
+ `<p>Der Link ist ${v("validFor")} gültig, bis ${v("validUntil")}.</p>`,
274
+ ]),
275
+ authMail("account-unlock", "en", "Unlock account", "Unlock your {{appName}} account", [
276
+ "<p>Hello,</p>",
277
+ `<p>your ${v("appName")} account was locked after several failed sign-ins. Unlock it with this link: <a href="{{actionUrl}}">Unlock account</a></p>`,
278
+ `<p>The link is valid for ${v("validFor")}, until ${v("validUntil")}.</p>`,
279
+ ]),
280
+ ];
281
+
282
+ const INVOICE_DOCUMENT_ROWS = `<table><tbody><tr><th><p>Leistung</p></th><th><p>Betrag</p></th></tr><tr data-each="lines" data-repeat-header=""><td><p>${v("description")}</p></td><td><p>${v("amount")}</p></td></tr></tbody></table>`;
283
+
284
+ export const SYSTEM_INVOICE_DOCUMENTS: readonly SeedTemplate[] = [
285
+ {
286
+ slug: "billing:invoice",
287
+ kind: "document-pdf",
288
+ locale: "de",
289
+ title: "Rechnung",
290
+ content: [
291
+ `<h1>Rechnung ${v("invoiceNumber")}</h1>`,
292
+ `<p>Rechnungsdatum: ${v("invoiceDate")}</p>`,
293
+ `<p>Guten Tag ${v("customerName")},</p>`,
294
+ "<p>für unsere Leistungen stellen wir Ihnen folgenden Betrag in Rechnung.</p>",
295
+ INVOICE_DOCUMENT_ROWS,
296
+ `<p><strong>Gesamtbetrag: ${v("total")}</strong></p>`,
297
+ "<p>Bitte überweisen Sie den Betrag innerhalb von 14 Tagen auf unser Konto.</p>",
298
+ ].join(""),
299
+ meta: { layoutSlug: "default", pageFormat: "A4", fileName: "Rechnung.pdf" },
300
+ variableSchema: DOCUMENT_LINES_SCHEMA,
301
+ },
302
+ {
303
+ slug: "billing:invoice",
304
+ kind: "document-pdf",
305
+ locale: "en",
306
+ title: "Invoice",
307
+ content: [
308
+ `<h1>Invoice ${v("invoiceNumber")}</h1>`,
309
+ `<p>Invoice date: ${v("invoiceDate")}</p>`,
310
+ `<p>Dear ${v("customerName")},</p>`,
311
+ "<p>we charge you the following amount for our services.</p>",
312
+ INVOICE_DOCUMENT_ROWS.replace("Leistung", "Service").replace("Betrag", "Amount"),
313
+ `<p><strong>Total: ${v("total")}</strong></p>`,
314
+ "<p>Please transfer the amount to our account within 14 days.</p>",
315
+ ].join(""),
316
+ meta: { layoutSlug: "default", pageFormat: "A4", fileName: "Invoice.pdf" },
317
+ variableSchema: DOCUMENT_LINES_SCHEMA,
318
+ },
319
+ ];
320
+
321
+ export const TENANT_UTILITY_STATEMENT: SeedTemplate = {
322
+ slug: "rental:utility-statement",
323
+ kind: "document-pdf",
324
+ locale: "de",
325
+ title: "Nebenkostenabrechnung",
326
+ content: [
327
+ `<h1>Nebenkostenabrechnung ${v("invoiceNumber")}</h1>`,
328
+ `<p>Abrechnungsdatum: ${v("invoiceDate")}</p>`,
329
+ `<p>Guten Tag ${v("customerName")},</p>`,
330
+ "<p>nachfolgend erhalten Sie die Abrechnung der Betriebskosten für den Abrechnungszeitraum.</p>",
331
+ INVOICE_DOCUMENT_ROWS,
332
+ `<p><strong>Ergebnis: ${v("total")}</strong></p>`,
333
+ "<p>Ein Guthaben überweisen wir Ihnen innerhalb von 30 Tagen, eine Nachzahlung ist zum Monatsende fällig.</p>",
334
+ ].join(""),
335
+ meta: { layoutSlug: "default", pageFormat: "A4", fileName: "Nebenkostenabrechnung.pdf" },
336
+ variableSchema: DOCUMENT_LINES_SCHEMA,
337
+ };
338
+
339
+ export const SYSTEM_TENANCY_CERTIFICATE: SeedTemplate = {
340
+ slug: "rental:tenancy-certificate",
341
+ kind: "document-pdf",
342
+ locale: "de",
343
+ title: "Mietbescheinigung",
344
+ content: [
345
+ "<h1>Mietbescheinigung</h1>",
346
+ `<p>Hiermit bestätigen wir, dass ${v("customerName")} bei uns Mieter ist und die Miete ordnungsgemäß zahlt.</p>`,
347
+ `<p>Ausgestellt am ${v("invoiceDate")}.</p>`,
348
+ ].join(""),
349
+ meta: { layoutSlug: "default", pageFormat: "A4", fileName: "Mietbescheinigung.pdf" },
350
+ variableSchema: {
351
+ customerName: { type: "text", required: true },
352
+ invoiceDate: { type: "date", required: true },
353
+ },
354
+ };
@@ -0,0 +1,68 @@
1
+ import { defineFeature, templateVariable } from "@cosmicdrift/kumiko-framework/engine";
2
+ import { toKeyFirst } from "../translations";
3
+ import { billingTranslations } from "./i18n";
4
+
5
+ // Both mails are sent by the host app's billing run, not by an event trigger in
6
+ // this sample; they exist so the template overview has real senders to show.
7
+ const INVOICE_ISSUED_VARIABLES = {
8
+ recipientName: templateVariable.text({
9
+ label: "Empfängername",
10
+ required: true,
11
+ example: "Familie Yilmaz",
12
+ }),
13
+ invoiceNumber: templateVariable.text({
14
+ label: "Rechnungsnummer",
15
+ required: true,
16
+ example: "RE-2026-0142",
17
+ }),
18
+ invoiceTotal: templateVariable.money({
19
+ label: "Rechnungsbetrag",
20
+ required: true,
21
+ example: { amount: 128450, currency: "EUR" },
22
+ }),
23
+ dueDate: templateVariable.date({
24
+ label: "Fälligkeitsdatum",
25
+ required: true,
26
+ example: "2026-10-30",
27
+ }),
28
+ invoiceUrl: templateVariable.link({
29
+ label: "Link zur Rechnung",
30
+ required: true,
31
+ example: "https://nordlicht-immobilien.de/rechnungen/RE-2026-0142",
32
+ }),
33
+ lines: templateVariable.list(
34
+ {
35
+ description: templateVariable.text({ label: "Bezeichnung" }),
36
+ amount: templateVariable.money({ label: "Betrag" }),
37
+ },
38
+ {
39
+ label: "Rechnungspositionen",
40
+ required: true,
41
+ example: [
42
+ { description: "Kaltmiete Oktober 2026, Lindenstraße 14 WE 3", amount: 98000 },
43
+ { description: "Betriebskostenvorauszahlung Oktober 2026", amount: 24500 },
44
+ { description: "Stellplatz 7, Oktober 2026", amount: 5950 },
45
+ ],
46
+ },
47
+ ),
48
+ paymentReference: templateVariable.text({
49
+ label: "Zahlungsreferenz",
50
+ example: "RE-2026-0142 / Yilmaz",
51
+ }),
52
+ } as const;
53
+
54
+ const PAYMENT_REMINDER_VARIABLES = {
55
+ customerName: templateVariable.text({ required: true }),
56
+ invoiceNumber: templateVariable.text({ required: true }),
57
+ amount: templateVariable.money({ required: true }),
58
+ dueDate: templateVariable.date({ required: true }),
59
+ invoiceUrl: templateVariable.link({ required: true }),
60
+ } as const;
61
+
62
+ export const billingFeature = defineFeature("billing", (r) => {
63
+ r.translations({ keys: toKeyFirst(billingTranslations) });
64
+
65
+ r.notification("invoice-issued", { variables: INVOICE_ISSUED_VARIABLES });
66
+ r.notification("invoice-corrected", { variables: INVOICE_ISSUED_VARIABLES });
67
+ r.notification("payment-reminder", { variables: PAYMENT_REMINDER_VARIABLES });
68
+ });
@@ -0,0 +1,18 @@
1
+ import type { TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
2
+
3
+ // The keys follow the document-designer's "used by" lookup:
4
+ // `<feature>:feature.label` and `<feature>:notify.<notification>.label`.
5
+ export const billingTranslations: TranslationsByLocale = {
6
+ de: {
7
+ "billing:feature.label": "Rechnungen",
8
+ "billing:notify.invoice-issued.label": "Rechnung gestellt",
9
+ "billing:notify.invoice-corrected.label": "Rechnung korrigiert",
10
+ "billing:notify.payment-reminder.label": "Mahnlauf",
11
+ },
12
+ en: {
13
+ "billing:feature.label": "Invoices",
14
+ "billing:notify.invoice-issued.label": "Invoice issued",
15
+ "billing:notify.invoice-corrected.label": "Invoice corrected",
16
+ "billing:notify.payment-reminder.label": "Dunning run",
17
+ },
18
+ };
@@ -0,0 +1,2 @@
1
+ export { billingFeature } from "./feature";
2
+ export { billingClient } from "./web";
@@ -0,0 +1,7 @@
1
+ import type { ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer-web";
2
+ import { billingTranslations } from "../i18n";
3
+
4
+ export const billingClient: ClientFeatureDefinition = {
5
+ name: "billing",
6
+ translations: billingTranslations,
7
+ };
@@ -467,7 +467,7 @@ export const leaseDetailGapsScreen: ProjectionDetailScreenDefinition = {
467
467
  {
468
468
  kind: "writeHandler",
469
469
  id: "terminate",
470
- icon: "x",
470
+ icon: "circle-stop",
471
471
  label: "rental.action.terminate",
472
472
  handler: RENTAL_WRITES.leaseTerminate,
473
473
  payload: { pick: ["id"] },
@@ -3,12 +3,48 @@
3
3
  // src/app/server.ts (dev boot) and kumiko/schema.ts (schema CLI) import
4
4
  // from here — migration and runtime cannot drift.
5
5
 
6
+ import { createAuditFeature } from "@cosmicdrift/kumiko-bundled-features/audit";
7
+ import {
8
+ createChannelEmailFeature,
9
+ createInMemoryTransport,
10
+ } from "@cosmicdrift/kumiko-bundled-features/channel-email";
11
+ import { createDeliveryFeature } from "@cosmicdrift/kumiko-bundled-features/delivery";
12
+ import { createManagedPagesFeature } from "@cosmicdrift/kumiko-bundled-features/managed-pages";
13
+ import { createRendererFoundationFeature } from "@cosmicdrift/kumiko-bundled-features/renderer-foundation";
14
+ import { createTemplateResolverFeature } from "@cosmicdrift/kumiko-bundled-features/template-resolver";
15
+ import { createDocumentDesignerFeature } from "@cosmicdrift/kumiko-document-designer";
6
16
  import { localeDe } from "@cosmicdrift/kumiko-locale-de";
17
+ import { createRendererMailHtmlFeature } from "@cosmicdrift/kumiko-renderer-mail-html";
18
+ import { TENANT_ADMIN_EMAIL } from "./app/auth-constants";
19
+ import { billingFeature } from "./features/billing";
7
20
  import { rentalFeature } from "./features/rental";
8
21
  import { taskFeature } from "./features/tasks";
9
22
  import { vehiclesFeature } from "./features/vehicles";
10
23
 
11
- export const APP_FEATURES = [localeDe(), taskFeature, rentalFeature, vehiclesFeature] as const;
24
+ export const APP_FEATURES = [
25
+ localeDe(),
26
+ taskFeature,
27
+ rentalFeature,
28
+ vehiclesFeature,
29
+ billingFeature,
30
+ createTemplateResolverFeature(),
31
+ // Only the branding rail of the layout editor needs managed-pages; the sample
32
+ // serves no public pages, so no host resolves to a tenant.
33
+ createManagedPagesFeature({ resolveApexTenant: () => null }),
34
+ createDocumentDesignerFeature(),
35
+ // Mounted individually: composeRendererStack() would add a second template-resolver.
36
+ createRendererFoundationFeature(),
37
+ createRendererMailHtmlFeature(),
38
+ createDeliveryFeature(),
39
+ // In-memory transport: the test mail of the mail editor is rendered and
40
+ // "sent" for real, nothing leaves the process. Every user resolves to the
41
+ // tenant admin's address because the sample has no per-user mail lookup.
42
+ createChannelEmailFeature({
43
+ transport: createInMemoryTransport(),
44
+ resolveEmail: async () => TENANT_ADMIN_EMAIL,
45
+ }),
46
+ createAuditFeature(),
47
+ ] as const;
12
48
 
13
49
  // runDevApp auto-mounts config/user/tenant/auth-email-password when
14
50
  // `auth: { … }` is set in server.ts (composeFeatures includeBundled).
@@ -16,7 +16,6 @@ import {
16
16
  createChannelEmailFeature,
17
17
  createInMemoryTransport,
18
18
  } from "@cosmicdrift/kumiko-bundled-features/channel-email";
19
- import { simpleRenderer } from "@cosmicdrift/kumiko-bundled-features/renderer-simple";
20
19
  import type { TenantDb } from "@cosmicdrift/kumiko-framework/db";
21
20
  import { defineFeature, type FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";
22
21
  import {
@@ -93,7 +92,6 @@ export function createGalleryBillingFeature(baseUrl: string): FeatureDefinition
93
92
  export function createGalleryEmailFeature(): FeatureDefinition {
94
93
  return createChannelEmailFeature({
95
94
  transport: galleryMailTransport,
96
- renderer: simpleRenderer,
97
95
  resolveEmail: async () => "unused@gallery.example",
98
96
  });
99
97
  }