@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
@@ -6,6 +6,7 @@ import {
6
6
  type AttachmentOrigin,
7
7
  type ChannelContext,
8
8
  type ChannelMessage,
9
+ currentNotificationType,
9
10
  DELIVERY_UNSUBSCRIBE_ONE_CLICK_HEADER_VALUE,
10
11
  DELIVERY_UNSUBSCRIBE_PATH,
11
12
  type DeliveryChannel,
@@ -163,18 +164,36 @@ async function resolveAttachments(
163
164
  return { kind: "resolved", attachments: resolved };
164
165
  }
165
166
 
166
- export type EmailChannelOptions = {
167
- /** The app-wide transport, used for every tenant `tenantTransport` returns null for. */
168
- readonly transport: EmailTransport;
169
- /** Resolves the sending tenant's own transport, null when it has none. Built per send and
170
- * never cached, so a provider change applies to the next mail; a throw fails the send. */
171
- readonly tenantTransport?: (ctx: ChannelContext) => Promise<EmailTransport | null>;
167
+ /** Resolves the sending tenant's own transport, null when it has none. Built per send and
168
+ * never cached, so a provider change applies to the next mail; a throw fails the send. */
169
+ export type TenantTransportResolver = (ctx: ChannelContext) => Promise<EmailTransport | null>;
170
+
171
+ // The app transport may only be left out when tenant transports exist: a channel with
172
+ // neither could never send.
173
+ type EmailChannelTransports =
174
+ | {
175
+ /** The app-wide transport for every mail that does not go through a tenant transport. */
176
+ readonly transport: EmailTransport;
177
+ /** Used only for notifications declared with `tenantTransport: true`. */
178
+ readonly tenantTransport?: TenantTransportResolver;
179
+ }
180
+ | {
181
+ readonly transport?: undefined;
182
+ readonly tenantTransport: TenantTransportResolver;
183
+ };
184
+
185
+ export type EmailChannelOptions = EmailChannelTransports & {
172
186
  readonly resolveEmail: (
173
187
  userId: string,
174
188
  ctx: { db: unknown; tenantId: TenantId },
175
189
  ) => Promise<string | null>;
176
190
  };
177
191
 
192
+ function isTenantTransportNotification(ctx: ChannelContext, notificationType: string): boolean {
193
+ const current = currentNotificationType(ctx.registry, notificationType);
194
+ return ctx.registry.getAllNotifications().get(current)?.tenantTransport === true;
195
+ }
196
+
178
197
  export function createEmailChannel(options: EmailChannelOptions): DeliveryChannel {
179
198
  const { transport, resolveEmail, tenantTransport } = options;
180
199
 
@@ -213,8 +232,12 @@ export function createEmailChannel(options: EmailChannelOptions): DeliveryChanne
213
232
  };
214
233
  }
215
234
 
216
- async function transportFor(ctx: ChannelContext): Promise<EmailTransport> {
235
+ async function transportFor(
236
+ message: ChannelMessage,
237
+ ctx: ChannelContext,
238
+ ): Promise<EmailTransport | undefined> {
217
239
  if (tenantTransport === undefined) return transport;
240
+ if (!isTenantTransportNotification(ctx, message.notificationType)) return transport;
218
241
  return (await tenantTransport(ctx)) ?? transport;
219
242
  }
220
243
 
@@ -260,7 +283,15 @@ export function createEmailChannel(options: EmailChannelOptions): DeliveryChanne
260
283
  return { status: "failed", error: "send_failed", address };
261
284
  }
262
285
  const resolvedAttachments = resolution.attachments;
263
- const sendTransport = await transportFor(ctx);
286
+ const sendTransport = await transportFor(message, ctx);
287
+ if (sendTransport === undefined) {
288
+ // Configuration, not a transient error: a retry cannot conjure a transport.
289
+ createFallbackLogger("delivery").warn("no mail transport for this mail, send failed", {
290
+ tenantId: ctx.tenantId,
291
+ notificationType: message.notificationType,
292
+ });
293
+ return { status: "failed", error: "missing_credentials", address };
294
+ }
264
295
  await sendTransport.send(
265
296
  guardEmailMessage({
266
297
  to: address,
@@ -10,7 +10,7 @@ export function createChannelEmailFeature(options: EmailChannelOptions): Feature
10
10
 
11
11
  return defineFeature("channel-email", (r) => {
12
12
  r.describe(
13
- "Wires an `EmailTransport` (typically `mail-transport-smtp` in production, `createInMemoryTransport()` in tests) into the delivery system as the `email` channel. Requires `delivery`; pass an `EmailChannelOptions` with a `transport` and a `resolveEmail` function that maps a user ID to their email address. Mails render from stored templates (`renderer-mail-html`): a notification routed to this channel needs `template` + `meta` on `r.notification`, otherwise its delivery fails. Pass `tenantTransport: tenantMailTransport` (from `mail-foundation`) to send each tenant's mail through its own configured provider: a broken provider fails the send, a tenant without one uses the app `transport`. Notifications declared with `unsubscribe: true` get a signed `data.unsubscribeUrl` from delivery, which turns into the `List-Unsubscribe` headers.",
13
+ "Wires an `EmailTransport` (typically `mail-transport-smtp` in production, `createInMemoryTransport()` in tests) into the delivery system as the `email` channel. Requires `delivery`; pass an `EmailChannelOptions` with a `transport` and a `resolveEmail` function that maps a user ID to their email address. Mails render from stored templates (`renderer-mail-html`): a notification routed to this channel needs `template` + `meta` on `r.notification`, otherwise its delivery fails. Pass `tenantTransport: tenantMailTransport` (from `mail-foundation`) to send the notifications declared with `tenantTransport: true` through the sending tenant's own configured provider: a broken provider fails the send, a tenant without one uses the app `transport`; every other notification (password reset, sign-in) always goes through the app `transport`. `transport` may be left out when `tenantTransport` is set; a mail that then has no transport fails with `missing_credentials`. Notifications declared with `unsubscribe: true` get a signed `data.unsubscribeUrl` from delivery, which turns into the `List-Unsubscribe` headers.",
14
14
  );
15
15
  r.uiHints({
16
16
  displayLabel: "Email Channel",
@@ -1,4 +1,8 @@
1
- export { createEmailChannel, type EmailChannelOptions } from "./email-channel.js";
1
+ export {
2
+ createEmailChannel,
3
+ type EmailChannelOptions,
4
+ type TenantTransportResolver,
5
+ } from "./email-channel.js";
2
6
  export { createChannelEmailFeature } from "./feature.js";
3
7
  export { guardEmailMessage, withPiiCiphertextGuard } from "./pii-guard.js";
4
8
  export {
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { inAppMessagesTable } from "../tables.js";
@@ -1,4 +1,4 @@
1
- import { updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { updateMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { inAppMessagesTable } from "../tables.js";
@@ -1,4 +1,4 @@
1
- import { updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { updateMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { NotFoundError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import * as z from "zod";
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { inAppMessagesTable } from "../tables.js";
@@ -1,10 +1,10 @@
1
- import { requireEntityTableMeta } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import {
3
2
  boolean,
4
3
  type EntityTableMeta,
5
4
  index,
6
5
  instant,
7
6
  table as pgTable,
7
+ requireEntityTableMeta,
8
8
  serial,
9
9
  sql,
10
10
  text,
@@ -1,9 +1,9 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import {
3
2
  type ComplianceProfileKey,
4
3
  type EffectiveComplianceProfile,
5
4
  resolveComplianceProfile,
6
5
  } from "@cosmicdrift/kumiko-framework/compliance";
6
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
7
7
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
8
8
  import * as z from "zod";
9
9
  import { parseComplianceProfileOverride } from "../_internal/parse-override.js";
@@ -1,6 +1,6 @@
1
1
  import { ROLES } from "@cosmicdrift/kumiko-framework/auth";
2
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
3
2
  import type { ComplianceProfileKey } from "@cosmicdrift/kumiko-framework/compliance";
3
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
4
4
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
5
5
  import * as z from "zod";
6
6
  import { tenantComplianceProfileTable } from "../schema/profile-selection.js";
@@ -1,9 +1,8 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import {
3
2
  complianceProfileOverrideSchema,
4
3
  SELECTABLE_PROFILE_KEYS,
5
4
  } from "@cosmicdrift/kumiko-framework/compliance";
6
- import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
5
+ import { createEventStoreExecutor, fetchOne } from "@cosmicdrift/kumiko-framework/db";
7
6
  import { access, defineWriteHandler, type TenantId } from "@cosmicdrift/kumiko-framework/engine";
8
7
  import {
9
8
  UnprocessableError,
@@ -8,13 +8,13 @@
8
8
  // Beide Pfade nutzen `resolveComplianceProfile` aus framework/compliance,
9
9
  // also kein Drift zwischen Query-API und Worker-Pfad.
10
10
 
11
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
12
11
  import {
13
12
  type ComplianceProfileKey,
14
13
  type EffectiveComplianceProfile,
15
14
  resolveComplianceProfile,
16
15
  } from "@cosmicdrift/kumiko-framework/compliance";
17
16
  import type { DbRunner, TenantDb } from "@cosmicdrift/kumiko-framework/db";
17
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
18
18
  import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
19
19
  import { isTenantDb } from "../shared/index.js";
20
20
  import { parseComplianceProfileOverride } from "./_internal/parse-override.js";
@@ -10,7 +10,6 @@
10
10
  //
11
11
  // Pattern matched seedTextBlock aus text-content.
12
12
 
13
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
14
13
  import type {
15
14
  ComplianceProfileKey,
16
15
  ComplianceProfileOverride,
@@ -19,10 +18,15 @@ import {
19
18
  createEventStoreExecutor,
20
19
  createTenantDb,
21
20
  type DbConnection,
21
+ fetchOne,
22
22
  } from "@cosmicdrift/kumiko-framework/db";
23
23
  import type { SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
24
- import { runEventStoreSeed, type SeedIfExists } from "@cosmicdrift/kumiko-framework/seeding";
25
- import { TestUsers } from "@cosmicdrift/kumiko-framework/stack";
24
+ import {
25
+ runEventStoreSeed,
26
+ type SeedIfExists,
27
+ TestUsers,
28
+ } from "@cosmicdrift/kumiko-framework/seeding";
29
+
26
30
  import {
27
31
  tenantComplianceProfileEntity,
28
32
  tenantComplianceProfileTable,
@@ -50,7 +54,7 @@ export async function seedComplianceProfile(
50
54
  // + Projection im selben Tenant-Bucket landen (Memory:
51
55
  // feedback_event_store_tenant_consistency).
52
56
  const by = opts.by ?? { ...TestUsers.systemAdmin, tenantId: opts.tenantId };
53
- const tdb = createTenantDb(db, opts.tenantId, "system");
57
+ const tdb = createTenantDb({ db, tenantId: opts.tenantId, mode: "system" });
54
58
  const overrideJson = opts.override !== undefined ? JSON.stringify(opts.override) : null;
55
59
 
56
60
  const existing = (await fetchOne(db, tenantComplianceProfileTable, {
@@ -13,22 +13,31 @@
13
13
  import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
14
14
  import { tenantsMissingProfileQuery } from "./handlers/tenants-missing-profile.query.js";
15
15
 
16
- export const complianceProfilesOpsFeature = defineFeature("compliance-profiles-ops", (r) => {
17
- r.describe(
18
- "Platform-wide SystemAdmin counterpart to `compliance-profiles`' `needs-profile` query (#2089): `tenants-missing-profile` lists every enabled tenant with no row in `tenantComplianceProfile` at all, tenant-wide instead of scoped to the caller's own tenant. Mount alongside `compliance-profiles` and `tenant` when an operator UI needs to see which tenants still silently run on `minimal-no-region`.",
19
- );
20
- r.uiHints({
21
- displayLabel: "Compliance Profiles · Operator Visibility",
22
- category: "compliance",
23
- recommended: false,
24
- });
25
- r.systemScope();
26
- r.requires({ features: ["compliance-profiles"] });
27
- r.requires({ features: ["tenant"] });
16
+ export function createComplianceProfilesOpsFeature() {
17
+ return defineFeature(
18
+ "compliance-profiles-ops",
19
+ (r) => {
20
+ r.describe(
21
+ "Platform-wide SystemAdmin counterpart to `compliance-profiles`' `needs-profile` query (#2089): `tenants-missing-profile` lists every enabled tenant with no row in `tenantComplianceProfile` at all, tenant-wide instead of scoped to the caller's own tenant. Mount alongside `compliance-profiles` and `tenant` when an operator UI needs to see which tenants still silently run on `minimal-no-region`.",
22
+ );
23
+ r.uiHints({
24
+ displayLabel: "Compliance Profiles · Operator Visibility",
25
+ category: "compliance",
26
+ recommended: false,
27
+ });
28
+ r.systemScope();
29
+ r.requires({ features: ["compliance-profiles"] });
30
+ r.requires({ features: ["tenant"] });
31
+
32
+ const queries = {
33
+ tenantsMissingProfile: r.queryHandler(tenantsMissingProfileQuery),
34
+ };
28
35
 
29
- const queries = {
30
- tenantsMissingProfile: r.queryHandler(tenantsMissingProfileQuery),
31
- };
36
+ return { queries };
37
+ },
38
+ { dedupeOptions: {} },
39
+ );
40
+ }
32
41
 
33
- return { queries };
34
- });
42
+ /** @deprecated Use createComplianceProfilesOpsFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
43
+ export const complianceProfilesOpsFeature = createComplianceProfilesOpsFeature();
@@ -1,5 +1,5 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbRunner, TenantDb } from "@cosmicdrift/kumiko-framework/db";
2
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
3
3
  import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
4
4
  import { configValuesTable } from "../../table.js";
5
5
 
@@ -125,7 +125,7 @@ export const reencryptJob: JobHandlerFn = async (rawPayload, ctx): Promise<void>
125
125
  function tdbFor(tenantId: TenantId): TenantDb {
126
126
  let existing = tdbCache.get(tenantId);
127
127
  if (!existing) {
128
- existing = createTenantDb(db, tenantId, "system");
128
+ existing = createTenantDb({ db, tenantId, mode: "system" });
129
129
  tdbCache.set(tenantId, existing);
130
130
  }
131
131
  return existing;
@@ -146,7 +146,7 @@ export const reencryptJob: JobHandlerFn = async (rawPayload, ctx): Promise<void>
146
146
  // tenant's writes — sharing it with sdbFor(SYSTEM_TENANT_ID) would make a
147
147
  // write-path cache entry double as the scan's ack gate.
148
148
  const scanDb = createSystemDbView(
149
- createTenantDb(db, SYSTEM_TENANT_ID, "system"),
149
+ createTenantDb({ db, tenantId: SYSTEM_TENANT_ID, mode: "system" }),
150
150
  undefined,
151
151
  reportEscapeHatchFor(SYSTEM_TENANT_ID),
152
152
  );
@@ -1,11 +1,11 @@
1
1
  import { requestContext } from "@cosmicdrift/kumiko-framework/api";
2
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
3
2
  import {
4
3
  configuredPiiSubjectKms,
5
4
  decryptPiiValueForSubject,
6
5
  type KmsContext,
7
6
  } from "@cosmicdrift/kumiko-framework/crypto";
8
7
  import type { DbConnection, TenantDb } from "@cosmicdrift/kumiko-framework/db";
8
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
9
9
  import type {
10
10
  ConfigCascade,
11
11
  ConfigCascadeLevel,
@@ -32,9 +32,8 @@ export const defaultTranslations: TranslationsByLocale = {
32
32
  "config.errors.unknownKey": "Unknown configuration key.",
33
33
  "config.errors.unknownExtensionPlugin": "This provider is not available.",
34
34
  "config.settings.extensionSelectorHint":
35
- "Choose a provider and save. Its settings appear below.",
35
+ "Choose a provider. Its settings appear below and are saved together with it.",
36
36
  "config.settings.provider": "Provider",
37
- "config.settings.saveProvider": "Save provider",
38
37
  "config.settings.audience.system":
39
38
  "Applies to every tenant unless a tenant sets its own value.",
40
39
  "config.settings.audience.tenant":
@@ -2,9 +2,9 @@
2
2
  // Extracted from set.write.ts so reset.write.ts + values.query.ts don't
3
3
  // have to cross-import from another handler file.
4
4
 
5
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
6
5
  import type { SubjectId } from "@cosmicdrift/kumiko-framework/crypto";
7
6
  import type { DbConnection, TenantDb } from "@cosmicdrift/kumiko-framework/db";
7
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
8
8
  import {
9
9
  type ConfigKeyDefinition,
10
10
  type ConfigScope,
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.368.0",
4
+ "type": "fix",
5
+ "title": "forget-subject closes the login door for users whose stream is already deleted",
6
+ "detail": "forget-subject returned 500 (\"user lifecycle update failed ... not_found\") when the user stream was deleted but the read_users status still read active, leaving sessions and PATs alive. The erasure now appends the status-deleted user.updated event to that stream too, so the login door closes, the handler returns 200 and a read_users rebuild keeps the state."
7
+ },
2
8
  {
3
9
  "version": "0.366.0",
4
10
  "type": "fix",
@@ -1,11 +1,6 @@
1
1
  import { requestContext } from "@cosmicdrift/kumiko-framework/api";
2
2
  import { ROLES } from "@cosmicdrift/kumiko-framework/auth";
3
- import {
4
- fetchOne,
5
- runInSavepointIfSupported,
6
- runnerCanBeginTransaction,
7
- transaction,
8
- } from "@cosmicdrift/kumiko-framework/bun-db";
3
+
9
4
  import {
10
5
  computeBlindIndex,
11
6
  configuredBlindIndexKey,
@@ -16,11 +11,15 @@ import {
16
11
  } from "@cosmicdrift/kumiko-framework/crypto";
17
12
  import {
18
13
  type DbRunner,
14
+ fetchOne,
19
15
  nullBlindIndexesForSubject,
20
16
  recordEventsOwnedExclusivelyByTenant,
21
17
  recordRowExistsInTenant,
22
18
  recordRowOwningTenantId,
19
+ runInSavepointIfSupported,
20
+ runnerCanBeginTransaction,
23
21
  subjectRowExistsInTenant,
22
+ transaction,
24
23
  WritePurposes,
25
24
  } from "@cosmicdrift/kumiko-framework/db";
26
25
  import {
@@ -365,7 +364,10 @@ async function closeUserLoginDoor(
365
364
  runner,
366
365
  userId,
367
366
  { status: USER_STATUS.Deleted },
368
- { writePurpose: WritePurposes.erasure },
367
+ // includeDeleted: a user whose stream is already deleted but whose status
368
+ // still reads active would otherwise fail with not_found (500) and keep
369
+ // sessions and PATs alive.
370
+ { writePurpose: WritePurposes.erasure, includeDeleted: true },
369
371
  );
370
372
  if (ctx.registry.features.has("personal-access-tokens")) {
371
373
  await revokeAllPatTokensForUser(runner, userId);
@@ -1,5 +1,5 @@
1
- import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
2
+ import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/db";
3
3
 
4
4
  export async function selectSerializedFieldDefinition(
5
5
  runner: DbRunner,
@@ -1,5 +1,5 @@
1
- import { asRawClient } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
2
+ import { asRawClient } from "@cosmicdrift/kumiko-framework/db";
3
3
  import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
4
4
 
5
5
  function quoteTable(tableName: string): string {
@@ -1,5 +1,5 @@
1
- import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
2
+ import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/db";
3
3
 
4
4
  export async function countTenantFieldDefinitions(
5
5
  runner: DbRunner,
@@ -1,5 +1,9 @@
1
- import { asRawClient, unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { type DbRunner, toPostgresArrayLiteral } from "@cosmicdrift/kumiko-framework/db";
1
+ import {
2
+ asRawClient,
3
+ type DbRunner,
4
+ toPostgresArrayLiteral,
5
+ unsafeReadRetrying,
6
+ } from "@cosmicdrift/kumiko-framework/db";
3
7
 
4
8
  export async function selectHostRowsWithCustomFields(
5
9
  db: DbRunner,
@@ -1,5 +1,5 @@
1
- import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
2
+ import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/db";
3
3
 
4
4
  function quoteTable(tableName: string): string {
5
5
  return `"${tableName.replace(/"/g, '""')}"`;
@@ -33,7 +33,7 @@
33
33
  // `customFieldsField()` (jsonb) deklarieren.
34
34
  //
35
35
  // **Exports-Pattern (2026-05-23 refactor)**:
36
- // `customFieldsFeature.exports.{setEvent,clearedEvent,fieldDefinitionDeletedEvent}`
36
+ // `createCustomFieldsFeature().exports.{setEvent,clearedEvent,fieldDefinitionDeletedEvent}`
37
37
  // liefern typed EventDef-handles. Handler + wire-for-entity nutzen
38
38
  // `<event>.name` als compile-time-literal-typed qualified-string — keine
39
39
  // hand-gebauten Template-Literals mehr (T1 hat den toKebab-collapse-drift
@@ -179,12 +179,9 @@ function registerCustomFields(
179
179
  return { setEvent, clearedEvent, fieldDefinitionDeletedEvent };
180
180
  }
181
181
 
182
- // Singleton feature-definition mit typed exports. Handler + wire-for-entity
183
- // importieren diesen `customFieldsFeature` und greifen lazy in ihrer
184
- // runtime-arrow-fn auf `.exports.<event>.name` zu — der module-cycle
185
- // (feature.ts -> handlers/*.write.ts -> feature.ts) löst sich auf weil
186
- // kein top-level-access stattfindet.
187
- export const customFieldsFeature = defineFeature(CUSTOM_FIELDS_FEATURE_NAME, (r) =>
182
+ // Handlers and wire-for-entity read `.exports.<event>.name` lazily inside their runtime
183
+ // arrow functions, which resolves the module cycle (feature.ts -> handlers/*.write.ts -> feature.ts).
184
+ const defaultCustomFieldsFeature = defineFeature(CUSTOM_FIELDS_FEATURE_NAME, (r) =>
188
185
  registerCustomFields(r, {
189
186
  defineTenantHandler: defineTenantFieldHandler,
190
187
  updateTenantHandler: updateTenantFieldHandler,
@@ -246,21 +243,18 @@ export function resolveFieldDefinitionListRoles(
246
243
  ];
247
244
  }
248
245
 
249
- // Backwards-compat-wrapper. Bestehende Caller (z.B. integration-tests,
250
- // host-apps) nutzen weiterhin `createCustomFieldsFeature()`. Returnt den
251
- // module-level-Singleton — kein neuer build pro Aufruf, was für consumer
252
- // nicht erkennbar ist (read-only inspection). Jede gesetzte Option baut
253
- // eine frische Feature-Definition mit den Varianten-Handlern.
246
+ // Without options this returns the module-level singleton (no rebuild per call); every
247
+ // option builds a fresh feature definition with the variant handlers.
254
248
  export function createCustomFieldsFeature(
255
249
  opts: CustomFieldsFeatureOptions = {},
256
- ): typeof customFieldsFeature {
250
+ ): typeof defaultCustomFieldsFeature {
257
251
  const hasOptions =
258
252
  opts.fieldDefinitionLimitPerTenant !== undefined ||
259
253
  opts.valueWriteRoles !== undefined ||
260
254
  opts.fieldDefinitionListRoles !== undefined ||
261
255
  opts.fieldDefinitionWriteRoles !== undefined;
262
256
  if (!hasOptions) {
263
- return customFieldsFeature;
257
+ return defaultCustomFieldsFeature;
264
258
  }
265
259
  const limit = opts.fieldDefinitionLimitPerTenant;
266
260
  const definitionWriteRoles = opts.fieldDefinitionWriteRoles;
@@ -287,3 +281,6 @@ export function createCustomFieldsFeature(
287
281
  }),
288
282
  );
289
283
  }
284
+
285
+ /** @deprecated Use createCustomFieldsFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
286
+ export const customFieldsFeature = createCustomFieldsFeature();
@@ -2,7 +2,7 @@ import type { WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import { failNotFound, failUnprocessable } from "@cosmicdrift/kumiko-framework/errors";
3
3
  import * as z from "zod";
4
4
  import { DEFAULT_VALUE_WRITE_ROLES } from "../constants.js";
5
- import { customFieldsFeature } from "../feature.js";
5
+ import { createCustomFieldsFeature } from "../feature.js";
6
6
  import { checkFieldAccessForWrite } from "../lib/field-access.js";
7
7
 
8
8
  export const clearCustomFieldPayloadSchema = z.object({
@@ -62,7 +62,7 @@ export const clearCustomFieldHandler: WriteHandlerDef = {
62
62
  await ctx.unsafeAppendEvent({
63
63
  aggregateId: payload.entityId,
64
64
  aggregateType: payload.entityName,
65
- type: customFieldsFeature.exports.clearedEvent.name,
65
+ type: createCustomFieldsFeature().exports.clearedEvent.name,
66
66
  payload: { fieldKey: payload.fieldKey },
67
67
  });
68
68
 
@@ -3,7 +3,7 @@ import { requireForTenant } from "../../shared/index.js";
3
3
  import { fieldDefinitionAggregateId } from "../aggregate-id.js";
4
4
  import { FIELD_DEFINITION_AGGREGATE_TYPE } from "../constants.js";
5
5
  import { fieldDefinitionExecutor } from "../executor.js";
6
- import { customFieldsFeature } from "../feature.js";
6
+ import { createCustomFieldsFeature } from "../feature.js";
7
7
  import { type DeleteFieldPayload, deleteFieldPayloadSchema } from "../schemas.js";
8
8
 
9
9
  // delete-system-field — SystemAdmin entfernt eine system-weite Field-
@@ -38,7 +38,7 @@ export const deleteSystemFieldHandler: WriteHandlerDef = {
38
38
  await ctx.unsafeAppendEvent({
39
39
  aggregateId,
40
40
  aggregateType: FIELD_DEFINITION_AGGREGATE_TYPE,
41
- type: customFieldsFeature.exports.fieldDefinitionDeletedEvent.name,
41
+ type: createCustomFieldsFeature().exports.fieldDefinitionDeletedEvent.name,
42
42
  payload: {
43
43
  entityName: payload.entityName,
44
44
  fieldKey: payload.fieldKey,
@@ -5,7 +5,7 @@ import {
5
5
  FIELD_DEFINITION_AGGREGATE_TYPE,
6
6
  } from "../constants.js";
7
7
  import { fieldDefinitionExecutor } from "../executor.js";
8
- import { customFieldsFeature } from "../feature.js";
8
+ import { createCustomFieldsFeature } from "../feature.js";
9
9
  import { type DeleteFieldPayload, deleteFieldPayloadSchema } from "../schemas.js";
10
10
 
11
11
  // delete-tenant-field — TenantAdmin löscht eigene Field-Definition.
@@ -59,7 +59,7 @@ export function createDeleteTenantFieldHandler(
59
59
  await ctx.unsafeAppendEvent({
60
60
  aggregateId,
61
61
  aggregateType: FIELD_DEFINITION_AGGREGATE_TYPE,
62
- type: customFieldsFeature.exports.fieldDefinitionDeletedEvent.name,
62
+ type: createCustomFieldsFeature().exports.fieldDefinitionDeletedEvent.name,
63
63
  payload: { entityName: payload.entityName, fieldKey: payload.fieldKey, tenantId },
64
64
  });
65
65
  }
@@ -2,7 +2,7 @@ import type { WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import { failNotFound, failUnprocessable } from "@cosmicdrift/kumiko-framework/errors";
3
3
  import * as z from "zod";
4
4
  import { DEFAULT_VALUE_WRITE_ROLES } from "../constants.js";
5
- import { customFieldsFeature } from "../feature.js";
5
+ import { createCustomFieldsFeature } from "../feature.js";
6
6
  import { fieldWriteAccessDeniedRoles, loadFieldDefinition } from "../lib/field-access.js";
7
7
  import { buildCustomFieldValueSchema } from "../lib/value-schema.js";
8
8
 
@@ -103,7 +103,7 @@ export const setCustomFieldHandler: WriteHandlerDef = {
103
103
  await ctx.unsafeAppendEvent({
104
104
  aggregateId: payload.entityId,
105
105
  aggregateType: payload.entityName,
106
- type: customFieldsFeature.exports.setEvent.name,
106
+ type: createCustomFieldsFeature().exports.setEvent.name,
107
107
  payload: { fieldKey: payload.fieldKey, value: payload.value },
108
108
  });
109
109
 
@@ -16,7 +16,7 @@ import {
16
16
  } from "./db/queries/projection.js";
17
17
 
18
18
  import type { CustomFieldClearedPayload, CustomFieldSetPayload } from "./events.js";
19
- import { customFieldsFeature } from "./feature.js";
19
+ import { createCustomFieldsFeature } from "./feature.js";
20
20
 
21
21
  // Helper für entity-definitions — fügt eine `customFields jsonb`-Spalte
22
22
  // hinzu. Consumer:
@@ -90,9 +90,9 @@ export function wireCustomFieldsFor<TReg extends FeatureRegistrar<string>>(
90
90
  // Qualified event-type-names — sourced from typed EventDef.name handles
91
91
  // (compile-time literal-typed, no Template-Literal-Drift à la toKebab-
92
92
  // collapse-bug die T1 aufgedeckt hat).
93
- const setEventType = customFieldsFeature.exports.setEvent.name;
94
- const clearedEventType = customFieldsFeature.exports.clearedEvent.name;
95
- const fieldDefDeletedType = customFieldsFeature.exports.fieldDefinitionDeletedEvent.name;
93
+ const setEventType = createCustomFieldsFeature().exports.setEvent.name;
94
+ const clearedEventType = createCustomFieldsFeature().exports.clearedEvent.name;
95
+ const fieldDefDeletedType = createCustomFieldsFeature().exports.fieldDefinitionDeletedEvent.name;
96
96
 
97
97
  // Geteilte apply-Bodies: die MSP liefert sie live (async cursor), die
98
98
  // entity-projection-extension replayt sie in rebuildProjection — gleiche
@@ -2,8 +2,8 @@
2
2
  // the forget runner and the `policy-for` query all go through here, so a caller
3
3
  // cannot skip a layer (e.g. the tenant preset) by accident.
4
4
 
5
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
6
5
  import type { DbRunner, TenantDb } from "@cosmicdrift/kumiko-framework/db";
6
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
7
7
  import type { Registry, TenantId } from "@cosmicdrift/kumiko-framework/engine";
8
8
  import { isTenantDb } from "../shared/index.js";
9
9
  import { parseRetentionOverrideOrNull } from "./_internal/parse-override.js";