@cosmicdrift/kumiko-samples 0.377.0 → 0.379.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 (526) hide show
  1. package/package.json +1 -1
  2. package/packages/bundled-features/package.json +18 -17
  3. package/packages/bundled-features/src/account-security/feature.ts +2 -2
  4. package/packages/bundled-features/src/account-security/index.ts +8 -8
  5. package/packages/bundled-features/src/account-security/{constants.ts → web/constants.ts} +0 -2
  6. package/packages/bundled-features/src/account-security/{i18n.ts → web/i18n.ts} +0 -1
  7. package/packages/bundled-features/src/admin-shell/feature.ts +10 -9
  8. package/packages/bundled-features/src/admin-shell/index.ts +8 -8
  9. package/packages/bundled-features/src/admin-shell/web/client-plugin.tsx +2 -3
  10. package/packages/bundled-features/src/admin-shell/{constants.ts → web/constants.ts} +0 -1
  11. package/packages/bundled-features/src/admin-shell/web/default-translations.ts +10 -0
  12. package/packages/bundled-features/src/admin-shell/web/i18n.ts +51 -9
  13. package/packages/bundled-features/src/admin-shell/web/index.ts +0 -1
  14. package/packages/bundled-features/src/audit/changes.json +7 -0
  15. package/packages/bundled-features/src/audit/feature.ts +72 -64
  16. package/packages/bundled-features/src/audit/handlers/audit-events.ts +153 -0
  17. package/packages/bundled-features/src/audit/handlers/audit-system-db.ts +13 -0
  18. package/packages/bundled-features/src/audit/handlers/details-all-tenants.query.ts +26 -0
  19. package/packages/bundled-features/src/audit/handlers/details.query.ts +11 -39
  20. package/packages/bundled-features/src/audit/handlers/list-all-tenants.query.ts +47 -0
  21. package/packages/bundled-features/src/audit/handlers/list.query.ts +16 -123
  22. package/packages/bundled-features/src/audit/handlers/resolve-audit-tenant.ts +21 -7
  23. package/packages/bundled-features/src/audit/index.ts +1 -1
  24. package/packages/bundled-features/src/audit/run-escape-hatch-retention.ts +4 -4
  25. package/packages/bundled-features/src/audit/screens.ts +82 -0
  26. package/packages/bundled-features/src/audit/web/client-plugin.tsx +2 -3
  27. package/packages/bundled-features/src/audit/{constants.ts → web/constants.ts} +11 -1
  28. package/packages/bundled-features/src/audit/web/default-translations.ts +7 -0
  29. package/packages/bundled-features/src/audit/web/i18n.ts +33 -7
  30. package/packages/bundled-features/src/audit/web/index.ts +0 -2
  31. package/packages/bundled-features/src/auth-email-password/bootstrap.ts +6 -6
  32. package/packages/bundled-features/src/auth-email-password/changes.json +6 -0
  33. package/packages/bundled-features/src/auth-email-password/errors.ts +1 -1
  34. package/packages/bundled-features/src/auth-email-password/feature.ts +2 -2
  35. package/packages/bundled-features/src/auth-email-password/handlers/confirm-account-unlock.write.ts +1 -1
  36. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +4 -4
  37. package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +3 -3
  38. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  39. package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +38 -4
  40. package/packages/bundled-features/src/auth-email-password/handlers/request-account-unlock.write.ts +1 -1
  41. package/packages/bundled-features/src/auth-email-password/handlers/request-email-verification.write.ts +1 -1
  42. package/packages/bundled-features/src/auth-email-password/handlers/request-password-reset.write.ts +1 -1
  43. package/packages/bundled-features/src/auth-email-password/handlers/reset-password.write.ts +1 -1
  44. package/packages/bundled-features/src/auth-email-password/handlers/verify-email.write.ts +1 -1
  45. package/packages/bundled-features/src/auth-email-password/index.ts +6 -1
  46. package/packages/bundled-features/src/auth-email-password/mail-notifications.ts +1 -1
  47. package/packages/bundled-features/src/auth-email-password/signup-activation.ts +1 -1
  48. package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +0 -1
  49. package/packages/bundled-features/src/auth-email-password/web/auth-form-logic.ts +0 -1
  50. package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +0 -1
  51. package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +0 -1
  52. package/packages/bundled-features/src/auth-email-password/web/auth-redirect.ts +0 -1
  53. package/packages/bundled-features/src/auth-email-password/web/client-actions.ts +0 -1
  54. package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +1 -2
  55. package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +0 -1
  56. package/packages/bundled-features/src/auth-email-password/{constants.ts → web/constants.ts} +3 -6
  57. package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +0 -1
  58. package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +0 -1
  59. package/packages/bundled-features/src/auth-email-password/{i18n.ts → web/i18n.ts} +3 -4
  60. package/packages/bundled-features/src/auth-email-password/web/index.ts +1 -2
  61. package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +2 -3
  62. package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +0 -1
  63. package/packages/bundled-features/src/auth-email-password/{mail-i18n.ts → web/mail-i18n.ts} +0 -1
  64. package/packages/bundled-features/src/auth-email-password/web/request-account-unlock-screen.tsx +0 -1
  65. package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +0 -1
  66. package/packages/bundled-features/src/auth-email-password/web/session-bootstrap-error.tsx +0 -1
  67. package/packages/bundled-features/src/auth-email-password/web/session.tsx +0 -1
  68. package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +2 -3
  69. package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +0 -1
  70. package/packages/bundled-features/src/auth-email-password/web/tenant-menu-items.tsx +0 -1
  71. package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +0 -1
  72. package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +0 -1
  73. package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +0 -1
  74. package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +0 -1
  75. package/packages/bundled-features/src/auth-mfa/changes.json +6 -0
  76. package/packages/bundled-features/src/auth-mfa/errors.ts +2 -2
  77. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +1 -1
  78. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  79. package/packages/bundled-features/src/auth-mfa/handlers/enable-start.write.ts +1 -1
  80. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  81. package/packages/bundled-features/src/auth-mfa/index.ts +8 -8
  82. package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +4 -4
  83. package/packages/bundled-features/src/auth-mfa/screens.ts +1 -1
  84. package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +0 -1
  85. package/packages/bundled-features/src/auth-mfa/{constants.ts → web/constants.ts} +0 -1
  86. package/packages/bundled-features/src/auth-mfa/web/i18n.ts +0 -1
  87. package/packages/bundled-features/src/auth-mfa/web/index.ts +0 -1
  88. package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +0 -1
  89. package/packages/bundled-features/src/auth-mfa/web/mfa-disable-dialog.tsx +1 -2
  90. package/packages/bundled-features/src/auth-mfa/web/mfa-recovery-codes-reveal.tsx +0 -1
  91. package/packages/bundled-features/src/auth-mfa/web/mfa-regenerate-recovery-dialog.tsx +1 -2
  92. package/packages/bundled-features/src/auth-mfa/web/mfa-setup-preauth-screen.tsx +21 -23
  93. package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +0 -1
  94. package/packages/bundled-features/src/billing-foundation/changes.json +18 -0
  95. package/packages/bundled-features/src/billing-foundation/checkout-core.ts +3 -3
  96. package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-text.ts +2 -2
  97. package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +11 -3
  98. package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +11 -1
  99. package/packages/bundled-features/src/billing-foundation/consumer-protection/register-consent.ts +1 -1
  100. package/packages/bundled-features/src/billing-foundation/consumer-protection/register-termination.ts +12 -1
  101. package/packages/bundled-features/src/billing-foundation/consumer-protection/stored-user-email.ts +12 -0
  102. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-mail.ts +6 -1
  103. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-notify.ts +1 -1
  104. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-pages.ts +167 -28
  105. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +102 -3
  106. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +43 -12
  107. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-revoke.ts +202 -0
  108. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +70 -0
  109. package/packages/bundled-features/src/billing-foundation/events.ts +20 -2
  110. package/packages/bundled-features/src/billing-foundation/feature.ts +5 -5
  111. package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +82 -9
  112. package/packages/bundled-features/src/billing-foundation/handlers/switch-plan.write.ts +1 -1
  113. package/packages/bundled-features/src/billing-foundation/handlers/sync-subscription.write.ts +1 -1
  114. package/packages/bundled-features/src/billing-foundation/index.ts +27 -27
  115. package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +7 -7
  116. package/packages/bundled-features/src/billing-foundation/screens.ts +1 -1
  117. package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +1 -1
  118. package/packages/bundled-features/src/billing-foundation/types.ts +17 -3
  119. package/packages/bundled-features/src/billing-foundation/validate-options.ts +3 -3
  120. package/packages/bundled-features/src/billing-foundation/web/billing-contact-plan.tsx +1 -3
  121. package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +5 -7
  122. package/packages/bundled-features/src/billing-foundation/web/cancel-contract-dialog.tsx +1 -3
  123. package/packages/bundled-features/src/billing-foundation/web/checkout-consent-dialog.tsx +1 -3
  124. package/packages/bundled-features/src/billing-foundation/web/client-plugin.tsx +1 -2
  125. package/packages/bundled-features/src/billing-foundation/{constants.ts → web/constants.ts} +37 -31
  126. package/packages/bundled-features/src/billing-foundation/{consumer-protection → web/consumer-protection}/consent-locale.ts +0 -1
  127. package/packages/bundled-features/src/billing-foundation/{contact-card.ts → web/contact-card.ts} +0 -2
  128. package/packages/bundled-features/src/billing-foundation/web/index.ts +14 -15
  129. package/packages/bundled-features/src/billing-foundation/web/localized-params.ts +0 -2
  130. package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +5 -2
  131. package/packages/bundled-features/src/cap-counter/changes.json +12 -0
  132. package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +9 -0
  133. package/packages/bundled-features/src/cap-overview/feature.ts +1 -1
  134. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -1
  135. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +2 -2
  136. package/packages/bundled-features/src/cap-overview/index.ts +9 -9
  137. package/packages/bundled-features/src/cap-overview/screens.ts +2 -2
  138. package/packages/bundled-features/src/cap-overview/web/cap-cards-panel.tsx +1 -2
  139. package/packages/bundled-features/src/cap-overview/web/cap-usage-bar.tsx +1 -2
  140. package/packages/bundled-features/src/cap-overview/web/cap-usage-cell.tsx +0 -2
  141. package/packages/bundled-features/src/cap-overview/web/client-plugin.tsx +3 -4
  142. package/packages/bundled-features/src/cap-overview/{constants.ts → web/constants.ts} +0 -1
  143. package/packages/bundled-features/src/cap-overview/web/index.ts +0 -1
  144. package/packages/bundled-features/src/cap-overview/{usage-math.ts → web/usage-math.ts} +1 -2
  145. package/packages/bundled-features/src/compliance-profiles/feature.ts +5 -5
  146. package/packages/bundled-features/src/compliance-profiles/index.ts +6 -6
  147. package/packages/bundled-features/src/compliance-profiles/web/client-plugin.tsx +2 -3
  148. package/packages/bundled-features/src/compliance-profiles/web/compliance-profile-catalog.tsx +1 -2
  149. package/packages/bundled-features/src/compliance-profiles/{constants.ts → web/constants.ts} +0 -1
  150. package/packages/bundled-features/src/compliance-profiles/web/i18n.ts +0 -1
  151. package/packages/bundled-features/src/compliance-profiles/web/index.ts +0 -1
  152. package/packages/bundled-features/src/config/index.ts +6 -6
  153. package/packages/bundled-features/src/config/web/client-plugin.ts +1 -2
  154. package/packages/bundled-features/src/config/{constants.ts → web/constants.ts} +0 -1
  155. package/packages/bundled-features/src/config/web/i18n.ts +1 -1
  156. package/packages/bundled-features/src/config/web/index.ts +1 -3
  157. package/packages/bundled-features/src/config/write-helpers.ts +1 -1
  158. package/packages/bundled-features/src/custom-fields/feature.ts +8 -8
  159. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +1 -1
  160. package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +1 -1
  161. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +1 -1
  162. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +4 -4
  163. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +1 -1
  164. package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +1 -1
  165. package/packages/bundled-features/src/custom-fields/index.ts +8 -8
  166. package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +1 -1
  167. package/packages/bundled-features/src/custom-fields/schemas.ts +1 -1
  168. package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +1 -2
  169. package/packages/bundled-features/src/custom-fields/{constants.ts → web/constants.ts} +18 -19
  170. package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +1 -2
  171. package/packages/bundled-features/src/custom-fields/web/i18n.ts +0 -1
  172. package/packages/bundled-features/src/custom-fields/web/index.ts +2 -3
  173. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +1 -2
  174. package/packages/bundled-features/src/delivery/address-opt-out.ts +1 -1
  175. package/packages/bundled-features/src/delivery/attempt-log-retention.ts +24 -8
  176. package/packages/bundled-features/src/delivery/changes.json +6 -0
  177. package/packages/bundled-features/src/delivery/constants.ts +2 -2
  178. package/packages/bundled-features/src/delivery/i18n.ts +1 -1
  179. package/packages/bundled-features/src/delivery/unsubscribe-page.ts +1 -1
  180. package/packages/bundled-features/src/delivery/web/client-plugin.tsx +6 -7
  181. package/packages/bundled-features/src/delivery/web/delivery-channel-cell.tsx +0 -1
  182. package/packages/bundled-features/src/delivery/web/delivery-error-cell.tsx +0 -1
  183. package/packages/bundled-features/src/delivery/web/delivery-status-cell.tsx +1 -2
  184. package/packages/bundled-features/src/delivery/web/delivery-time-cell.tsx +0 -1
  185. package/packages/bundled-features/src/delivery/web/delivery-type-cell.tsx +0 -1
  186. package/packages/bundled-features/src/delivery/web/index.ts +0 -1
  187. package/packages/bundled-features/src/delivery/{public-names.ts → web/public-names.ts} +0 -1
  188. package/packages/bundled-features/src/document-ingest-foundation/changes.json +6 -0
  189. package/packages/bundled-features/src/document-ingest-foundation/events.ts +4 -0
  190. package/packages/bundled-features/src/document-ingest-foundation/executor.ts +2 -1
  191. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +18 -4
  192. package/packages/bundled-features/src/document-ingest-foundation/index.ts +1 -0
  193. package/packages/bundled-features/src/feature-toggles/feature.ts +7 -7
  194. package/packages/bundled-features/src/feature-toggles/handlers/list.query.ts +1 -1
  195. package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +1 -1
  196. package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -3
  197. package/packages/bundled-features/src/feature-toggles/index.ts +6 -6
  198. package/packages/bundled-features/src/feature-toggles/web/client-plugin.tsx +1 -2
  199. package/packages/bundled-features/src/feature-toggles/{constants.ts → web/constants.ts} +0 -1
  200. package/packages/bundled-features/src/feature-toggles/web/i18n.ts +0 -1
  201. package/packages/bundled-features/src/feature-toggles/web/index.ts +0 -1
  202. package/packages/bundled-features/src/files/changes.json +7 -0
  203. package/packages/bundled-features/src/folders/feature.ts +1 -1
  204. package/packages/bundled-features/src/folders/handlers/clear-folder.write.ts +1 -1
  205. package/packages/bundled-features/src/folders/handlers/delete-folder.write.ts +1 -1
  206. package/packages/bundled-features/src/folders/handlers/set-folder.write.ts +1 -1
  207. package/packages/bundled-features/src/folders/index.ts +8 -8
  208. package/packages/bundled-features/src/folders/web/client-plugin.tsx +1 -3
  209. package/packages/bundled-features/src/folders/{constants.ts → web/constants.ts} +0 -1
  210. package/packages/bundled-features/src/folders/web/folder-manager.tsx +1 -2
  211. package/packages/bundled-features/src/folders/web/folder-section.tsx +1 -2
  212. package/packages/bundled-features/src/folders/web/i18n.ts +0 -1
  213. package/packages/bundled-features/src/folders/web/index.ts +1 -2
  214. package/packages/bundled-features/src/folders/web/tree.ts +0 -1
  215. package/packages/bundled-features/src/form-draft/changes.json +7 -0
  216. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +25 -11
  217. package/packages/bundled-features/src/form-draft/decrypt-draft.ts +24 -0
  218. package/packages/bundled-features/src/form-draft/entity.ts +6 -9
  219. package/packages/bundled-features/src/form-draft/feature.ts +1 -1
  220. package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +26 -5
  221. package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
  222. package/packages/bundled-features/src/form-draft/handlers/get.query.ts +6 -7
  223. package/packages/bundled-features/src/form-draft/handlers/list.query.ts +13 -7
  224. package/packages/bundled-features/src/form-draft/handlers/save.write.ts +5 -5
  225. package/packages/bundled-features/src/form-draft/index.ts +8 -8
  226. package/packages/bundled-features/src/form-draft/lookup.ts +10 -4
  227. package/packages/bundled-features/src/form-draft/schemas.ts +1 -1
  228. package/packages/bundled-features/src/form-draft/{constants.ts → web/constants.ts} +0 -1
  229. package/packages/bundled-features/src/form-draft-user-data/hooks.ts +2 -2
  230. package/packages/bundled-features/src/inbound-mail-foundation/changes.json +6 -0
  231. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +11 -4
  232. package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +10 -10
  233. package/packages/bundled-features/src/jobs/feature.ts +7 -7
  234. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  235. package/packages/bundled-features/src/jobs/handlers/trigger.write.ts +1 -1
  236. package/packages/bundled-features/src/jobs/index.ts +1 -1
  237. package/packages/bundled-features/src/jobs/web/client-plugin.tsx +2 -3
  238. package/packages/bundled-features/src/jobs/{constants.ts → web/constants.ts} +0 -1
  239. package/packages/bundled-features/src/jobs/web/default-translations.ts +7 -0
  240. package/packages/bundled-features/src/jobs/web/i18n.ts +53 -7
  241. package/packages/bundled-features/src/jobs/web/index.ts +0 -1
  242. package/packages/bundled-features/src/ledger/changes.json +7 -0
  243. package/packages/bundled-features/src/ledger/entity.ts +1 -1
  244. package/packages/bundled-features/src/ledger/feature.ts +1 -1
  245. package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +2 -10
  246. package/packages/bundled-features/src/ledger/handlers/create-transaction.write.ts +1 -1
  247. package/packages/bundled-features/src/ledger/handlers/reports.query.ts +1 -1
  248. package/packages/bundled-features/src/ledger/handlers/reverse-transaction.write.ts +1 -1
  249. package/packages/bundled-features/src/ledger/index.ts +13 -13
  250. package/packages/bundled-features/src/ledger/recurring.ts +1 -1
  251. package/packages/bundled-features/src/ledger/reports.ts +1 -1
  252. package/packages/bundled-features/src/ledger/schemas.ts +1 -1
  253. package/packages/bundled-features/src/ledger/{constants.ts → web/constants.ts} +0 -1
  254. package/packages/bundled-features/src/ledger/web/index.ts +11 -12
  255. package/packages/bundled-features/src/legal-pages/README.md +1 -1
  256. package/packages/bundled-features/src/legal-pages/feature.ts +5 -5
  257. package/packages/bundled-features/src/legal-pages/index.ts +11 -11
  258. package/packages/bundled-features/src/legal-pages/lib/boot-check.ts +1 -1
  259. package/packages/bundled-features/src/legal-pages/lib/validate-routes.ts +1 -1
  260. package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +1 -2
  261. package/packages/bundled-features/src/legal-pages/{constants.ts → web/constants.ts} +6 -8
  262. package/packages/bundled-features/src/legal-pages/web/index.ts +0 -1
  263. package/packages/bundled-features/src/mail-foundation/changes.json +6 -0
  264. package/packages/bundled-features/src/mail-foundation/i18n.ts +3 -2
  265. package/packages/bundled-features/src/mail-transport-smtp/i18n.ts +1 -1
  266. package/packages/bundled-features/src/managed-pages/feature.ts +1 -1
  267. package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +1 -2
  268. package/packages/bundled-features/src/managed-pages/web/default-translations.ts +17 -0
  269. package/packages/bundled-features/src/managed-pages/web/i18n.ts +59 -16
  270. package/packages/bundled-features/src/managed-pages/web/index.ts +1 -2
  271. package/packages/bundled-features/src/metrics/compute.ts +1 -1
  272. package/packages/bundled-features/src/metrics/feature.ts +6 -6
  273. package/packages/bundled-features/src/metrics/index.ts +8 -8
  274. package/packages/bundled-features/src/metrics/types.ts +1 -1
  275. package/packages/bundled-features/src/metrics/validate.ts +1 -1
  276. package/packages/bundled-features/src/metrics/{constants.ts → web/constants.ts} +0 -1
  277. package/packages/bundled-features/src/metrics/window.ts +1 -1
  278. package/packages/bundled-features/src/notes-history/feature.ts +1 -1
  279. package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
  280. package/packages/bundled-features/src/notes-history/index.ts +8 -8
  281. package/packages/bundled-features/src/notes-history/web/client-plugin.tsx +1 -3
  282. package/packages/bundled-features/src/notes-history/{constants.ts → web/constants.ts} +0 -1
  283. package/packages/bundled-features/src/notes-history/web/i18n.ts +0 -1
  284. package/packages/bundled-features/src/notes-history/web/index.ts +2 -3
  285. package/packages/bundled-features/src/notes-history/web/notes-section.tsx +2 -3
  286. package/packages/bundled-features/src/personal-access-tokens/feature.ts +12 -10
  287. package/packages/bundled-features/src/personal-access-tokens/handlers/available-scopes.query.ts +1 -1
  288. package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +1 -1
  289. package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
  290. package/packages/bundled-features/src/personal-access-tokens/hash.ts +1 -1
  291. package/packages/bundled-features/src/personal-access-tokens/i18n.ts +2 -2
  292. package/packages/bundled-features/src/personal-access-tokens/index.ts +5 -5
  293. package/packages/bundled-features/src/personal-access-tokens/resolver.ts +1 -1
  294. package/packages/bundled-features/src/personal-access-tokens/schema/api-token.ts +1 -1
  295. package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -2
  296. package/packages/bundled-features/src/personal-access-tokens/{constants.ts → web/constants.ts} +0 -1
  297. package/packages/bundled-features/src/personal-access-tokens/{scopes.ts → web/scopes.ts} +0 -1
  298. package/packages/bundled-features/src/presets/changes.json +7 -0
  299. package/packages/bundled-features/src/presets/index.ts +0 -1
  300. package/packages/bundled-features/src/presets/security-baseline.ts +1 -1
  301. package/packages/bundled-features/src/renderer-foundation/types.ts +1 -1
  302. package/packages/bundled-features/src/secrets/feature.ts +1 -1
  303. package/packages/bundled-features/src/secrets/handlers/delete.write.ts +1 -1
  304. package/packages/bundled-features/src/secrets/handlers/list.query.ts +1 -1
  305. package/packages/bundled-features/src/secrets/handlers/set.write.ts +1 -1
  306. package/packages/bundled-features/src/secrets/i18n.ts +1 -1
  307. package/packages/bundled-features/src/secrets/index.ts +8 -8
  308. package/packages/bundled-features/src/secrets/{constants.ts → web/constants.ts} +0 -1
  309. package/packages/bundled-features/src/secrets/write-gate.ts +1 -1
  310. package/packages/bundled-features/src/sessions/feature.ts +7 -4
  311. package/packages/bundled-features/src/sessions/{i18n.ts → web/i18n.ts} +0 -1
  312. package/packages/bundled-features/src/shared/index.ts +6 -1
  313. package/packages/bundled-features/src/shared/purge-files-reaching-subject.ts +10 -2
  314. package/packages/bundled-features/src/shared/web/translate-or-raw.ts +0 -1
  315. package/packages/bundled-features/src/subscription-stripe/feature.ts +2 -0
  316. package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +19 -0
  317. package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +1 -0
  318. package/packages/bundled-features/src/tags/changes.json +6 -0
  319. package/packages/bundled-features/src/tags/feature.ts +1 -1
  320. package/packages/bundled-features/src/tags/handlers/assign-tag.write.ts +11 -7
  321. package/packages/bundled-features/src/tags/handlers/create-tag.write.ts +1 -1
  322. package/packages/bundled-features/src/tags/handlers/delete-tag.write.ts +4 -1
  323. package/packages/bundled-features/src/tags/handlers/remove-tag.write.ts +1 -1
  324. package/packages/bundled-features/src/tags/handlers/update-tag.write.ts +1 -1
  325. package/packages/bundled-features/src/tags/index.ts +12 -12
  326. package/packages/bundled-features/src/tags/screens.ts +1 -1
  327. package/packages/bundled-features/src/tags/web/client-plugin.tsx +1 -3
  328. package/packages/bundled-features/src/tags/{constants.ts → web/constants.ts} +4 -1
  329. package/packages/bundled-features/src/tags/web/entity-tags.tsx +1 -2
  330. package/packages/bundled-features/src/tags/web/i18n.ts +2 -2
  331. package/packages/bundled-features/src/tags/web/index.ts +2 -3
  332. package/packages/bundled-features/src/tags/web/tag-chip.tsx +0 -1
  333. package/packages/bundled-features/src/tags/web/tag-filter.tsx +1 -2
  334. package/packages/bundled-features/src/tags/web/tag-manager.tsx +5 -4
  335. package/packages/bundled-features/src/tags/web/tag-picker.tsx +0 -1
  336. package/packages/bundled-features/src/tags/web/tag-section.tsx +1 -2
  337. package/packages/bundled-features/src/tags/web/tags-cell.tsx +1 -2
  338. package/packages/bundled-features/src/template-resolver/README.md +1 -1
  339. package/packages/bundled-features/src/template-resolver/api.ts +75 -28
  340. package/packages/bundled-features/src/template-resolver/changes.json +63 -0
  341. package/packages/bundled-features/src/template-resolver/compile-document-body.ts +62 -4
  342. package/packages/bundled-features/src/template-resolver/compile-steps-block.ts +2 -2
  343. package/packages/bundled-features/src/template-resolver/document-ops.ts +5 -5
  344. package/packages/bundled-features/src/template-resolver/document-sanitizer.ts +39 -4
  345. package/packages/bundled-features/src/template-resolver/feature.ts +88 -38
  346. package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +6 -1
  347. package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +6 -2
  348. package/packages/bundled-features/src/template-resolver/handlers/collection-item.query.ts +1 -1
  349. package/packages/bundled-features/src/template-resolver/handlers/collection-list.query.ts +1 -1
  350. package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +20 -7
  351. package/packages/bundled-features/src/template-resolver/handlers/collection-shared.ts +0 -6
  352. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +69 -60
  353. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +7 -1
  354. package/packages/bundled-features/src/template-resolver/handlers/discard-draft.write.ts +37 -14
  355. package/packages/bundled-features/src/template-resolver/handlers/document-base.ts +8 -2
  356. package/packages/bundled-features/src/template-resolver/handlers/document-blocks.query.ts +2 -2
  357. package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +5 -2
  358. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +4 -2
  359. package/packages/bundled-features/src/template-resolver/handlers/import-bundle.write.ts +37 -28
  360. package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +10 -5
  361. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +5 -2
  362. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +132 -70
  363. package/packages/bundled-features/src/template-resolver/handlers/patch-draft.write.ts +106 -97
  364. package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +62 -49
  365. package/packages/bundled-features/src/template-resolver/handlers/resource-link-pdf.write.ts +44 -29
  366. package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +52 -36
  367. package/packages/bundled-features/src/template-resolver/handlers/resource-shared.ts +1 -1
  368. package/packages/bundled-features/src/template-resolver/handlers/resource-upload.write.ts +127 -107
  369. package/packages/bundled-features/src/template-resolver/handlers/send-test-shared.ts +38 -0
  370. package/packages/bundled-features/src/template-resolver/handlers/send-test-status.query.ts +31 -0
  371. package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +106 -112
  372. package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +111 -104
  373. package/packages/bundled-features/src/template-resolver/handlers/shared.ts +1 -1
  374. package/packages/bundled-features/src/template-resolver/handlers/template-gates.ts +6 -6
  375. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +2 -2
  376. package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +56 -28
  377. package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +38 -29
  378. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +8 -2
  379. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +4 -2
  380. package/packages/bundled-features/src/template-resolver/i18n.ts +25 -0
  381. package/packages/bundled-features/src/template-resolver/index.ts +68 -60
  382. package/packages/bundled-features/src/template-resolver/layout-appearance.ts +1 -1
  383. package/packages/bundled-features/src/template-resolver/layout-regions.ts +1 -1
  384. package/packages/bundled-features/src/template-resolver/seeding.ts +16 -7
  385. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +2 -2
  386. package/packages/bundled-features/src/template-resolver/table.ts +1 -1
  387. package/packages/bundled-features/src/template-resolver/template-bundle.ts +2 -2
  388. package/packages/bundled-features/src/template-resolver/template-delivery-policy.ts +82 -0
  389. package/packages/bundled-features/src/template-resolver/template-draft.ts +1 -1
  390. package/packages/bundled-features/src/template-resolver/template-edit-policy.ts +91 -0
  391. package/packages/bundled-features/src/template-resolver/template-meta.ts +2 -2
  392. package/packages/bundled-features/src/template-resolver/template-preview.ts +22 -12
  393. package/packages/bundled-features/src/template-resolver/template-usage.ts +1 -1
  394. package/packages/bundled-features/src/template-resolver/template-validation.ts +33 -12
  395. package/packages/bundled-features/src/template-resolver/testing.ts +2 -2
  396. package/packages/bundled-features/src/template-resolver/user-content-table.ts +1 -1
  397. package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +4 -5
  398. package/packages/bundled-features/src/template-resolver/{constants.ts → web/constants.ts} +10 -10
  399. package/packages/bundled-features/src/template-resolver/{document-blocks.ts → web/document-blocks.ts} +3 -2
  400. package/packages/bundled-features/src/template-resolver/web/document-editor-extensions.ts +31 -3
  401. package/packages/bundled-features/src/template-resolver/web/document-editor.tsx +0 -1
  402. package/packages/bundled-features/src/template-resolver/web/document-images.ts +28 -0
  403. package/packages/bundled-features/src/template-resolver/{document-schema.ts → web/document-schema.ts} +5 -1
  404. package/packages/bundled-features/src/template-resolver/{document-steps.ts → web/document-steps.ts} +0 -1
  405. package/packages/bundled-features/src/template-resolver/web/document-tiptap-editor.tsx +48 -11
  406. package/packages/bundled-features/src/template-resolver/web/document-toolbar-blocks.ts +4 -3
  407. package/packages/bundled-features/src/template-resolver/web/editor-handle.ts +1 -2
  408. package/packages/bundled-features/src/template-resolver/web/i18n.ts +8 -1
  409. package/packages/bundled-features/src/template-resolver/web/index.ts +13 -14
  410. package/packages/bundled-features/src/template-resolver/{mail-constants.ts → web/mail-constants.ts} +0 -1
  411. package/packages/bundled-features/src/template-resolver/{pdf-constants.ts → web/pdf-constants.ts} +0 -1
  412. package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor-lazy.tsx +0 -1
  413. package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor.tsx +5 -4
  414. package/packages/bundled-features/src/template-resolver/{placeholder-text.ts → web/placeholder-text.ts} +0 -1
  415. package/packages/bundled-features/src/template-resolver/{qualified-names.ts → web/qualified-names.ts} +2 -1
  416. package/packages/bundled-features/src/template-resolver/web/use-stable-by-key.ts +0 -1
  417. package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +1 -1
  418. package/packages/bundled-features/src/tenant/index.ts +7 -7
  419. package/packages/bundled-features/src/tenant/invitation-table.ts +1 -1
  420. package/packages/bundled-features/src/tenant/invited-membership.ts +1 -1
  421. package/packages/bundled-features/src/tenant/last-tenant-admin.ts +1 -1
  422. package/packages/bundled-features/src/tenant/member-role-options.ts +1 -1
  423. package/packages/bundled-features/src/tenant/screens.ts +2 -2
  424. package/packages/bundled-features/src/tenant/web/client-plugin.tsx +1 -2
  425. package/packages/bundled-features/src/tenant/{constants.ts → web/constants.ts} +3 -6
  426. package/packages/bundled-features/src/tenant/web/index.ts +0 -1
  427. package/packages/bundled-features/src/tenant/web/member-roles-cell.tsx +0 -1
  428. package/packages/bundled-features/src/tenant/web/member-status-cell.tsx +0 -1
  429. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +2 -2
  430. package/packages/bundled-features/src/tier-engine/entity.ts +1 -1
  431. package/packages/bundled-features/src/tier-engine/feature.ts +7 -7
  432. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +1 -1
  433. package/packages/bundled-features/src/tier-engine/index.ts +8 -8
  434. package/packages/bundled-features/src/tier-engine/web/client-plugin.tsx +2 -3
  435. package/packages/bundled-features/src/tier-engine/{constants.ts → web/constants.ts} +2 -3
  436. package/packages/bundled-features/src/tier-engine/{i18n.ts → web/i18n.ts} +0 -1
  437. package/packages/bundled-features/src/tier-engine/web/index.ts +0 -1
  438. package/packages/bundled-features/src/user/handlers/create.write.ts +1 -1
  439. package/packages/bundled-features/src/user/handlers/update-roles.ts +1 -1
  440. package/packages/bundled-features/src/user/handlers/update.write.ts +1 -1
  441. package/packages/bundled-features/src/user/index.ts +1 -1
  442. package/packages/bundled-features/src/user/invited-global-roles.ts +1 -1
  443. package/packages/bundled-features/src/user/schema/user.ts +1 -1
  444. package/packages/bundled-features/src/user/{constants.ts → web/constants.ts} +0 -1
  445. package/packages/bundled-features/src/user-data-rights/changes.json +14 -0
  446. package/packages/bundled-features/src/user-data-rights/env.ts +1 -1
  447. package/packages/bundled-features/src/user-data-rights/feature.ts +9 -9
  448. package/packages/bundled-features/src/user-data-rights/index.ts +1 -1
  449. package/packages/bundled-features/src/user-data-rights/lib/resolve-tenant-model.ts +1 -1
  450. package/packages/bundled-features/src/user-data-rights/mail-notifications.ts +1 -1
  451. package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +2 -3
  452. package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +0 -1
  453. package/packages/bundled-features/src/user-data-rights/{constants.ts → web/constants.ts} +11 -12
  454. package/packages/bundled-features/src/user-data-rights/web/default-translations.ts +91 -0
  455. package/packages/bundled-features/src/user-data-rights/web/i18n.ts +41 -91
  456. package/packages/bundled-features/src/user-data-rights/web/index.ts +1 -2
  457. package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +1 -2
  458. package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +0 -1
  459. package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +0 -1
  460. package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +10 -1
  461. package/packages/bundled-features/src/user-profile/feature.ts +2 -2
  462. package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +1 -1
  463. package/packages/bundled-features/src/user-profile/index.ts +3 -2
  464. package/packages/bundled-features/src/user-profile/web/client-plugin.ts +2 -3
  465. package/packages/bundled-features/src/user-profile/{constants.ts → web/constants.ts} +0 -1
  466. package/packages/bundled-features/src/user-profile/{i18n.ts → web/i18n.ts} +0 -1
  467. package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +2 -3
  468. package/packages/bundled-features/src/waitlist/changes.json +6 -0
  469. package/packages/bundled-features/src/waitlist/entity.ts +1 -1
  470. package/packages/bundled-features/src/waitlist/feature.ts +5 -5
  471. package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +3 -3
  472. package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +5 -1
  473. package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
  474. package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +3 -3
  475. package/packages/bundled-features/src/waitlist/import.ts +1 -1
  476. package/packages/bundled-features/src/waitlist/index.ts +11 -11
  477. package/packages/bundled-features/src/waitlist/legacy-migrate.ts +1 -1
  478. package/packages/bundled-features/src/waitlist/link-on-signup.ts +1 -1
  479. package/packages/bundled-features/src/waitlist/mail.ts +7 -6
  480. package/packages/bundled-features/src/waitlist/payloads.ts +1 -1
  481. package/packages/bundled-features/src/waitlist/screens.ts +1 -1
  482. package/packages/bundled-features/src/waitlist/{constants.ts → web/constants.ts} +0 -1
  483. package/samples/apps/styleguide/src/features/content/web.tsx +0 -1
  484. package/samples/apps/ui-walkthrough/src/app/client.tsx +2 -0
  485. package/samples/apps/ui-walkthrough/src/app/help-action.tsx +37 -0
  486. package/samples/apps/ui-walkthrough/src/app/seed-rental.ts +17 -1
  487. package/samples/apps/ui-walkthrough/src/app/seed-templates.ts +13 -0
  488. package/samples/apps/ui-walkthrough/src/app/server.ts +2 -1
  489. package/samples/apps/ui-walkthrough/src/app/shell.tsx +6 -0
  490. package/samples/apps/ui-walkthrough/src/app/template-seed-data.ts +20 -0
  491. package/samples/apps/ui-walkthrough/src/features/billing/feature.ts +35 -7
  492. package/samples/apps/ui-walkthrough/src/features/billing/i18n.ts +6 -0
  493. package/samples/apps/ui-walkthrough/src/features/rental/entities.ts +27 -0
  494. package/samples/apps/ui-walkthrough/src/features/rental/feature.ts +120 -2
  495. package/samples/apps/ui-walkthrough/src/features/rental/i18n.ts +94 -0
  496. package/samples/apps/ui-walkthrough/src/features/rental/invoice-receive.ts +19 -0
  497. package/samples/apps/ui-walkthrough/src/features/rental/lease-support.ts +32 -1
  498. package/samples/apps/ui-walkthrough/src/features/rental/qualified-names.ts +5 -0
  499. package/samples/apps/ui-walkthrough/src/features/rental/receipts-upload.ts +70 -0
  500. package/samples/apps/ui-walkthrough/src/features/rental/screens.ts +156 -0
  501. package/samples/apps/ui-walkthrough/src/features/subscription-plans/feature.ts +103 -0
  502. package/samples/apps/ui-walkthrough/src/features/subscription-plans/i18n.ts +36 -0
  503. package/samples/apps/ui-walkthrough/src/features/subscription-plans/index.ts +2 -0
  504. package/samples/apps/ui-walkthrough/src/features/subscription-plans/seed.ts +21 -0
  505. package/samples/apps/ui-walkthrough/src/features/tasks/i18n.ts +8 -0
  506. package/samples/apps/ui-walkthrough/src/run-config.ts +43 -3
  507. package/samples/apps/use-all-bundled/e2e-billing-gallery/server.ts +1 -1
  508. package/samples/apps/use-all-bundled/feature-manifest.json +5 -5
  509. package/samples/apps/use-all-bundled/scripts/check-coverage.ts +1 -1
  510. package/samples/apps/use-all-bundled/src/app/dev-app-options.ts +3 -1
  511. package/samples/recipes/compose-stacks/README.md +1 -2
  512. package/samples/recipes/delivery-notifications/README.md +1 -1
  513. package/samples/recipes/embedded/README.md +8 -0
  514. package/samples/recipes/embedded/src/feature.ts +8 -0
  515. package/samples/recipes/embedded/src/handlers/invoice-receive.write.ts +37 -0
  516. package/samples/recipes/embedded/src/screens/invoice-receive.screen.ts +56 -0
  517. package/samples/recipes/legal-pages/README.md +2 -2
  518. package/samples/recipes/legal-pages/src/feature.ts +1 -1
  519. package/samples/recipes/reference-data/src/feature.ts +3 -7
  520. package/packages/bundled-features/src/admin-shell/i18n.ts +0 -54
  521. package/packages/bundled-features/src/audit/i18n.ts +0 -25
  522. package/packages/bundled-features/src/auth-mfa/web/qrcode-browser.d.ts +0 -11
  523. package/packages/bundled-features/src/jobs/i18n.ts +0 -55
  524. package/packages/bundled-features/src/managed-pages/i18n.ts +0 -63
  525. package/packages/bundled-features/src/presets/dsgvo-self-service.ts +0 -35
  526. package/packages/bundled-features/src/user-data-rights/i18n.ts +0 -44
@@ -7,9 +7,14 @@ import {
7
7
  import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
8
8
  import * as z from "zod";
9
9
  import { requireForTenant } from "../../shared/index.ts";
10
- import { TEMPLATE_KINDS, TEXT_BLOCK_KIND, UPSERT_KINDS } from "../constants.ts";
11
10
  import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
11
+ import {
12
+ refuseTemplateEdit,
13
+ type TemplateEditPolicy,
14
+ templateEditAccess,
15
+ } from "../template-edit-policy.ts";
12
16
  import { resolveTemplateVariables } from "../template-validation.ts";
17
+ import { TEMPLATE_KINDS, TEXT_BLOCK_KIND, UPSERT_KINDS } from "../web/constants.ts";
13
18
  import { contentFormatSchema, executor, folderSchema, localeSchema, slugSchema } from "./shared.ts";
14
19
  import { parseStoredJson, storedRecord } from "./template-gates.ts";
15
20
  import { gateTemplateWrite } from "./template-write.ts";
@@ -33,115 +38,117 @@ import { gateTemplateWrite } from "./template-write.ts";
33
38
  //
34
39
  // Kinds that upsertSystem/upsertTenant also write run the same validation
35
40
  // pipeline here, and because saving publishes, publish issues reject too.
36
- export const setWrite = defineWriteHandler({
37
- name: "set",
38
- schema: z.object({
39
- slug: slugSchema,
40
- locale: localeSchema,
41
- /** Which kind to author. Defaults to text-block. */
42
- kind: z.enum(TEMPLATE_KINDS).optional(),
43
- title: z.string().min(1).max(200),
44
- content: z.string().max(200_000).nullable(),
45
- contentFormat: contentFormatSchema.default("markdown"),
46
- /** Folder path for the content tree. Optional + null = root node. */
47
- folder: folderSchema.nullable().optional(),
48
- /** Optional cross-tenant write — SystemAdmin only. Typical use: the
49
- * editor lets a SystemAdmin write onto SYSTEM_TENANT_ID, otherwise the
50
- * text lands on their own platform tenant and the legal routes miss it. */
51
- tenantIdOverride: z.string().min(1).optional(),
52
- }),
53
- // SystemAdmin is a global role, TenantAdmin is per tenant-membership — both
54
- // paths are needed explicitly, otherwise nobody can set SYSTEM_TENANT texts.
55
- access: { roles: ["TenantAdmin", "SystemAdmin"] },
56
- description:
57
- "Creates or overwrites one content-tree resource addressed by slug, kind and locale, carrying a title and folder and going live on save with no draft stage; a SystemAdmin may target the system tenant, where shared legal and marketing copy lives.",
58
- handler: async (event, ctx) => {
59
- const override = event.payload.tenantIdOverride;
60
- // @cast-boundary engine-payload — override is a zod-validated string, the
61
- // user's own tenantId is already TenantId-branded.
62
- const tenantId = (override ?? event.user.tenantId) as TenantId;
63
- const { db, streamTenantId } = requireForTenant(ctx, tenantId);
41
+ export function makeSetWrite(policy: TemplateEditPolicy) {
42
+ return defineWriteHandler({
43
+ name: "set",
44
+ schema: z.object({
45
+ slug: slugSchema,
46
+ locale: localeSchema,
47
+ /** Which kind to author. Defaults to text-block. */
48
+ kind: z.enum(TEMPLATE_KINDS).optional(),
49
+ title: z.string().min(1).max(200),
50
+ content: z.string().max(200_000).nullable(),
51
+ contentFormat: contentFormatSchema.default("markdown"),
52
+ /** Folder path for the content tree. Optional + null = root node. */
53
+ folder: folderSchema.nullable().optional(),
54
+ /** Optional cross-tenant write — SystemAdmin only. Typical use: the
55
+ * editor lets a SystemAdmin write onto SYSTEM_TENANT_ID, otherwise the
56
+ * text lands on their own platform tenant and the legal routes miss it. */
57
+ tenantIdOverride: z.string().min(1).optional(),
58
+ }),
59
+ access: templateEditAccess(policy.tenantEditable),
60
+ description:
61
+ "Creates or overwrites one content-tree resource addressed by slug, kind and locale, carrying a title and folder and going live on save with no draft stage; a SystemAdmin may target the system tenant, where shared legal and marketing copy lives. A TenantAdmin may write only the slug and kind pairs the app lists in tenantEditable, otherwise SystemAdmin only.",
62
+ handler: async (event, ctx) => {
63
+ const kind = event.payload.kind ?? TEXT_BLOCK_KIND;
64
+ const refused = refuseTemplateEdit(policy, event.user, { slug: event.payload.slug, kind });
65
+ if (refused !== null) return refused;
66
+ const override = event.payload.tenantIdOverride;
67
+ // @cast-boundary engine-payload — override is a zod-validated string, the
68
+ // user's own tenantId is already TenantId-branded.
69
+ const tenantId = (override ?? event.user.tenantId) as TenantId;
70
+ const { db, streamTenantId } = requireForTenant(ctx, tenantId);
64
71
 
65
- const kind = event.payload.kind ?? TEXT_BLOCK_KIND;
66
- const existing = await fetchOne<TemplateResourceRow>(db, templateResourcesTable, {
67
- tenantId,
68
- slug: event.payload.slug,
69
- kind,
70
- locale: event.payload.locale,
71
- });
72
+ const existing = await fetchOne<TemplateResourceRow>(db, templateResourcesTable, {
73
+ tenantId,
74
+ slug: event.payload.slug,
75
+ kind,
76
+ locale: event.payload.locale,
77
+ });
72
78
 
73
- const scope = tenantId === SYSTEM_TENANT_ID ? ("system" as const) : ("tenant" as const);
74
- let content = event.payload.content;
75
- if (isOneOf(UPSERT_KINDS, kind)) {
76
- const gated = gateTemplateWrite(
77
- {
78
- kind,
79
- scope,
80
- contentFormat: event.payload.contentFormat,
81
- content,
82
- rawMeta: parseStoredJson(existing?.meta ?? null),
83
- variables: resolveTemplateVariables(
84
- ctx.registry,
85
- event.payload.slug,
86
- storedRecord(existing?.variableSchema ?? null),
87
- ),
88
- },
89
- "active",
90
- );
91
- if (!gated.ok) return gated.failure;
92
- content = gated.evaluated.content;
93
- }
79
+ const scope = tenantId === SYSTEM_TENANT_ID ? ("system" as const) : ("tenant" as const);
80
+ let content = event.payload.content;
81
+ if (isOneOf(UPSERT_KINDS, kind)) {
82
+ const gated = gateTemplateWrite(
83
+ {
84
+ kind,
85
+ scope,
86
+ contentFormat: event.payload.contentFormat,
87
+ content,
88
+ rawMeta: parseStoredJson(existing?.meta ?? null),
89
+ variables: resolveTemplateVariables(
90
+ ctx.registry,
91
+ event.payload.slug,
92
+ storedRecord(existing?.variableSchema ?? null),
93
+ ),
94
+ },
95
+ "active",
96
+ );
97
+ if (!gated.ok) return gated.failure;
98
+ content = gated.evaluated.content;
99
+ }
94
100
 
95
- const fields = {
96
- slug: event.payload.slug,
97
- kind,
98
- locale: event.payload.locale,
99
- title: event.payload.title,
100
- content,
101
- contentFormat: event.payload.contentFormat,
102
- folder: event.payload.folder ?? null,
103
- variableSchema: "{}",
104
- linkedResources: "{}",
105
- scope,
106
- parentTemplateId: null,
107
- // Text blocks have no draft stage — saving publishes, so resolveTemplate
108
- // (which only returns active rows) finds them.
109
- status: "active" as const,
110
- };
101
+ const fields = {
102
+ slug: event.payload.slug,
103
+ kind,
104
+ locale: event.payload.locale,
105
+ title: event.payload.title,
106
+ content,
107
+ contentFormat: event.payload.contentFormat,
108
+ folder: event.payload.folder ?? null,
109
+ variableSchema: "{}",
110
+ linkedResources: "{}",
111
+ scope,
112
+ parentTemplateId: null,
113
+ // Text blocks have no draft stage — saving publishes, so resolveTemplate
114
+ // (which only returns active rows) finds them.
115
+ status: "active" as const,
116
+ };
111
117
 
112
- if (existing) {
113
- const result = await executor.update(
114
- {
115
- id: existing.id,
116
- version: existing.version,
117
- // Only the editable columns — slug/kind/locale are the unique key,
118
- // and rewriting scope/status/variableSchema here would reset whatever
119
- // the template upserts put on the row.
120
- changes: {
121
- title: fields.title,
122
- content: fields.content,
123
- contentFormat: fields.contentFormat,
124
- folder: fields.folder,
118
+ if (existing) {
119
+ const result = await executor.update(
120
+ {
121
+ id: existing.id,
122
+ version: existing.version,
123
+ // Only the editable columns — slug/kind/locale are the unique key,
124
+ // and rewriting scope/status/variableSchema here would reset whatever
125
+ // the template upserts put on the row.
126
+ changes: {
127
+ title: fields.title,
128
+ content: fields.content,
129
+ contentFormat: fields.contentFormat,
130
+ folder: fields.folder,
131
+ },
125
132
  },
126
- },
127
- event.user,
128
- db,
129
- { streamTenantId },
130
- );
133
+ event.user,
134
+ db,
135
+ { streamTenantId },
136
+ );
137
+ if (!result.isSuccess) return result;
138
+ return {
139
+ isSuccess: true as const,
140
+ data: { slug: event.payload.slug, locale: event.payload.locale, isNew: false },
141
+ };
142
+ }
143
+
144
+ const result = await executor.create({ ...fields, tenantId }, event.user, db, {
145
+ streamTenantId,
146
+ });
131
147
  if (!result.isSuccess) return result;
132
148
  return {
133
149
  isSuccess: true as const,
134
- data: { slug: event.payload.slug, locale: event.payload.locale, isNew: false },
150
+ data: { slug: event.payload.slug, locale: event.payload.locale, isNew: true },
135
151
  };
136
- }
137
-
138
- const result = await executor.create({ ...fields, tenantId }, event.user, db, {
139
- streamTenantId,
140
- });
141
- if (!result.isSuccess) return result;
142
- return {
143
- isSuccess: true as const,
144
- data: { slug: event.payload.slug, locale: event.payload.locale, isNew: true },
145
- };
146
- },
147
- });
152
+ },
153
+ });
154
+ }
@@ -1,8 +1,8 @@
1
1
  import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
2
2
  import * as z from "zod";
3
- import { CONTENT_FORMATS, TEMPLATE_STATUSES, UPSERT_KINDS } from "../constants.ts";
4
3
  import { templateResourceEntity, templateResourcesTable } from "../table.ts";
5
4
  import { templateSlugSchema } from "../template-meta.ts";
5
+ import { CONTENT_FORMATS, TEMPLATE_STATUSES, UPSERT_KINDS } from "../web/constants.ts";
6
6
 
7
7
  // One executor per bundle, shared by all four handlers for create/update via
8
8
  // event store + optimistic lock.
@@ -1,12 +1,6 @@
1
1
  import type { Registry, TemplateVariables } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import type { FieldIssue } from "@cosmicdrift/kumiko-framework/errors";
3
3
  import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
4
- import {
5
- CONTENT_FORMATS,
6
- type ContentFormat,
7
- TEMPLATE_KINDS,
8
- type TemplateKind,
9
- } from "../constants.ts";
10
4
  import { documentViolationsToFieldIssues } from "../document-sanitizer.ts";
11
5
  import { sanitizeTemplateWriteBody, type TemplateWriteScope } from "../layout-regions.ts";
12
6
  import { imageResourceKeysOf } from "../linked-resources.ts";
@@ -17,6 +11,12 @@ import {
17
11
  type TemplateValidation,
18
12
  validateTemplatePlaceholders,
19
13
  } from "../template-validation.ts";
14
+ import {
15
+ CONTENT_FORMATS,
16
+ type ContentFormat,
17
+ TEMPLATE_KINDS,
18
+ type TemplateKind,
19
+ } from "../web/constants.ts";
20
20
 
21
21
  const PLACEHOLDER_VALIDATED_KINDS: ReadonlySet<TemplateKind> = new Set([
22
22
  "mail",
@@ -16,13 +16,13 @@ import {
16
16
  writeFailure,
17
17
  } from "@cosmicdrift/kumiko-framework/errors";
18
18
  import { requireForTenant } from "../../shared/index.ts";
19
- import type { ContentFormat, TemplateKind } from "../constants.ts";
20
19
  import type { TemplateWriteScope } from "../layout-regions.ts";
21
- import { TemplateResolverErrors } from "../qualified-names.ts";
22
20
  import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
23
21
  import { activationChanges, serializeTemplateDraft } from "../template-draft.ts";
24
22
  import { isSystemOnlyTemplate } from "../template-system-only.ts";
25
23
  import type { TemplateValidation } from "../template-validation.ts";
24
+ import type { ContentFormat, TemplateKind } from "../web/constants.ts";
25
+ import { TemplateResolverErrors } from "../web/qualified-names.ts";
26
26
  import { executor } from "./shared.ts";
27
27
  import {
28
28
  evaluateTemplateWrite,
@@ -15,6 +15,12 @@ import { requireForTenant } from "../../shared/index.ts";
15
15
  import type { TemplateResourceRow } from "../table.ts";
16
16
  import { templateResourcesTable } from "../table.ts";
17
17
  import { activationChanges, parseTemplateDraft, toWorkingRow } from "../template-draft.ts";
18
+ import {
19
+ refuseMissingTemplate,
20
+ refuseTemplateEdit,
21
+ type TemplateEditPolicy,
22
+ templateEditAccess,
23
+ } from "../template-edit-policy.ts";
18
24
  import { executor } from "./shared.ts";
19
25
  import { publishGateIssues } from "./template-gates.ts";
20
26
 
@@ -27,8 +33,10 @@ function isRowOfTarget(row: TemplateResourceRow, target: StatusTarget, callerTen
27
33
  : row.tenantId === callerTenantId && row.scope === "tenant";
28
34
  }
29
35
 
30
- export function writeAccessFor(target: StatusTarget) {
31
- return { roles: target === "system" ? ["SystemAdmin"] : ["TenantAdmin", "SystemAdmin"] };
36
+ export function writeAccessFor(target: StatusTarget, policy: TemplateEditPolicy) {
37
+ return target === "system"
38
+ ? { roles: ["SystemAdmin"] }
39
+ : templateEditAccess(policy.tenantEditable);
32
40
  }
33
41
 
34
42
  // The tenant db also reads system rows; the row's own tenant must match the
@@ -65,6 +73,7 @@ function planStatusChange(
65
73
  }
66
74
 
67
75
  function createStatusUpdateHandler(
76
+ policy: TemplateEditPolicy,
68
77
  name: string,
69
78
  target: StatusTarget,
70
79
  status: TemplateStatus,
@@ -73,13 +82,20 @@ function createStatusUpdateHandler(
73
82
  return defineWriteHandler({
74
83
  name,
75
84
  schema: z.object({ id: z.string().min(1) }),
76
- access: writeAccessFor(target),
85
+ access: writeAccessFor(target, policy),
77
86
  // A system template change reaches every tenant without an override.
78
87
  ...(target === "system" ? { agent: { risk: "high" as const } } : {}),
79
88
  description,
80
89
  handler: async (event, ctx) => {
81
90
  const { db, scoped, row } = await loadTargetRow(ctx, target, event.user, event.payload.id);
82
- if (!row) return writeFailure(new NotFoundError("template-resource", event.payload.id));
91
+ if (!row) {
92
+ const refused = target === "own" ? refuseMissingTemplate(policy, event.user) : null;
93
+ return refused ?? writeFailure(new NotFoundError("template-resource", event.payload.id));
94
+ }
95
+ if (target === "own") {
96
+ const refused = refuseTemplateEdit(policy, event.user, row);
97
+ if (refused !== null) return refused;
98
+ }
83
99
  const plan = planStatusChange(ctx, row, status);
84
100
  if (!plan.ok) return plan.failure;
85
101
  const result = await executor.update(
@@ -94,27 +110,39 @@ function createStatusUpdateHandler(
94
110
  });
95
111
  }
96
112
 
97
- export const archiveWrite = createStatusUpdateHandler(
98
- "archive",
99
- "own",
100
- "archived",
101
- "Sets one template resource of the caller's tenant to archived so the resolver stops serving it while the row and its content survive; use it to retire a template reversibly instead of deleting it. An open draft stays.",
102
- );
103
- export const publishWrite = createStatusUpdateHandler(
104
- "publish",
105
- "own",
106
- "active",
107
- "Sets one template resource of the caller's tenant to active so the resolver starts serving it; use it to release a draft written by upsert-tenant (a draft saved beside an active version replaces it), or to bring an archived template back; a version with unknown placeholders or unused required variables is refused and the served version stays.",
108
- );
109
- export const archiveSystemWrite = createStatusUpdateHandler(
110
- "archive-system",
111
- "system",
112
- "archived",
113
- "Sets one system-default template to archived so the resolver stops serving it to every tenant that has no override; SystemAdmin only, reversible with publish-system.",
114
- );
115
- export const publishSystemWrite = createStatusUpdateHandler(
116
- "publish-system",
117
- "system",
118
- "active",
119
- "Sets one system-default template to active so the resolver serves it again to every tenant that has no override; an open draft beside the active version replaces it; SystemAdmin only, a version with unknown placeholders or unused required variables is refused.",
120
- );
113
+ export function makeArchiveWrite(policy: TemplateEditPolicy) {
114
+ return createStatusUpdateHandler(
115
+ policy,
116
+ "archive",
117
+ "own",
118
+ "archived",
119
+ "Sets one template resource of the caller's tenant to archived so the resolver stops serving it while the row and its content survive; use it to retire a template reversibly instead of deleting it. An open draft stays. Outside the templates the app lists in tenantEditable only a SystemAdmin may use it.",
120
+ );
121
+ }
122
+ export function makePublishWrite(policy: TemplateEditPolicy) {
123
+ return createStatusUpdateHandler(
124
+ policy,
125
+ "publish",
126
+ "own",
127
+ "active",
128
+ "Sets one template resource of the caller's tenant to active so the resolver starts serving it; use it to release a draft written by upsert-tenant (a draft saved beside an active version replaces it), or to bring an archived template back; a version with unknown placeholders or unused required variables is refused and the served version stays. Outside the templates the app lists in tenantEditable only a SystemAdmin may use it.",
129
+ );
130
+ }
131
+ export function makeArchiveSystemWrite(policy: TemplateEditPolicy) {
132
+ return createStatusUpdateHandler(
133
+ policy,
134
+ "archive-system",
135
+ "system",
136
+ "archived",
137
+ "Sets one system-default template to archived so the resolver stops serving it to every tenant that has no override; SystemAdmin only, reversible with publish-system.",
138
+ );
139
+ }
140
+ export function makePublishSystemWrite(policy: TemplateEditPolicy) {
141
+ return createStatusUpdateHandler(
142
+ policy,
143
+ "publish-system",
144
+ "system",
145
+ "active",
146
+ "Sets one system-default template to active so the resolver serves it again to every tenant that has no override; an open draft beside the active version replaces it; SystemAdmin only, a version with unknown placeholders or unused required variables is refused.",
147
+ );
148
+ }
@@ -1,5 +1,10 @@
1
1
  import { defineWriteHandler, type TenantId } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import * as z from "zod";
3
+ import {
4
+ refuseTemplateEdit,
5
+ type TemplateEditPolicy,
6
+ templateEditAccess,
7
+ } from "../template-edit-policy.ts";
3
8
  import { resolveTemplateVariables } from "../template-validation.ts";
4
9
  import { upsertPayloadSchema } from "./shared.ts";
5
10
  import { writeTemplateRow } from "./template-write.ts";
@@ -9,32 +14,36 @@ import { writeTemplateRow } from "./template-write.ts";
9
14
  // via publish-Handler. SystemAdmin kann via tenantIdOverride für
10
15
  // einen anderen Tenant schreiben (typisch: Plattform-Admin-UI das
11
16
  // Tenant-Templates kuratiert).
12
- export const upsertTenantWrite = defineWriteHandler({
13
- name: "upsert-tenant",
14
- schema: upsertPayloadSchema.extend({
15
- tenantIdOverride: z.string().min(1).optional(),
16
- status: z.enum(["draft", "active"]).default("draft"),
17
- }),
18
- access: { roles: ["TenantAdmin", "SystemAdmin"] },
19
- description:
20
- "Creates or overwrites a tenant-scoped template override with its variable schema, landing as a draft that only publish makes live (over an active override the draft is stored beside it, the active version keeps being served until publish); it refuses a system-tenant target, which is what upsert-system is for.",
21
- handler: async (event, ctx) => {
22
- // @cast-boundary engine-payload — override aus Zod-parsed string,
23
- // event.user.tenantId schon TenantId-branded; union als TenantId casten
24
- // ist legit (override ist UUID-Format-validiert in schema).
25
- const tenantId = (event.payload.tenantIdOverride ?? event.user.tenantId) as TenantId;
26
- return writeTemplateRow({
27
- ctx,
28
- user: event.user,
29
- tenantId,
30
- scope: "tenant",
31
- status: event.payload.status,
32
- variables: resolveTemplateVariables(
33
- ctx.registry,
34
- event.payload.slug,
35
- event.payload.variableSchema,
36
- ),
37
- payload: event.payload,
38
- });
39
- },
40
- });
17
+ export function makeUpsertTenantWrite(policy: TemplateEditPolicy) {
18
+ return defineWriteHandler({
19
+ name: "upsert-tenant",
20
+ schema: upsertPayloadSchema.extend({
21
+ tenantIdOverride: z.string().min(1).optional(),
22
+ status: z.enum(["draft", "active"]).default("draft"),
23
+ }),
24
+ access: templateEditAccess(policy.tenantEditable),
25
+ description:
26
+ "Creates or overwrites a tenant-scoped template override with its variable schema, landing as a draft that only publish makes live (over an active override the draft is stored beside it, the active version keeps being served until publish); it refuses a system-tenant target, which is what upsert-system is for; a TenantAdmin may write it only for templates the app lists in tenantEditable, otherwise SystemAdmin only.",
27
+ handler: async (event, ctx) => {
28
+ const refused = refuseTemplateEdit(policy, event.user, event.payload);
29
+ if (refused !== null) return refused;
30
+ // @cast-boundary engine-payload — override is a zod-validated string and
31
+ // event.user.tenantId is already TenantId-branded; forTenant rejects the
32
+ // override for non-SystemAdmins.
33
+ const tenantId = (event.payload.tenantIdOverride ?? event.user.tenantId) as TenantId;
34
+ return writeTemplateRow({
35
+ ctx,
36
+ user: event.user,
37
+ tenantId,
38
+ scope: "tenant",
39
+ status: event.payload.status,
40
+ variables: resolveTemplateVariables(
41
+ ctx.registry,
42
+ event.payload.slug,
43
+ event.payload.variableSchema,
44
+ ),
45
+ payload: event.payload,
46
+ });
47
+ },
48
+ });
49
+ }
@@ -1,10 +1,11 @@
1
1
  import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
- import { TEMPLATE_KINDS } from "../constants.ts";
5
4
  import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
5
+ import { deliveryPolicyOf } from "../template-delivery-policy.ts";
6
6
  import { templateSlugSchema } from "../template-meta.ts";
7
7
  import { collectTemplateUsage } from "../template-usage.ts";
8
+ import { TEMPLATE_KINDS } from "../web/constants.ts";
8
9
  import { effectiveMailLayoutSlugs } from "./overview.query.ts";
9
10
 
10
11
  const MAIL_ROW_LIMIT = 5000;
@@ -25,7 +26,12 @@ export const usageQuery = defineQueryHandler({
25
26
  { limit: MAIL_ROW_LIMIT },
26
27
  );
27
28
  return {
28
- usedBy: collectTemplateUsage(ctx.registry, slug, kind, effectiveMailLayoutSlugs(mailRows)),
29
+ usedBy: collectTemplateUsage(
30
+ ctx.registry,
31
+ slug,
32
+ kind,
33
+ effectiveMailLayoutSlugs(mailRows, deliveryPolicyOf(ctx.registry)),
34
+ ),
29
35
  };
30
36
  },
31
37
  });
@@ -6,12 +6,13 @@ import {
6
6
  SYSTEM_TENANT_ID,
7
7
  } from "@cosmicdrift/kumiko-framework/engine";
8
8
  import * as z from "zod";
9
- import type { ContentFormat, UpsertKind } from "../constants.ts";
10
9
  import type { TemplateWriteScope } from "../layout-regions.ts";
11
10
  import { imageResourceKeysOf } from "../linked-resources.ts";
12
11
  import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
12
+ import { deliveryPolicyOf, isRowServedTo } from "../template-delivery-policy.ts";
13
13
  import { isSystemAdmin } from "../template-draft.ts";
14
14
  import { resolveTemplateVariables, systemPlaceholdersFor } from "../template-validation.ts";
15
+ import type { ContentFormat, UpsertKind } from "../web/constants.ts";
15
16
  import { contentFormatSchema, kindSchema, localeSchema, templateSlugSchema } from "./shared.ts";
16
17
  import { evaluateTemplateWrite } from "./template-gates.ts";
17
18
 
@@ -67,7 +68,8 @@ export async function knownResourceKeysFor(
67
68
  scope: "system",
68
69
  locale,
69
70
  })),
70
- ...(scope === "tenant"
71
+ ...(scope === "tenant" &&
72
+ isRowServedTo(deliveryPolicyOf(ctx.registry), user, { tenantId: user.tenantId, kind, slug })
71
73
  ? await knownResourceKeys(ctx.db, { tenantId: user.tenantId, slug, kind, scope, locale })
72
74
  : []),
73
75
  ];
@@ -0,0 +1,25 @@
1
+ import { handlerTitleKey } from "@cosmicdrift/kumiko-framework/engine";
2
+ import { TemplateResolverHandlers as H } from "./web/qualified-names.ts";
3
+
4
+ // The AI assistant and its approval prompts name a handler by its title key; without
5
+ // one the user reads the raw handler name. de/es/fr/it live in the locale packages.
6
+ export const TEMPLATE_RESOLVER_I18N: Readonly<Record<string, { readonly en: string }>> = {
7
+ [handlerTitleKey(H.upsertSystem)]: { en: "Save system template" },
8
+ [handlerTitleKey(H.upsertTenant)]: { en: "Save template" },
9
+ [handlerTitleKey(H.publish)]: { en: "Publish template" },
10
+ [handlerTitleKey(H.archive)]: { en: "Archive template" },
11
+ [handlerTitleKey(H.publishSystem)]: { en: "Publish system template" },
12
+ [handlerTitleKey(H.archiveSystem)]: { en: "Archive system template" },
13
+ [handlerTitleKey(H.discardDraft)]: { en: "Discard draft" },
14
+ [handlerTitleKey(H.discardDraftSystem)]: { en: "Discard system template draft" },
15
+ [handlerTitleKey(H.resetToSystem)]: { en: "Reset to system template" },
16
+ [handlerTitleKey(H.set)]: { en: "Save text" },
17
+ [handlerTitleKey(H.importBundle)]: { en: "Import template" },
18
+ [handlerTitleKey(H.importBundleSystem)]: { en: "Import system template" },
19
+ [handlerTitleKey(H.copyLocale)]: { en: "Copy template to another language" },
20
+ [handlerTitleKey(H.resourceUpload)]: { en: "Upload image or attachment" },
21
+ [handlerTitleKey(H.resourceRemove)]: { en: "Remove image or attachment" },
22
+ [handlerTitleKey(H.resourceLinkPdf)]: { en: "Attach PDF template" },
23
+ [handlerTitleKey(H.sendTest)]: { en: "Send test mail" },
24
+ [handlerTitleKey(H.patchDraft)]: { en: "Edit template draft" },
25
+ };