@cosmicdrift/kumiko-samples 0.367.0 → 0.368.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 (385) 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-in-app/handlers/inbox.query.ts +1 -1
  39. package/packages/bundled-features/src/channel-in-app/handlers/mark-all-read.write.ts +1 -1
  40. package/packages/bundled-features/src/channel-in-app/handlers/mark-read.write.ts +1 -1
  41. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +1 -1
  42. package/packages/bundled-features/src/channel-in-app/tables.ts +1 -1
  43. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +1 -1
  44. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +1 -1
  45. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +1 -2
  46. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +1 -1
  47. package/packages/bundled-features/src/compliance-profiles/seeding.ts +8 -4
  48. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +26 -17
  49. package/packages/bundled-features/src/config/db/queries/resolver.ts +1 -1
  50. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +2 -2
  51. package/packages/bundled-features/src/config/resolver.ts +1 -1
  52. package/packages/bundled-features/src/config/write-helpers.ts +1 -1
  53. package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
  54. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +9 -7
  55. package/packages/bundled-features/src/custom-fields/db/queries/field-access.ts +1 -1
  56. package/packages/bundled-features/src/custom-fields/db/queries/projection.ts +1 -1
  57. package/packages/bundled-features/src/custom-fields/db/queries/quota.ts +1 -1
  58. package/packages/bundled-features/src/custom-fields/db/queries/retention.ts +6 -2
  59. package/packages/bundled-features/src/custom-fields/db/queries/user-data-rights.ts +1 -1
  60. package/packages/bundled-features/src/custom-fields/feature.ts +11 -14
  61. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +2 -2
  62. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +2 -2
  63. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +2 -2
  64. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +2 -2
  65. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +4 -4
  66. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  67. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +16 -10
  68. package/packages/bundled-features/src/delivery/address-opt-out.ts +5 -2
  69. package/packages/bundled-features/src/delivery/attempt-log-retention.ts +1 -1
  70. package/packages/bundled-features/src/delivery/channel-context.ts +1 -1
  71. package/packages/bundled-features/src/delivery/db/queries/address-opt-outs.ts +1 -1
  72. package/packages/bundled-features/src/delivery/db/queries/preferences.ts +1 -1
  73. package/packages/bundled-features/src/delivery/delivery-service.ts +16 -6
  74. package/packages/bundled-features/src/delivery/feature.ts +1 -1
  75. package/packages/bundled-features/src/delivery/handlers/log.query.ts +3 -2
  76. package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +1 -1
  77. package/packages/bundled-features/src/delivery/upsert-preference.ts +5 -2
  78. package/packages/bundled-features/src/derivatives-sharp/feature.ts +21 -12
  79. package/packages/bundled-features/src/derivatives-sharp/index.ts +1 -1
  80. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +112 -103
  81. package/packages/bundled-features/src/document-ingest-foundation/forget-extract-with-file-ref.ts +3 -3
  82. package/packages/bundled-features/src/document-ingest-foundation/index.ts +4 -1
  83. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  84. package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -5
  85. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  86. package/packages/bundled-features/src/file-derivatives/feature.ts +134 -129
  87. package/packages/bundled-features/src/file-derivatives/handlers/public-variant-by-file-ref.query.ts +1 -1
  88. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  89. package/packages/bundled-features/src/file-foundation/feature.ts +38 -29
  90. package/packages/bundled-features/src/file-foundation/index.ts +1 -0
  91. package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +1 -1
  92. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +32 -21
  93. package/packages/bundled-features/src/file-provider-inmemory/index.ts +6 -1
  94. package/packages/bundled-features/src/file-provider-s3/changes.json +10 -1
  95. package/packages/bundled-features/src/file-provider-s3/env-feature.ts +62 -0
  96. package/packages/bundled-features/src/file-provider-s3/feature.ts +107 -73
  97. package/packages/bundled-features/src/file-provider-s3/index.ts +6 -1
  98. package/packages/bundled-features/src/file-provider-s3/lib/index.ts +3 -0
  99. package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/s3-provider.ts +19 -19
  100. package/packages/bundled-features/src/file-provider-s3-env/index.ts +7 -2
  101. package/packages/bundled-features/src/files-provider-s3/index.ts +11 -3
  102. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +1 -1
  103. package/packages/bundled-features/src/files-tenant-data/hooks.ts +1 -2
  104. package/packages/bundled-features/src/folders/feature.ts +8 -3
  105. package/packages/bundled-features/src/folders-user-data/index.ts +27 -18
  106. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
  107. package/packages/bundled-features/src/form-draft/db/queries/draft-count.ts +1 -1
  108. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +3 -2
  109. package/packages/bundled-features/src/form-draft/feature.ts +6 -1
  110. package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +2 -2
  111. package/packages/bundled-features/src/form-draft/index.ts +1 -1
  112. package/packages/bundled-features/src/form-draft/lookup.ts +1 -1
  113. package/packages/bundled-features/src/form-draft-user-data/index.ts +19 -10
  114. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +165 -154
  115. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +1 -2
  116. package/packages/bundled-features/src/inbound-mail-foundation/index.ts +1 -1
  117. package/packages/bundled-features/src/inbound-mail-foundation/oauth-access-token.ts +5 -2
  118. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +3 -2
  119. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +1 -1
  120. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +22 -13
  121. package/packages/bundled-features/src/inbound-provider-imap/index.ts +6 -1
  122. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +20 -12
  123. package/packages/bundled-features/src/inbound-provider-inmemory/index.ts +1 -0
  124. package/packages/bundled-features/src/jobs/db/queries/retention.ts +1 -1
  125. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +1 -1
  126. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +1 -1
  127. package/packages/bundled-features/src/jobs/handlers/list.query.ts +7 -2
  128. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  129. package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +1 -1
  130. package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +1 -1
  131. package/packages/bundled-features/src/jobs/job-run-logger.ts +11 -10
  132. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  133. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  134. package/packages/bundled-features/src/ledger/feature.ts +6 -3
  135. package/packages/bundled-features/src/mail-foundation/feature.ts +57 -46
  136. package/packages/bundled-features/src/mail-foundation/index.ts +1 -0
  137. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +25 -17
  138. package/packages/bundled-features/src/mail-transport-inmemory/index.ts +6 -1
  139. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +91 -79
  140. package/packages/bundled-features/src/mail-transport-smtp/index.ts +1 -0
  141. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +1 -1
  142. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +1 -2
  143. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +1 -2
  144. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -4
  145. package/packages/bundled-features/src/metrics/compute.ts +1 -1
  146. package/packages/bundled-features/src/metrics/filters.ts +1 -1
  147. package/packages/bundled-features/src/metrics/validate.ts +1 -1
  148. package/packages/bundled-features/src/notes-history/feature.ts +6 -3
  149. package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
  150. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  151. package/packages/bundled-features/src/notes-history-user-data/index.ts +27 -18
  152. package/packages/bundled-features/src/personal-access-tokens/changes.json +6 -0
  153. package/packages/bundled-features/src/personal-access-tokens/feature.ts +17 -2
  154. package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +1 -1
  155. package/packages/bundled-features/src/personal-access-tokens/handlers/list.query.ts +2 -2
  156. package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
  157. package/packages/bundled-features/src/personal-access-tokens/resolver.ts +1 -1
  158. package/packages/bundled-features/src/personal-access-tokens/revoke-for-user.ts +2 -2
  159. package/packages/bundled-features/src/personal-access-tokens/roles.ts +8 -6
  160. package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -0
  161. package/packages/bundled-features/src/readiness/feature.ts +25 -16
  162. package/packages/bundled-features/src/readiness/index.ts +1 -1
  163. package/packages/bundled-features/src/secrets/db/queries/read.ts +1 -1
  164. package/packages/bundled-features/src/secrets/feature.ts +8 -3
  165. package/packages/bundled-features/src/secrets/handlers/rotate.job.ts +2 -2
  166. package/packages/bundled-features/src/secrets/secrets-context.ts +4 -3
  167. package/packages/bundled-features/src/sessions/db/queries/cleanup.ts +1 -1
  168. package/packages/bundled-features/src/sessions/handlers/detail.query.ts +1 -1
  169. package/packages/bundled-features/src/sessions/handlers/list.query.ts +2 -2
  170. package/packages/bundled-features/src/sessions/handlers/mine.query.ts +1 -1
  171. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +1 -1
  172. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +1 -1
  173. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  174. package/packages/bundled-features/src/sessions/session-callbacks.ts +14 -7
  175. package/packages/bundled-features/src/sessions/testing.ts +1 -1
  176. package/packages/bundled-features/src/tags/feature.ts +6 -3
  177. package/packages/bundled-features/src/template-resolver/api.ts +1 -1
  178. package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +1 -1
  179. package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +1 -1
  180. package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +1 -2
  181. package/packages/bundled-features/src/template-resolver/handlers/collection-item.query.ts +1 -1
  182. package/packages/bundled-features/src/template-resolver/handlers/collection-list.query.ts +1 -2
  183. package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +1 -1
  184. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +1 -1
  185. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +1 -1
  186. package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +1 -1
  187. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +1 -1
  188. package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +1 -1
  189. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
  190. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +1 -1
  191. package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +1 -1
  192. package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +1 -1
  193. package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +1 -1
  194. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +1 -1
  195. package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +1 -1
  196. package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +1 -1
  197. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +1 -1
  198. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +1 -1
  199. package/packages/bundled-features/src/template-resolver/seeding.ts +3 -3
  200. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +1 -1
  201. package/packages/bundled-features/src/template-resolver/template-preview.ts +1 -1
  202. package/packages/bundled-features/src/template-resolver/template-resources.ts +1 -1
  203. package/packages/bundled-features/src/template-resolver/testing.ts +1 -1
  204. package/packages/bundled-features/src/template-resolver-user-data/index.ts +23 -14
  205. package/packages/bundled-features/src/tenant/handlers/active-tenant-ids.query.ts +1 -1
  206. package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +1 -2
  207. package/packages/bundled-features/src/tenant/handlers/cancel-invitation.write.ts +1 -1
  208. package/packages/bundled-features/src/tenant/handlers/invitations.query.ts +1 -1
  209. package/packages/bundled-features/src/tenant/handlers/me.query.ts +1 -1
  210. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
  211. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  212. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  213. package/packages/bundled-features/src/tenant/handlers/remove-member.write.ts +2 -1
  214. package/packages/bundled-features/src/tenant/handlers/resolve-user-ids.query.ts +1 -1
  215. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  216. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
  217. package/packages/bundled-features/src/tenant/handlers/update-member-roles.write.ts +1 -2
  218. package/packages/bundled-features/src/tenant/invited-membership.ts +2 -2
  219. package/packages/bundled-features/src/tenant/last-tenant-admin.ts +1 -2
  220. package/packages/bundled-features/src/tenant/seeding.ts +12 -12
  221. package/packages/bundled-features/src/tenant-lifecycle/handlers/cancel-destruction.write.ts +1 -2
  222. package/packages/bundled-features/src/tenant-lifecycle/handlers/request-destruction.write.ts +1 -2
  223. package/packages/bundled-features/src/tenant-lifecycle/lib/revoke-tenant-sessions.ts +1 -1
  224. package/packages/bundled-features/src/tenant-lifecycle/lifecycle-gate.ts +1 -1
  225. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +3 -3
  226. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +10 -5
  227. package/packages/bundled-features/src/tenant-lifecycle/testing.ts +3 -3
  228. package/packages/bundled-features/src/tenant-settings/feature.ts +34 -29
  229. package/packages/bundled-features/src/tier-engine/feature.ts +426 -428
  230. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +2 -3
  231. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +5 -2
  232. package/packages/bundled-features/src/user/changes.json +6 -0
  233. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +1 -1
  234. package/packages/bundled-features/src/user/handlers/create.write.ts +1 -2
  235. package/packages/bundled-features/src/user/handlers/find-for-auth.query.ts +1 -1
  236. package/packages/bundled-features/src/user/handlers/list.query.ts +1 -1
  237. package/packages/bundled-features/src/user/handlers/update-roles.ts +2 -1
  238. package/packages/bundled-features/src/user/index.ts +5 -1
  239. package/packages/bundled-features/src/user/invited-global-roles.ts +2 -2
  240. package/packages/bundled-features/src/user/principal-status.ts +13 -3
  241. package/packages/bundled-features/src/user/resolve-display-names.ts +1 -1
  242. package/packages/bundled-features/src/user/seeding.ts +5 -5
  243. package/packages/bundled-features/src/user-data-rights/audit-download.ts +2 -2
  244. package/packages/bundled-features/src/user-data-rights/db/queries/export-jobs.ts +1 -1
  245. package/packages/bundled-features/src/user-data-rights/db/queries/forget-cleanup.ts +1 -1
  246. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +1 -1
  247. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +1 -1
  248. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +1 -1
  249. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +1 -1
  250. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +1 -1
  251. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +1 -2
  252. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +3 -3
  253. package/packages/bundled-features/src/user-data-rights/lib/deny-if-target-outside-admin-tenant.ts +1 -1
  254. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +7 -2
  255. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +7 -3
  256. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +11 -5
  257. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +10 -5
  258. package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +1 -2
  259. package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
  260. package/packages/bundled-features/src/waitlist/lib.ts +5 -2
  261. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +1 -1
  262. package/packages/bundled-features/src/workflow-runner/feature.ts +58 -47
  263. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +1 -1
  264. package/packages/bundled-features/src/workflow-runner/index.ts +1 -1
  265. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +1 -1
  266. package/samples/apps/admin-console/src/run-config.ts +2 -2
  267. package/samples/apps/cap-billing-demo/package.json +3 -0
  268. package/samples/apps/cap-billing-demo/src/feature.ts +2 -2
  269. package/samples/apps/cap-billing-demo/src/run-config.ts +8 -8
  270. package/samples/apps/marketing-demo/src/app/seed.ts +1 -1
  271. package/samples/apps/marketing-demo/src/db/queries/seed-counts.ts +1 -1
  272. package/samples/apps/showcase/package.json +3 -0
  273. package/samples/apps/showcase/src/app/seed-items.ts +1 -1
  274. package/samples/apps/styleguide/src/app/seed.ts +2 -2
  275. package/samples/apps/styleguide/src/features/ai-settings/seed.ts +2 -2
  276. package/samples/apps/ui-walkthrough/scripts/emit-e2e-data.ts +1 -1
  277. package/samples/apps/ui-walkthrough/src/app/auth-constants.ts +1 -1
  278. package/samples/apps/ui-walkthrough/src/app/seed-rental.ts +2 -2
  279. package/samples/apps/ui-walkthrough/src/app/seed-vehicles.ts +1 -1
  280. package/samples/apps/ui-walkthrough/src/app/seed.ts +1 -1
  281. package/samples/apps/ui-walkthrough/src/db/queries/row-counts.ts +1 -1
  282. package/samples/apps/ui-walkthrough/src/db/queries/task-counts.ts +1 -1
  283. package/samples/apps/use-all-bundled/package.json +3 -0
  284. package/samples/apps/use-all-bundled/scripts/check-coverage.ts +2 -2
  285. package/samples/apps/use-all-bundled/src/app/auth-constants.ts +1 -1
  286. package/samples/apps/use-all-bundled/src/app/cap-overview-caps.ts +2 -2
  287. package/samples/apps/use-all-bundled/src/app/dev-app-options.ts +1 -1
  288. package/samples/apps/use-all-bundled/src/app/seed-documents.ts +1 -1
  289. package/samples/apps/use-all-bundled/src/app/seed.ts +11 -5
  290. package/samples/apps/use-all-bundled/src/run-config.ts +55 -56
  291. package/samples/apps/user-data-rights-demo/README.md +2 -2
  292. package/samples/apps/user-data-rights-demo/package.json +3 -0
  293. package/samples/apps/user-data-rights-demo/src/run-config.ts +7 -7
  294. package/samples/apps/workspaces/package.json +3 -0
  295. package/samples/recipes/access-control/package.json +3 -0
  296. package/samples/recipes/anonymous-access/package.json +3 -0
  297. package/samples/recipes/anonymous-access-multitenant/package.json +3 -0
  298. package/samples/recipes/apex-landing/package.json +1 -0
  299. package/samples/recipes/apex-surface-auth/package.json +3 -0
  300. package/samples/recipes/apex-surface-auth/src/feature.ts +2 -2
  301. package/samples/recipes/api-worker-split/package.json +3 -0
  302. package/samples/recipes/api-worker-split/src/feature.ts +1 -2
  303. package/samples/recipes/auth-claims/package.json +3 -0
  304. package/samples/recipes/auth-foundation-providers/src/feature.ts +1 -1
  305. package/samples/recipes/auth-mfa/package.json +3 -0
  306. package/samples/recipes/basic-entity/package.json +3 -0
  307. package/samples/recipes/chat-channels/package.json +3 -0
  308. package/samples/recipes/compliance-profiles-demo/package.json +3 -0
  309. package/samples/recipes/cross-feature-events/package.json +3 -1
  310. package/samples/recipes/cross-feature-events/src/feature.ts +1 -1
  311. package/samples/recipes/crypto-shredding-hr/package.json +3 -0
  312. package/samples/recipes/currencies-global/package.json +3 -0
  313. package/samples/recipes/currencies-per-tenant/package.json +3 -0
  314. package/samples/recipes/custom-fields-basic/package.json +3 -0
  315. package/samples/recipes/custom-handlers/package.json +3 -0
  316. package/samples/recipes/dashboard-stats/package.json +3 -0
  317. package/samples/recipes/delivery-notifications/package.json +3 -0
  318. package/samples/recipes/e2e-generator/package.json +3 -0
  319. package/samples/recipes/embedded/package.json +3 -0
  320. package/samples/recipes/embedded-entity-form/package.json +1 -0
  321. package/samples/recipes/encrypted-tenant-config/README.md +1 -1
  322. package/samples/recipes/encrypted-tenant-config/package.json +3 -0
  323. package/samples/recipes/error-contract/package.json +3 -0
  324. package/samples/recipes/event-sourcing/package.json +3 -1
  325. package/samples/recipes/event-sourcing/src/feature.ts +16 -20
  326. package/samples/recipes/event-sourcing/tsconfig.json +2 -6
  327. package/samples/recipes/feature-toggles/package.json +3 -0
  328. package/samples/recipes/field-access/package.json +3 -0
  329. package/samples/recipes/files-post-processing/package.json +1 -0
  330. package/samples/recipes/golden-path/README.md +30 -0
  331. package/samples/recipes/golden-path/package.json +11 -0
  332. package/samples/recipes/golden-path/src/feature.ts +70 -0
  333. package/samples/recipes/idempotency/package.json +3 -0
  334. package/samples/recipes/inbound-mail-triage/package.json +3 -0
  335. package/samples/recipes/lane-routing/package.json +3 -0
  336. package/samples/recipes/ledger-banking/package.json +3 -0
  337. package/samples/recipes/ledger-invoicing/package.json +3 -0
  338. package/samples/recipes/legal-pages/package.json +3 -0
  339. package/samples/recipes/lifecycle-hooks/package.json +3 -0
  340. package/samples/recipes/managed-config/package.json +3 -0
  341. package/samples/recipes/managed-pages/package.json +3 -0
  342. package/samples/recipes/notes-history-basic/package.json +3 -0
  343. package/samples/recipes/ownership/package.json +3 -0
  344. package/samples/recipes/pdf-audit-export/package.json +1 -0
  345. package/samples/recipes/pipeline-basics/package.json +3 -0
  346. package/samples/recipes/public-share-token/package.json +3 -0
  347. package/samples/recipes/public-share-token/src/feature.ts +1 -1
  348. package/samples/recipes/rate-limiting/package.json +3 -0
  349. package/samples/recipes/realtime-sse/package.json +3 -0
  350. package/samples/recipes/record-detail-layout/package.json +1 -0
  351. package/samples/recipes/reference-data/package.json +3 -0
  352. package/samples/recipes/relations/package.json +3 -0
  353. package/samples/recipes/screens-nav/package.json +3 -0
  354. package/samples/recipes/search/package.json +3 -0
  355. package/samples/recipes/secrets-demo/package.json +3 -0
  356. package/samples/recipes/security-baseline/src/feature.ts +2 -2
  357. package/samples/recipes/session-revocation/README.md +1 -1
  358. package/samples/recipes/session-revocation/package.json +3 -0
  359. package/samples/recipes/session-revocation/src/feature.ts +1 -1
  360. package/samples/recipes/state-machine/package.json +3 -1
  361. package/samples/recipes/state-machine/src/entities/invoice.ts +2 -2
  362. package/samples/recipes/state-machine/src/events.ts +19 -0
  363. package/samples/recipes/state-machine/src/feature.ts +25 -30
  364. package/samples/recipes/state-machine/src/handlers/_helpers.ts +13 -14
  365. package/samples/recipes/state-machine/src/handlers/create.ts +1 -1
  366. package/samples/recipes/state-machine/src/handlers/transitions.ts +129 -122
  367. package/samples/recipes/state-machine/src/reducer.ts +1 -1
  368. package/samples/recipes/state-machine/tsconfig.json +2 -6
  369. package/samples/recipes/tags-basic/package.json +3 -0
  370. package/samples/recipes/tenant-isolation/package.json +3 -0
  371. package/samples/recipes/tenant-settings/package.json +3 -0
  372. package/samples/recipes/tier-admin/package.json +3 -0
  373. package/samples/recipes/timezones/package.json +3 -0
  374. package/samples/recipes/tsconfig.base.json +1 -1
  375. package/samples/recipes/user-data-rights/package.json +3 -0
  376. package/samples/recipes/user-data-rights/src/feature.ts +6 -2
  377. package/samples/recipes/user-profile/package.json +3 -0
  378. package/samples/recipes/user-profile/src/feature.ts +2 -2
  379. package/samples/recipes/webhook-step/package.json +3 -0
  380. package/samples/recipes/wizard-form/package.json +1 -0
  381. package/samples/recipes/workflow-engine/package.json +3 -0
  382. package/samples/recipes/workflow-engine/src/db/queries/suspended-runs.ts +5 -2
  383. package/samples/recipes/writeform-section/package.json +1 -0
  384. package/packages/bundled-features/src/file-provider-s3-env/feature.ts +0 -58
  385. /package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/env-helper.ts +0 -0
@@ -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,
@@ -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";
@@ -38,10 +38,10 @@
38
38
  // Rows weiter (reference bleibt alt), deshalb id-Cursor-Paging statt einer
39
39
  // einzelnen Page — sonst verstopfen erledigte Rows das batchLimit-Fenster.
40
40
 
41
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
42
41
  import {
43
42
  collectPiiSubjectFields,
44
43
  configuredPiiSubjectKms,
44
+ isRecordKeyedField,
45
45
  isSelfPiiField,
46
46
  type KmsAdapter,
47
47
  resolveSubjectForField,
@@ -53,6 +53,7 @@ import {
53
53
  createTenantDb,
54
54
  type DbRunner,
55
55
  nullBlindIndexesForSubject,
56
+ selectMany,
56
57
  type TenantDb,
57
58
  type WhereObject,
58
59
  WritePurposes,
@@ -160,10 +161,17 @@ async function purgeMatchingRows(
160
161
  // (purgeMatchingRows's hardDelete select) is enough; the with-files path's
161
162
  // full row works the same way.
162
163
  //
163
- // userOwned/tenantOwned are explicitly excluded: hardDelete only destroys
164
+ // userOwned/tenantOwned are explicitly excluded (except a whenAbsent: "self" field
165
+ // of an ownerless row, which resolves to this row's own record key): hardDelete only destroys
164
166
  // THIS row's own data, but the owning user's/tenant's key may still protect
165
167
  // OTHER live rows that reference the same subject — erasing it here would
166
168
  // be a silent cross-row data-loss bug, not a retention fix.
169
+ function mayResolveToOwnRecordKey(field: EntityDefinition["fields"][string]): boolean {
170
+ if ("tenantOwned" in field && field.tenantOwned === true) return false;
171
+ if ("userOwned" in field && field.userOwned !== undefined) return isRecordKeyedField(field);
172
+ return ("recordOwned" in field && field.recordOwned === true) || isSelfPiiField(field);
173
+ }
174
+
167
175
  function collectHardDeleteEraseSubjects(
168
176
  entity: EntityDefinition,
169
177
  entityName: string,
@@ -173,13 +181,11 @@ function collectHardDeleteEraseSubjects(
173
181
  const subjectsByKey = new Map<string, SubjectId>();
174
182
  for (const fieldName of collectPiiSubjectFields(entity)) {
175
183
  const field = entity.fields[fieldName];
176
- if (!field) continue;
177
- const isRecordOwned = "recordOwned" in field && field.recordOwned === true;
178
- const isUserOwned = "userOwned" in field && field.userOwned !== undefined;
179
- const isTenantOwned = "tenantOwned" in field && field.tenantOwned === true;
180
- if (isUserOwned || isTenantOwned) continue; // never erase — see header comment
181
- if (!isRecordOwned && !isSelfPiiField(field)) continue;
184
+ if (!field || !mayResolveToOwnRecordKey(field)) continue;
182
185
  const subject = resolveSubjectForField(entity, fieldName, row, { tenantId, entityName });
186
+ // whenAbsent: "self" resolves to the owner's key while the row has an owner — never erased here
187
+ const isUserOwned = "userOwned" in field && field.userOwned !== undefined;
188
+ if (isUserOwned && subject?.kind !== "record") continue;
183
189
  if (subject) subjectsByKey.set(subjectIdToKey(subject), subject);
184
190
  }
185
191
  return Array.from(subjectsByKey.values());
@@ -236,7 +242,7 @@ async function forgetRowAndEraseKeys(args: {
236
242
  readonly registry: Registry;
237
243
  }): Promise<{ readonly isSuccess: boolean }> {
238
244
  return runInSubTransaction(args.db, async (sp) => {
239
- const tdb = createTenantDb(sp, args.tenantId, "system");
245
+ const tdb = createTenantDb({ db: sp, tenantId: args.tenantId, mode: "system" });
240
246
  const result = await args.executor.forget(
241
247
  { id: args.row["id"] as EntityId },
242
248
  args.systemUser,
@@ -666,7 +672,7 @@ export async function runRetentionCleanup(
666
672
  // the daily cron converges (hardDelete removes rows, softDelete's isDeleted
667
673
  // filter shrinks the set). A single batched forget/delete event is a follow-up.
668
674
  const systemUser = createSystemUser(tenantId);
669
- const tdb = createTenantDb(db, tenantId, "system");
675
+ const tdb = createTenantDb({ db, tenantId, mode: "system" });
670
676
  const fileHolders = collectSingleFileHolders(registry);
671
677
 
672
678
  // Pre-load every override row for this tenant ONCE — N entities × M
@@ -1,6 +1,9 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import { computeBlindIndex, configuredBlindIndexKey } from "@cosmicdrift/kumiko-framework/crypto";
3
- import { createEventStoreExecutor, type TenantDb } from "@cosmicdrift/kumiko-framework/db";
2
+ import {
3
+ createEventStoreExecutor,
4
+ fetchOne,
5
+ type TenantDb,
6
+ } from "@cosmicdrift/kumiko-framework/db";
4
7
  import type { SessionUser, TenantId, WriteResult } from "@cosmicdrift/kumiko-framework/engine";
5
8
  import { ConflictError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
6
9
  import { generateDeterministicId } from "@cosmicdrift/kumiko-framework/utils";
@@ -1,5 +1,5 @@
1
- import { deleteManyBatched } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
2
+ import { deleteManyBatched } from "@cosmicdrift/kumiko-framework/db";
3
3
  import { type PruneEventsOptions, pruneEvents } from "@cosmicdrift/kumiko-framework/pipeline";
4
4
  import { deliveryAttemptsTable } from "./tables.js";
5
5
 
@@ -148,7 +148,7 @@ export function buildChannelContext(
148
148
  filesForTenant?: (tenantId: string) => FileContext | undefined,
149
149
  ): ChannelContext {
150
150
  return {
151
- db: createTenantDb(db, tenantId),
151
+ db: createTenantDb({ db, tenantId }),
152
152
  registry,
153
153
  sseBroker,
154
154
  tenantId,
@@ -1,5 +1,5 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbConnection } 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 { notificationAddressOptOutsTable } from "../../tables.js";
5
5
 
@@ -1,5 +1,5 @@
1
- import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
2
+ import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/db";
3
3
  import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
4
4
 
5
5
  export type NotificationPreferenceRow = {
@@ -15,6 +15,7 @@ import type {
15
15
  } from "@cosmicdrift/kumiko-framework/engine";
16
16
  import {
17
17
  assertNotificationVariables,
18
+ bridgeStub,
18
19
  createSystemUser,
19
20
  } from "@cosmicdrift/kumiko-framework/engine";
20
21
  import type { FileContext } from "@cosmicdrift/kumiko-framework/files";
@@ -24,7 +25,6 @@ import {
24
25
  createEscapeHatchReporter,
25
26
  } from "@cosmicdrift/kumiko-framework/pipeline";
26
27
  import type { SecretsContext } from "@cosmicdrift/kumiko-framework/secrets";
27
- import { bridgeStub } from "@cosmicdrift/kumiko-framework/testing/handler-context";
28
28
  import { generateId } from "@cosmicdrift/kumiko-framework/utils";
29
29
  import type { Redis } from "ioredis";
30
30
  import { fileContextFromResolver } from "../file-foundation/index.js";
@@ -273,17 +273,27 @@ export function createDeliveryService(options: DeliveryServiceOptions): Delivery
273
273
  // path a cross-tenant read the dispatcher never allows. Cross-tenant reach only
274
274
  // exists through the grant-carrying systemDb view below.
275
275
  const isSystem = registry.isHandlerSystemScoped(tenantUserIdsQuery);
276
- const tenantDb = createTenantDb(run.db, tenantId, "tenant", undefined, undefined, undefined, {
277
- report,
276
+ const tenantDb = createTenantDb({
277
+ db: run.db,
278
+ tenantId,
279
+ mode: "tenant",
280
+ grants: {
281
+ report,
282
+ },
278
283
  });
279
284
  // The dispatcher grants a systemScope handler's ctx.systemDb.unsafeRaw() ungated —
280
285
  // the grant comes from the handler's own r.systemScope() registration, not from this
281
286
  // caller. Only the systemDb view's own source TenantDb carries the grant, so it
282
287
  // can't leak onto ctx.db.
283
288
  const systemDbSourceTenantDb = isSystem
284
- ? createTenantDb(run.db, tenantId, "system", undefined, undefined, undefined, {
285
- report,
286
- unsafeRaw: { reason: `r.systemScope() handler "${tenantUserIdsQuery}"` },
289
+ ? createTenantDb({
290
+ db: run.db,
291
+ tenantId,
292
+ mode: "system",
293
+ grants: {
294
+ report,
295
+ unsafeRaw: { reason: `r.systemScope() handler "${tenantUserIdsQuery}"` },
296
+ },
287
297
  })
288
298
  : undefined;
289
299
  // Hand-built context, not routed through the dispatcher — this needs both
@@ -1,5 +1,5 @@
1
- import { updateMany, upsertByPk } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
2
+ import { updateMany, upsertByPk } from "@cosmicdrift/kumiko-framework/db";
3
3
  import {
4
4
  access,
5
5
  defineFeature,