@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
@@ -21,7 +21,7 @@
21
21
  },
22
22
  {
23
23
  "name": "admin-shell",
24
- "description": "Registers tenant-admin and platform-admin workspaces with provider nav into owner-feature screens (`tenant:screen:members`, `audit:screen:audit-log`, `tenant:screen:tenant-list`, `jobs:screen:job-runs`, optional `tier-engine:screen:tier-admin`, optional `cap-overview:screen:my-caps`/`cap-overview:screen:tenant-cap-list`, optional `document-designer` template navs) and the two overview dashboards, built from the metrics list (`metrics` option, default DEFAULT_METRICS). Mount after user, tenant, audit, jobs, metrics and metrics-system; pass `workspaceIds` to match app URL conventions (e.g. Studio `d`/`s`, PublicStatus `admin`/`sysadmin`). Client: `adminShellClient()`, `tenantClient()`, `auditClient()`, `jobsClient()`, optional `tierEngineClient()`.",
24
+ "description": "Registers tenant-admin and platform-admin workspaces with provider nav into owner-feature screens (`tenant:screen:members`, `audit:screen:audit-log`, `audit:screen:audit-log-all-tenants`, `tenant:screen:tenant-list`, `jobs:screen:job-runs`, optional `tier-engine:screen:tier-admin`, optional `cap-overview:screen:my-caps`/`cap-overview:screen:tenant-cap-list`, optional `document-designer` template navs) and the two overview dashboards, built from the metrics list (`metrics` option, default DEFAULT_METRICS). Mount after user, tenant, audit, jobs, metrics and metrics-system; pass `workspaceIds` to match app URL conventions (e.g. Studio `d`/`s`, PublicStatus `admin`/`sysadmin`). Client: `adminShellClient()`, `tenantClient()`, `auditClient()`, `jobsClient()`, optional `tierEngineClient()`.",
25
25
  "toggleableDefault": null,
26
26
  "requires": [
27
27
  "user",
@@ -69,7 +69,7 @@
69
69
  },
70
70
  {
71
71
  "name": "audit",
72
- "description": "Exposes the framework's event store as a paginated, filterable audit log via the `audit:query:list` handler (accessible to `Admin` and `SystemAdmin` roles). No separate table or projection — the event store is the audit trail by construction: every entity write already records who, when, what entity, and the event payload with PII stripped. A SystemAdmin can pass `scope: \"system\"` to read the app-instance system events such as `app.started`. Filter by `aggregateType`, `aggregateId`, `eventType`, `userId`, or time range. Also records `audit:event:escape-hatch-used` whenever a handler uses one of the framework's escape hatches (unsafeRaw, acknowledgeCrossTenant, db.global() writes, or a granted identity switch).",
72
+ "description": "Exposes the framework's event store as a paginated, filterable audit log via the `audit:query:list` handler (accessible to `Admin` and `SystemAdmin` roles). No separate table or projection — the event store is the audit trail by construction: every entity write already records who, when, what entity, and the event payload with PII stripped. A SystemAdmin can pass `scope: \"system\"` to read the app-instance system events such as `app.started`, and reads the events of every tenant (system tenant excluded) through `audit:query:list-all-tenants` and the `audit-log-all-tenants` screen. Filter by `aggregateType`, `aggregateId`, `eventType`, `userId`, or time range. Also records `audit:event:escape-hatch-used` whenever a handler uses one of the framework's escape hatches (unsafeRaw, acknowledgeCrossTenant, db.global() writes, or a granted identity switch).",
73
73
  "toggleableDefault": null,
74
74
  "requires": [
75
75
  "tenant",
@@ -795,7 +795,7 @@
795
795
  },
796
796
  {
797
797
  "name": "document-designer",
798
- "description": "Template overview and layout editor: lists the mail, PDF and layout templates of a tenant (platform admins see the system templates and how many tenants customised each) and edits the mail layout and the PDF letterhead in the browser. Mount after template-resolver and, for the branding rail, managed-pages. Client: `documentDesignerClient()`; admin-shell lists the navs with `includeDocumentDesigner`.",
798
+ "description": "Template overview and layout editor: lists the mail, PDF and layout templates of a tenant (platform admins see the system templates and how many tenants customised each) and edits the mail layout and the PDF letterhead in the browser. Mount after template-resolver and, for the branding rail, managed-pages. Client: `documentDesignerClient()`; admin-shell lists the navs with `includeDocumentDesigner`. The tenant overview and the editors are for SystemAdmin only; the `access` option adds roles (normally `templateEditAccess(tenantEditable)` of the template-resolver mount), and the server still enforces per template which of them may save.",
799
799
  "toggleableDefault": null,
800
800
  "requires": [
801
801
  "template-resolver"
@@ -2209,7 +2209,7 @@
2209
2209
  },
2210
2210
  {
2211
2211
  "name": "renderer-puppeteer-client",
2212
- "description": "A `renderer-foundation` plugin that prints documents to PDF through a separately deployed `puppeteer-service`. A `document-pdf` request names a stored template (`{ slug, locale, variables }`): the plugin resolves the template and its `pdf-layout` (header, signature and footer regions), embeds every image as a data URI, turns repeating table header rows into a real table head and sends the finished HTML to the service, which performs no network fetches itself. The page format, margins, file name pattern and title come from the template meta. A write handler renders with `renderPdfBeforeTransaction(ctx, { slug, locale, variables })` as its `beforeTransaction` phase, so the print service call holds no database connection, and stores the result with `storeRenderedPdf(ctx, event.prepared)` in the handler: a file plus a `rendered-pdf` record that keeps the template and layout version, so a stored document can always be traced to the text it was created from. The `puppeteer-status` query tells a TenantAdmin whether the service answers; while it does not, rendering fails with a `puppeteer_unavailable` error (HTTP 503) and no PDF is created. `image-snapshot` requests still take ready HTML in `payload.content`, which must embed all resources as data: URIs because the service fetches no http(s) resources. Configure the endpoint and token with `PUPPETEER_SERVICE_URL` and `PUPPETEER_AUTH_TOKEN`; the client retries 5xx and network errors with exponential backoff (default 3 retries), 4xx fails at once. The feature adds the `rendered_pdfs` table, so apps that mount it need a schema migration.",
2212
+ "description": "A `renderer-foundation` plugin that prints documents to PDF through a separately deployed `puppeteer-service`. A `document-pdf` request names a stored template (`{ slug, locale, variables }`): the plugin resolves the template and its `pdf-layout` (header, signature and footer regions), embeds every image as a data URI, turns repeating table header rows into a real table head and sends the finished HTML to the service, which performs no network fetches itself. The page format, margins, file name pattern and title come from the template meta. A write handler renders with `renderPdfBeforeTransaction(ctx, { slug, locale, variables })` as its `beforeTransaction` phase, so the print service call holds no database connection, and stores the result with `storeRenderedPdf(ctx, event.prepared)` in the handler: a file plus a `rendered-pdf` record that keeps the template and layout version, so a stored document can always be traced to the text it was created from. The `puppeteer-status` query tells a TenantAdmin whether the service answers; while it does not, rendering fails with a `puppeteer_unavailable` error (HTTP 503) and no PDF is created. `image-snapshot` requests still take ready HTML in `payload.content`, which must embed all resources as data: URIs because the service fetches no http(s) resources. Configure the endpoint and token with `PUPPETEER_SERVICE_URL` and `PUPPETEER_AUTH_TOKEN`; the client retries 502, 503 and network errors with exponential backoff (default 3 retries); 4xx, other 5xx and client timeouts fail at once, because the render has already run. The feature adds the `rendered_pdfs` table, so apps that mount it need a schema migration.",
2213
2213
  "toggleableDefault": null,
2214
2214
  "requires": [
2215
2215
  "renderer-foundation"
@@ -2602,7 +2602,7 @@
2602
2602
  },
2603
2603
  {
2604
2604
  "name": "template-resolver",
2605
- "description": "Every piece of editable text lives here, in one entity: mail bodies, notification texts, PDF document templates, AI prompts and plain text blocks. What a record is used for is the `kind` (`notification`, `mail`, `mail-layout`, `document-pdf`, `pdf-layout`, `ai-prompt`, `text-block`, `snippet`, `image-snapshot`).\n\nReading is one call — `ctx.templateResolver.resolveTemplate({ tenantId, slug, kind, locale })`. It walks four levels: tenant+locale, system+locale, tenant+fallback-locale, system+fallback-locale. A tenant overrides a system default by simply having its own record; no application code changes. Writing programmatically goes through the `upsertSystem`, `upsertTenant`, `publish` and `archive` write handlers; a SystemAdmin retires or restores a system default with `publishSystem` and `archiveSystem`, and a tenant drops its override with `resetToSystem`. Saving a draft over an active template keeps the active version served and stores the edit beside it (column `draft`); `publish` makes it the served version, `discardDraft` / `discardDraftSystem` throws it away.\n\nText an editor should be able to change belongs in a collection, declared at mount: `createTemplateResolverFeature({ collections: [{ id, kind, access: { roles }, nav }] })`. It appears in the navigation, and `access` is part of the mount because a bundled feature cannot know the host's roles. Each collection gets its own `<id>-list` / `<id>-item` / `<id>-set` handlers, so the dispatcher enforces the separation.\n\nHow a collection is edited follows from `contentFormat`: `plain` gives a text area, `rich` a small WYSIWYG (bold, italic, headings, lists, links), `markdown` a text area that stores markdown text (same insertable chips as `plain`). All three offer the collection's `variableSchema` as insertable chips and a preview rendered with sample data — an editor sees what `{{firstName}}` becomes without sending a mail. An app can register its own editor for a format; the last `clientFeature` that registers a format wins (a conflict logs a warning).\n\nA collection is tenant-wide by default. With `ownership: \"user\"` every user keeps their own entries — mail signatures being the obvious case. Those rows live in the separate `user-content-entry` entity and count as user data, so mounting one also requires the `template-resolver-user-data` feature and a migration on the app side.\n\n`validate` dry-runs the write pipeline for a draft (sanitizer, layout rules, placeholders) and reports what the template uses and misses. `export-bundle` / `import-bundle` (and `import-bundle-system`) move one template with all locales and resource files between tenants or environments; `copy-locale` starts a translation from an existing locale. Layouts are structured: a mail or PDF layout is `data-header` / `data-content` / `data-signature` / `data-footer` regions, and mjml layout source is system-only.\n\n`preview` renders a draft (or the stored template) with sample values taken from the `example` of each declared variable, through the same gates and the same mail renderer as a real send, and returns subject, html, `displayHtml` (the html with cid images as data URIs for an editor), text, attachments (inline images and files) and `checks` (images resolved, plain text present, size under 10 MiB, required placeholders used); nothing is saved or sent. `send-test` mails that rendering to the calling user's own address only, subject prefixed with `[TEST]`, at most 10 per user and hour; it needs `delivery`, `channel-email` and `renderer-mail-html` to be mounted.\n\nImages used by a template (`<img data-resource=\"logo\">`) are uploaded with `resourceUpload`, which re-encodes them, stores a file and links it under the key; `resourceRemove` unlinks it. `linkedResources` is written only through these two handlers. With `purpose: \"attachment\"` and a `fileName`, `resourceUpload` stores a PDF, PNG or JPEG as a file attachment of a mail template (original bytes, at most 10) that the mail renderer attaches after the inline images. `resourceLinkPdf` instead links a `document-pdf` template under a key: every mail sent from the template then carries that PDF, rendered at send time with the mail's own variables and locale, under a file name pattern such as `invoice-{{number}}.pdf`; files and linked PDFs share the limit of 10.\n\nReplaces the former `text-content` feature; its blocks now live here as kind `text-block`.",
2605
+ "description": "Every piece of editable text lives here, in one entity: mail bodies, notification texts, PDF document templates, AI prompts and plain text blocks. What a record is used for is the `kind` (`notification`, `mail`, `mail-layout`, `document-pdf`, `pdf-layout`, `ai-prompt`, `text-block`, `snippet`, `image-snapshot`).\n\nReading is one call — `ctx.templateResolver.resolveTemplate({ tenantId, slug, kind, locale })`. It walks four levels: tenant+locale, system+locale, tenant+fallback-locale, system+fallback-locale. A tenant overrides a system default by simply having its own record; no application code changes. Writing programmatically goes through the `upsertSystem`, `upsertTenant`, `publish` and `archive` write handlers; a SystemAdmin retires or restores a system default with `publishSystem` and `archiveSystem`, and a tenant drops its override with `resetToSystem`. Saving a draft over an active template keeps the active version served and stores the edit beside it (column `draft`); `publish` makes it the served version, `discardDraft` / `discardDraftSystem` throws it away.\n\nEditing templates is for SystemAdmin only. A TenantAdmin edits only the templates the app unlocks at the mount site, `createTemplateResolverFeature({ tenantEditable: [{ kind: \"mail\", slug: \"status-update\", access: { roles: [\"TenantAdmin\"] } }] })`, and every write handler enforces that on the server (override, draft, publish, archive, reset, copy-locale, import, resources, `set`). Each entry carries the `access` roles allowed to edit it, because a bundled feature cannot know the host's roles. The same list decides delivery: a tenant override is served (mail, PDF, layouts, text blocks) only while its template is listed in tenantEditable; otherwise the system version is served. A locked override stays stored, a SystemAdmin sees it in the overview marked as not delivered, and listing the template makes it effective again. Tenant rows of a collection mounted with `access` are always served. A collection mounted without `access` is SystemAdmin only.\n\nText an editor should be able to change belongs in a collection, declared at mount: `createTemplateResolverFeature({ collections: [{ id, kind, access: { roles }, nav }] })`. It appears in the navigation, and `access` is part of the mount because a bundled feature cannot know the host's roles. Each collection gets its own `<id>-list` / `<id>-item` / `<id>-set` handlers, so the dispatcher enforces the separation.\n\nHow a collection is edited follows from `contentFormat`: `plain` gives a text area, `rich` a small WYSIWYG (bold, italic, headings, lists, links), `markdown` a text area that stores markdown text (same insertable chips as `plain`). All three offer the collection's `variableSchema` as insertable chips and a preview rendered with sample data — an editor sees what `{{firstName}}` becomes without sending a mail. An app can register its own editor for a format; the last `clientFeature` that registers a format wins (a conflict logs a warning).\n\nA collection is tenant-wide by default. With `ownership: \"user\"` every user keeps their own entries — mail signatures being the obvious case. Those rows live in the separate `user-content-entry` entity and count as user data, so mounting one also requires the `template-resolver-user-data` feature and a migration on the app side.\n\n`validate` dry-runs the write pipeline for a draft (sanitizer, layout rules, placeholders) and reports what the template uses and misses. `export-bundle` / `import-bundle` (and `import-bundle-system`) move one template with all locales and resource files between tenants or environments; `copy-locale` starts a translation from an existing locale. Layouts are structured: a mail or PDF layout is `data-header` / `data-content` / `data-signature` / `data-footer` regions, and mjml layout source is system-only.\n\n`preview` renders a draft (or the stored template) with sample values taken from the `example` of each declared variable, through the same gates and the same mail renderer as a real send, and returns subject, html, `displayHtml` (the html with cid images as data URIs for an editor), text, attachments (inline images and files) and `checks` (images resolved, plain text present, size under 10 MiB, required placeholders used); nothing is saved or sent. `send-test` mails that rendering to the calling user's own address only, subject prefixed with `[TEST]`, at most 10 per user and hour; it needs `delivery`, `channel-email` and `renderer-mail-html` to be mounted. `send-test-status` tells an editor beforehand whether that send can work for the caller (`canSend`, else `reason` `no_channel` or `no_address`), never returning the address.\n\nImages used by a template (`<img data-resource=\"logo\">`) are uploaded with `resourceUpload`, which re-encodes them, stores a file and links it under the key; `resourceRemove` unlinks it. `linkedResources` is written only through these two handlers. With `purpose: \"attachment\"` and a `fileName`, `resourceUpload` stores a PDF, PNG or JPEG as a file attachment of a mail template (original bytes, at most 10) that the mail renderer attaches after the inline images. `resourceLinkPdf` instead links a `document-pdf` template under a key: every mail sent from the template then carries that PDF, rendered at send time with the mail's own variables and locale, under a file name pattern such as `invoice-{{number}}.pdf`; files and linked PDFs share the limit of 10.\n\nReplaces the former `text-content` feature; its blocks now live here as kind `text-block`.",
2606
2606
  "toggleableDefault": null,
2607
2607
  "requires": [],
2608
2608
  "optionalRequires": [],
@@ -28,7 +28,7 @@ const FRAMEWORK_ROOT = resolve(ROOT, "..", "..", "..");
28
28
  const EXPECTED_HELD_BACK = new Set([
29
29
  "foundation-shared", // utilities (requireDefined/requireNonEmpty), kein feature
30
30
  "page-render", // shared HTML render/cache helpers (legal/managed-pages), kein defineFeature
31
- "presets", // deprecated feature-bundle helpers (dsgvoSelfServiceFeatures, securityBaselineFeatures), kein defineFeature
31
+ "presets", // deprecated feature-bundle helpers (securityBaselineFeatures), kein defineFeature
32
32
  ]);
33
33
 
34
34
  // Sub-paths in bundled-features's package.json exports (./tenant/seeding,
@@ -34,7 +34,9 @@ export const devAppOptions = {
34
34
  htmlPath: "./public/index.html",
35
35
  watchDirs: ["./src", "../../../packages/*/src"],
36
36
  anonymousAccess: { defaultTenantId: SYSTEM_TENANT_ID },
37
- extraContext: ({ db }) => ({ templateResolver: createTemplateResolverApi(db) }),
37
+ extraContext: ({ db, registry }) => ({
38
+ templateResolver: createTemplateResolverApi(db, registry),
39
+ }),
38
40
  seeds: [seedScreenshotData],
39
41
  auth: {
40
42
  admin: {
@@ -18,8 +18,7 @@ the option.
18
18
  `securityBaselineFeatures()`.
19
19
  - **`composeGdprStack({ tenantLifecycle, selfService })`**: `data-retention`
20
20
  and `compliance-profiles`, optionally `tenant-lifecycle`. `selfService` adds
21
- `sessions`, `user-data-rights` and `user-profile` (needs `mail`) and
22
- replaces `dsgvoSelfServiceFeatures()`.
21
+ `sessions`, `user-data-rights` and `user-profile` (needs `mail`).
23
22
  - **`composeSaasStack({ billing, tiers, caps, waitlist })`**:
24
23
  `billing-foundation` and `tier-engine`, plus `cap-counter`/`cap-overview`
25
24
  and `waitlist` when configured. `billing: "stripe"` leaves
@@ -8,7 +8,7 @@ Shows how a feature sends notifications to multiple channels (InApp + Email + Pu
8
8
 
9
9
  **Mail text is stored data:** The boot seed (`seedNotificationTemplates`) writes the declared `template` and `meta` into the template store as system templates. The email channel renders them with `renderer-mail-html`. A notification routed to email without `template` and `meta` fails its delivery.
10
10
 
11
- **Tenant override:** A tenant admin overrides the text through the template-resolver handlers (`upsertTenant`, then `publish`). The next mail for that tenant uses the override; the system text stays for everyone else.
11
+ **Tenant override:** Only a SystemAdmin edits templates unless the app unlocks them. The app lists the mail in `createTemplateResolverFeature({ tenantEditable: [{ kind: "mail", slug, access: { roles: ["TenantAdmin"] } }] })`; then a tenant admin overrides the text through the template-resolver handlers (`upsertTenant`, then `publish`) and every other template is refused with 403. The next mail for that tenant uses the override; the system text stays for everyone else.
12
12
 
13
13
  **Sending:** The write handler calls `ctx.notify(type, { to, data })`. The `data` keys are the template variables; sending fails loudly when a required variable is missing.
14
14
 
@@ -19,6 +19,14 @@ object and an embedded list rendered by a declarative `entityEdit` screen.
19
19
  `createEmbeddedListField`; its renderer receives `embeddedListCells`, so no
20
20
  custom screen component is required.
21
21
 
22
+ - **Derived head totals** (`src/screens/invoice-receive.screen.ts`): an
23
+ `actionForm` declares `derive` so net, VAT, and gross follow the lines
24
+ (`listSum`); the list requires at least one line (`minItems: 1`), so there
25
+ is no lineless input to cover. The head totals are not laid out; the lines footer shows Net, VAT, and Gross through labelled `totals`
26
+ entries (`{ label, from }`). The handler wraps its schema with
27
+ `withFormDerivations(schema, screen)` (`src/handlers/invoice-receive.write.ts`),
28
+ so totals sent by the client are replaced on the server.
29
+
22
30
  ## When to reach for it
23
31
 
24
32
  Use an embedded field or list when the nested data is created, changed, and
@@ -15,6 +15,9 @@
15
15
  // on its `lines` sub-fields (Issue #1835), plus a declarative
16
16
  // entityEdit screen that renders the list end-to-end via
17
17
  // EmbeddedListField, no custom-screen code required
18
+ // invoice-receive — actionForm whose net/VAT/gross head fields are derived
19
+ // from the lines (`derive`); the handler recomputes them with
20
+ // `withFormDerivations`, so client-sent totals are never trusted
18
21
 
19
22
  import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
20
23
  import { contactEntity } from "./entities/contact";
@@ -22,6 +25,8 @@ import { invoiceEntity } from "./entities/invoice";
22
25
  import { productEntity } from "./entities/product";
23
26
  import { contactCreate } from "./handlers/contact-create.write";
24
27
  import { contactDetail } from "./handlers/contact-detail.query";
28
+ import { invoiceReceive } from "./handlers/invoice-receive.write";
29
+ import { invoiceReceiveScreen } from "./screens/invoice-receive.screen";
25
30
 
26
31
  export { contactEntity } from "./entities/contact";
27
32
  export { invoiceEntity } from "./entities/invoice";
@@ -43,6 +48,7 @@ export const embeddedFeature = defineFeature("contacts", (r) => {
43
48
 
44
49
  r.writeHandler(contactCreate);
45
50
  r.queryHandler(contactDetail);
51
+ r.writeHandler(invoiceReceive);
46
52
 
47
53
  r.crud("product", productEntity, { write: adminWrite, read: openRead });
48
54
  r.crud("invoice", invoiceEntity, { write: adminWrite, read: openRead });
@@ -55,4 +61,6 @@ export const embeddedFeature = defineFeature("contacts", (r) => {
55
61
  sections: [{ columns: 1, fields: ["customer", "lines"] }],
56
62
  },
57
63
  });
64
+
65
+ r.screen(invoiceReceiveScreen);
58
66
  });
@@ -0,0 +1,37 @@
1
+ import {
2
+ defineWriteHandler,
3
+ fieldToZod,
4
+ withFormDerivations,
5
+ } from "@cosmicdrift/kumiko-framework/engine";
6
+ import { z } from "zod";
7
+ import { invoiceReceiveLines, invoiceReceiveScreen } from "../screens/invoice-receive.screen";
8
+
9
+ const moneyPayload = z.object({ amount: z.number(), currency: z.string().min(1) });
10
+
11
+ // The preprocess recomputes net/VAT/gross before validation: totals sent by the
12
+ // client never reach the handler.
13
+ const receiveInput = withFormDerivations(
14
+ z.object({
15
+ supplier: z.string().min(1),
16
+ invoiceNumber: z.string().min(1),
17
+ lines: fieldToZod(invoiceReceiveLines, ["EUR"]),
18
+ netTotal: moneyPayload,
19
+ vatTotal: moneyPayload,
20
+ grossTotal: moneyPayload,
21
+ }),
22
+ invoiceReceiveScreen,
23
+ );
24
+
25
+ export const invoiceReceive = defineWriteHandler({
26
+ name: "invoice:receive",
27
+ schema: receiveInput,
28
+ access: { roles: ["Admin"] },
29
+ handler: async (event) => ({
30
+ isSuccess: true,
31
+ data: {
32
+ netTotal: event.payload.netTotal,
33
+ vatTotal: event.payload.vatTotal,
34
+ grossTotal: event.payload.grossTotal,
35
+ },
36
+ }),
37
+ });
@@ -0,0 +1,56 @@
1
+ import {
2
+ type ActionFormScreenDefinition,
3
+ createEmbeddedListField,
4
+ createTextField,
5
+ } from "@cosmicdrift/kumiko-framework/engine";
6
+
7
+ const euro = { kind: "literal", code: "EUR" } as const;
8
+
9
+ export const invoiceReceiveLines = createEmbeddedListField(
10
+ {
11
+ description: { type: "text", required: true },
12
+ amount: { type: "money", required: true },
13
+ vatRate: { type: "decimal", scale: 2, required: true },
14
+ vatAmount: { type: "money" },
15
+ },
16
+ {
17
+ minItems: 1,
18
+ derived: { vatAmount: { op: "percent", from: ["amount", "vatRate"] } },
19
+ totals: [
20
+ { label: "invoice.total.net", from: ["amount"] },
21
+ { label: "invoice.total.vat", from: ["vatAmount"] },
22
+ { label: "invoice.total.gross", from: ["amount", "vatAmount"] },
23
+ ],
24
+ },
25
+ );
26
+
27
+ // Net/VAT/gross are derived on the server from the lines (at least one is required)
28
+ // and shown only in the list footer, so the head totals are declared but not laid out.
29
+ export const invoiceReceiveScreen: ActionFormScreenDefinition = {
30
+ id: "invoice-receive",
31
+ type: "actionForm",
32
+ handler: "contacts:write:invoice:receive",
33
+ fields: {
34
+ supplier: createTextField({ required: true, personal: "tenant", find: "none" }),
35
+ invoiceNumber: createTextField({
36
+ required: true,
37
+ personal: false,
38
+ reason: "is_business_data",
39
+ }),
40
+ lines: invoiceReceiveLines,
41
+ netTotal: { type: "money", currency: euro },
42
+ vatTotal: { type: "money", currency: euro },
43
+ grossTotal: { type: "money", currency: euro },
44
+ },
45
+ derive: {
46
+ netTotal: { op: "listSum", list: "lines", cell: "amount" },
47
+ vatTotal: { op: "listSum", list: "lines", cell: "vatAmount" },
48
+ grossTotal: { op: "sum", from: ["netTotal", "vatTotal"] },
49
+ },
50
+ layout: {
51
+ sections: [
52
+ { columns: 2, fields: ["supplier", "invoiceNumber"] },
53
+ { columns: 1, fields: ["lines"] },
54
+ ],
55
+ },
56
+ };
@@ -73,7 +73,7 @@ await runProdApp({
73
73
  anonymousAccess: { defaultTenantId: SYSTEM_TENANT_ID },
74
74
  // Required (2): boot check + internal lookup use ctx.templateResolver
75
75
  extraContext: ({ db }) => ({
76
- templateResolver: createTemplateResolverApi(db),
76
+ templateResolver: createTemplateResolverApi(db, registry),
77
77
  }),
78
78
  });
79
79
  ```
@@ -207,7 +207,7 @@ from SYSTEM_TENANT:
207
207
  | Symptom | Cause | Fix |
208
208
  |---|---|---|
209
209
  | Route returns `503 legal page unavailable` | `anonymousAccess` not configured in `runProdApp` | Set `anonymousAccess: { defaultTenantId: SYSTEM_TENANT_ID }` |
210
- | Boot check throws `ctx.templateResolver missing` | `extraContext.templateResolver` not wired | Set `extraContext: ({ db }) => ({ templateResolver: createTemplateResolverApi(db) })` |
210
+ | Boot check throws `ctx.templateResolver missing` | `extraContext.templateResolver` not wired | Set `extraContext: ({ db, registry }) => ({ templateResolver: createTemplateResolverApi(db, registry) })` |
211
211
  | Route returns `404 not configured` | Required block doesn't exist or has `content=null` | `seedTextBlock` with a content string |
212
212
  | Multi-tenant app: tenant subdomain shows an empty page | (Bug regression?) Routes should ALWAYS show SYSTEM_TENANT texts | The `legal-pages.integration.test.ts` test "SYSTEM_TENANT routing" covers this — should be green |
213
213
  | `<script>` tags in a Markdown body land 1:1 in the HTML | Deliberately accepted right now — see [legal-pages/README.md XSS section](../../../packages/bundled-features/src/legal-pages/README.md#xss--currently-not-secured-by-design) | DOMPurify is a Phase 2 once a multi-author setup arrives |
@@ -27,7 +27,7 @@
27
27
  // - `anonymousAccess` muss in runProdApp/runDevApp konfiguriert sein
28
28
  // (defaultTenantId = SYSTEM_TENANT_ID), sonst antworten die
29
29
  // legal-pages-Routes mit 503
30
- // - `extraContext.templateResolver = createTemplateResolverApi(db)` muss
30
+ // - `extraContext.templateResolver = createTemplateResolverApi(db, registry)` muss
31
31
  // gewired sein, sonst wirft der Boot-Check mit Wiring-Hinweis
32
32
  // - Beim ersten Boot müssen die TextBlocks geseedet sein —
33
33
  // template-resolver/seeding `seedTextBlock` oder via API
@@ -1,7 +1,7 @@
1
1
  // Reference Data Sample
2
2
  // Shows: r.referenceData() for static seed data with upsert logic
3
3
 
4
- import { table, text } from "@cosmicdrift/kumiko-framework/db";
4
+ import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
5
5
  import { createEntity, createTextField, defineFeature } from "@cosmicdrift/kumiko-framework/engine";
6
6
 
7
7
  export const categoryEntity = createEntity({
@@ -13,12 +13,8 @@ export const categoryEntity = createEntity({
13
13
  },
14
14
  });
15
15
 
16
- // Drizzle table for direct DB queries in tests
17
- export const categoryTable = table("read_sample_categories", {
18
- code: text("code").notNull(),
19
- name: text("name").notNull(),
20
- description: text("description"),
21
- });
16
+ // Read-model table for direct DB queries in tests
17
+ export const categoryTable = buildEntityTable("category", categoryEntity);
22
18
 
23
19
  export const categoryFeature = defineFeature("catalog", (r) => {
24
20
  r.entity({ name: "category", ...categoryEntity });
@@ -1,54 +0,0 @@
1
- // @runtime client
2
- // Pure-Data i18n keys for admin-shell (server r.translations + client pivot).
3
- // Without these keys nav labels and workspace tabs render raw QNs in the shell.
4
-
5
- type LocalizedString = { readonly en: string };
6
-
7
- export const ADMIN_SHELL_I18N: Readonly<Record<string, LocalizedString>> = {
8
- "screen:tenant-overview.title": { en: "Overview" },
9
- "screen:platform-overview.title": { en: "Overview" },
10
- "admin-shell.screen.tenant-overview.subtitle": {
11
- en: "Activity, failed jobs and deliveries, quotas and open admin tasks of this tenant.",
12
- },
13
- "admin-shell.screen.platform-overview.subtitle": {
14
- en: "Tenant, user, job and delivery health across the whole installation.",
15
- },
16
- "admin-shell:workspace.tenant": { en: "Administration" },
17
- "admin-shell:workspace.platform": { en: "Platform" },
18
- "admin-shell:nav.tenantOverview": { en: "Overview" },
19
- "admin-shell:nav.platformOverview": { en: "Overview" },
20
- "admin-shell:nav.tenants": { en: "Tenants" },
21
- "admin-shell:nav.tierAdmin": { en: "Assign tier" },
22
- "admin-shell:nav.myCaps": { en: "Plans & Caps" },
23
- "admin-shell:nav.tenantCaps": { en: "Plans & Caps" },
24
- "admin-shell:overview.kpi.activeTenants": { en: "Active tenants" },
25
- "admin-shell:overview.kpi.activeUsers7d": { en: "Active users, 7 days" },
26
- "admin-shell:overview.kpi.activeMembers7d": { en: "Active members, 7 days" },
27
- "admin-shell:overview.kpi.failedJobs24h": { en: "Failed jobs, 24 h" },
28
- "admin-shell:overview.kpi.failedDeliveries24h": { en: "Failed deliveries, 24 h" },
29
- "admin-shell:overview.chart.jobRunsByStatus": { en: "Job runs by status" },
30
- "admin-shell:overview.chart.deliveriesByChannel": { en: "Deliveries by channel" },
31
- "admin-shell:overview.chart.auditWrites": { en: "Changes per day" },
32
- "admin-shell:overview.chart.auditWritesSubtitle": { en: "Audit log, 14 days" },
33
- "admin-shell:overview.list.recentFailures": { en: "Recent failures" },
34
- "admin-shell:overview.list.recentFailuresEmpty": { en: "No failed jobs" },
35
- "admin-shell:overview.list.quotas": { en: "Quotas" },
36
- "admin-shell:overview.list.quotasEmpty": { en: "No quotas configured" },
37
- "admin-shell:overview.col.job": { en: "Job" },
38
- "admin-shell:overview.col.startedAt": { en: "Started" },
39
- "admin-shell:overview.col.failedAt": { en: "Failed at" },
40
- "admin-shell:overview.col.reason": { en: "Reason" },
41
- "admin-shell:overview.col.quota": { en: "Quota" },
42
- "admin-shell:overview.col.used": { en: "Used" },
43
- "admin-shell:overview.col.limit": { en: "Limit" },
44
- "admin-shell:overview.col.usage": { en: "Usage" },
45
- "admin-shell:overview.range.24h": { en: "24 hours" },
46
- "admin-shell:overview.range.7d": { en: "7 days" },
47
- "admin-shell:overview.range.30d": { en: "30 days" },
48
- "admin-shell:overview.scope.badge": { en: "All tenants" },
49
- "admin-shell:overview.scope.notice": {
50
- en: "You are viewing data of all tenants. Cross-tenant queries are recorded in the audit log.",
51
- },
52
- "admin-shell:overview.filter.tenant": { en: "Tenant" },
53
- "admin-shell:overview.filter.allTenants": { en: "All tenants" },
54
- };
@@ -1,25 +0,0 @@
1
- // @runtime client
2
- // Server + client i18n for audit (nav labels + audit-log/-detail screens).
3
-
4
- type LocalizedString = { readonly en: string };
5
-
6
- export const AUDIT_I18N: Readonly<Record<string, LocalizedString>> = {
7
- "screen:audit-log.title": { en: "Audit log" },
8
- "screen:audit-log-detail.title": { en: "Event" },
9
- "audit.log.detail.subtitle": {
10
- en: "Read-only detail view of one audit event showing actor, timestamp, aggregate and the raw event payload and metadata; reached from a row of the audit log.",
11
- },
12
- "audit.errors.systemScopeRequiresSystemAdmin": {
13
- en: "Only SystemAdmin may read system events.",
14
- },
15
- "audit:nav.auditLog": { en: "Audit" },
16
- "audit.log.col.when": { en: "When" },
17
- "audit.log.col.type": { en: "Event" },
18
- "audit.log.col.aggregateType": { en: "Aggregate type" },
19
- "audit.log.col.aggregateId": { en: "Aggregate ID" },
20
- "audit.log.col.actor": { en: "Actor" },
21
- "audit.log.details": { en: "Details" },
22
- "audit.log.detail.payload": { en: "Event payload" },
23
- "audit.log.detail.metadata": { en: "Metadata" },
24
- "audit.log.detail.field.id": { en: "Event ID" },
25
- };
@@ -1,11 +0,0 @@
1
- // @types/qrcode only declares the main "qrcode" entry, not the browser-only
2
- // subpath (see mfa-setup-preauth-screen.tsx's import — the main entry pulls
3
- // in Node-only deps like yargs/pngjs via qrcode's own package.json#browser
4
- // remap, which Metro doesn't honor). Same runtime shape, just re-typed.
5
- // `export *` never re-exports a default — `import QRCode from "..."`
6
- // resolving here relies on the consuming app's esModuleInterop/
7
- // allowSyntheticDefaultImports (which synthesizes a default from the
8
- // namespace); without it, the default import comes back undefined.
9
- declare module "qrcode/lib/browser.js" {
10
- export * from "qrcode";
11
- }
@@ -1,55 +0,0 @@
1
- // @runtime client
2
- // Server + client i18n for jobs operator screens.
3
-
4
- type LocalizedString = { readonly en: string };
5
-
6
- export const JOBS_I18N: Readonly<Record<string, LocalizedString>> = {
7
- "screen:job-runs.title": { en: "Job runs" },
8
- "screen:job-run-detail.title": { en: "Job run" },
9
- "screen:job-trigger.title": { en: "Trigger job" },
10
- "jobs.screen.job-trigger.subtitle": {
11
- en: "Start a job manually by name, with an optional JSON payload.",
12
- },
13
- "jobs.screen.job-run-detail.subtitle": {
14
- en: "Status, timings, error and log lines of one job run.",
15
- },
16
- "jobs:entity:__action-form__:field:jobName": { en: "Job name" },
17
- "jobs:entity:__action-form__:field:payload": { en: "JSON payload" },
18
- "jobs:nav.jobRuns": { en: "Jobs" },
19
- "jobs.runs.open": { en: "Details" },
20
- "jobs.runs.filter.status": { en: "Status" },
21
- "jobs.runs.filter.completed": { en: "Completed" },
22
- "jobs.runs.filter.failed": { en: "Failed" },
23
- "jobs.runs.filter.running": { en: "Running" },
24
- "jobs.runs.filter.queued": { en: "Queued" },
25
- "jobs.runs.col.job": { en: "Job" },
26
- "jobs.runs.col.status": { en: "Status" },
27
- "jobs.runs.col.started": { en: "Started" },
28
- "jobs.runs.col.duration": { en: "Duration (ms)" },
29
- "jobs.detail.field.job": { en: "Job" },
30
- "jobs.detail.field.status": { en: "Status" },
31
- "jobs.detail.field.id": { en: "Run ID" },
32
- "jobs.detail.field.started": { en: "Started" },
33
- "jobs.detail.field.finished": { en: "Finished" },
34
- "jobs.detail.field.duration": { en: "Duration (ms)" },
35
- "jobs.detail.field.error": { en: "Error" },
36
- "jobs.detail.logs": { en: "Logs" },
37
- "jobs.detail.retry": { en: "Retry" },
38
- "jobs.trigger.title": { en: "Run a job" },
39
- "jobs.errors.invalidCursor": { en: "The pagination cursor is invalid." },
40
- "jobs.trigger.submit": { en: "Run" },
41
- "jobs.errors.unknownJob": { en: "Unknown job." },
42
- "jobs.errors.notManual": {
43
- en: "This job cannot be triggered manually.",
44
- },
45
- "jobs.errors.invalidPayload": {
46
- en: "The payload must be a valid JSON object.",
47
- },
48
- "jobs.errors.notFound": { en: "Not found." },
49
- "jobs.errors.onlyFailedCanRetry": {
50
- en: "Only failed runs can be retried.",
51
- },
52
- "jobs.errors.payloadErased": {
53
- en: "This run's payload can no longer be read — the triggering user's data was erased.",
54
- },
55
- };
@@ -1,63 +0,0 @@
1
- // @runtime client
2
- // Pure-Data (i18n-Keys) — client-marked, damit das web/-Bundle sie in den
3
- // Browser-Store pivotieren darf; feature.ts (server) importiert sie ebenso
4
- // (server darf client-safe Pure-Data importieren, wie PAT constants.ts).
5
- //
6
- // Übersetzungs-Bundle für die managed-pages Admin-Screens. Ohne diese Keys
7
- // rendert die UI die Roh-i18n-Keys (screen:*.title, entity:*:field:*, Section-
8
- // Header). Der Boot-Validator (required-surface-keys) verlangt — sobald ein
9
- // Feature r.translations ruft — den KOMPLETTEN Required-Surface-Satz in de+en;
10
- // diese Datei deckt jeden Screen/Feld/Section-Key ab, den managed-pages
11
- // registriert. Die zwei customCss-Keys werden unconditional geliefert (schaden
12
- // bei allowCustomCss:false nicht, sind aber Pflicht für Consumer die es aktivieren).
13
-
14
- type LocalizedString = { readonly en: string };
15
-
16
- export const MANAGED_PAGES_I18N: Readonly<Record<string, LocalizedString>> = {
17
- // Screen-Titel (global/unpräfixiert — screenTitleKey = screen:<id>.title)
18
- "screen:page-list.title": { en: "Pages" },
19
- "screen:page-edit.title": { en: "Edit page" },
20
- "screen:branding-settings.title": { en: "Branding" },
21
-
22
- // Page-Entity Feld-Labels (managed-pages:entity:page:field:*)
23
- "managed-pages:entity:page:field:slug": { en: "Slug" },
24
- "managed-pages:entity:page:field:lang": { en: "Language" },
25
- "managed-pages:entity:page:field:title": { en: "Title" },
26
- "managed-pages:entity:page:field:published": { en: "Published" },
27
- "managed-pages:entity:page:field:published:option:true": {
28
- en: "Published",
29
- },
30
- "managed-pages:entity:page:field:published:option:false": { en: "Draft" },
31
- "managed-pages:entity:page:field:description": { en: "Description" },
32
- "managed-pages:entity:page:field:ogImage": { en: "OG image" },
33
- "managed-pages:entity:page:field:body": { en: "Content" },
34
-
35
- // Config-Edit Feld-Labels (managed-pages:entity:__config-edit__:field:*, camelCase Form-Keys)
36
- "managed-pages:entity:__config-edit__:field:title": { en: "Site title" },
37
- "managed-pages:entity:__config-edit__:field:description": {
38
- en: "Description",
39
- },
40
- "managed-pages:entity:__config-edit__:field:siteUrl": { en: "Site URL" },
41
- "managed-pages:entity:__config-edit__:field:accentColor": {
42
- en: "Accent color",
43
- },
44
- "managed-pages:entity:__config-edit__:field:logoUrl": { en: "Logo URL" },
45
- "managed-pages:entity:__config-edit__:field:logoFile": { en: "Logo file" },
46
- "managed-pages:entity:__config-edit__:field:layoutPreset": { en: "Layout" },
47
-
48
- // Section-Header
49
- "managed-pages:section.meta": { en: "Metadata" },
50
- "managed-pages:section.body": { en: "Content" },
51
- "managed-pages:branding.section.identity": { en: "Identity" },
52
-
53
- // Row-Actions + Confirm (pageListScreen)
54
- "managed-pages:actions.edit": { en: "Edit" },
55
- "managed-pages:actions.delete": { en: "Delete" },
56
- "managed-pages:confirms.page-delete": {
57
- en: "Delete this page?",
58
- },
59
-
60
- // Nur bei allowCustomCss:true im Screen — unconditional geliefert
61
- "managed-pages:entity:__config-edit__:field:customCss": { en: "Custom CSS" },
62
- "managed-pages:branding.section.custom-css": { en: "Custom CSS" },
63
- };
@@ -1,35 +0,0 @@
1
- import type { FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";
2
- import { createComplianceProfilesFeature } from "../compliance-profiles/index.ts";
3
- import { createDataRetentionFeature } from "../data-retention/index.ts";
4
- import { createSessionsFeature } from "../sessions/index.ts";
5
- import {
6
- createUserDataRightsFeature,
7
- type UserDataRightsOptions,
8
- } from "../user-data-rights/index.ts";
9
- import { createUserProfileFeature } from "../user-profile/index.ts";
10
-
11
- export type DsgvoSelfServiceOptions = {
12
- /** Passed through to createUserDataRightsFeature — export/deletion mail
13
- * callbacks + Apex deletion HMAC. Default {} (no-op mail side). */
14
- readonly userDataRights?: UserDataRightsOptions;
15
- };
16
-
17
- // DSGVO + account self-service chain every Kumiko SaaS app mounts (privacy
18
- // center, account deletion Art. 17, export Art. 20, sessions). Order is
19
- // load-bearing (require-order): user-data-rights needs data-retention +
20
- // compliance-profiles + sessions, user-profile needs user-data-rights. This
21
- // exact order used to be hand-copied into every app with an explainer
22
- // comment. text-content + legal-pages stay out deliberately — legal-pages
23
- // has an app-specific wrapLayout, text-content is a standalone foundation;
24
- // both are spread in by the app itself.
25
- /** @deprecated Removed in the next release. Use `composeGdprStack({ selfService: { userDataRights } })`
26
- * from `@cosmicdrift/kumiko-dev-server/compose-stacks`. */
27
- export function dsgvoSelfServiceFeatures(opts: DsgvoSelfServiceOptions = {}): FeatureDefinition[] {
28
- return [
29
- createDataRetentionFeature(),
30
- createComplianceProfilesFeature(),
31
- createSessionsFeature(),
32
- createUserDataRightsFeature(opts.userDataRights ?? {}),
33
- createUserProfileFeature(),
34
- ];
35
- }
@@ -1,44 +0,0 @@
1
- // @runtime client
2
- // Server + client i18n for user-data-rights (operator screens + nav). Pure
3
- // data, importable from the web bundle (web/i18n.ts derives the client keys).
4
- type LocalizedString = { readonly en: string };
5
-
6
- export const USER_DATA_RIGHTS_I18N: Readonly<Record<string, LocalizedString>> = {
7
- "user-data-rights:feature.label": { en: "Privacy" },
8
- "user-data-rights:notify.export-ready.label": { en: "Data export ready" },
9
- "user-data-rights:notify.export-failed.label": { en: "Data export failed" },
10
- "user-data-rights:notify.deletion-requested.label": { en: "Deletion requested" },
11
- "user-data-rights:notify.deletion-executed.label": { en: "Deletion completed" },
12
- "user-data-rights:nav.exportJobs": { en: "GDPR exports" },
13
- "screen:export-job-list.title": { en: "GDPR exports" },
14
- "screen:export-job-detail.title": { en: "Export job" },
15
- "screen:download-attempt-list.title": { en: "Download attempts" },
16
- "screen:privacy-center.title": { en: "Privacy" },
17
- "userDataRights.privacyCenter.subtitle": {
18
- en: "Logged-in GDPR self-service page where a user requests and downloads a data export (Art. 20), restricts processing of their account (Art. 18) and requests its deletion (Art. 17).",
19
- },
20
- "user-data-rights:entity:export-job:field:userId": { en: "User" },
21
- "user-data-rights:entity:export-job:field:status": { en: "Status" },
22
- "user-data-rights:entity:export-job:field:requestedAt": { en: "Requested" },
23
- "user-data-rights:entity:export-job:field:completedAt": { en: "Completed" },
24
- "user-data-rights:entity:export-job:field:expiresAt": { en: "Expires" },
25
- "user-data-rights:entity:export-job:field:requestedFromTenantId": {
26
- en: "Tenant",
27
- },
28
- "user-data-rights:entity:export-job:field:startedAt": { en: "Started" },
29
- "user-data-rights:entity:export-job:field:downloadStorageKey": {
30
- en: "Storage key",
31
- },
32
- "user-data-rights:entity:export-job:field:bytesWritten": { en: "Bytes" },
33
- "user-data-rights:entity:export-job:field:errorMessage": { en: "Error" },
34
- "user-data-rights:entity:download-attempt:field:attemptedAt": {
35
- en: "Attempted at",
36
- },
37
- "user-data-rights:entity:download-attempt:field:result": { en: "Result" },
38
- "user-data-rights:entity:download-attempt:field:via": { en: "Via" },
39
- "user-data-rights:entity:download-attempt:field:ip": { en: "IP" },
40
- "user-data-rights:entity:download-attempt:field:attemptedByUserId": {
41
- en: "User",
42
- },
43
- "user-data-rights:entity:download-attempt:field:jobId": { en: "Job" },
44
- };