@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
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.369.0",
4
+ "type": "fix",
5
+ "title": "secrets:write:set and secrets:write:delete join the request transaction",
6
+ "detail": "Both handlers ran on the boot database connection, so in an /api/batch a later failing command rolled back the config writes but kept the stored secret. They now run on the request transaction (escape hatch unsafeRaw, reason documented on the handler), so a batch of config and secret writes is stored as a whole or not at all."
7
+ },
2
8
  {
3
9
  "version": "0.365.0",
4
10
  "type": "fix",
@@ -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
  import type { StoredEnvelope } from "../../table.js";
5
5
 
@@ -3,6 +3,7 @@ import {
3
3
  type AccessRule,
4
4
  defineFeature,
5
5
  type FeatureDefinition,
6
+ SYSTEM_ROLE,
6
7
  } from "@cosmicdrift/kumiko-framework/engine";
7
8
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
8
9
  import { SETTINGS_HUB_I18N } from "@cosmicdrift/kumiko-framework/i18n";
@@ -63,6 +64,11 @@ export {
63
64
  } from "./secrets-context.js";
64
65
  export { type StoredEnvelope, type StoredMetadata, tenantSecretsTable } from "./table.js";
65
66
 
67
+ // The settings form saves config values and secrets in one /api/batch; the secret
68
+ // write has to join that transaction so a rejected command rolls it back too.
69
+ export const JOIN_REQUEST_TRANSACTION_REASON =
70
+ "the secret write runs on the request transaction so a failing batch rolls it back together with the config writes";
71
+
66
72
  // AppContext carries ctx.secrets via extraContext. requireSecretsContext
67
73
  // wraps that raw context so every `.get(...)` call auto-includes the
68
74
  // current user + handler as audit metadata — feature code can't forget
@@ -72,8 +78,13 @@ export { type StoredEnvelope, type StoredMetadata, tenantSecretsTable } from "./
72
78
  // FileProviderContext-Pfade (S3-Plugin im Worker) liefern dieselben
73
79
  // zwei Felder, also reicht die schmale ctx-shape — kein voller
74
80
  // HandlerContext-Import noetig.
81
+ // Handler contexts carry the caller as ctx.user, provider contexts set _userId (takes precedence).
75
82
  export function requireSecretsContext(
76
- ctx: { readonly secrets?: SecretsContext; readonly _userId?: string | undefined },
83
+ ctx: {
84
+ readonly secrets?: SecretsContext;
85
+ readonly _userId?: string | undefined;
86
+ readonly user?: { readonly id: string };
87
+ },
77
88
  handlerName: string,
78
89
  ): SecretsContext {
79
90
  if (!ctx.secrets) {
@@ -83,10 +94,10 @@ export function requireSecretsContext(
83
94
  "createSecretsContext({db, masterKeyProvider, registry}) via extraContext.secrets at boot.",
84
95
  });
85
96
  }
86
- const userId = ctx._userId;
97
+ const userId = ctx._userId ?? ctx.user?.id;
87
98
  if (!userId) {
88
99
  throw new InternalError({
89
- message: `[${handlerName}] ctx._userId missing — cannot audit secret reads without a caller identity.`,
100
+ message: `[${handlerName}] ctx._userId missing (and no ctx.user) — cannot audit secret reads without a caller identity.`,
90
101
  });
91
102
  }
92
103
  const withAudit = (raw: SecretsContext): SecretsContext => ({
@@ -128,11 +139,20 @@ function resolveSecretsAccess(opts: SecretsFeatureOptions): AccessRule {
128
139
  return DEFAULT_SECRETS_ACCESS;
129
140
  }
130
141
 
142
+ // Server-side system writes (dispatchSystemWrite, e.g. a wire hook migrating credentials) take the
143
+ // same declared-key gate, value check and cache-sync announce as an admin instead of bypassing them
144
+ // via SecretsContext.set. The system role is in-process only and never minted into a session.
145
+ function withSystemWriter(rule: AccessRule): AccessRule {
146
+ if (!("roles" in rule) || rule.roles.includes(SYSTEM_ROLE)) return rule;
147
+ return { ...rule, roles: [SYSTEM_ROLE, ...rule.roles] };
148
+ }
149
+
131
150
  export function createSecretsFeature(opts: SecretsFeatureOptions = {}): FeatureDefinition {
132
151
  const access = resolveSecretsAccess(opts);
152
+ const writeAccess = withSystemWriter(access);
133
153
  return defineFeature(SECRETS_FEATURE_NAME, (r) => {
134
154
  r.describe(
135
- 'Stores arbitrary per-tenant secrets (API keys, tokens, credentials) encrypted at rest using AES-256 with a KEK loaded from `KUMIKO_SECRETS_MASTER_KEY_V1` (and successive versions for rotation). Read a secret in handlers via `ctx.secrets.get(tenantId, handle)`, which automatically appends a `tenantSecretRead` audit event so every access is traceable. A `rotate` job re-encrypts all envelopes after a KEK version bump. The `set`/`delete`/`list` handlers share one access rule — default { roles: ["TenantAdmin"] }; adopt the host\'s role vocabulary with createSecretsFeature({ roles }) or open it to every authenticated tenant user with { access: { openToAll: { reason } } } (larger blast radius: any tenant member can then read secret previews and write/delete secrets, not just admins).',
155
+ 'Stores arbitrary per-tenant secrets (API keys, tokens, credentials) encrypted at rest using AES-256 with a KEK loaded from `KUMIKO_SECRETS_MASTER_KEY_V1` (and successive versions for rotation). Read a secret in handlers via `ctx.secrets.get(tenantId, handle)`, which automatically appends a `tenantSecretRead` audit event so every access is traceable. A `rotate` job re-encrypts all envelopes after a KEK version bump. The `set`/`delete`/`list` handlers share one access rule — default { roles: ["TenantAdmin"] }; adopt the host\'s role vocabulary with createSecretsFeature({ roles }) or open it to every authenticated tenant user with { access: { openToAll: { reason } } } (larger blast radius: any tenant member can then read secret previews and write/delete secrets, not just admins). Server-side code writes a tenant secret with `dispatchSystemWrite({ handlerQn: "secrets:write:set", payload, tenantId })`: set and delete also admit the in-process system identity, so such writes pass the same declared-key and value checks.',
136
156
  );
137
157
  r.uiHints({
138
158
  displayLabel: "Tenant Secrets",
@@ -172,8 +192,8 @@ export function createSecretsFeature(opts: SecretsFeatureOptions = {}): FeatureD
172
192
  // The rotation job deliberately reaches for ctx.db.unsafeRaw() (raw,
173
193
  // cross-tenant) because rotation is a deployment-wide operation — no
174
194
  // feature-wide r.systemScope() needed.
175
- r.writeHandler(createSetHandler(access));
176
- r.writeHandler(createDeleteHandler(access));
195
+ r.writeHandler(createSetHandler(writeAccess));
196
+ r.writeHandler(createDeleteHandler(writeAccess));
177
197
  r.queryHandler(createListHandler(access));
178
198
  // Manual-only by design: ops triggers rotation after a KEK version flip.
179
199
  // BullMQ delivers to exactly one worker, so running it against a busy
@@ -3,7 +3,7 @@ import { failNotFound } from "@cosmicdrift/kumiko-framework/errors";
3
3
  import * as z from "zod";
4
4
  import { announceSecretChange } from "../announce-secret-change.js";
5
5
  import { DEFAULT_SECRETS_ACCESS } from "../constants.js";
6
- import { requireSecretsContext } from "../feature.js";
6
+ import { JOIN_REQUEST_TRANSACTION_REASON, requireSecretsContext } from "../feature.js";
7
7
  import { checkSecretKeyWrite } from "../write-gate.js";
8
8
 
9
9
  export function createDeleteHandler(access: AccessRule = DEFAULT_SECRETS_ACCESS) {
@@ -16,8 +16,11 @@ export function createDeleteHandler(access: AccessRule = DEFAULT_SECRETS_ACCESS)
16
16
  key: z.string().min(1).max(100),
17
17
  }),
18
18
  access,
19
+ escapeHatch: { grants: ["unsafeRaw"], reason: JOIN_REQUEST_TRANSACTION_REASON },
19
20
  handler: async (event, ctx) => {
20
- const secrets = requireSecretsContext(ctx, "secrets:write:delete");
21
+ const secrets = requireSecretsContext(ctx, "secrets:write:delete").withRunner(
22
+ ctx.db.unsafeRaw(),
23
+ );
21
24
  const gate = checkSecretKeyWrite(ctx.registry, event.user.roles, event.payload.key, {
22
25
  allowUndeclared: true,
23
26
  });
@@ -17,11 +17,11 @@
17
17
  // that landed the row on the new kekVersion first surfaces here as a
18
18
  // version_conflict error (counted as "skipped", not "failed").
19
19
 
20
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
21
20
  import {
22
21
  createEventStoreExecutor,
23
22
  createTenantDb,
24
23
  type DbConnection,
24
+ selectMany,
25
25
  type TenantDb,
26
26
  } from "@cosmicdrift/kumiko-framework/db";
27
27
  import type { JobContext, SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
@@ -81,7 +81,7 @@ export async function rotateJob(
81
81
  function tdbFor(tenantId: TenantId): TenantDb {
82
82
  let existing = tdbCache.get(tenantId);
83
83
  if (!existing) {
84
- existing = createTenantDb(db, tenantId, "system");
84
+ existing = createTenantDb({ db, tenantId, mode: "system" });
85
85
  tdbCache.set(tenantId, existing);
86
86
  }
87
87
  return existing;
@@ -2,7 +2,7 @@ import { type AccessRule, defineWriteHandler } from "@cosmicdrift/kumiko-framewo
2
2
  import * as z from "zod";
3
3
  import { announceSecretChange } from "../announce-secret-change.js";
4
4
  import { DEFAULT_SECRETS_ACCESS } from "../constants.js";
5
- import { requireSecretsContext } from "../feature.js";
5
+ import { JOIN_REQUEST_TRANSACTION_REASON, requireSecretsContext } from "../feature.js";
6
6
  import { checkSecretKeyWrite, checkSecretValue } from "../write-gate.js";
7
7
 
8
8
  export function createSetHandler(access: AccessRule = DEFAULT_SECRETS_ACCESS) {
@@ -23,8 +23,11 @@ export function createSetHandler(access: AccessRule = DEFAULT_SECRETS_ACCESS) {
23
23
  hint: z.string().max(200).optional(),
24
24
  }),
25
25
  access,
26
+ escapeHatch: { grants: ["unsafeRaw"], reason: JOIN_REQUEST_TRANSACTION_REASON },
26
27
  handler: async (event, ctx) => {
27
- const secrets = requireSecretsContext(ctx, "secrets:write:set");
28
+ const secrets = requireSecretsContext(ctx, "secrets:write:set").withRunner(
29
+ ctx.db.unsafeRaw(),
30
+ );
28
31
  const { key, value, redactedPreview, hint } = event.payload;
29
32
 
30
33
  // Preview-priority: explicit payload param > feature-declared redact
@@ -12,12 +12,13 @@
12
12
  // read logged") now sits on the events-table instead of a
13
13
  // dedicated audit-table.
14
14
 
15
- import { fetchOne, transaction } from "@cosmicdrift/kumiko-framework/bun-db";
16
15
  import {
17
16
  createEventStoreExecutor,
18
17
  createTenantDb,
19
18
  type DbConnection,
20
19
  type DbRunner,
20
+ fetchOne,
21
+ transaction,
21
22
  } from "@cosmicdrift/kumiko-framework/db";
22
23
  import type { SessionUser } from "@cosmicdrift/kumiko-framework/engine";
23
24
  import { InternalError, type WriteErrorInfo } from "@cosmicdrift/kumiko-framework/errors";
@@ -205,7 +206,7 @@ function buildSecretsContext(
205
206
  tenantId,
206
207
  roles: SYSTEM_ROLES,
207
208
  };
208
- const tdb = createTenantDb(db, tenantId, "system");
209
+ const tdb = createTenantDb({ db, tenantId, mode: "system" });
209
210
 
210
211
  const existing = await lookup(tenantId, key);
211
212
  const commonFields = {
@@ -270,7 +271,7 @@ function buildSecretsContext(
270
271
  tenantId,
271
272
  roles: SYSTEM_ROLES,
272
273
  };
273
- const tdb = createTenantDb(db, tenantId, "system");
274
+ const tdb = createTenantDb({ db, tenantId, mode: "system" });
274
275
  const result = await executor.delete({ id: existing.id }, actor, tdb);
275
276
  return result.isSuccess;
276
277
  },
@@ -1,5 +1,5 @@
1
- import { asRawClient } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
2
+ import { asRawClient } from "@cosmicdrift/kumiko-framework/db";
3
3
 
4
4
  export async function deleteStaleSessionsBatch(
5
5
  db: DbConnection,
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { access, defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { decryptStoredPii } from "../../shared/index.js";
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import {
3
3
  access,
4
4
  definePagedQueryHandler,
@@ -11,7 +11,7 @@ import { userSessionTable } from "../schema/user-session.js";
11
11
 
12
12
  // `sort` arrives raw from the client's query string. selectMany's orderBy
13
13
  // has no column-existence check — an unrecognised field just gets
14
- // snake_cased and quoted as-is (bun-db/query.ts columnOf) — so this
14
+ // snake_cased and quoted as-is (db/query.ts columnOf) — so this
15
15
  // allowlist is what stops a client sorting by ip/userAgent or any other
16
16
  // non-exposed column.
17
17
  const SORTABLE_COLUMNS = ["id", "userId", "createdAt", "expiresAt", "revokedAt"] as const;
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { definePagedQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { decryptStoredPii } from "../../shared/index.js";
@@ -1,5 +1,5 @@
1
1
  import { requestContext } from "@cosmicdrift/kumiko-framework/api";
2
- import { updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
+ import { updateMany } from "@cosmicdrift/kumiko-framework/db";
3
3
  import { access, defineWriteHandler, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
4
4
  import { UnprocessableError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
5
5
  import { append } from "@cosmicdrift/kumiko-framework/event-store";
@@ -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 { UnprocessableError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { generateId } from "@cosmicdrift/kumiko-framework/utils";
@@ -1,4 +1,4 @@
1
- import { fetchOne, updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne, updateMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { UnprocessableError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { generateId } from "@cosmicdrift/kumiko-framework/utils";
@@ -9,8 +9,8 @@ import type {
9
9
 
10
10
  export type { SessionMassRevoker } from "@cosmicdrift/kumiko-framework/api";
11
11
 
12
- import { fetchOne, insertOne, transaction, updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
13
12
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
13
+ import { fetchOne, insertOne, transaction, updateMany } from "@cosmicdrift/kumiko-framework/db";
14
14
  import type { SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
15
15
  import { buildSessionRoles, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
16
16
  import { append } from "@cosmicdrift/kumiko-framework/event-store";
@@ -18,7 +18,12 @@ import { generateId, parseRoles } from "@cosmicdrift/kumiko-framework/utils";
18
18
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
19
19
  import { encryptForDirectWrite } from "../shared/index.js";
20
20
  import { tenantMembershipsTable } from "../tenant/index.js";
21
- import { isPrincipalBlocked, type UserStatus, userTable } from "../user/index.js";
21
+ import {
22
+ isPrincipalBlocked,
23
+ isPrincipalRowBlocked,
24
+ type UserStatus,
25
+ userTable,
26
+ } from "../user/index.js";
22
27
  import {
23
28
  DEFAULT_SESSION_EXPIRY_MS,
24
29
  LAST_SEEN_REFRESH_MS,
@@ -190,16 +195,18 @@ export function createSessionCallbacks(opts: SessionCallbacksOptions): SessionCa
190
195
  // missing row is a legitimate "no tenant roles" outcome. Both branches
191
196
  // return the bare "live" string (no re-derived roles) — the middleware
192
197
  // falls back to the JWT's frozen roles claim.
193
- let user: { status: UserStatus; roles: string | null } | undefined;
198
+ let user: { status: UserStatus; isDeleted: boolean; roles: string | null } | undefined;
194
199
  try {
195
- user = await fetchOne<{ status: UserStatus; roles: string | null }>(db, userTable, {
196
- id: expectedUserId,
197
- });
200
+ user = await fetchOne<{ status: UserStatus; isDeleted: boolean; roles: string | null }>(
201
+ db,
202
+ userTable,
203
+ { id: expectedUserId },
204
+ );
198
205
  } catch {
199
206
  return "live";
200
207
  }
201
208
  if (!user) return "live";
202
- if (isPrincipalBlocked(user.status)) return "blocked";
209
+ if (isPrincipalRowBlocked(user)) return "blocked";
203
210
 
204
211
  // Same fail-open reasoning as the userTable lookup above — a transient
205
212
  // DB error on the membership read must not lock the user out. A
@@ -19,7 +19,7 @@
19
19
 
20
20
  import type { AuthRoutesConfig, SessionCreator } from "@cosmicdrift/kumiko-framework/api";
21
21
  import type { SessionUser } from "@cosmicdrift/kumiko-framework/engine";
22
- import type { LateBoundHolder } from "@cosmicdrift/kumiko-framework/testing";
22
+ import type { LateBoundHolder } from "@cosmicdrift/kumiko-testing/helpers";
23
23
  import type { SessionCallbacks, SessionMassRevoker } from "./session-callbacks.js";
24
24
 
25
25
  export type BoundSessionCallbacks = {
@@ -130,7 +130,7 @@ function registerTags(
130
130
  r.translations({ keys: TAGS_FEATURE_I18N });
131
131
  }
132
132
 
133
- export const tagsFeature = defineFeature(TAGS_FEATURE_NAME, (r) =>
133
+ const defaultTagsFeature = defineFeature(TAGS_FEATURE_NAME, (r) =>
134
134
  registerTags(r, DEFAULT_TAG_ACCESS, undefined, undefined, undefined),
135
135
  );
136
136
 
@@ -183,7 +183,7 @@ function resolveAccess(opts: TagsFeatureOptions): AccessRule {
183
183
  // Backwards-compat / options wrapper. Without options returns the module-level
184
184
  // singleton (no rebuild). access/roles/toggleable/ownership build a fresh
185
185
  // feature-definition.
186
- export function createTagsFeature(opts: TagsFeatureOptions = {}): typeof tagsFeature {
186
+ export function createTagsFeature(opts: TagsFeatureOptions = {}): typeof defaultTagsFeature {
187
187
  if (
188
188
  opts.access === undefined &&
189
189
  opts.roles === undefined &&
@@ -191,7 +191,7 @@ export function createTagsFeature(opts: TagsFeatureOptions = {}): typeof tagsFea
191
191
  opts.ownership === undefined &&
192
192
  opts.parents === undefined
193
193
  ) {
194
- return tagsFeature;
194
+ return defaultTagsFeature;
195
195
  }
196
196
  if (opts.parents !== undefined && opts.parents.length === 0) {
197
197
  throw new Error(
@@ -207,3 +207,6 @@ export function createTagsFeature(opts: TagsFeatureOptions = {}): typeof tagsFea
207
207
  registerTags(r, access, opts.toggleable, opts.ownership, opts.parents),
208
208
  );
209
209
  }
210
+
211
+ /** @deprecated Use createTagsFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
212
+ export const tagsFeature = createTagsFeature();
@@ -2,8 +2,8 @@
2
2
  // delivery and apps import types ONLY and take the implementation from
3
3
  // ctx.templateResolver at runtime.
4
4
 
5
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
6
5
  import type { DbRunner, TenantDb } from "@cosmicdrift/kumiko-framework/db";
6
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
7
7
  import type { SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
8
8
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
9
9
  import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
@@ -90,7 +90,6 @@ export const DEFAULT_PDF_LAYOUT_SLUG = "default";
90
90
  // The mail transport enforces no size limit of its own; 10 MiB is a common provider ceiling.
91
91
  export const MAIL_PREVIEW_MAX_BYTES = 10 * 1024 * 1024;
92
92
 
93
- export const TEST_MAIL_NOTIFICATION_TYPE = "template-resolver:test-mail";
94
93
  export const TEST_MAIL_SUBJECT_PREFIX = "[TEST] ";
95
94
 
96
95
  // System-Templates leben unter der canonical SYSTEM_TENANT_ID-Sentinel-UUID.
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import type {
3
3
  BeforeTransactionResult,
4
4
  HandlerContext,
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { TEXT_BLOCK_KIND } from "../constants.js";
@@ -1,5 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { castTenantRows } from "@cosmicdrift/kumiko-framework/db";
1
+ import { castTenantRows, selectMany } from "@cosmicdrift/kumiko-framework/db";
3
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
4
3
  import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
5
4
  import * as z from "zod";
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import {
3
3
  type ContentCollectionDefinition,
4
4
  defineQueryHandler,
@@ -1,5 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { castTenantRows } from "@cosmicdrift/kumiko-framework/db";
1
+ import { castTenantRows, selectMany } from "@cosmicdrift/kumiko-framework/db";
3
2
  import {
4
3
  type ContentCollectionDefinition,
5
4
  defineQueryHandler,
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import {
3
3
  type ContentCollectionDefinition,
4
4
  defineWriteHandler,
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import {
3
3
  defineWriteHandler,
4
4
  type HandlerContext,
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineQueryHandler, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { NotFoundError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import * as z from "zod";
@@ -1,5 +1,5 @@
1
1
  import { isDeepStrictEqual } from "node:util";
2
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
3
3
  import { defineQueryHandler, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
4
4
  import { NotFoundError, ValidationError } from "@cosmicdrift/kumiko-framework/errors";
5
5
  import * as z from "zod";
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { type TemplateResourceRow, templateResourcesTable } from "../table.js";
@@ -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 { FALLBACK_LOCALE } from "../constants.js";
@@ -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 { TEMPLATE_KINDS, TEMPLATE_STATUSES } from "../constants.js";
@@ -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 { DEFAULT_MAIL_LAYOUT_SLUG, FALLBACK_LOCALE, type TemplateStatus } from "../constants.js";
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineWriteHandler, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { NotFoundError, ValidationError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import * as z from "zod";
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } 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";
@@ -7,7 +7,7 @@ import {
7
7
  EMAIL_CHANNEL_NAME,
8
8
  } from "../../delivery/index.js";
9
9
  import { fileContextForTenant } from "../../file-foundation/index.js";
10
- import { TEST_MAIL_NOTIFICATION_TYPE, TEST_MAIL_SUBJECT_PREFIX } from "../constants.js";
10
+ import { TEST_MAIL_SUBJECT_PREFIX } from "../constants.js";
11
11
  import { TemplateResolverErrors } from "../qualified-names.js";
12
12
  import { renderTemplatePreview } from "../template-preview.js";
13
13
  import { localeSchema, templateSlugSchema } from "./shared.js";
@@ -75,6 +75,7 @@ export const sendTestWrite = defineWriteHandler({
75
75
  sseBroker: undefined,
76
76
  tenantId: event.user.tenantId,
77
77
  secrets: ctx.secrets,
78
+ config: ctx.config,
78
79
  readAttachment: createEmailAttachmentReader(
79
80
  ctx.db,
80
81
  ctx.registry,
@@ -98,7 +99,8 @@ export const sendTestWrite = defineWriteHandler({
98
99
  const result = await channel.send(
99
100
  address,
100
101
  {
101
- notificationType: TEST_MAIL_NOTIFICATION_TYPE,
102
+ // The template slug is the notification name, so the test mail takes the transport the real mail takes.
103
+ notificationType: event.payload.slug,
102
104
  title: subject,
103
105
  body: undefined,
104
106
  data: undefined,
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import {
3
3
  defineWriteHandler,
4
4
  SYSTEM_TENANT_ID,
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import {
3
3
  type HandlerContext,
4
4
  type Registry,
@@ -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, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { TenantQueries } from "../../tenant/index.js";
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import {
3
3
  defineWriteHandler,
4
4
  type HandlerContext,
@@ -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 { TEMPLATE_KINDS } from "../constants.js";
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import {
3
3
  defineQueryHandler,
4
4
  type HandlerContext,
@@ -9,12 +9,12 @@
9
9
  // Default ifExists="skip". The actor is `createSystemUser(SYSTEM_TENANT_ID)`,
10
10
  // deliberately not TestUsers (prod seeds are not test utilities).
11
11
 
12
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
13
12
  import {
14
13
  createTenantDb,
15
14
  type DbConnection,
16
15
  deleteMany,
17
16
  type EntityTableMeta,
17
+ fetchOne,
18
18
  type TenantDb,
19
19
  } from "@cosmicdrift/kumiko-framework/db";
20
20
  import {
@@ -89,7 +89,7 @@ export async function seedSystemTemplate(
89
89
  ): Promise<{ id: string }> {
90
90
  const tenantId = SYSTEM_TENANT_ID;
91
91
  const by = opts.by ?? createSystemUser(tenantId);
92
- const tdb = createTenantDb(db, tenantId, "system");
92
+ const tdb = createTenantDb({ db, tenantId, mode: "system" });
93
93
 
94
94
  const label = `seedSystemTemplate ${opts.slug}/${opts.kind}/${opts.locale}`;
95
95
  const slug = templateSlugSchema.safeParse(opts.slug);
@@ -379,7 +379,7 @@ export async function seedTextBlock(
379
379
  opts: SeedTextBlockOptions,
380
380
  ): Promise<{ id: string }> {
381
381
  const by = opts.by ?? createSystemUser(opts.tenantId);
382
- const tdb = createTenantDb(db, opts.tenantId, "system");
382
+ const tdb = createTenantDb({ db, tenantId: opts.tenantId, mode: "system" });
383
383
 
384
384
  const existingRow = await fetchOne<TemplateResourceRow>(db, templateResourcesTable, {
385
385
  tenantId: opts.tenantId,
@@ -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 type {
3
3
  BeforeTransactionResult,
4
4
  ConfigAccessor,
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import type {
3
3
  HandlerContext,
4
4
  SessionUser,
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import type {
3
3
  HandlerContext,
4
4
  SessionUser,