@cosmicdrift/kumiko-samples 0.386.0 → 0.388.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 (530) hide show
  1. package/LICENSE +21 -57
  2. package/README.md +1 -1
  3. package/package.json +2 -2
  4. package/packages/bundled-features/package.json +9 -2
  5. package/packages/bundled-features/src/agent-tools/changes.json +6 -0
  6. package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
  7. package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +9 -9
  8. package/packages/bundled-features/src/audit/changes.json +12 -0
  9. package/packages/bundled-features/src/audit/handlers/audit-events.ts +1 -1
  10. package/packages/bundled-features/src/audit/screens.ts +1 -1
  11. package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
  12. package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
  13. package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
  14. package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
  15. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
  16. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
  17. package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
  18. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  19. package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
  20. package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
  21. package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
  22. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +34 -37
  23. package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
  24. package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
  25. package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
  26. package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
  27. package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
  28. package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
  29. package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
  30. package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
  31. package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
  32. package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
  33. package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
  34. package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
  35. package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
  36. package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
  37. package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
  38. package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
  39. package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
  40. package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
  41. package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
  42. package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
  43. package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
  44. package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
  45. package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
  46. package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
  47. package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
  48. package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
  49. package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
  50. package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
  51. package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
  52. package/packages/bundled-features/src/auth-mfa/changes.json +6 -0
  53. package/packages/bundled-features/src/auth-mfa/feature-exports.ts +2 -2
  54. package/packages/bundled-features/src/auth-mfa/feature.ts +6 -0
  55. package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
  56. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
  57. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
  58. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  59. package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
  60. package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
  61. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  62. package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
  63. package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
  64. package/packages/bundled-features/src/auth-mfa/web/i18n.ts +9 -4
  65. package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
  66. package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
  67. package/packages/bundled-features/src/auth-mfa/web/mfa-code-or-recovery-field.tsx +68 -0
  68. package/packages/bundled-features/src/auth-mfa/web/mfa-disable-dialog.tsx +23 -13
  69. package/packages/bundled-features/src/auth-mfa/web/mfa-regenerate-recovery-dialog.tsx +23 -13
  70. package/packages/bundled-features/src/auth-mfa/web/mfa-setup-preauth-screen.tsx +15 -6
  71. package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +71 -24
  72. package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
  73. package/packages/bundled-features/src/billing-foundation/changes.json +55 -0
  74. package/packages/bundled-features/src/billing-foundation/checkout-core.ts +32 -42
  75. package/packages/bundled-features/src/billing-foundation/consumer-protection/confirmation-mail.ts +8 -2
  76. package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-gate.ts +2 -0
  77. package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +14 -3
  78. package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +3 -4
  79. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-receipt-limit.ts +12 -6
  80. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +35 -19
  81. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +12 -8
  82. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-revoke.ts +14 -8
  83. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +5 -0
  84. package/packages/bundled-features/src/billing-foundation/consumer-protection/withdrawal-period.ts +8 -10
  85. package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
  86. package/packages/bundled-features/src/billing-foundation/events.ts +23 -21
  87. package/packages/bundled-features/src/billing-foundation/feature.ts +45 -44
  88. package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
  89. package/packages/bundled-features/src/billing-foundation/handlers/billing-plans.query.ts +71 -6
  90. package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +19 -17
  91. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
  92. package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
  93. package/packages/bundled-features/src/billing-foundation/handlers/plan-switch-preview.query.ts +65 -0
  94. package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +29 -22
  95. package/packages/bundled-features/src/billing-foundation/handlers/start-plan-checkout.write.ts +44 -8
  96. package/packages/bundled-features/src/billing-foundation/handlers/switch-plan.write.ts +72 -82
  97. package/packages/bundled-features/src/billing-foundation/handlers/sync-subscription.write.ts +14 -1
  98. package/packages/bundled-features/src/billing-foundation/i18n.ts +22 -0
  99. package/packages/bundled-features/src/billing-foundation/index.ts +2 -0
  100. package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +62 -27
  101. package/packages/bundled-features/src/billing-foundation/plan-switch.ts +84 -0
  102. package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
  103. package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
  104. package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
  105. package/packages/bundled-features/src/billing-foundation/types.ts +144 -66
  106. package/packages/bundled-features/src/billing-foundation/validate-options.ts +19 -0
  107. package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +123 -51
  108. package/packages/bundled-features/src/billing-foundation/web/checkout-consent-dialog.tsx +89 -42
  109. package/packages/bundled-features/src/billing-foundation/web/constants.ts +4 -0
  110. package/packages/bundled-features/src/billing-foundation/web/plan-price.ts +55 -0
  111. package/packages/bundled-features/src/billing-foundation/web/plan-switch-confirm-dialog.tsx +224 -0
  112. package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
  113. package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
  114. package/packages/bundled-features/src/cap-counter/cap-reservation.ts +5 -1
  115. package/packages/bundled-features/src/cap-counter/changes.json +18 -0
  116. package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
  117. package/packages/bundled-features/src/cap-counter/enforce-cap.ts +66 -68
  118. package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
  119. package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
  120. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
  121. package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
  122. package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +9 -2
  123. package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
  124. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
  125. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
  126. package/packages/bundled-features/src/channel-email/changes.json +6 -0
  127. package/packages/bundled-features/src/channel-email/feature.ts +1 -1
  128. package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
  129. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
  130. package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
  131. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
  132. package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
  133. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
  134. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
  135. package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
  136. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
  137. package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
  138. package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
  139. package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
  140. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
  141. package/packages/bundled-features/src/config/changes.json +12 -0
  142. package/packages/bundled-features/src/config/handlers/cascade.query.ts +4 -2
  143. package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
  144. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
  145. package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
  146. package/packages/bundled-features/src/config/handlers/values.query.ts +4 -2
  147. package/packages/bundled-features/src/config/resolver.ts +4 -4
  148. package/packages/bundled-features/src/config/table.ts +10 -10
  149. package/packages/bundled-features/src/config/write-helpers.ts +28 -9
  150. package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
  151. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +23 -21
  152. package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
  153. package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
  154. package/packages/bundled-features/src/custom-fields/events.ts +7 -8
  155. package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
  156. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
  157. package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
  158. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
  159. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
  160. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
  161. package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
  162. package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
  163. package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.ts +1 -1
  164. package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
  165. package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -12
  166. package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
  167. package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
  168. package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
  169. package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
  170. package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
  171. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
  172. package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
  173. package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
  174. package/packages/bundled-features/src/data-retention/feature.ts +11 -18
  175. package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
  176. package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
  177. package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
  178. package/packages/bundled-features/src/data-retention/presets.ts +18 -23
  179. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  180. package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
  181. package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
  182. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
  183. package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
  184. package/packages/bundled-features/src/delivery/changes.json +30 -0
  185. package/packages/bundled-features/src/delivery/channel-context.ts +9 -3
  186. package/packages/bundled-features/src/delivery/db/queries/preferences.ts +2 -2
  187. package/packages/bundled-features/src/delivery/delivery-service.ts +35 -5
  188. package/packages/bundled-features/src/delivery/feature.ts +3 -3
  189. package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
  190. package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +20 -1
  191. package/packages/bundled-features/src/delivery/handlers/unsubscribe-page-chrome.query.ts +1 -1
  192. package/packages/bundled-features/src/delivery/tables.ts +9 -8
  193. package/packages/bundled-features/src/delivery/unsubscribe-link.ts +3 -1
  194. package/packages/bundled-features/src/delivery/unsubscribe-page-strings.ts +1 -0
  195. package/packages/bundled-features/src/delivery/unsubscribe-page.ts +6 -0
  196. package/packages/bundled-features/src/delivery/unsubscribe.ts +40 -19
  197. package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
  198. package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
  199. package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
  200. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
  201. package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
  202. package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +4 -4
  203. package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
  204. package/packages/bundled-features/src/feature-toggles/feature.ts +1 -1
  205. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  206. package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
  207. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  208. package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
  209. package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
  210. package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
  211. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  212. package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
  213. package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
  214. package/packages/bundled-features/src/file-foundation/index.ts +1 -0
  215. package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +7 -1
  216. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
  217. package/packages/bundled-features/src/file-provider-s3/env-named-feature.ts +0 -2
  218. package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
  219. package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
  220. package/packages/bundled-features/src/files/README.md +1 -1
  221. package/packages/bundled-features/src/files/feature.ts +6 -6
  222. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
  223. package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
  224. package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
  225. package/packages/bundled-features/src/folders/feature.ts +1 -1
  226. package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
  227. package/packages/bundled-features/src/folders/web/tree.ts +5 -5
  228. package/packages/bundled-features/src/form-draft/changes.json +6 -0
  229. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +3 -3
  230. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
  231. package/packages/bundled-features/src/form-draft/decrypt-draft.ts +4 -1
  232. package/packages/bundled-features/src/form-draft/entity.ts +3 -3
  233. package/packages/bundled-features/src/form-draft/feature.ts +4 -5
  234. package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
  235. package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
  236. package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
  237. package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
  238. package/packages/bundled-features/src/host-routing/README.md +1 -1
  239. package/packages/bundled-features/src/host-routing/changes.json +6 -0
  240. package/packages/bundled-features/src/host-routing/dispatch.ts +16 -17
  241. package/packages/bundled-features/src/host-routing/options.ts +2 -1
  242. package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
  243. package/packages/bundled-features/src/inbound-mail-foundation/changes.json +18 -0
  244. package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
  245. package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
  246. package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
  247. package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
  248. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
  249. package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
  250. package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
  251. package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
  252. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
  253. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
  254. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
  255. package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
  256. package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +27 -15
  257. package/packages/bundled-features/src/inbound-mail-foundation/i18n.ts +0 -1
  258. package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
  259. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
  260. package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
  261. package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
  262. package/packages/bundled-features/src/inbound-mail-foundation/screens.ts +0 -3
  263. package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
  264. package/packages/bundled-features/src/inbound-mail-foundation/types.ts +70 -70
  265. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +101 -84
  266. package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
  267. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
  268. package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
  269. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
  270. package/packages/bundled-features/src/jobs/changes.json +13 -0
  271. package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
  272. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
  273. package/packages/bundled-features/src/jobs/events.ts +1 -1
  274. package/packages/bundled-features/src/jobs/feature.ts +20 -11
  275. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
  276. package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
  277. package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
  278. package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
  279. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  280. package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +45 -40
  281. package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +63 -59
  282. package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
  283. package/packages/bundled-features/src/jobs/job-run-logger.ts +19 -19
  284. package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
  285. package/packages/bundled-features/src/jobs/screens.ts +1 -1
  286. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  287. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  288. package/packages/bundled-features/src/ledger/entity.ts +5 -5
  289. package/packages/bundled-features/src/ledger/feature.ts +3 -3
  290. package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
  291. package/packages/bundled-features/src/ledger/recurring.ts +12 -12
  292. package/packages/bundled-features/src/ledger/schemas.ts +1 -1
  293. package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
  294. package/packages/bundled-features/src/ledger/web/index.ts +7 -7
  295. package/packages/bundled-features/src/legal-pages/README.md +1 -1
  296. package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
  297. package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
  298. package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
  299. package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
  300. package/packages/bundled-features/src/mail-foundation/changes.json +6 -0
  301. package/packages/bundled-features/src/mail-foundation/feature.ts +31 -30
  302. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
  303. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
  304. package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
  305. package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
  306. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
  307. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
  308. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
  309. package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
  310. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
  311. package/packages/bundled-features/src/managed-pages/table.ts +16 -15
  312. package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
  313. package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
  314. package/packages/bundled-features/src/notes-history/entity.ts +4 -4
  315. package/packages/bundled-features/src/notes-history/feature.ts +2 -2
  316. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  317. package/packages/bundled-features/src/page-render/layout.ts +9 -9
  318. package/packages/bundled-features/src/page-render/markdown.ts +11 -11
  319. package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
  320. package/packages/bundled-features/src/personal-access-tokens/feature.ts +9 -6
  321. package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
  322. package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
  323. package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
  324. package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
  325. package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
  326. package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
  327. package/packages/bundled-features/src/renderer-pdf/changes.json +6 -0
  328. package/packages/bundled-features/src/renderer-pdf/render-table-pdf.ts +27 -10
  329. package/packages/bundled-features/src/secrets/feature.ts +9 -9
  330. package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
  331. package/packages/bundled-features/src/seo/feature.ts +3 -3
  332. package/packages/bundled-features/src/sessions/constants.ts +1 -1
  333. package/packages/bundled-features/src/sessions/feature.ts +16 -11
  334. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
  335. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +2 -2
  336. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  337. package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
  338. package/packages/bundled-features/src/sessions/screens.ts +2 -2
  339. package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
  340. package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
  341. package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
  342. package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +11 -1
  343. package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
  344. package/packages/bundled-features/src/shared/index.ts +1 -1
  345. package/packages/bundled-features/src/shared/mail-template-body.ts +10 -3
  346. package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
  347. package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
  348. package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
  349. package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
  350. package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
  351. package/packages/bundled-features/src/step-dispatcher/changes.json +6 -0
  352. package/packages/bundled-features/src/step-dispatcher/feature.ts +1 -0
  353. package/packages/bundled-features/src/subscription-dodo/changes.json +14 -0
  354. package/packages/bundled-features/src/subscription-dodo/client.ts +45 -0
  355. package/packages/bundled-features/src/subscription-dodo/constants.ts +24 -0
  356. package/packages/bundled-features/src/subscription-dodo/feature.ts +207 -0
  357. package/packages/bundled-features/src/subscription-dodo/index.ts +16 -0
  358. package/packages/bundled-features/src/subscription-dodo/plugin-methods.ts +345 -0
  359. package/packages/bundled-features/src/subscription-dodo/runtime.ts +126 -0
  360. package/packages/bundled-features/src/subscription-dodo/verify-webhook.ts +262 -0
  361. package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
  362. package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
  363. package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
  364. package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
  365. package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
  366. package/packages/bundled-features/src/subscription-stripe/changes.json +12 -0
  367. package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
  368. package/packages/bundled-features/src/subscription-stripe/feature.ts +45 -43
  369. package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
  370. package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
  371. package/packages/bundled-features/src/subscription-stripe/runtime.ts +9 -8
  372. package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
  373. package/packages/bundled-features/src/tags/feature.ts +3 -3
  374. package/packages/bundled-features/src/tags/screens.ts +1 -1
  375. package/packages/bundled-features/src/template-resolver/api.ts +41 -14
  376. package/packages/bundled-features/src/template-resolver/changes.json +48 -0
  377. package/packages/bundled-features/src/template-resolver/compile-document-body.ts +1 -0
  378. package/packages/bundled-features/src/template-resolver/feature.ts +2 -2
  379. package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +3 -2
  380. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +27 -5
  381. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +3 -2
  382. package/packages/bundled-features/src/template-resolver/handlers/document-base.ts +3 -2
  383. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +8 -7
  384. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +19 -20
  385. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +15 -5
  386. package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
  387. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
  388. package/packages/bundled-features/src/template-resolver/handlers/tenant-override-counts.query.ts +9 -5
  389. package/packages/bundled-features/src/template-resolver/handlers/tenant-override-selection.ts +8 -6
  390. package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +44 -5
  391. package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
  392. package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
  393. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +37 -26
  394. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +7 -2
  395. package/packages/bundled-features/src/template-resolver/seeding.ts +36 -18
  396. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +22 -4
  397. package/packages/bundled-features/src/template-resolver/table.ts +13 -14
  398. package/packages/bundled-features/src/template-resolver/template-delivery-policy.ts +0 -11
  399. package/packages/bundled-features/src/template-resolver/template-meta.ts +12 -4
  400. package/packages/bundled-features/src/template-resolver/template-preview.ts +11 -3
  401. package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
  402. package/packages/bundled-features/src/template-resolver/web/constants.ts +7 -5
  403. package/packages/bundled-features/src/template-resolver/web/index.ts +7 -0
  404. package/packages/bundled-features/src/template-resolver/web/mail-layout-constants.ts +8 -0
  405. package/packages/bundled-features/src/tenant/changes.json +6 -0
  406. package/packages/bundled-features/src/tenant/feature.ts +7 -7
  407. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +10 -4
  408. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  409. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  410. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  411. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +8 -5
  412. package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
  413. package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
  414. package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
  415. package/packages/bundled-features/src/tenant/screens.ts +1 -1
  416. package/packages/bundled-features/src/tenant/seeding.ts +19 -18
  417. package/packages/bundled-features/src/tenant/testing.ts +5 -6
  418. package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
  419. package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
  420. package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
  421. package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
  422. package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
  423. package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
  424. package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
  425. package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
  426. package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
  427. package/packages/bundled-features/src/tenant-lifecycle/changes.json +6 -0
  428. package/packages/bundled-features/src/tenant-lifecycle/constants.ts +5 -0
  429. package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
  430. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +7 -3
  431. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
  432. package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
  433. package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
  434. package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
  435. package/packages/bundled-features/src/tier-engine/changes.json +6 -0
  436. package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
  437. package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
  438. package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
  439. package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
  440. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
  441. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +12 -9
  442. package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
  443. package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
  444. package/packages/bundled-features/src/tier-engine/web/constants.ts +3 -3
  445. package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
  446. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
  447. package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
  448. package/packages/bundled-features/src/user/schema/user.ts +45 -44
  449. package/packages/bundled-features/src/user/seeding.ts +40 -40
  450. package/packages/bundled-features/src/user/testing.ts +3 -3
  451. package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
  452. package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
  453. package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
  454. package/packages/bundled-features/src/user-data-rights/feature.ts +112 -113
  455. package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
  456. package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
  457. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
  458. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
  459. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
  460. package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
  461. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
  462. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +4 -4
  463. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
  464. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
  465. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
  466. package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
  467. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
  468. package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
  469. package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
  470. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
  471. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +169 -280
  472. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +87 -108
  473. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
  474. package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
  475. package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
  476. package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
  477. package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
  478. package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
  479. package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
  480. package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
  481. package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
  482. package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
  483. package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
  484. package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
  485. package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
  486. package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
  487. package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
  488. package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
  489. package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
  490. package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +1 -1
  491. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
  492. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
  493. package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
  494. package/packages/bundled-features/src/user-profile/index.ts +3 -3
  495. package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
  496. package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
  497. package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
  498. package/packages/bundled-features/src/waitlist/changes.json +18 -0
  499. package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +2 -1
  500. package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +5 -5
  501. package/packages/bundled-features/src/waitlist/import.ts +5 -0
  502. package/packages/bundled-features/src/waitlist/legacy-migrate.ts +22 -3
  503. package/packages/bundled-features/src/waitlist/link-on-signup.ts +20 -10
  504. package/packages/bundled-features/src/waitlist/options.ts +3 -0
  505. package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
  506. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
  507. package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
  508. package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
  509. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
  510. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
  511. package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
  512. package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
  513. package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
  514. package/samples/apps/styleguide/src/features/widgets/i18n.ts +11 -0
  515. package/samples/apps/styleguide/src/features/widgets/web/Widgets.tsx +24 -0
  516. package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-constants.ts +5 -0
  517. package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-features.ts +90 -15
  518. package/samples/apps/use-all-bundled/e2e-billing-gallery/server.ts +16 -6
  519. package/samples/apps/use-all-bundled/feature-manifest.json +120 -3
  520. package/samples/apps/use-all-bundled/src/run-config.ts +9 -3
  521. package/samples/recipes/auth-mfa/README.md +5 -0
  522. package/samples/recipes/auth-mfa/package.json +5 -2
  523. package/samples/recipes/auth-mfa/src/web/confirmation-code-step.tsx +49 -0
  524. package/samples/recipes/auth-mfa/tsconfig.json +8 -0
  525. package/samples/recipes/env-composition/README.md +3 -1
  526. package/samples/recipes/env-composition/src/env.ts +2 -0
  527. package/samples/recipes/legal-pages/README.md +1 -1
  528. package/samples/recipes/rate-limiting/README.md +18 -0
  529. package/samples/recipes/rate-limiting/src/feature.ts +12 -0
  530. package/packages/bundled-features/src/billing-foundation/consumer-protection/stored-user-email.ts +0 -12
@@ -2,34 +2,33 @@
2
2
  //
3
3
  // mail-foundation as a Kumiko bundled feature.
4
4
  //
5
- // **Was diese Feature liefert:**
6
- // 1. **Plugin-API** für Mail-Transport-Provider via `r.extendsRegistrar
7
- // ("mailTransport", ...)`. Provider-Features (mail-transport-smtp,
8
- // mail-transport-brevo-api, ...) registrieren sich namentlich.
9
- // 2. **Tenant-Config-key** `provider`: select-Wert der zur Runtime
10
- // bestimmt welcher registrierte Plugin verwendet wird.
11
- // 3. **createTransportForTenant(ctx, tenantId)** Factory die den
12
- // gewählten Plugin im Registry sucht und seine `build`-Methode
13
- // aufruft.
5
+ // **What this feature provides:**
6
+ // 1. **Plugin API** for mail transport providers via `r.extendsRegistrar
7
+ // ("mailTransport", ...)`. Provider features (mail-transport-smtp,
8
+ // mail-transport-brevo-api, ...) register by name.
9
+ // 2. **Tenant config key** `provider`: a selection value that determines at
10
+ // runtime which registered plugin is used.
11
+ // 3. **createTransportForTenant(ctx, tenantId)** factory that looks up the
12
+ // selected plugin in the registry and calls its `build` method.
14
13
  //
15
- // **Was diese Foundation NICHT mehr macht (im Vergleich zur ersten
16
- // Iteration):**
17
- // - Keine SMTP/Brevo/Postmark-spezifischen Config-Keys mehr in
18
- // mail-foundation. Provider-spezifische Config (host/port/from/
19
- // authUser für SMTP, apiUrl/accountId für Brevo etc.) lebt im
20
- // jeweiligen Provider-Plugin-Feature.
21
- // - Kein direkter Import von `createSmtpTransport`. Die Foundation
22
- // kennt nur das `EmailTransport`-Interface (Type-Import, kein
23
- // runtime-coupling), nicht die konkrete Implementation.
14
+ // **What this foundation no longer does (compared with the first
15
+ // iteration):**
16
+ // - No SMTP/Brevo/Postmark-specific config keys in mail-foundation.
17
+ // Provider-specific config (host/port/from/authUser for SMTP,
18
+ // apiUrl/accountId for Brevo, etc.) lives in the respective provider
19
+ // plugin feature.
20
+ // - No direct import of `createSmtpTransport`. The foundation knows only
21
+ // the `EmailTransport` interface (type import, no runtime coupling), not
22
+ // the concrete implementation.
24
23
  //
25
- // **Pattern-Vorbild:** identisch zu `delivery` + `channel-email`. Die
26
- // delivery-feature deklariert `r.extendsRegistrar("deliveryChannel")`,
27
- // channel-email registriert sich via `r.useExtension("deliveryChannel",
28
- // "email", {...})`. Selbe Trennung Foundation ↔ Provider.
24
+ // **Pattern precedent:** identical to `delivery` + `channel-email`. The
25
+ // delivery feature declares `r.extendsRegistrar("deliveryChannel")`, and
26
+ // channel-email registers via `r.useExtension("deliveryChannel",
27
+ // "email", {...})`. The foundation ↔ provider separation is the same.
29
28
  //
30
- // **Standalone:** Foundation ist ohne tier-engine nutzbar. Existing
31
- // `channel-email` (App-wide-Mail-Sender via delivery) bleibt unangetastet
32
- // — additive Feature.
29
+ // **Standalone:** The foundation can be used without tier-engine. Existing
30
+ // `channel-email` (app-wide mail sender via delivery) remains unchanged—an
31
+ // additive feature.
33
32
 
34
33
  import {
35
34
  type EmailTransport,
@@ -76,9 +75,9 @@ export const MAIL_TRANSPORT_EXTENSION = "mailTransport" as const;
76
75
  * config — tenant config reads (the plugin's host/port/from/...)
77
76
  * registry — extension lookup in the factory (not plugin-internal)
78
77
  * secrets — tenant secret reads (smtp.password)
79
- * auditUserId — audit identity for secret reads. Handler path: the
80
- * dispatcher sets the caller's user id; worker path: the
81
- * r.job wrap sets a system identity.
78
+ * auditUserId — audit identity for secret reads. Handler path: unset,
79
+ * requireSecretsContext falls back to ctx.user.id; worker path:
80
+ * the r.job wrap sets a system identity.
82
81
  */
83
82
  export type MailTransportContext = {
84
83
  readonly config?: ConfigAccessor;
@@ -97,8 +96,8 @@ export type MailTransportContext = {
97
96
  * an EmailTransport. Per-call construction so a tenant editing config
98
97
  * sees the change on the next mail.
99
98
  *
100
- * **Plugin-Author-Warnung:** `ctx` ist EXPLIZIT ein MailTransportContext,
101
- * nicht ein voller HandlerContext (siehe MailTransportContext-Doc).
99
+ * **Plugin-author warning:** `ctx` is EXPLICITLY a MailTransportContext,
100
+ * not a full HandlerContext (see the MailTransportContext doc).
102
101
  */
103
102
  export type MailTransportPlugin = {
104
103
  readonly build: (ctx: MailTransportContext, tenantId: string) => Promise<EmailTransport>;
@@ -277,6 +276,8 @@ export type TenantMailTransportScope = {
277
276
  export function tenantMailTransport(
278
277
  scope: TenantMailTransportScope,
279
278
  ): Promise<EmailTransport | null> {
279
+ // Without a tenant config the provider cannot be read: use the app transport.
280
+ if (scope.config === undefined) return Promise.resolve(null);
280
281
  return createTransportForTenantIfConfigured(
281
282
  {
282
283
  config: scope.config,
@@ -1,25 +1,25 @@
1
1
  // kumiko-feature-version: 1
2
2
  //
3
- // mail-transport-inmemory — In-Memory-EmailTransport für die mail-
4
- // foundation Plugin-API. Sammelt Mails in einem per-Tenant-Buffer
5
- // statt sie über einen echten SMTP-Server zu senden. Designed für
6
- // Demos, Sample-Apps und Tests die ohne Mailpit/Mailcrab/echten SMTP
7
- // laufen sollen.
3
+ // mail-transport-inmemory — In-memory email transport for the mail-
4
+ // foundation plugin API. Collects emails in a per-tenant buffer
5
+ // instead of sending them through a real SMTP server. Designed for
6
+ // demos, sample apps, and tests that should run without Mailpit,
7
+ // Mailcrab, or real SMTP.
8
8
  //
9
- // **Was diese Feature liefert:**
10
- // 1. Plugin-Registration via `r.useExtension("mailTransport",
11
- // "inmemory", { build })`. Tenants setzen
12
- // "mail-foundation:config:provider" auf "inmemory" und kriegen
13
- // die buffered-Variante.
14
- // 2. **Pro-Tenant Inbox.** Jeder Tenant hat einen eigenen
15
- // Mail-Buffer (Map<tenantId, EmailMessage[]>). Demo-Apps können
16
- // die Inbox via `getInbox(tenantId)` lesen + UI rendern.
9
+ // **What this feature provides:**
10
+ // 1. Plugin registration via `r.useExtension("mailTransport",
11
+ // "inmemory", { build })`. Tenants set
12
+ // "mail-foundation:config:provider" to "inmemory" and receive
13
+ // the buffered variant.
14
+ // 2. **Per-tenant inbox.** Each tenant has its own mail buffer
15
+ // (Map<tenantId, EmailMessage[]>). Demo apps can read the inbox
16
+ // via `getInbox(tenantId)` and render a UI.
17
17
  //
18
- // **Pattern-Vorbild:** mirrors mail-transport-smtp.
18
+ // **Pattern reference:** mirrors mail-transport-smtp.
19
19
  //
20
- // **NICHT für Production.** Buffer ist im Process-Memory, geht beim
21
- // Restart verloren. Cap-Counter / Audit-Trail bleiben trotzdem korrekt
22
- // — die hängen am event-store, nicht am Transport.
20
+ // **NOT for production.** The buffer is in process memory and is lost
21
+ // on restart. Cap counters and the audit trail remain correct because
22
+ // they are tied to the event store, not the transport.
23
23
 
24
24
  import type {
25
25
  EmailMessage,
@@ -39,9 +39,9 @@ const FEATURE_NAME = "mail-transport-inmemory";
39
39
  // Per-tenant in-memory buffer
40
40
  // =============================================================================
41
41
  //
42
- // Module-level Map weil der Plugin-build-call pro Send einen neuen
43
- // Transport-Wrapper baut, aber wir wollen dass alle Wrapper für
44
- // denselben Tenant auf denselben Buffer zeigen. Map<tenantId,
42
+ // The module-level Map is needed because the plugin build call creates
43
+ // a new transport wrapper for each send, while all wrappers for the
44
+ // same tenant must point to the same buffer. Map<tenantId,
45
45
  // InMemoryTransport>.
46
46
 
47
47
  const transportsByTenant = new Map<string, ReturnType<typeof createInMemoryTransport>>();
@@ -56,16 +56,16 @@ function getOrCreateTransportForTenant(tenantId: string) {
56
56
  }
57
57
 
58
58
  /**
59
- * Demo/Test-Helper: lies die "versendeten" Mails eines Tenants. Im
60
- * Sample-App rendert ein query-Handler darauf die Inbox-UI.
59
+ * Demo/test helper: reads the emails "sent" for a tenant. A query
60
+ * handler in the sample app uses this to render the inbox UI.
61
61
  */
62
62
  export function getInbox(tenantId: string): readonly EmailMessage[] {
63
63
  return transportsByTenant.get(tenantId)?.sent ?? [];
64
64
  }
65
65
 
66
66
  /**
67
- * Demo/Test-Helper: clear einen Tenant-Buffer (z.B. zwischen Test-
68
- * Szenarien).
67
+ * Demo/test helper: clears a tenant's buffer, for example between
68
+ * test scenarios.
69
69
  */
70
70
  export function clearInbox(tenantId: string): void {
71
71
  const t = transportsByTenant.get(tenantId);
@@ -82,10 +82,9 @@ export function createMailTransportInMemoryFeature() {
82
82
  r.describe(
83
83
  'Registers an in-process `"inmemory"` provider for `mail-foundation` that buffers sent mails per tenant instead of contacting an SMTP server. Use `getInbox(tenantId)` and `clearInbox(tenantId)` in demo apps and tests; not for production (buffer is process-memory, lost on restart).',
84
84
  );
85
- // Kein requires auf "config" oder "secrets" — der
86
- // In-Memory-Transport hat keine Config (nichts zu konfigurieren) und
87
- // kein Secret. Der einzige hard-require ist mail-foundation, das den
88
- // extension-point "mailTransport" definiert.
85
+ // No `config` or `secrets` requirement: the in-memory transport has
86
+ // no configuration and no secret. The only hard requirement is
87
+ // mail-foundation, which defines the "mailTransport" extension point.
89
88
  r.requires({ features: ["mail-foundation"] });
90
89
 
91
90
  const plugin: MailTransportPlugin = {
@@ -1,29 +1,29 @@
1
1
  // kumiko-feature-version: 1
2
2
  //
3
- // mail-transport-smtp — concrete SMTP-implementation for the
4
- // mail-foundation plugin-API.
3
+ // mail-transport-smtp — concrete SMTP implementation for the
4
+ // mail-foundation plugin API.
5
5
  //
6
- // **Was diese Feature liefert:**
7
- // 1. Provider-spezifische Tenant-Config (host/port/secure/from/authUser)
8
- // und Secret (smtp.password). Self-contained — mail-foundation kennt
9
- // diese Schlüssel nicht; wenn ein App-Owner zwischen SMTP und Brevo-
10
- // API wechseln will, hat er pro-Plugin eigenständige Config-Sets.
11
- // 2. **Plugin-Registration** via `r.useExtension("mailTransport",
12
- // "smtp", { build })`. Beim Boot kennt mail-foundation's
13
- // Factory-Lookup damit den name "smtp" ↔ build-Funktion.
14
- // 3. `build(ctx, tenantId)` liest die config-keys + secret und ruft
15
- // `createSmtpTransport()` aus channel-email auf. Das ist der
16
- // EINZIGE Cross-Feature-Import dieses Plugins — bewusst lokal
17
- // gehalten, mail-foundation bleibt provider-frei.
6
+ // **What this feature provides:**
7
+ // 1. Provider-specific tenant config (host/port/secure/from/authUser)
8
+ // and secret (smtp.password). Self-contained — mail-foundation does not
9
+ // know these keys; when an app owner switches between SMTP and the Brevo
10
+ // API, each plugin has its own independent config sets.
11
+ // 2. **Plugin registration** via `r.useExtension("mailTransport",
12
+ // "smtp", { build })`. At boot, mail-foundation's factory lookup maps
13
+ // the name "smtp" to the build function.
14
+ // 3. `build(ctx, tenantId)` reads the config keys and secret, then calls
15
+ // `createSmtpTransport()` from channel-email. This is the plugin's
16
+ // ONLY cross-feature import, deliberately kept local so
17
+ // mail-foundation remains provider-independent.
18
18
  //
19
- // **Pattern-Vorbild:** mirrors `channel-email` registering itself for
20
- // `delivery`. Diese Feature ist analog: registriert sich für
21
- // mail-foundation's "mailTransport"-Extension-Point.
19
+ // **Pattern reference:** mirrors `channel-email` registering itself for
20
+ // `delivery`. This feature is analogous: it registers for
21
+ // mail-foundation's "mailTransport" extension point.
22
22
  //
23
- // **Boot-Dependencies:**
23
+ // **Boot dependencies:**
24
24
  // - `mail-foundation` — extension-point owner
25
- // - `config` — für die Tenant-Config-Keys
26
- // - `secrets` — für das verschlüsselte SMTP-Password
25
+ // - `config` — for the tenant config keys
26
+ // - `secrets` — for the encrypted SMTP password
27
27
 
28
28
  import type { lookup } from "node:dns/promises";
29
29
  import {
@@ -20,13 +20,13 @@ import { type BrandingTokens, EMPTY_BRANDING } from "../page-render/index.ts";
20
20
  // `write: access.withSystem(access.admin)` — tenant admins self-service via
21
21
  // configEdit AND the system actor (ctx.systemWriteAs) may provision/migrate
22
22
  // these keys. The scope default (`access.admin`, admin-only) has no system
23
- // path, so a continuity migration could not set them (issue #396). Adding
24
- // SYSTEM_ROLE keeps the keys human-writable (checkWriteAccess collapses to
23
+ // path, so a continuity migration could not set them. Adding SYSTEM_ROLE
24
+ // keeps the keys human-writable (checkWriteAccess collapses to
25
25
  // system-only only when system is the SOLE writer), so self-service survives.
26
26
  //
27
- // CONTINUITY (Phase 5 — Prod trap): these keys land under
27
+ // CONTINUITY (Prod trap): these keys land under
28
28
  // `managed-pages:config:branding-*`, NOT the live `publicstatus:config:
29
- // branding-*`. The publicstatus consumer (Phase 5) MUST migrate the existing
29
+ // branding-*`. The publicstatus consumer MUST migrate the existing
30
30
  // read_config_values rows to the new QNs per tenant BEFORE switching the read
31
31
  // path, or every tenant resets to defaults on deploy. The migration is
32
32
  // deliberately NOT built here — the source QNs belong to the consumer app.
@@ -37,7 +37,7 @@ import { type BrandingTokens, EMPTY_BRANDING } from "../page-render/index.ts";
37
37
  // also renders. text keys carry an explicit length cap too — `validateType`
38
38
  // only checks the JS type, and the configEdit `maxLength` is client-side, so a
39
39
  // direct config:write:set would otherwise be unbounded (the page body is
40
- // likewise capped in Phase 2).
40
+ // likewise capped).
41
41
  const HEX_PATTERN = {
42
42
  regex: "^$|^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
43
43
  } as const;
@@ -67,7 +67,7 @@ export const MANAGED_PAGES_CSS_FEATURE = "managed-pages-css";
67
67
  // site-url`. BRANDING_QN below is the single source those QN strings are read
68
68
  // from (configEdit screen + render read); the integration test pins write-
69
69
  // target == read-source end-to-end.
70
- // Admin self-service + system provisioning (see write-access note above, #396).
70
+ // Admin self-service + system provisioning.
71
71
  const BRANDING_WRITE = access.withSystem(access.admin);
72
72
 
73
73
  export const BRANDING_KEYS = {
@@ -23,13 +23,13 @@ import { MANAGED_PAGES_I18N } from "./web/i18n.ts";
23
23
  // 60s-shared-cache saves the origin-revalidate roundtrip; CMS edits are live within 60s.
24
24
  const PUBLIC_PAGE_CACHE = { kind: "revalidate", maxAgeSeconds: 60 } as const;
25
25
 
26
- // QN-Konstante als dokumentierter Public-Contract — der Render-Pfad ruft
27
- // die by-slug-Query via systemQuery in-process (kein Code-Import des
28
- // Handlers, symmetrisch zum legal-pages-Muster).
26
+ // QN constant as a documented public contract — the render path calls
27
+ // the by-slug query in-process via systemQuery (without importing the
28
+ // handler's code, symmetrically with the legal-pages pattern).
29
29
  const BY_SLUG_QN = "managed-pages:query:by-slug";
30
30
 
31
- // Raw Handler-Return von bySlugQuery (published-only) — systemQuery dispatcht
32
- // direkt gegen den Handler, keine `{data}`-Envelope wie am /api/query-Wire.
31
+ // Raw handler return from bySlugQuery (published-only) — systemQuery dispatches
32
+ // directly to the handler, without the `{data}` envelope used on the /api/query wire.
33
33
  type BySlugQueryResult = {
34
34
  title: string;
35
35
  body: string;
@@ -83,61 +83,61 @@ export type ManagedPagesWrapLayout = (opts: {
83
83
  }) => string;
84
84
 
85
85
  export type ManagedPagesOptions = {
86
- /** Host → tenantId für anonyme per-Tenant-Auslieferung. NULL → 404 (kein
87
- * Tenant für diesen Host). Apex-/Marketing-Apps geben hier ihre Subdomain-
88
- * /Custom-Domain-Auflösung rein; single-tenant gibt konstant einen
89
- * tenantId (oder SYSTEM_TENANT_ID) zurück. Erforderlich, weil der Apex-
90
- * Host keinen ambient ctx.tenantId hat. */
86
+ /** Host → tenantId for anonymous per-tenant delivery. NULL → 404 (no
87
+ * tenant for this host). Apex/marketing apps provide their subdomain or
88
+ * custom-domain resolution here; single-tenant apps return a constant
89
+ * tenantId (or SYSTEM_TENANT_ID). Required because the apex host has no
90
+ * ambient ctx.tenantId. */
91
91
  readonly resolveApexTenant: (host: string) => Promise<string | null> | string | null;
92
- /** Custom Layout-Wrapper (Branding/Chrome). Default: minimaler
93
- * page-render-Skeleton. Erhält slug + SEO-Meta zur freien Nutzung.
94
- * **`branding` ist RAW, untrusted tenant input.** `title`/`description`
95
- * sind am Write nur längen-gecappt, NICHT HTML-escaped; `customCss` ist
96
- * ungesanitet. Der Wrapper MUSS sie über die Boundary-Helper emittieren
97
- * (alle re-exported von `@cosmicdrift/kumiko-bundled-features/managed-pages`):
98
- * `brandingHeaderHtml(branding)` + `brandingStyleBlock(branding)` (escapen
99
- * Header/Theme) und — mit allowCustomCss — `tenantStyleBlock(branding.
100
- * customCss)` ins `<head>` plus `TENANT_CONTENT_ATTR` am Body-Container. Ein
101
- * Custom-Wrapper der `branding.title` selbst interpoliert ist stored XSS;
102
- * der Default-Wrapper nutzt durchweg die Helper. */
92
+ /** Custom layout wrapper (branding/chrome). Default: a minimal page-render
93
+ * skeleton. Receives slug + SEO meta for free use.
94
+ * **`branding` is RAW, untrusted tenant input.** `title`/`description`
95
+ * are only length-capped on write, NOT HTML-escaped; `customCss` is
96
+ * unsanitized. The wrapper MUST emit them through the boundary helpers
97
+ * (all re-exported from `@cosmicdrift/kumiko-bundled-features/managed-pages`):
98
+ * `brandingHeaderHtml(branding)` + `brandingStyleBlock(branding)` (which
99
+ * escape header/theme) and, with allowCustomCss, `tenantStyleBlock(branding.
100
+ * customCss)` in the `<head>` plus `TENANT_CONTENT_ATTR` on the body
101
+ * container. A custom wrapper that interpolates `branding.title` itself is
102
+ * stored XSS; the default wrapper uses the helpers throughout. */
103
103
  readonly wrapLayout?: ManagedPagesWrapLayout;
104
- /** Basis-Pfad der Page-Routes. Default "/p" → GET /p/:slug. */
104
+ /** Base path for page routes. Default "/p" → GET /p/:slug. */
105
105
  readonly basePath?: string;
106
- /** Default-Sprache wenn `?lang=` fehlt. Default "en". */
106
+ /** Default language when `?lang=` is missing. Default "en". */
107
107
  readonly defaultLang?: string;
108
- /** Aktiviert die per-Tenant Custom-CSS-Capability (raw, untrusted): ein
109
- * `branding-custom-css` Config-Key + ein CSS-Feld im Branding-Editor + die
110
- * Render-Emission als scoped, allowlist-sanitized `<style data-tenant-css>`.
111
- * Default **false** (fail-closed — opt-in für untrusted-Tenant-Input). Auch
112
- * wenn true, wird die Emission zusätzlich per-Tenant über das
113
- * `managed-pages-css`-Toggle (createManagedPagesCssFeature) gegated, sobald
114
- * ein feature-toggles/tier-engine-Runtime verdrahtet ist. Der Render-time-
115
- * Sanitizer (page-render/css-sanitize) ist der Safety-Boundary. */
108
+ /** Enables the per-tenant custom CSS capability (raw, untrusted): a
109
+ * `branding-custom-css` config key + a CSS field in the branding editor +
110
+ * render emission as a scoped, allowlist-sanitized `<style data-tenant-css>`.
111
+ * Default **false** (fail-closed — opt-in for untrusted tenant input). Even
112
+ * when true, emission is additionally gated per tenant by the
113
+ * `managed-pages-css` toggle (createManagedPagesCssFeature) once a
114
+ * feature-toggles/tier-engine runtime is wired. The render-time sanitizer
115
+ * (page-render/css-sanitize) is the safety boundary. */
116
116
  readonly allowCustomCss?: boolean;
117
117
  };
118
118
 
119
- // managed-pages — vom Tenant editierbare, server-gerenderte Public-Pages.
120
- // Generalisiert das legal-pages-Render-Muster: eine dynamische Slug-Route
121
- // (`GET /p/:slug`), die den Tenant aus dem Host auflöst (resolveApexTenant),
122
- // die published Page lädt, Markdown gehärtet rendert (page-render) und über
123
- // einen optionalen wrapLayout in Chrome legt. Drafts → 404. Per-Tenant-
124
- // Content wird per `Vary: Host` cache-isoliert.
119
+ // managed-pages — tenant-editable, server-rendered public pages.
120
+ // Generalizes the legal-pages rendering pattern: a dynamic slug route
121
+ // (`GET /p/:slug`) that resolves the tenant from the Host (resolveApexTenant),
122
+ // loads the published page, renders hardened Markdown (page-render), and wraps
123
+ // it in chrome through an optional wrapLayout. Drafts → 404. Per-tenant
124
+ // content is cache-isolated through `Vary: Host`.
125
125
  //
126
- // Admin-Authoring: registriert entityList + entityEdit für `page` (TenantAdmin/
127
- // SystemAdmin) + die Convention-CRUD-Handler die der Renderer per Konvention
128
- // dispatcht. Die Screens MÜSSEN hier liegen (Boot-Validator verlangt entity-Ref
129
- // same-feature); Nav/Workspace bleibt App-Sache.
126
+ // Admin authoring: registers entityList + entityEdit for `page` (TenantAdmin/
127
+ // SystemAdmin) and the convention CRUD handlers dispatched by the renderer.
128
+ // The screens MUST live here (the boot validator requires the entity reference
129
+ // in the same feature); navigation/workspace remains the app's responsibility.
130
130
  //
131
- // Voraussetzungen am App-Bootstrap:
132
- // • anonymousAccess so verdrahtet, dass der X-Tenant-Header honoriert wird
133
- // — Multi-Tenant nutzt einen tenantResolver (oder keinen defaultTenantId).
134
- // Ein fixer defaultTenantId lockt Single-Tenant und lehnt den per-Page
135
- // gesetzten X-Tenant mit 400 tenant_mismatch ab.
136
- // • Admin-UI: die App zeigt via `r.nav({ screen: "managed-pages:screen:
137
- // page-list" })` + Workspace-Eintrag auf die hier deklarierten Screens
138
- // (cross-feature Nav→Screen ist global-validiert) und grantet ihren Admins
139
- // TenantAdmin. Ohne Nav bleiben die Screens dormant — kein Leak in
140
- // flat-nav-Apps die managed-pages nur zum Public-Render nutzen.
131
+ // App bootstrap requirements:
132
+ // • anonymousAccess must be wired to honor the X-Tenant header
133
+ // — multi-tenant apps use a tenantResolver (or no defaultTenantId).
134
+ // A fixed defaultTenantId locks the app to single-tenant mode and rejects
135
+ // the per-page X-Tenant with 400 tenant_mismatch.
136
+ // • Admin UI: the app exposes these screens via `r.nav({ screen:
137
+ // "managed-pages:screen:page-list" })` plus a workspace entry
138
+ // (cross-feature Nav→Screen is globally validated) and grants its admins
139
+ // TenantAdmin. Without navigation, the screens remain dormant — no leak in
140
+ // flat-nav apps that use managed-pages only for public rendering.
141
141
  export function createManagedPagesFeature(opts: ManagedPagesOptions): FeatureDefinition {
142
142
  const wrapLayout: ManagedPagesWrapLayout =
143
143
  opts.wrapLayout ??
@@ -192,8 +192,8 @@ export function createManagedPagesFeature(opts: ManagedPagesOptions): FeatureDef
192
192
  path: `${basePath}/:slug`,
193
193
  anonymous: true,
194
194
  handler: async (c, { systemQuery }) => {
195
- // `param("slug")` ist string|undefined, weil `path` ein computed
196
- // Template ist (Hono inferiert `:slug` nur aus String-Literalen).
195
+ // `param("slug")` is string|undefined because `path` is a computed
196
+ // template (Hono infers `:slug` only from string literals).
197
197
  const slug = c.req.param("slug");
198
198
  if (!slug) return c.text("not found", 404);
199
199
  const lang = c.req.query("lang") || defaultLang;
@@ -204,13 +204,13 @@ export function createManagedPagesFeature(opts: ManagedPagesOptions): FeatureDef
204
204
  const tenantId = await opts.resolveApexTenant(host);
205
205
  if (!tenantId) return c.text("not found", 404);
206
206
 
207
- // Page + branding read in parallel, beide über systemQuery in-
208
- // process gegen den host-resolved tenantId erzwungen (kein X-Tenant-
209
- // Header-Trick über app.fetch — der sähe für einen host-basierten
210
- // anonymousAccess-Resolver wie ein Client-Override aus und würde
211
- // von resolverTrust: "authoritative" zurecht abgelehnt; siehe
212
- // systemQuery's Doc in http-route.ts). Branding ist Deko → ein
213
- // Fehlschlag degradiert zum unbranded Default, blockt nie die Page.
207
+ // Page and branding are read in parallel, both forced through systemQuery
208
+ // in-process for the host-resolved tenantId (no X-Tenant header trick
209
+ // through app.fetch — for a host-based anonymousAccess resolver, that
210
+ // would look like a client override and would rightly be rejected by
211
+ // resolverTrust: "authoritative"; see systemQuery's documentation in
212
+ // http-route.ts). Branding is decorative → a failure degrades to the
213
+ // unbranded default and never blocks the page.
214
214
  let pageSettled: { ok: true; data: BySlugQueryResult } | { ok: false };
215
215
  let brandingResult: BrandingTokens;
216
216
  try {
@@ -246,8 +246,8 @@ export function createManagedPagesFeature(opts: ManagedPagesOptions): FeatureDef
246
246
  "content-type": "text/html; charset=utf-8",
247
247
  vary: "Host",
248
248
  } as const;
249
- // 304 (Revision unverändert) und HEAD überspringen beide das
250
- // Markdown-Rendern — der Body wird ohnehin verworfen.
249
+ // 304 (unchanged revision) and HEAD both skip Markdown rendering — the body
250
+ // would be discarded anyway.
251
251
  if (etagMatches(c.req.raw.headers.get("if-none-match"), etag) || c.req.method === "HEAD") {
252
252
  return cachedSecurePageResponse(c.req.raw, {
253
253
  body: null,
@@ -3,12 +3,11 @@ import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { type PageRow, pagesTable } from "../table.ts";
5
5
 
6
- // Public-Read by (tenantId, slug, lang). Anonymous-capable (Landing-/
7
- // Marketing-Pages). Tenant kommt aus query.user.tenantId — am Render-Pfad
8
- // via X-Tenant = Host-resolved-tenant gesetzt. Liefert NUR published Pages
9
- // mit Body: Drafts + leere Pages sind für anonyme Besucher unsichtbar
10
- // (Route → 404). Admin-Editing nutzt die Entity-List/Edit-Screens, nicht
11
- // diese Query.
6
+ // Public read by (tenantId, slug, lang), including anonymous access for landing and
7
+ // marketing pages. The tenant comes from query.user.tenantId, set on the render path
8
+ // via X-Tenant = Host-resolved-tenant. Returns ONLY published pages with a body:
9
+ // drafts and empty pages are invisible to anonymous visitors (the route returns 404).
10
+ // Admin editing uses the entity list/edit screens instead of this query.
12
11
  export const bySlugQuery = defineQueryHandler({
13
12
  name: "by-slug",
14
13
  schema: z.object({
@@ -3,12 +3,12 @@ import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { type PageRow, pagesTable } from "../table.ts";
5
5
 
6
- // Public-Read aller published Pages eines Tenants — Discovery-Quelle für
7
- // sitemap.xml/llms.txt (siehe seo-Feature). Anders als by-slug (single-row,
8
- // nur der angefragte Slug) listet dies alle published Slugs auf einmal, SQL-
9
- // seitig auf `published = true` gefiltert (Drafts nie im Ergebnis, kein
10
- // Body-Content — Discovery-Zweck braucht nur Slug/Title/updatedAt).
11
- // Anonymous: explizit in roles, symmetrisch zu text-content's by-tenant.
6
+ // Public read of all published pages for a tenant, used to discover URLs for
7
+ // sitemap.xml/llms.txt (see the seo feature). Unlike by-slug, which fetches one
8
+ // slug's content, this lists all published slugs in one query, filtered in SQL
9
+ // with `published = true`; drafts never appear, and only slug/title/updatedAt are
10
+ // returned because discovery does not require body content.
11
+ // Anonymous access is explicit in roles, matching text-content's by-tenant.
12
12
  export type PublishedPageSummary = {
13
13
  readonly slug: string;
14
14
  readonly lang: string;
@@ -19,8 +19,8 @@ export type PublishedPageSummary = {
19
19
  export const byTenantPublishedQuery = defineQueryHandler({
20
20
  name: "by-tenant-published",
21
21
  schema: z.object({
22
- /** Optional cross-tenant read — nur für SystemAdmin. Symmetrisch zur
23
- * by-slug.query Override-Logik. */
22
+ /** Optional cross-tenant read — only for SystemAdmin. Matches the override
23
+ * logic in by-slug.query. */
24
24
  tenantIdOverride: z.string().min(1).optional(),
25
25
  }),
26
26
  access: { roles: ["anonymous", "User", "TenantAdmin", "SystemAdmin"] },
@@ -18,12 +18,10 @@ const langSchema = z
18
18
 
19
19
  const executor = createEventStoreExecutor(pagesTable, pageEntity, { entityName: "page" });
20
20
 
21
- // Upsert einer Page — eine Operation pro (tenantId, slug, lang). Tenant-
22
- // Scope default aus event.user; SystemAdmin kann via `tenantIdOverride`
23
- // für einen anderen Tenant schreiben (typisch SYSTEM_TENANT_ID für app-
24
- // weite Pages). published/description/ogImage werden bei Update preserved
25
- // wenn im Payload weggelassen (undefined) — damit ein Publish-Toggle nicht
26
- // den Body überschreiben muss und umgekehrt.
21
+ // Upserts one page per (tenantId, slug, lang). The tenant scope defaults to event.user;
22
+ // SystemAdmin can write to another tenant via `tenantIdOverride` (typically SYSTEM_TENANT_ID
23
+ // for app-wide pages). On update, omitted published/description/ogImage values are preserved
24
+ // so a publish toggle does not overwrite the body, and vice versa.
27
25
  export const setWrite = defineWriteHandler({
28
26
  name: "set",
29
27
  schema: z.object({
@@ -34,7 +32,7 @@ export const setWrite = defineWriteHandler({
34
32
  description: z.string().max(500).nullable().optional(),
35
33
  ogImage: z.string().max(2000).nullable().optional(),
36
34
  published: z.boolean().optional(),
37
- /** Cross-tenant write — nur SystemAdmin (z.B. SYSTEM_TENANT_ID-Pages). */
35
+ /** Cross-tenant write — only SystemAdmin (for example, SYSTEM_TENANT_ID pages). */
38
36
  tenantIdOverride: z.string().min(1).optional(),
39
37
  }),
40
38
  access: { roles: ["TenantAdmin", "SystemAdmin"] },
@@ -3,14 +3,14 @@ import type {
3
3
  EntityListScreenDefinition,
4
4
  } from "@cosmicdrift/kumiko-framework/engine";
5
5
 
6
- // Admin-Authoring-Screens für die `page`-Entity. Reine Daten (JSON-safe) —
7
- // der generische DataTable-/Form-Renderer mountet sie, kein React-Component
8
- // nötig. Beide MÜSSEN im managed-pages-Feature registriert werden (nicht in
9
- // der App): der Boot-Validator verlangt, dass `entity: "page"` im selben
10
- // Feature deklariert ist wie der Screen. Nav/Workspace bleibt App-Sache
11
- // (placement-spezifisch, `default`-Workspace ist ein App-Singleton) — die
12
- // App zeigt via `r.nav({ screen: "managed-pages:screen:page-list" })` darauf
13
- // (cross-feature Nav→Screen ist gegen den globalen Screen-QN-Set validiert).
6
+ // Admin authoring screens for the `page` entity. These are JSON-safe data only —
7
+ // the generic DataTable/form renderer mounts them, so no React component is
8
+ // needed. Both MUST be registered in the managed-pages feature (not in the
9
+ // app): the boot validator requires `entity: "page"` to be declared in the
10
+ // same feature as the screen. Navigation and workspace placement remain app-
11
+ // specific (`default` workspace is an app singleton) — the app points to this
12
+ // via `r.nav({ screen: "managed-pages:screen:page-list" })`.
13
+ // Cross-feature Nav→Screen is validated against the global screen QN set.
14
14
 
15
15
  const ADMIN_ROLES = ["TenantAdmin", "SystemAdmin"] as const;
16
16
 
@@ -72,9 +72,9 @@ export const pageEditScreen: EntityEditScreenDefinition = {
72
72
  { field: "title", span: 2 },
73
73
  { field: "description", span: 2 },
74
74
  { field: "ogImage", span: 2 },
75
- // Publish/Unpublish: der `published`-Toggle hier IST der
76
- // Publish-Mechanismus (kein separater One-Click-List-Action —
77
- // rowAction-payload kann keine Konstanten injizieren).
75
+ // Publish/Unpublish: the `published` toggle here IS the publishing
76
+ // mechanism (there is no separate one-click list action —
77
+ // rowAction-payload cannot inject constants).
78
78
  { field: "published", span: 1 },
79
79
  ],
80
80
  },