@cosmicdrift/kumiko-samples 0.367.0 → 0.369.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 (406) hide show
  1. package/package.json +1 -1
  2. package/packages/bundled-features/package.json +16 -2
  3. package/packages/bundled-features/src/audit/handlers/details.query.ts +1 -1
  4. package/packages/bundled-features/src/audit/handlers/list.query.ts +1 -1
  5. package/packages/bundled-features/src/audit/run-escape-hatch-retention.ts +5 -5
  6. package/packages/bundled-features/src/auth-email-password/bootstrap.ts +1 -1
  7. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +10 -3
  8. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +10 -3
  9. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  10. package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +6 -2
  11. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +1 -1
  12. package/packages/bundled-features/src/auth-email-password/seeding.ts +2 -2
  13. package/packages/bundled-features/src/auth-foundation/feature.ts +43 -34
  14. package/packages/bundled-features/src/auth-foundation/index.ts +1 -0
  15. package/packages/bundled-features/src/auth-mfa/db/queries.ts +5 -2
  16. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +1 -1
  17. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  18. package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +2 -2
  19. package/packages/bundled-features/src/auth-mfa/handlers/status.query.ts +1 -1
  20. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  21. package/packages/bundled-features/src/auth-mfa/mfa-code-verifier.ts +1 -1
  22. package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +1 -1
  23. package/packages/bundled-features/src/auth-mfa-user-data/index.ts +19 -10
  24. package/packages/bundled-features/src/billing-foundation/billing-info-query.ts +1 -1
  25. package/packages/bundled-features/src/billing-foundation/feature.ts +138 -135
  26. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +1 -1
  27. package/packages/bundled-features/src/billing-foundation/projection.ts +3 -2
  28. package/packages/bundled-features/src/cap-counter/calendar-cap-usage-reservation.ts +52 -1
  29. package/packages/bundled-features/src/cap-counter/cap-reservation.ts +203 -15
  30. package/packages/bundled-features/src/cap-counter/changes.json +13 -0
  31. package/packages/bundled-features/src/cap-counter/feature.ts +84 -73
  32. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +3 -4
  33. package/packages/bundled-features/src/cap-counter/index.ts +9 -1
  34. package/packages/bundled-features/src/cap-counter/tables.ts +10 -3
  35. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -2
  36. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +6 -2
  37. package/packages/bundled-features/src/cap-overview/handlers/tenant-options.query.ts +1 -1
  38. package/packages/bundled-features/src/channel-email/changes.json +7 -0
  39. package/packages/bundled-features/src/channel-email/email-channel.ts +39 -8
  40. package/packages/bundled-features/src/channel-email/feature.ts +1 -1
  41. package/packages/bundled-features/src/channel-email/index.ts +5 -1
  42. package/packages/bundled-features/src/channel-in-app/handlers/inbox.query.ts +1 -1
  43. package/packages/bundled-features/src/channel-in-app/handlers/mark-all-read.write.ts +1 -1
  44. package/packages/bundled-features/src/channel-in-app/handlers/mark-read.write.ts +1 -1
  45. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +1 -1
  46. package/packages/bundled-features/src/channel-in-app/tables.ts +1 -1
  47. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +1 -1
  48. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +1 -1
  49. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +1 -2
  50. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +1 -1
  51. package/packages/bundled-features/src/compliance-profiles/seeding.ts +8 -4
  52. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +26 -17
  53. package/packages/bundled-features/src/config/db/queries/resolver.ts +1 -1
  54. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +2 -2
  55. package/packages/bundled-features/src/config/resolver.ts +1 -1
  56. package/packages/bundled-features/src/config/web/i18n.ts +1 -2
  57. package/packages/bundled-features/src/config/write-helpers.ts +1 -1
  58. package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
  59. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +9 -7
  60. package/packages/bundled-features/src/custom-fields/db/queries/field-access.ts +1 -1
  61. package/packages/bundled-features/src/custom-fields/db/queries/projection.ts +1 -1
  62. package/packages/bundled-features/src/custom-fields/db/queries/quota.ts +1 -1
  63. package/packages/bundled-features/src/custom-fields/db/queries/retention.ts +6 -2
  64. package/packages/bundled-features/src/custom-fields/db/queries/user-data-rights.ts +1 -1
  65. package/packages/bundled-features/src/custom-fields/feature.ts +11 -14
  66. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +2 -2
  67. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +2 -2
  68. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +2 -2
  69. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +2 -2
  70. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +4 -4
  71. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  72. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +16 -10
  73. package/packages/bundled-features/src/delivery/address-opt-out.ts +5 -2
  74. package/packages/bundled-features/src/delivery/attempt-log-retention.ts +1 -1
  75. package/packages/bundled-features/src/delivery/changes.json +6 -0
  76. package/packages/bundled-features/src/delivery/channel-context.ts +1 -1
  77. package/packages/bundled-features/src/delivery/db/queries/address-opt-outs.ts +1 -1
  78. package/packages/bundled-features/src/delivery/db/queries/preferences.ts +1 -1
  79. package/packages/bundled-features/src/delivery/delivery-service.ts +16 -6
  80. package/packages/bundled-features/src/delivery/feature.ts +2 -2
  81. package/packages/bundled-features/src/delivery/handlers/log.query.ts +3 -2
  82. package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +1 -1
  83. package/packages/bundled-features/src/delivery/index.ts +8 -1
  84. package/packages/bundled-features/src/delivery/unsubscribe.ts +66 -37
  85. package/packages/bundled-features/src/delivery/upsert-preference.ts +5 -2
  86. package/packages/bundled-features/src/derivatives-sharp/feature.ts +21 -12
  87. package/packages/bundled-features/src/derivatives-sharp/index.ts +1 -1
  88. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +112 -103
  89. package/packages/bundled-features/src/document-ingest-foundation/forget-extract-with-file-ref.ts +3 -3
  90. package/packages/bundled-features/src/document-ingest-foundation/index.ts +4 -1
  91. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  92. package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -5
  93. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  94. package/packages/bundled-features/src/file-derivatives/feature.ts +134 -129
  95. package/packages/bundled-features/src/file-derivatives/handlers/public-variant-by-file-ref.query.ts +1 -1
  96. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  97. package/packages/bundled-features/src/file-foundation/feature.ts +38 -29
  98. package/packages/bundled-features/src/file-foundation/index.ts +1 -0
  99. package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +1 -1
  100. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +32 -21
  101. package/packages/bundled-features/src/file-provider-inmemory/index.ts +6 -1
  102. package/packages/bundled-features/src/file-provider-s3/changes.json +10 -1
  103. package/packages/bundled-features/src/file-provider-s3/env-feature.ts +62 -0
  104. package/packages/bundled-features/src/file-provider-s3/feature.ts +107 -73
  105. package/packages/bundled-features/src/file-provider-s3/index.ts +6 -1
  106. package/packages/bundled-features/src/file-provider-s3/lib/index.ts +3 -0
  107. package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/s3-provider.ts +19 -19
  108. package/packages/bundled-features/src/file-provider-s3-env/index.ts +7 -2
  109. package/packages/bundled-features/src/files-provider-s3/index.ts +11 -3
  110. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +1 -1
  111. package/packages/bundled-features/src/files-tenant-data/hooks.ts +1 -2
  112. package/packages/bundled-features/src/folders/feature.ts +8 -3
  113. package/packages/bundled-features/src/folders-user-data/index.ts +27 -18
  114. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
  115. package/packages/bundled-features/src/form-draft/db/queries/draft-count.ts +1 -1
  116. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +3 -2
  117. package/packages/bundled-features/src/form-draft/feature.ts +6 -1
  118. package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +2 -2
  119. package/packages/bundled-features/src/form-draft/index.ts +1 -1
  120. package/packages/bundled-features/src/form-draft/lookup.ts +1 -1
  121. package/packages/bundled-features/src/form-draft-user-data/index.ts +19 -10
  122. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +165 -154
  123. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +1 -2
  124. package/packages/bundled-features/src/inbound-mail-foundation/index.ts +1 -1
  125. package/packages/bundled-features/src/inbound-mail-foundation/oauth-access-token.ts +5 -2
  126. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +3 -2
  127. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +1 -1
  128. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +22 -13
  129. package/packages/bundled-features/src/inbound-provider-imap/index.ts +6 -1
  130. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +20 -12
  131. package/packages/bundled-features/src/inbound-provider-inmemory/index.ts +1 -0
  132. package/packages/bundled-features/src/jobs/db/queries/retention.ts +1 -1
  133. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +1 -1
  134. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +1 -1
  135. package/packages/bundled-features/src/jobs/handlers/list.query.ts +7 -2
  136. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  137. package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +1 -1
  138. package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +1 -1
  139. package/packages/bundled-features/src/jobs/job-run-logger.ts +11 -10
  140. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  141. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  142. package/packages/bundled-features/src/ledger/feature.ts +6 -3
  143. package/packages/bundled-features/src/mail-foundation/feature.ts +66 -46
  144. package/packages/bundled-features/src/mail-foundation/i18n.ts +8 -0
  145. package/packages/bundled-features/src/mail-foundation/index.ts +1 -0
  146. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +31 -17
  147. package/packages/bundled-features/src/mail-transport-inmemory/index.ts +6 -1
  148. package/packages/bundled-features/src/mail-transport-smtp/changes.json +7 -0
  149. package/packages/bundled-features/src/mail-transport-smtp/config-keys.ts +67 -0
  150. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +67 -82
  151. package/packages/bundled-features/src/mail-transport-smtp/i18n.ts +28 -0
  152. package/packages/bundled-features/src/mail-transport-smtp/index.ts +1 -0
  153. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +1 -1
  154. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +1 -2
  155. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +1 -2
  156. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -4
  157. package/packages/bundled-features/src/metrics/compute.ts +1 -1
  158. package/packages/bundled-features/src/metrics/filters.ts +1 -1
  159. package/packages/bundled-features/src/metrics/validate.ts +1 -1
  160. package/packages/bundled-features/src/notes-history/feature.ts +6 -3
  161. package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
  162. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  163. package/packages/bundled-features/src/notes-history-user-data/index.ts +27 -18
  164. package/packages/bundled-features/src/personal-access-tokens/changes.json +6 -0
  165. package/packages/bundled-features/src/personal-access-tokens/feature.ts +17 -2
  166. package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +1 -1
  167. package/packages/bundled-features/src/personal-access-tokens/handlers/list.query.ts +2 -2
  168. package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
  169. package/packages/bundled-features/src/personal-access-tokens/resolver.ts +1 -1
  170. package/packages/bundled-features/src/personal-access-tokens/revoke-for-user.ts +2 -2
  171. package/packages/bundled-features/src/personal-access-tokens/roles.ts +8 -6
  172. package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -0
  173. package/packages/bundled-features/src/readiness/feature.ts +25 -16
  174. package/packages/bundled-features/src/readiness/index.ts +1 -1
  175. package/packages/bundled-features/src/secrets/changes.json +6 -0
  176. package/packages/bundled-features/src/secrets/db/queries/read.ts +1 -1
  177. package/packages/bundled-features/src/secrets/feature.ts +26 -6
  178. package/packages/bundled-features/src/secrets/handlers/delete.write.ts +5 -2
  179. package/packages/bundled-features/src/secrets/handlers/rotate.job.ts +2 -2
  180. package/packages/bundled-features/src/secrets/handlers/set.write.ts +5 -2
  181. package/packages/bundled-features/src/secrets/secrets-context.ts +4 -3
  182. package/packages/bundled-features/src/sessions/db/queries/cleanup.ts +1 -1
  183. package/packages/bundled-features/src/sessions/handlers/detail.query.ts +1 -1
  184. package/packages/bundled-features/src/sessions/handlers/list.query.ts +2 -2
  185. package/packages/bundled-features/src/sessions/handlers/mine.query.ts +1 -1
  186. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +1 -1
  187. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +1 -1
  188. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  189. package/packages/bundled-features/src/sessions/session-callbacks.ts +14 -7
  190. package/packages/bundled-features/src/sessions/testing.ts +1 -1
  191. package/packages/bundled-features/src/tags/feature.ts +6 -3
  192. package/packages/bundled-features/src/template-resolver/api.ts +1 -1
  193. package/packages/bundled-features/src/template-resolver/constants.ts +0 -1
  194. package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +1 -1
  195. package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +1 -1
  196. package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +1 -2
  197. package/packages/bundled-features/src/template-resolver/handlers/collection-item.query.ts +1 -1
  198. package/packages/bundled-features/src/template-resolver/handlers/collection-list.query.ts +1 -2
  199. package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +1 -1
  200. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +1 -1
  201. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +1 -1
  202. package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +1 -1
  203. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +1 -1
  204. package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +1 -1
  205. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
  206. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +1 -1
  207. package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +1 -1
  208. package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +1 -1
  209. package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +4 -2
  210. package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +1 -1
  211. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +1 -1
  212. package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +1 -1
  213. package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +1 -1
  214. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +1 -1
  215. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +1 -1
  216. package/packages/bundled-features/src/template-resolver/seeding.ts +3 -3
  217. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +1 -1
  218. package/packages/bundled-features/src/template-resolver/template-preview.ts +1 -1
  219. package/packages/bundled-features/src/template-resolver/template-resources.ts +1 -1
  220. package/packages/bundled-features/src/template-resolver/testing.ts +1 -1
  221. package/packages/bundled-features/src/template-resolver-user-data/index.ts +23 -14
  222. package/packages/bundled-features/src/tenant/handlers/active-tenant-ids.query.ts +1 -1
  223. package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +1 -2
  224. package/packages/bundled-features/src/tenant/handlers/cancel-invitation.write.ts +1 -1
  225. package/packages/bundled-features/src/tenant/handlers/invitations.query.ts +1 -1
  226. package/packages/bundled-features/src/tenant/handlers/me.query.ts +1 -1
  227. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
  228. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  229. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  230. package/packages/bundled-features/src/tenant/handlers/remove-member.write.ts +2 -1
  231. package/packages/bundled-features/src/tenant/handlers/resolve-user-ids.query.ts +1 -1
  232. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  233. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
  234. package/packages/bundled-features/src/tenant/handlers/update-member-roles.write.ts +1 -2
  235. package/packages/bundled-features/src/tenant/invited-membership.ts +2 -2
  236. package/packages/bundled-features/src/tenant/last-tenant-admin.ts +1 -2
  237. package/packages/bundled-features/src/tenant/seeding.ts +12 -12
  238. package/packages/bundled-features/src/tenant-lifecycle/handlers/cancel-destruction.write.ts +1 -2
  239. package/packages/bundled-features/src/tenant-lifecycle/handlers/request-destruction.write.ts +1 -2
  240. package/packages/bundled-features/src/tenant-lifecycle/lib/revoke-tenant-sessions.ts +1 -1
  241. package/packages/bundled-features/src/tenant-lifecycle/lifecycle-gate.ts +1 -1
  242. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +3 -3
  243. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +10 -5
  244. package/packages/bundled-features/src/tenant-lifecycle/testing.ts +3 -3
  245. package/packages/bundled-features/src/tenant-settings/feature.ts +34 -29
  246. package/packages/bundled-features/src/tier-engine/feature.ts +426 -428
  247. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +2 -3
  248. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +5 -2
  249. package/packages/bundled-features/src/user/changes.json +6 -0
  250. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +1 -1
  251. package/packages/bundled-features/src/user/handlers/create.write.ts +1 -2
  252. package/packages/bundled-features/src/user/handlers/find-for-auth.query.ts +1 -1
  253. package/packages/bundled-features/src/user/handlers/list.query.ts +1 -1
  254. package/packages/bundled-features/src/user/handlers/update-roles.ts +2 -1
  255. package/packages/bundled-features/src/user/index.ts +5 -1
  256. package/packages/bundled-features/src/user/invited-global-roles.ts +2 -2
  257. package/packages/bundled-features/src/user/principal-status.ts +13 -3
  258. package/packages/bundled-features/src/user/resolve-display-names.ts +1 -1
  259. package/packages/bundled-features/src/user/seeding.ts +5 -5
  260. package/packages/bundled-features/src/user-data-rights/audit-download.ts +2 -2
  261. package/packages/bundled-features/src/user-data-rights/changes.json +6 -0
  262. package/packages/bundled-features/src/user-data-rights/db/queries/export-jobs.ts +1 -1
  263. package/packages/bundled-features/src/user-data-rights/db/queries/forget-cleanup.ts +1 -1
  264. package/packages/bundled-features/src/user-data-rights/feature.ts +7 -4
  265. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +1 -1
  266. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +1 -1
  267. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +1 -1
  268. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +1 -1
  269. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +1 -1
  270. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +1 -2
  271. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +3 -3
  272. package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +40 -3
  273. package/packages/bundled-features/src/user-data-rights/lib/deny-if-target-outside-admin-tenant.ts +1 -1
  274. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +7 -2
  275. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +7 -3
  276. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +11 -5
  277. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +10 -5
  278. package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +1 -2
  279. package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
  280. package/packages/bundled-features/src/waitlist/lib.ts +5 -2
  281. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +1 -1
  282. package/packages/bundled-features/src/workflow-runner/feature.ts +58 -47
  283. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +1 -1
  284. package/packages/bundled-features/src/workflow-runner/index.ts +1 -1
  285. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +1 -1
  286. package/samples/apps/admin-console/src/run-config.ts +2 -2
  287. package/samples/apps/cap-billing-demo/package.json +3 -0
  288. package/samples/apps/cap-billing-demo/src/feature.ts +2 -2
  289. package/samples/apps/cap-billing-demo/src/run-config.ts +8 -8
  290. package/samples/apps/marketing-demo/src/app/seed.ts +1 -1
  291. package/samples/apps/marketing-demo/src/db/queries/seed-counts.ts +1 -1
  292. package/samples/apps/showcase/package.json +3 -0
  293. package/samples/apps/showcase/src/app/seed-items.ts +1 -1
  294. package/samples/apps/styleguide/src/app/seed.ts +2 -2
  295. package/samples/apps/styleguide/src/features/ai-settings/seed.ts +2 -2
  296. package/samples/apps/ui-walkthrough/scripts/emit-e2e-data.ts +1 -1
  297. package/samples/apps/ui-walkthrough/src/app/auth-constants.ts +1 -1
  298. package/samples/apps/ui-walkthrough/src/app/seed-rental.ts +2 -2
  299. package/samples/apps/ui-walkthrough/src/app/seed-vehicles.ts +1 -1
  300. package/samples/apps/ui-walkthrough/src/app/seed.ts +1 -1
  301. package/samples/apps/ui-walkthrough/src/db/queries/row-counts.ts +1 -1
  302. package/samples/apps/ui-walkthrough/src/db/queries/task-counts.ts +1 -1
  303. package/samples/apps/use-all-bundled/feature-manifest.json +16 -16
  304. package/samples/apps/use-all-bundled/package.json +3 -0
  305. package/samples/apps/use-all-bundled/scripts/check-coverage.ts +2 -2
  306. package/samples/apps/use-all-bundled/src/app/auth-constants.ts +1 -1
  307. package/samples/apps/use-all-bundled/src/app/cap-overview-caps.ts +2 -2
  308. package/samples/apps/use-all-bundled/src/app/dev-app-options.ts +1 -1
  309. package/samples/apps/use-all-bundled/src/app/seed-documents.ts +1 -1
  310. package/samples/apps/use-all-bundled/src/app/seed.ts +11 -5
  311. package/samples/apps/use-all-bundled/src/run-config.ts +55 -56
  312. package/samples/apps/user-data-rights-demo/README.md +2 -2
  313. package/samples/apps/user-data-rights-demo/package.json +3 -0
  314. package/samples/apps/user-data-rights-demo/src/run-config.ts +7 -7
  315. package/samples/apps/workspaces/package.json +3 -0
  316. package/samples/recipes/access-control/package.json +3 -0
  317. package/samples/recipes/anonymous-access/package.json +3 -0
  318. package/samples/recipes/anonymous-access-multitenant/package.json +3 -0
  319. package/samples/recipes/apex-landing/package.json +1 -0
  320. package/samples/recipes/apex-surface-auth/package.json +3 -0
  321. package/samples/recipes/apex-surface-auth/src/feature.ts +2 -2
  322. package/samples/recipes/api-worker-split/package.json +3 -0
  323. package/samples/recipes/api-worker-split/src/feature.ts +1 -2
  324. package/samples/recipes/auth-claims/package.json +3 -0
  325. package/samples/recipes/auth-foundation-providers/src/feature.ts +1 -1
  326. package/samples/recipes/auth-mfa/package.json +3 -0
  327. package/samples/recipes/basic-entity/package.json +3 -0
  328. package/samples/recipes/chat-channels/package.json +3 -0
  329. package/samples/recipes/compliance-profiles-demo/package.json +3 -0
  330. package/samples/recipes/cross-feature-events/package.json +3 -1
  331. package/samples/recipes/cross-feature-events/src/feature.ts +1 -1
  332. package/samples/recipes/crypto-shredding-hr/package.json +3 -0
  333. package/samples/recipes/currencies-global/package.json +3 -0
  334. package/samples/recipes/currencies-per-tenant/package.json +3 -0
  335. package/samples/recipes/custom-fields-basic/package.json +3 -0
  336. package/samples/recipes/custom-handlers/package.json +3 -0
  337. package/samples/recipes/dashboard-stats/package.json +3 -0
  338. package/samples/recipes/delivery-notifications/package.json +3 -0
  339. package/samples/recipes/e2e-generator/package.json +3 -0
  340. package/samples/recipes/embedded/package.json +3 -0
  341. package/samples/recipes/embedded-entity-form/package.json +1 -0
  342. package/samples/recipes/encrypted-tenant-config/README.md +1 -1
  343. package/samples/recipes/encrypted-tenant-config/package.json +3 -0
  344. package/samples/recipes/error-contract/package.json +3 -0
  345. package/samples/recipes/event-sourcing/package.json +3 -1
  346. package/samples/recipes/event-sourcing/src/feature.ts +16 -20
  347. package/samples/recipes/event-sourcing/tsconfig.json +2 -6
  348. package/samples/recipes/feature-toggles/package.json +3 -0
  349. package/samples/recipes/field-access/package.json +3 -0
  350. package/samples/recipes/files-post-processing/package.json +1 -0
  351. package/samples/recipes/golden-path/README.md +30 -0
  352. package/samples/recipes/golden-path/package.json +11 -0
  353. package/samples/recipes/golden-path/src/feature.ts +70 -0
  354. package/samples/recipes/idempotency/package.json +3 -0
  355. package/samples/recipes/inbound-mail-triage/package.json +3 -0
  356. package/samples/recipes/lane-routing/package.json +3 -0
  357. package/samples/recipes/ledger-banking/package.json +3 -0
  358. package/samples/recipes/ledger-invoicing/package.json +3 -0
  359. package/samples/recipes/legal-pages/package.json +3 -0
  360. package/samples/recipes/lifecycle-hooks/package.json +3 -0
  361. package/samples/recipes/managed-config/package.json +3 -0
  362. package/samples/recipes/managed-pages/package.json +3 -0
  363. package/samples/recipes/notes-history-basic/package.json +3 -0
  364. package/samples/recipes/ownership/package.json +3 -0
  365. package/samples/recipes/pdf-audit-export/package.json +1 -0
  366. package/samples/recipes/pipeline-basics/package.json +3 -0
  367. package/samples/recipes/public-share-token/package.json +3 -0
  368. package/samples/recipes/public-share-token/src/feature.ts +1 -1
  369. package/samples/recipes/rate-limiting/package.json +3 -0
  370. package/samples/recipes/realtime-sse/package.json +3 -0
  371. package/samples/recipes/record-detail-layout/package.json +1 -0
  372. package/samples/recipes/reference-data/package.json +3 -0
  373. package/samples/recipes/relations/package.json +3 -0
  374. package/samples/recipes/screens-nav/package.json +3 -0
  375. package/samples/recipes/search/package.json +3 -0
  376. package/samples/recipes/secrets-demo/package.json +3 -0
  377. package/samples/recipes/security-baseline/src/feature.ts +2 -2
  378. package/samples/recipes/session-revocation/README.md +1 -1
  379. package/samples/recipes/session-revocation/package.json +3 -0
  380. package/samples/recipes/session-revocation/src/feature.ts +1 -1
  381. package/samples/recipes/state-machine/package.json +3 -1
  382. package/samples/recipes/state-machine/src/entities/invoice.ts +2 -2
  383. package/samples/recipes/state-machine/src/events.ts +19 -0
  384. package/samples/recipes/state-machine/src/feature.ts +25 -30
  385. package/samples/recipes/state-machine/src/handlers/_helpers.ts +13 -14
  386. package/samples/recipes/state-machine/src/handlers/create.ts +1 -1
  387. package/samples/recipes/state-machine/src/handlers/transitions.ts +129 -122
  388. package/samples/recipes/state-machine/src/reducer.ts +1 -1
  389. package/samples/recipes/state-machine/tsconfig.json +2 -6
  390. package/samples/recipes/tags-basic/package.json +3 -0
  391. package/samples/recipes/tenant-isolation/package.json +3 -0
  392. package/samples/recipes/tenant-settings/package.json +3 -0
  393. package/samples/recipes/tier-admin/package.json +3 -0
  394. package/samples/recipes/timezones/package.json +3 -0
  395. package/samples/recipes/tsconfig.base.json +1 -1
  396. package/samples/recipes/user-data-rights/package.json +3 -0
  397. package/samples/recipes/user-data-rights/src/feature.ts +6 -2
  398. package/samples/recipes/user-profile/package.json +3 -0
  399. package/samples/recipes/user-profile/src/feature.ts +2 -2
  400. package/samples/recipes/webhook-step/package.json +3 -0
  401. package/samples/recipes/wizard-form/package.json +1 -0
  402. package/samples/recipes/workflow-engine/package.json +3 -0
  403. package/samples/recipes/workflow-engine/src/db/queries/suspended-runs.ts +5 -2
  404. package/samples/recipes/writeform-section/package.json +1 -0
  405. package/packages/bundled-features/src/file-provider-s3-env/feature.ts +0 -58
  406. /package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/env-helper.ts +0 -0
@@ -272,17 +272,26 @@ export const imapInboundMailPlugin: InboundMailProviderPlugin = {
272
272
  // gehören den OAuth-Providern (M365/Gmail).
273
273
  };
274
274
 
275
- export const inboundProviderImapFeature = defineFeature(FEATURE_NAME, (r) => {
276
- r.describe(
277
- 'Registers the `"imap"` provider for `inbound-mail-foundation` using imapflow — password/app-password auth covers classic IMAP hosts without any OAuth (plus an XOAUTH2 fallback consuming an access token from the secret slot). Incremental sync via a UIDVALIDITY:lastUid cursor (UIDVALIDITY change triggers a cursor-invalid full resync), initial backfill bounded by the foundation backfill window, and live push via IMAP IDLE for the watch supervisor. Store the per-account connection JSON (host/port/secure/user/password) in the account credential secret slot before the first sync.',
275
+ export function createInboundProviderImapFeature() {
276
+ return defineFeature(
277
+ FEATURE_NAME,
278
+ (r) => {
279
+ r.describe(
280
+ 'Registers the `"imap"` provider for `inbound-mail-foundation` using imapflow — password/app-password auth covers classic IMAP hosts without any OAuth (plus an XOAUTH2 fallback consuming an access token from the secret slot). Incremental sync via a UIDVALIDITY:lastUid cursor (UIDVALIDITY change triggers a cursor-invalid full resync), initial backfill bounded by the foundation backfill window, and live push via IMAP IDLE for the watch supervisor. Store the per-account connection JSON (host/port/secure/user/password) in the account credential secret slot before the first sync.',
281
+ );
282
+ r.uiHints({
283
+ displayLabel: "Inbound Mail · IMAP",
284
+ category: "notifications",
285
+ recommended: false,
286
+ });
287
+ r.requires({ features: ["inbound-mail-foundation"] });
288
+ r.requires({ features: ["secrets"] });
289
+ r.envSchema(mailAllowedPrivateHostsEnvSchema);
290
+ r.useExtension(INBOUND_MAIL_PROVIDER_EXTENSION, IMAP_PROVIDER_KEY, imapInboundMailPlugin);
291
+ },
292
+ { dedupeOptions: {} },
278
293
  );
279
- r.uiHints({
280
- displayLabel: "Inbound Mail · IMAP",
281
- category: "notifications",
282
- recommended: false,
283
- });
284
- r.requires({ features: ["inbound-mail-foundation"] });
285
- r.requires({ features: ["secrets"] });
286
- r.envSchema(mailAllowedPrivateHostsEnvSchema);
287
- r.useExtension(INBOUND_MAIL_PROVIDER_EXTENSION, IMAP_PROVIDER_KEY, imapInboundMailPlugin);
288
- });
294
+ }
295
+
296
+ /** @deprecated Use createInboundProviderImapFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
297
+ export const inboundProviderImapFeature = createInboundProviderImapFeature();
@@ -6,7 +6,12 @@ export {
6
6
  type ParseCredentialResult,
7
7
  parseImapCredentialDocument,
8
8
  } from "./credential-document.js";
9
- export { IMAP_PROVIDER_KEY, inboundProviderImapFeature, setImapMailHostLookup } from "./feature.js";
9
+ export {
10
+ createInboundProviderImapFeature,
11
+ IMAP_PROVIDER_KEY,
12
+ inboundProviderImapFeature,
13
+ setImapMailHostLookup,
14
+ } from "./feature.js";
10
15
  export {
11
16
  assertUidValidity,
12
17
  buildProviderMessageId,
@@ -139,16 +139,24 @@ export const inMemoryInboundMailPlugin: InboundMailProviderPlugin = {
139
139
  // =============================================================================
140
140
  // Feature-definition
141
141
  // =============================================================================
142
-
143
- export const inboundProviderInMemoryFeature = defineFeature(FEATURE_NAME, (r) => {
144
- r.describe(
145
- 'Registers a scriptable in-process `"inmemory"` provider for `inbound-mail-foundation`. Seed messages with `seedInboundMessage(accountId, msg)` — an active watch pushes them immediately (IDLE simulation) and the cursor-based `fetch` re-delivers them on the reconciliation path, exercising the foundation dedup guarantee. Error injection via `failNextFetchWith`/`failNextVerifyWith`/`emitWatchError`; reset state with `resetInboundInMemory()`. For tests, demos and sample apps — not for production.',
142
+ export function createInboundProviderInMemoryFeature() {
143
+ return defineFeature(
144
+ FEATURE_NAME,
145
+ (r) => {
146
+ r.describe(
147
+ 'Registers a scriptable in-process `"inmemory"` provider for `inbound-mail-foundation`. Seed messages with `seedInboundMessage(accountId, msg)` — an active watch pushes them immediately (IDLE simulation) and the cursor-based `fetch` re-delivers them on the reconciliation path, exercising the foundation dedup guarantee. Error injection via `failNextFetchWith`/`failNextVerifyWith`/`emitWatchError`; reset state with `resetInboundInMemory()`. For tests, demos and sample apps — not for production.',
148
+ );
149
+ r.uiHints({
150
+ displayLabel: "Inbound Mail · In-Memory Provider",
151
+ category: "notifications",
152
+ recommended: false,
153
+ });
154
+ r.requires({ features: ["inbound-mail-foundation"] });
155
+ r.useExtension("inboundMailProvider", INMEMORY_PROVIDER_KEY, inMemoryInboundMailPlugin);
156
+ },
157
+ { dedupeOptions: {} },
146
158
  );
147
- r.uiHints({
148
- displayLabel: "Inbound Mail · In-Memory Provider",
149
- category: "notifications",
150
- recommended: false,
151
- });
152
- r.requires({ features: ["inbound-mail-foundation"] });
153
- r.useExtension("inboundMailProvider", INMEMORY_PROVIDER_KEY, inMemoryInboundMailPlugin);
154
- });
159
+ }
160
+
161
+ /** @deprecated Use createInboundProviderInMemoryFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
162
+ export const inboundProviderInMemoryFeature = createInboundProviderInMemoryFeature();
@@ -1,6 +1,7 @@
1
1
  // Public API of the inbound-provider-inmemory bundled-feature.
2
2
 
3
3
  export {
4
+ createInboundProviderInMemoryFeature,
4
5
  emitWatchError,
5
6
  failNextFetchWith,
6
7
  failNextVerifyWith,
@@ -10,8 +10,8 @@
10
10
  // deleteManyBatched (typed query API, no raw SQL in this file) chunks each
11
11
  // delete so a large backlog doesn't hold one lock for the whole sweep.
12
12
 
13
- import { deleteManyBatched } from "@cosmicdrift/kumiko-framework/bun-db";
14
13
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
14
+ import { deleteManyBatched } from "@cosmicdrift/kumiko-framework/db";
15
15
  import { jobRunLogsTable, jobRunsTable } from "../../job-run-table.js";
16
16
  import { tenantJobFailuresTable } from "../../tenant-job-failure-table.js";
17
17
  import { tenantJobRunsTable } from "../../tenant-job-run-table.js";
@@ -12,8 +12,8 @@
12
12
  // the run becomes retriable via the existing jobs:write:retry gate
13
13
  // (retry.write.ts only allows retry from "failed").
14
14
 
15
- import { deleteManyBatched, selectMany, updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
16
15
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
16
+ import { deleteManyBatched, selectMany, updateMany } from "@cosmicdrift/kumiko-framework/db";
17
17
  import { mapWithConcurrency } from "../../../shared/index.js";
18
18
  import { DEFAULT_JOB_RUN_RETENTION_DAYS } from "../../handlers/retention-cleanup.job.js";
19
19
  import { encryptFailureError } from "../../job-run-logger.js";
@@ -1,4 +1,4 @@
1
- import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import * as z from "zod";
@@ -1,5 +1,10 @@
1
- import { countWhere, selectMany, type WhereObject } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { decodeCursor, encodeCursor } from "@cosmicdrift/kumiko-framework/db";
1
+ import {
2
+ countWhere,
3
+ decodeCursor,
4
+ encodeCursor,
5
+ selectMany,
6
+ type WhereObject,
7
+ } from "@cosmicdrift/kumiko-framework/db";
3
8
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
4
9
  import { InternalError, ValidationError } from "@cosmicdrift/kumiko-framework/errors";
5
10
  import * as z from "zod";
@@ -1,5 +1,5 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import { isPiiCiphertext, PII_ERASED_SENTINEL } from "@cosmicdrift/kumiko-framework/crypto";
2
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
3
3
  import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
4
4
  import {
5
5
  InternalError,
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { access, defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { serializeJobSubject } from "@cosmicdrift/kumiko-framework/jobs";
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { access, defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { serializeJobSubject } from "@cosmicdrift/kumiko-framework/jobs";
@@ -1,4 +1,14 @@
1
1
  import {
2
+ configuredPiiSubjectKms,
3
+ encryptPiiValueForSubject,
4
+ KeyErasedError,
5
+ type LocalKeyKmsAdapter,
6
+ PII_ERASED_SENTINEL,
7
+ type SubjectId,
8
+ } from "@cosmicdrift/kumiko-framework/crypto";
9
+ import {
10
+ acquireNamespacedAdvisoryLock,
11
+ type DbConnection,
2
12
  deleteMany,
3
13
  fetchOne,
4
14
  insertMany,
@@ -7,16 +17,7 @@ import {
7
17
  transaction,
8
18
  updateMany,
9
19
  upsertOnConflict,
10
- } from "@cosmicdrift/kumiko-framework/bun-db";
11
- import {
12
- configuredPiiSubjectKms,
13
- encryptPiiValueForSubject,
14
- KeyErasedError,
15
- type LocalKeyKmsAdapter,
16
- PII_ERASED_SENTINEL,
17
- type SubjectId,
18
- } from "@cosmicdrift/kumiko-framework/crypto";
19
- import { acquireNamespacedAdvisoryLock, type DbConnection } from "@cosmicdrift/kumiko-framework/db";
20
+ } from "@cosmicdrift/kumiko-framework/db";
20
21
  import { type Registry, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
21
22
  import type {
22
23
  JobDroppedMeta,
@@ -1,9 +1,9 @@
1
- import { requireEntityTableMeta } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import {
3
2
  type EntityTableMeta,
4
3
  index,
5
4
  instant,
6
5
  table as pgTable,
6
+ requireEntityTableMeta,
7
7
  serial,
8
8
  sql,
9
9
  text,
@@ -1,9 +1,9 @@
1
- import { requireEntityTableMeta } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import {
3
2
  type EntityTableMeta,
4
3
  index,
5
4
  instant,
6
5
  table as pgTable,
6
+ requireEntityTableMeta,
7
7
  serial,
8
8
  sql,
9
9
  text,
@@ -151,7 +151,7 @@ function registerLedger(
151
151
  r.queryHandler(createBalanceSheetHandler(access));
152
152
  }
153
153
 
154
- export const ledgerFeature = defineFeature(LEDGER_FEATURE_NAME, (r) =>
154
+ const defaultLedgerFeature = defineFeature(LEDGER_FEATURE_NAME, (r) =>
155
155
  registerLedger(r, DEFAULT_LEDGER_ACCESS, undefined),
156
156
  );
157
157
 
@@ -174,10 +174,13 @@ function resolveAccess(opts: LedgerFeatureOptions): AccessRule {
174
174
 
175
175
  // Options wrapper. Without options returns the module-level singleton (no
176
176
  // rebuild). access/roles/toggleable build a fresh feature-definition.
177
- export function createLedgerFeature(opts: LedgerFeatureOptions = {}): typeof ledgerFeature {
177
+ export function createLedgerFeature(opts: LedgerFeatureOptions = {}): typeof defaultLedgerFeature {
178
178
  if (opts.access === undefined && opts.roles === undefined && opts.toggleable === undefined) {
179
- return ledgerFeature;
179
+ return defaultLedgerFeature;
180
180
  }
181
181
  const access = resolveAccess(opts);
182
182
  return defineFeature(LEDGER_FEATURE_NAME, (r) => registerLedger(r, access, opts.toggleable));
183
183
  }
184
+
185
+ /** @deprecated Use createLedgerFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
186
+ export const ledgerFeature = createLedgerFeature();
@@ -45,6 +45,7 @@ import {
45
45
  type Registry,
46
46
  type TenantId,
47
47
  } from "@cosmicdrift/kumiko-framework/engine";
48
+ import { MAIL_FOUNDATION_I18N } from "./i18n.js";
48
49
 
49
50
  const FEATURE_NAME = "mail-foundation";
50
51
 
@@ -102,6 +103,10 @@ export type MailTransportContext = {
102
103
  */
103
104
  export type MailTransportPlugin = {
104
105
  readonly build: (ctx: MailTransportContext, tenantId: string) => Promise<EmailTransport>;
106
+ /** `false` keeps the provider out of the generated settings: it can still be set by a
107
+ * seed or config write, but a tenant admin is never offered it (e.g. a test inbox
108
+ * that swallows every mail). */
109
+ readonly selectableInSettings?: false;
105
110
  };
106
111
 
107
112
  // extension-usage `options` is engine-payload (unknown) — structurally validate
@@ -120,56 +125,71 @@ declare module "@cosmicdrift/kumiko-framework/engine" {
120
125
  // =============================================================================
121
126
  // Feature-definition
122
127
  // =============================================================================
128
+ export function createMailFoundationFeature() {
129
+ return defineFeature(
130
+ FEATURE_NAME,
131
+ (r) => {
132
+ r.describe(
133
+ "Defines the `mailTransport` extension point and a per-tenant `provider` config key that selects which registered transport plugin to use at runtime. Call `createTransportForTenant(ctx, tenantId)` to get an `EmailTransport` ready for sending \u2014 use this feature together with at least one `mail-transport-*` feature; use `delivery` + `channel-email` instead when you need the full notification pipeline with delivery attempts and user preferences. Pass `tenantMailTransport` as `tenantTransport` to `createChannelEmailFeature`: notifications declared with `tenantTransport: true` then go through the tenant's own transport when it has a provider and through the app transport otherwise. Tenant admins pick the provider and fill in its settings on the generated Email sending settings screen; an empty provider is a valid choice and means the platform sends.",
134
+ );
135
+ r.uiHints({
136
+ displayLabel: "Mail Transport Foundation",
137
+ category: "notifications",
138
+ recommended: false,
139
+ });
140
+ r.requires({ features: ["config"] });
123
141
 
124
- export const mailFoundationFeature = defineFeature(FEATURE_NAME, (r) => {
125
- r.describe(
126
- "Defines the `mailTransport` extension point and a per-tenant `provider` config key that selects which registered transport plugin to use at runtime. Call `createTransportForTenant(ctx, tenantId)` to get an `EmailTransport` ready for sending \u2014 use this feature together with at least one `mail-transport-*` feature; use `delivery` + `channel-email` instead when you need the full notification pipeline with delivery attempts and user preferences. Pass `tenantMailTransport` as `tenantTransport` to `createChannelEmailFeature` so a tenant with a provider configured sends delivery mails through its own transport and other tenants through the app transport.",
127
- );
128
- r.uiHints({
129
- displayLabel: "Mail Transport Foundation",
130
- category: "notifications",
131
- recommended: false,
132
- });
133
- r.requires({ features: ["config"] });
142
+ // Plugin extension-point. Provider-features register here. The
143
+ // entityName at registration time becomes the value tenants pick in
144
+ // `provider` config-key (e.g. "smtp", "brevo-api").
145
+ r.extendsRegistrar(MAIL_TRANSPORT_EXTENSION, {
146
+ onRegister: () => {
147
+ // No side-effects at register-time — the registry stores the
148
+ // usage, factory looks it up at request-time. Same shape as
149
+ // delivery's extendsRegistrar.
150
+ },
151
+ });
134
152
 
135
- // Plugin extension-point. Provider-features register here. The
136
- // entityName at registration time becomes the value tenants pick in
137
- // `provider` config-key (e.g. "smtp", "brevo-api").
138
- r.extendsRegistrar(MAIL_TRANSPORT_EXTENSION, {
139
- onRegister: () => {
140
- // No side-effects at register-time — the registry stores the
141
- // usage, factory looks it up at request-time. Same shape as
142
- // delivery's extendsRegistrar.
143
- },
144
- });
153
+ // Empty = this tenant has no own provider: tenantMailTransport yields null and
154
+ // channel-email uses the app transport, so empty is a valid choice a tenant can
155
+ // return to (reset in the settings mask) and readiness must not flag it.
156
+ // createTransportForTenant still throws on empty.
157
+ const providerConfigKey = r.config(
158
+ "provider",
159
+ createTenantConfig("text", {
160
+ default: "",
161
+ // No SystemAdmin: a platform-level provider would be inherited by every tenant,
162
+ // whose own credentials (tenant secrets) are missing, and break all their mail.
163
+ write: access.withSystem(access.roles("TenantAdmin")),
164
+ read: access.roles("TenantAdmin", "SystemAdmin", "User"),
165
+ mask: {
166
+ title: "mail-foundation.provider",
167
+ description: "mail-foundation.provider.description",
168
+ icon: "mail",
169
+ order: 1,
170
+ },
171
+ }),
172
+ );
173
+ // Readiness gating: transport-plugins' required keys/secrets count only
174
+ // while their plugin is the one this key selects.
175
+ r.extensionSelector(MAIL_TRANSPORT_EXTENSION, providerConfigKey);
145
176
 
146
- // Provider-selector. Default empty so the boot-validator throws if a
147
- // tenant tries to send mail without first picking + setting up a
148
- // provider — better than a silent fallback. The actual list of valid
149
- // values lives in the registered plugins, not here — Designer-UI can
150
- // render `getExtensionUsages("mailTransport").map(u => u.entityName)`
151
- // as the option-list.
152
- const providerConfigKey = r.config(
153
- "provider",
154
- createTenantConfig("text", {
155
- default: "",
156
- // required: ohne gewählten Provider wirft createTransportForTenant —
157
- // readiness meldete vorher ready:true und der erste Mail-Send
158
- // lieferte den UnconfiguredError (280/1).
159
- required: true,
160
- write: access.roles("TenantAdmin", "SystemAdmin"),
161
- read: access.roles("TenantAdmin", "SystemAdmin", "User"),
162
- }),
177
+ r.translations({ keys: MAIL_FOUNDATION_I18N });
178
+
179
+ return {
180
+ /** Config-key-handle for the provider-selector. */
181
+ providerConfigKey,
182
+ };
183
+ },
184
+ { dedupeOptions: {} },
163
185
  );
164
- // Readiness gating: transport-plugins' required keys/secrets count only
165
- // while their plugin is the one this key selects.
166
- r.extensionSelector(MAIL_TRANSPORT_EXTENSION, providerConfigKey);
186
+ }
187
+
188
+ // The typed handles below come from one shared instance; each factory call builds its own handle objects.
189
+ const sharedMailFoundationFeature = createMailFoundationFeature();
167
190
 
168
- return {
169
- /** Config-key-handle for the provider-selector. */
170
- providerConfigKey,
171
- };
172
- });
191
+ /** @deprecated Use createMailFoundationFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
192
+ export const mailFoundationFeature = sharedMailFoundationFeature;
173
193
 
174
194
  // =============================================================================
175
195
  // Transport-factory — looks up the registered plugin + delegates
@@ -224,7 +244,7 @@ export async function createTransportForTenantIfConfigured(
224
244
  }
225
245
 
226
246
  const provider = requireDefined(
227
- await ctxConfig(mailFoundationFeature.exports.providerConfigKey),
247
+ await ctxConfig(sharedMailFoundationFeature.exports.providerConfigKey),
228
248
  FEATURE_NAME,
229
249
  "provider",
230
250
  ) as string; // @cast-boundary engine-payload
@@ -0,0 +1,8 @@
1
+ export const MAIL_FOUNDATION_I18N = {
2
+ "screen:mail-foundation-tenant.title": { en: "Email sending" },
3
+ "mail-foundation.settings": { en: "Email sending" },
4
+ "mail-foundation.provider": { en: "Own mail server" },
5
+ "mail-foundation.provider.description": {
6
+ en: "Without one, the platform sends the mails. Reset the choice to go back to that.",
7
+ },
8
+ } as const;
@@ -8,6 +8,7 @@
8
8
  // when registering via `r.useExtension("mailTransport", ...)`
9
9
 
10
10
  export {
11
+ createMailFoundationFeature,
11
12
  createTransportForTenant,
12
13
  createTransportForTenantIfConfigured,
13
14
  isMailTransportPlugin,
@@ -75,23 +75,37 @@ export function clearInbox(tenantId: string): void {
75
75
  // =============================================================================
76
76
  // Feature-definition
77
77
  // =============================================================================
78
+ export function createMailTransportInMemoryFeature() {
79
+ return defineFeature(
80
+ FEATURE_NAME,
81
+ (r) => {
82
+ r.describe(
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
+ );
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.
89
+ r.requires({ features: ["mail-foundation"] });
78
90
 
79
- export const mailTransportInMemoryFeature = defineFeature(FEATURE_NAME, (r) => {
80
- r.describe(
81
- '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).',
91
+ const plugin: MailTransportPlugin = {
92
+ // Solon and studio mount it next to smtp in production; offering it there would
93
+ // let a tenant admin route every mail into process memory.
94
+ selectableInSettings: false,
95
+ build: async (_ctx: MailTransportContext, tenantId: string): Promise<EmailTransport> => {
96
+ // Returns the per-tenant buffer. Identity-stable across calls so the
97
+ // demo inbox keeps accumulating.
98
+ return getOrCreateTransportForTenant(tenantId);
99
+ }, // @wrapper-known semantic-alias
100
+ };
101
+ r.useExtension(MAIL_TRANSPORT_EXTENSION, "inmemory", plugin);
102
+ r.translations({
103
+ keys: { "mail-transport-inmemory.settings": { en: "Test inbox (in memory)" } },
104
+ });
105
+ },
106
+ { dedupeOptions: {} },
82
107
  );
83
- // Kein requires auf "config" oder "secrets" — der
84
- // In-Memory-Transport hat keine Config (nichts zu konfigurieren) und
85
- // kein Secret. Der einzige hard-require ist mail-foundation, das den
86
- // extension-point "mailTransport" definiert.
87
- r.requires({ features: ["mail-foundation"] });
108
+ }
88
109
 
89
- const plugin: MailTransportPlugin = {
90
- build: async (_ctx: MailTransportContext, tenantId: string): Promise<EmailTransport> => {
91
- // Returnt den per-tenant Buffer. Identitätsstabil zwischen calls
92
- // damit die Demo-Inbox accumulated bleibt.
93
- return getOrCreateTransportForTenant(tenantId);
94
- }, // @wrapper-known semantic-alias
95
- };
96
- r.useExtension(MAIL_TRANSPORT_EXTENSION, "inmemory", plugin);
97
- });
110
+ /** @deprecated Use createMailTransportInMemoryFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
111
+ export const mailTransportInMemoryFeature = createMailTransportInMemoryFeature();
@@ -1,3 +1,8 @@
1
1
  // Public API of the mail-transport-inmemory bundled-feature.
2
2
 
3
- export { clearInbox, getInbox, mailTransportInMemoryFeature } from "./feature.js";
3
+ export {
4
+ clearInbox,
5
+ createMailTransportInMemoryFeature,
6
+ getInbox,
7
+ mailTransportInMemoryFeature,
8
+ } from "./feature.js";
@@ -1,4 +1,11 @@
1
1
  [
2
+ {
3
+ "version": "0.369.0",
4
+ "type": "breaking",
5
+ "title": "Tenant admins edit their own SMTP server on the Email sending screen",
6
+ "detail": "mail-foundation's provider key and the SMTP keys (host, port, SSL/TLS, user name, sender address) carry settings masks, so the generated Settings-Hub shows tenant admins one Email sending form: the provider choice, the chosen provider's connection fields and its password, each field with a help text and every label in English, German and Spanish, saved together by one Save button in one /api/batch. Switching the provider swaps the fields at once; fields of a provider that is not selected are not saved. A selector owner's selection screen (`<owner>-tenant-selection`) now carries the plugins' config keys (field id `<owner>-<key>`) and secrets (field id `<plugin>-<key>`, listed in the new ConfigEditScreenDefinition.secretKeys) behind a visible condition on the provider field; the separate `<plugin>-tenant` and `<plugin>-tenant-secrets` screens and their dashboard panels are gone, and so is the `config.settings.saveProvider` label. A secret with its own writeRoles stays on the global secrets screen. Boot validation checks every secretKeys field (tenant scope, writeOnly text, declared secret). The configEdit renderer loads secretKeys fields from secrets:query:list (set or unset, no preview), writes them with secrets:write:set or secrets:write:delete in the same batch, and leaves hidden fields out. The provider key is no longer required: empty means the tenant has no own server and the platform sends, so readiness no longer reports it as missing (createTransportForTenant still throws on an empty provider). The provider and SMTP keys are written by TenantAdmin and the system identity, no longer by SystemAdmin, because a platform-level provider would reach every tenant without that tenant's password. The secrets set and delete handlers also admit the system identity, so server code stores a tenant secret via dispatchSystemWrite through the same key and value checks as an admin; the settings screens keep showing only the human roles. The provider choice shows each plugin's `<feature>.settings` name, also for a plugin without settings of its own, and keeps the English name when a locale feature mounted earlier declares the same key in its own language only. A MailTransportPlugin with `selectableInSettings: false` stays allowed on the server but is not offered in the form; the in-memory transport sets it, because apps mount it next to smtp in production and a tenant admin picking it would drop every mail. A plugin's secrets section takes an optional `<feature>.settings.secrets` title (SMTP password under \"SMTP sign-in\").",
7
+ "migration": "E2E specs that used the testIds `dashboard-panel-<plugin>-tenant`, `dashboard-panel-<plugin>-tenant-secrets` or the separate secret input of these screens address the fields of `<owner>-tenant-selection` instead (one Save). Code that wrote these keys as a SystemAdmin user writes them as the tenant's TenantAdmin or via dispatchSystemWrite. Apps that relied on readiness flagging an empty provider check it themselves."
8
+ },
2
9
  {
3
10
  "version": "0.326.1",
4
11
  "type": "fix",
@@ -0,0 +1,67 @@
1
+ import { access, createTenantConfig } from "@cosmicdrift/kumiko-framework/engine";
2
+
3
+ // No SystemAdmin write: the password is a tenant secret, so platform-level SMTP keys
4
+ // could never form a working transport (see mail-foundation's provider key).
5
+ const tenantAdminWrite = access.withSystem(access.roles("TenantAdmin"));
6
+ const tenantAdminRead = access.roles("TenantAdmin", "SystemAdmin");
7
+
8
+ // required: true ↔ the requireNonEmpty calls in buildSmtpTransport — keep in sync.
9
+ export const SMTP_CONFIG_KEYS = {
10
+ host: createTenantConfig("text", {
11
+ required: true,
12
+ default: "",
13
+ write: tenantAdminWrite,
14
+ read: tenantAdminRead,
15
+ mask: {
16
+ title: "mail-transport-smtp.host",
17
+ description: "mail-transport-smtp.host.description",
18
+ icon: "server",
19
+ order: 1,
20
+ },
21
+ }),
22
+ port: createTenantConfig("number", {
23
+ default: 587,
24
+ bounds: { min: 1, max: 65535 },
25
+ write: tenantAdminWrite,
26
+ mask: {
27
+ title: "mail-transport-smtp.port",
28
+ description: "mail-transport-smtp.port.description",
29
+ icon: "hash",
30
+ order: 2,
31
+ },
32
+ }),
33
+ secure: createTenantConfig("boolean", {
34
+ default: false,
35
+ write: tenantAdminWrite,
36
+ mask: {
37
+ title: "mail-transport-smtp.secure",
38
+ description: "mail-transport-smtp.secure.description",
39
+ icon: "lock",
40
+ order: 3,
41
+ },
42
+ }),
43
+ authUser: createTenantConfig("text", {
44
+ required: true,
45
+ default: "",
46
+ write: tenantAdminWrite,
47
+ read: tenantAdminRead,
48
+ mask: {
49
+ title: "mail-transport-smtp.authUser",
50
+ description: "mail-transport-smtp.authUser.description",
51
+ icon: "user",
52
+ order: 4,
53
+ },
54
+ }),
55
+ from: createTenantConfig("text", {
56
+ required: true,
57
+ default: "",
58
+ write: tenantAdminWrite,
59
+ read: tenantAdminRead,
60
+ mask: {
61
+ title: "mail-transport-smtp.from",
62
+ description: "mail-transport-smtp.from.description",
63
+ icon: "mail",
64
+ order: 5,
65
+ },
66
+ }),
67
+ };