@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.388.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (643) hide show
  1. package/LICENSE +21 -57
  2. package/dist/agent-tools/tool-catalog.js +1 -1
  3. package/dist/agent-tools/tool-dispatch.d.ts +7 -7
  4. package/dist/agent-tools/tool-dispatch.js +9 -9
  5. package/dist/audit/handlers/audit-events.js +1 -1
  6. package/dist/audit/screens.js +1 -1
  7. package/dist/auth-email-password/feature.js +1 -1
  8. package/dist/auth-email-password/handlers/change-password.write.js +3 -3
  9. package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
  10. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
  11. package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
  12. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  13. package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
  14. package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
  15. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
  16. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  17. package/dist/auth-email-password/handlers/login.write.js +1 -1
  18. package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
  19. package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
  20. package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
  21. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  22. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
  23. package/dist/auth-email-password/index.js +5 -5
  24. package/dist/auth-email-password/lockout-store.js +1 -1
  25. package/dist/auth-email-password/seeding.d.ts +42 -45
  26. package/dist/auth-email-password/seeding.js +51 -53
  27. package/dist/auth-email-password/signup-token-store.js +8 -8
  28. package/dist/auth-email-password/testing.js +3 -3
  29. package/dist/auth-email-password/web/auth-client.d.ts +2 -2
  30. package/dist/auth-email-password/web/auth-client.js +36 -37
  31. package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
  32. package/dist/auth-email-password/web/auth-gate.js +15 -16
  33. package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
  34. package/dist/auth-email-password/web/client-plugin.js +4 -5
  35. package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
  36. package/dist/auth-email-password/web/constants.js +3 -3
  37. package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
  38. package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
  39. package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
  40. package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
  41. package/dist/auth-email-password/web/index.js +5 -5
  42. package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
  43. package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
  44. package/dist/auth-email-password/web/login-screen.d.ts +1 -1
  45. package/dist/auth-email-password/web/login-screen.js +2 -3
  46. package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
  47. package/dist/auth-email-password/web/reset-password-screen.js +12 -13
  48. package/dist/auth-email-password/web/session.d.ts +10 -9
  49. package/dist/auth-email-password/web/session.js +28 -29
  50. package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
  51. package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
  52. package/dist/auth-email-password/web/signup-screen.js +13 -13
  53. package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
  54. package/dist/auth-email-password/web/tenant-switcher.js +21 -22
  55. package/dist/auth-email-password/web/use-shell-user.js +12 -13
  56. package/dist/auth-email-password/web/user-menu.d.ts +4 -4
  57. package/dist/auth-email-password/web/user-menu.js +12 -13
  58. package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
  59. package/dist/auth-email-password/web/verify-email-screen.js +9 -10
  60. package/dist/auth-foundation/boot-checks.js +4 -4
  61. package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
  62. package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
  63. package/dist/auth-foundation/types.js +2 -2
  64. package/dist/auth-mfa/feature-exports.d.ts +2 -2
  65. package/dist/auth-mfa/feature.js +8 -0
  66. package/dist/auth-mfa/handlers/disable.write.js +3 -3
  67. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
  68. package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
  69. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
  70. package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
  71. package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
  72. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  73. package/dist/auth-mfa/token-secrets.js +1 -1
  74. package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
  75. package/dist/auth-mfa/web/client-plugin.js +1 -1
  76. package/dist/auth-mfa/web/i18n.js +8 -4
  77. package/dist/auth-mfa/web/index.js +4 -4
  78. package/dist/auth-mfa/web/mfa-client.js +17 -16
  79. package/dist/auth-mfa/web/mfa-code-or-recovery-field.d.ts +11 -0
  80. package/dist/auth-mfa/web/mfa-code-or-recovery-field.js +12 -0
  81. package/dist/auth-mfa/web/mfa-disable-dialog.js +14 -3
  82. package/dist/auth-mfa/web/mfa-regenerate-recovery-dialog.js +14 -3
  83. package/dist/auth-mfa/web/mfa-setup-preauth-screen.js +10 -5
  84. package/dist/auth-mfa/web/mfa-verify-screen.js +32 -11
  85. package/dist/billing-foundation/aggregate-id.d.ts +5 -5
  86. package/dist/billing-foundation/aggregate-id.js +10 -11
  87. package/dist/billing-foundation/checkout-core.d.ts +9 -14
  88. package/dist/billing-foundation/checkout-core.js +24 -39
  89. package/dist/billing-foundation/consumer-protection/confirmation-mail.js +8 -2
  90. package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +1 -0
  91. package/dist/billing-foundation/consumer-protection/consent-gate.js +1 -0
  92. package/dist/billing-foundation/consumer-protection/issue-confirmation.js +9 -3
  93. package/dist/billing-foundation/consumer-protection/mail-notifications.js +3 -1
  94. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.d.ts +4 -2
  95. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.js +6 -5
  96. package/dist/billing-foundation/consumer-protection/termination-record.d.ts +5 -1
  97. package/dist/billing-foundation/consumer-protection/termination-record.js +27 -17
  98. package/dist/billing-foundation/consumer-protection/termination-request.js +12 -7
  99. package/dist/billing-foundation/consumer-protection/termination-revoke.js +12 -7
  100. package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +1 -1
  101. package/dist/billing-foundation/consumer-protection/termination-texts.js +3 -0
  102. package/dist/billing-foundation/consumer-protection/withdrawal-period.d.ts +5 -2
  103. package/dist/billing-foundation/consumer-protection/withdrawal-period.js +8 -9
  104. package/dist/billing-foundation/entities.js +27 -27
  105. package/dist/billing-foundation/events.d.ts +1 -0
  106. package/dist/billing-foundation/events.js +19 -17
  107. package/dist/billing-foundation/feature.js +45 -44
  108. package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
  109. package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
  110. package/dist/billing-foundation/handlers/billing-plans.query.js +35 -5
  111. package/dist/billing-foundation/handlers/create-checkout-session.write.js +19 -17
  112. package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
  113. package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
  114. package/dist/billing-foundation/handlers/plan-switch-preview.query.d.ts +13 -0
  115. package/dist/billing-foundation/handlers/plan-switch-preview.query.js +48 -0
  116. package/dist/billing-foundation/handlers/process-event.write.d.ts +6 -0
  117. package/dist/billing-foundation/handlers/process-event.write.js +28 -22
  118. package/dist/billing-foundation/handlers/start-plan-checkout.write.js +32 -5
  119. package/dist/billing-foundation/handlers/switch-plan.write.d.ts +2 -2
  120. package/dist/billing-foundation/handlers/switch-plan.write.js +56 -64
  121. package/dist/billing-foundation/handlers/sync-subscription.write.js +12 -1
  122. package/dist/billing-foundation/i18n.js +22 -0
  123. package/dist/billing-foundation/index.d.ts +1 -1
  124. package/dist/billing-foundation/plan-catalog.d.ts +21 -5
  125. package/dist/billing-foundation/plan-catalog.js +25 -16
  126. package/dist/billing-foundation/plan-switch.d.ts +12 -0
  127. package/dist/billing-foundation/plan-switch.js +60 -0
  128. package/dist/billing-foundation/projection.d.ts +15 -11
  129. package/dist/billing-foundation/projection.js +38 -37
  130. package/dist/billing-foundation/subscription-tier-sync.js +3 -3
  131. package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
  132. package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
  133. package/dist/billing-foundation/types.d.ts +97 -42
  134. package/dist/billing-foundation/types.js +29 -20
  135. package/dist/billing-foundation/validate-options.js +17 -0
  136. package/dist/billing-foundation/web/billing-plans-panel.js +82 -36
  137. package/dist/billing-foundation/web/checkout-consent-dialog.d.ts +17 -3
  138. package/dist/billing-foundation/web/checkout-consent-dialog.js +14 -10
  139. package/dist/billing-foundation/web/constants.d.ts +4 -0
  140. package/dist/billing-foundation/web/constants.js +4 -0
  141. package/dist/billing-foundation/web/plan-price.d.ts +15 -0
  142. package/dist/billing-foundation/web/plan-price.js +32 -0
  143. package/dist/billing-foundation/web/plan-switch-confirm-dialog.d.ts +15 -0
  144. package/dist/billing-foundation/web/plan-switch-confirm-dialog.js +66 -0
  145. package/dist/cap-counter/aggregate-id.js +8 -9
  146. package/dist/cap-counter/cap-reservation.js +5 -1
  147. package/dist/cap-counter/constants.js +11 -12
  148. package/dist/cap-counter/enforce-cap.d.ts +59 -62
  149. package/dist/cap-counter/enforce-cap.js +49 -49
  150. package/dist/cap-counter/entity.js +29 -29
  151. package/dist/cap-counter/feature.js +34 -35
  152. package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
  153. package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
  154. package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
  155. package/dist/cap-counter/stock-cap-guard.js +8 -2
  156. package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
  157. package/dist/channel-email/feature.js +1 -1
  158. package/dist/channel-email/smtp-transport.d.ts +18 -17
  159. package/dist/channel-email/smtp-transport.js +24 -21
  160. package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
  161. package/dist/compliance-profiles/feature.js +4 -4
  162. package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
  163. package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
  164. package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
  165. package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
  166. package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
  167. package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
  168. package/dist/compliance-profiles/schema/profile-selection.js +18 -23
  169. package/dist/compliance-profiles/seeding.js +14 -15
  170. package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
  171. package/dist/compliance-profiles-ops/index.js +2 -2
  172. package/dist/config/handlers/cascade.query.d.ts +5 -0
  173. package/dist/config/handlers/cascade.query.js +4 -3
  174. package/dist/config/handlers/readiness.query.d.ts +4 -4
  175. package/dist/config/handlers/readiness.query.js +1 -1
  176. package/dist/config/handlers/reencrypt.job.js +4 -5
  177. package/dist/config/handlers/set.write.js +4 -4
  178. package/dist/config/handlers/values.query.d.ts +5 -0
  179. package/dist/config/handlers/values.query.js +4 -3
  180. package/dist/config/resolver.js +4 -4
  181. package/dist/config/table.js +10 -10
  182. package/dist/config/write-helpers.d.ts +1 -0
  183. package/dist/config/write-helpers.js +19 -10
  184. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
  185. package/dist/crypto-shredding/handlers/forget-subject.write.js +25 -21
  186. package/dist/custom-fields/aggregate-id.d.ts +12 -13
  187. package/dist/custom-fields/aggregate-id.js +16 -17
  188. package/dist/custom-fields/entity.js +49 -47
  189. package/dist/custom-fields/events.js +7 -8
  190. package/dist/custom-fields/feature.d.ts +14 -14
  191. package/dist/custom-fields/feature.js +53 -54
  192. package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
  193. package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
  194. package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
  195. package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
  196. package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
  197. package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
  198. package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
  199. package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
  200. package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
  201. package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
  202. package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
  203. package/dist/custom-fields/lib/field-access.js +2 -2
  204. package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
  205. package/dist/custom-fields/lib/quota.js +1 -1
  206. package/dist/custom-fields/lib/value-schema.js +10 -12
  207. package/dist/custom-fields/run-retention.js +3 -3
  208. package/dist/custom-fields/schemas.js +14 -14
  209. package/dist/custom-fields/web/client-plugin.js +2 -5
  210. package/dist/custom-fields/web/constants.js +2 -2
  211. package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
  212. package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
  213. package/dist/custom-fields/wire-for-entity.js +65 -67
  214. package/dist/custom-fields/wire-user-data-rights.js +3 -3
  215. package/dist/data-retention/_internal/parse-override.js +2 -3
  216. package/dist/data-retention/feature.js +11 -18
  217. package/dist/data-retention/handlers/policy-for.query.js +6 -6
  218. package/dist/data-retention/keep-for.d.ts +7 -7
  219. package/dist/data-retention/keep-for.js +15 -15
  220. package/dist/data-retention/override-schema.d.ts +3 -4
  221. package/dist/data-retention/override-schema.js +13 -15
  222. package/dist/data-retention/presets.d.ts +4 -5
  223. package/dist/data-retention/presets.js +18 -23
  224. package/dist/data-retention/resolve-tenant-preset.js +17 -16
  225. package/dist/data-retention/resolver.d.ts +12 -12
  226. package/dist/data-retention/resolver.js +24 -23
  227. package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
  228. package/dist/data-retention/run-retention-cleanup.js +61 -51
  229. package/dist/data-retention/schema/tenant-retention-override.js +13 -11
  230. package/dist/delivery/channel-context.js +6 -3
  231. package/dist/delivery/db/queries/preferences.js +2 -2
  232. package/dist/delivery/delivery-service.js +22 -7
  233. package/dist/delivery/feature.js +2 -2
  234. package/dist/delivery/handlers/log.query.js +1 -1
  235. package/dist/delivery/handlers/preferences.query.d.ts +1 -1
  236. package/dist/delivery/handlers/preferences.query.js +20 -1
  237. package/dist/delivery/handlers/unsubscribe-page-chrome.query.js +1 -1
  238. package/dist/delivery/tables.js +9 -8
  239. package/dist/delivery/unsubscribe-link.d.ts +3 -1
  240. package/dist/delivery/unsubscribe-page-strings.d.ts +1 -0
  241. package/dist/delivery/unsubscribe-page-strings.js +1 -0
  242. package/dist/delivery/unsubscribe-page.d.ts +2 -0
  243. package/dist/delivery/unsubscribe-page.js +5 -0
  244. package/dist/delivery/unsubscribe.js +29 -11
  245. package/dist/document-ingest-foundation/entity.js +4 -4
  246. package/dist/document-ingest-foundation/events.js +2 -2
  247. package/dist/document-ingest-foundation/feature.js +2 -2
  248. package/dist/document-ingest-foundation/pages.js +1 -1
  249. package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
  250. package/dist/feature-toggles/compose-tier-resolver.js +1 -1
  251. package/dist/feature-toggles/feature.js +1 -1
  252. package/dist/feature-toggles/global-feature-state-table.js +1 -1
  253. package/dist/feature-toggles/handlers/registered.query.js +5 -5
  254. package/dist/feature-toggles/toggle-sync-signal.js +1 -1
  255. package/dist/feature-toggles/web/constants.js +1 -1
  256. package/dist/file-derivatives/feature.d.ts +1 -1
  257. package/dist/file-derivatives/feature.js +1 -1
  258. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  259. package/dist/file-derivatives/presets.js +1 -1
  260. package/dist/file-foundation/feature.js +6 -6
  261. package/dist/file-foundation/index.d.ts +1 -1
  262. package/dist/file-foundation/index.js +1 -1
  263. package/dist/file-foundation/read-file-ref-content.d.ts +3 -0
  264. package/dist/file-foundation/read-file-ref-content.js +6 -1
  265. package/dist/file-provider-inmemory/feature.d.ts +1 -1
  266. package/dist/file-provider-inmemory/feature.js +16 -16
  267. package/dist/file-provider-s3/env-named-feature.d.ts +0 -2
  268. package/dist/file-provider-s3/feature.js +16 -16
  269. package/dist/file-provider-s3/lib/s3-provider.js +6 -6
  270. package/dist/files/feature.js +6 -6
  271. package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
  272. package/dist/files-tenant-data/hooks.js +24 -26
  273. package/dist/files-tenant-data/index.js +1 -1
  274. package/dist/folders/feature.d.ts +1 -1
  275. package/dist/folders/web/folder-manager.js +2 -2
  276. package/dist/folders/web/tree.js +5 -5
  277. package/dist/form-draft/db/queries/cleanup.js +3 -3
  278. package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
  279. package/dist/form-draft/decrypt-draft.js +5 -1
  280. package/dist/form-draft/entity.js +3 -3
  281. package/dist/form-draft/feature.js +4 -5
  282. package/dist/form-draft/handlers/discard.write.js +1 -1
  283. package/dist/form-draft/release-file-refs.js +6 -6
  284. package/dist/form-draft/schemas.js +3 -3
  285. package/dist/form-draft/web/constants.js +0 -2
  286. package/dist/host-routing/dispatch.js +11 -20
  287. package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
  288. package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
  289. package/dist/inbound-mail-foundation/connect-routes.js +4 -3
  290. package/dist/inbound-mail-foundation/constants.d.ts +22 -24
  291. package/dist/inbound-mail-foundation/constants.js +30 -33
  292. package/dist/inbound-mail-foundation/entities.d.ts +12 -12
  293. package/dist/inbound-mail-foundation/entities.js +47 -48
  294. package/dist/inbound-mail-foundation/events.d.ts +4 -3
  295. package/dist/inbound-mail-foundation/events.js +50 -47
  296. package/dist/inbound-mail-foundation/feature.js +39 -39
  297. package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
  298. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
  299. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
  300. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
  301. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
  302. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
  303. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
  304. package/dist/inbound-mail-foundation/handlers/update-account.write.d.ts +2 -2
  305. package/dist/inbound-mail-foundation/handlers/update-account.write.js +22 -14
  306. package/dist/inbound-mail-foundation/i18n.js +0 -1
  307. package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
  308. package/dist/inbound-mail-foundation/oauth-state.js +11 -10
  309. package/dist/inbound-mail-foundation/projection.d.ts +4 -4
  310. package/dist/inbound-mail-foundation/projection.js +31 -29
  311. package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
  312. package/dist/inbound-mail-foundation/provider-factory.js +9 -9
  313. package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
  314. package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
  315. package/dist/inbound-mail-foundation/screens.js +0 -3
  316. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
  317. package/dist/inbound-mail-foundation/types.d.ts +49 -49
  318. package/dist/inbound-mail-foundation/types.js +21 -21
  319. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
  320. package/dist/inbound-mail-foundation/watch-supervisor.js +85 -67
  321. package/dist/inbound-provider-imap/credential-document.js +13 -13
  322. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  323. package/dist/inbound-provider-imap/feature.js +42 -40
  324. package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
  325. package/dist/inbound-provider-imap/imap-client.js +20 -19
  326. package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
  327. package/dist/inbound-provider-inmemory/feature.js +19 -19
  328. package/dist/jobs/db/queries/retention.js +2 -2
  329. package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
  330. package/dist/jobs/events.js +1 -1
  331. package/dist/jobs/feature.d.ts +1 -0
  332. package/dist/jobs/feature.js +13 -10
  333. package/dist/jobs/handlers/detail.query.js +4 -4
  334. package/dist/jobs/handlers/list.query.js +1 -1
  335. package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
  336. package/dist/jobs/handlers/reindex-entity.job.js +1 -1
  337. package/dist/jobs/handlers/retry.write.js +1 -1
  338. package/dist/jobs/handlers/tenant-failures.query.d.ts +1 -1
  339. package/dist/jobs/handlers/tenant-failures.query.js +45 -41
  340. package/dist/jobs/handlers/tenant-runs.query.d.ts +1 -1
  341. package/dist/jobs/handlers/tenant-runs.query.js +54 -50
  342. package/dist/jobs/job-instant.js +1 -1
  343. package/dist/jobs/job-run-logger.js +15 -15
  344. package/dist/jobs/job-run-table.js +3 -3
  345. package/dist/jobs/screens.js +1 -1
  346. package/dist/jobs/tenant-job-failure-table.js +1 -1
  347. package/dist/jobs/tenant-job-run-table.js +1 -1
  348. package/dist/ledger/entity.js +5 -5
  349. package/dist/ledger/feature.js +3 -3
  350. package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
  351. package/dist/ledger/recurring.js +12 -12
  352. package/dist/ledger/schemas.js +1 -1
  353. package/dist/ledger/web/constants.js +2 -2
  354. package/dist/ledger/web/index.js +7 -7
  355. package/dist/legal-pages/feature.d.ts +4 -4
  356. package/dist/legal-pages/feature.js +25 -26
  357. package/dist/legal-pages/markdown.js +3 -3
  358. package/dist/legal-pages/web/client-plugin.js +23 -24
  359. package/dist/legal-pages/web/index.js +0 -1
  360. package/dist/mail-foundation/feature.d.ts +5 -5
  361. package/dist/mail-foundation/feature.js +27 -25
  362. package/dist/mail-transport-inmemory/feature.d.ts +4 -4
  363. package/dist/mail-transport-inmemory/feature.js +27 -28
  364. package/dist/mail-transport-smtp/feature.js +20 -20
  365. package/dist/managed-pages/branding.js +6 -6
  366. package/dist/managed-pages/feature.d.ts +26 -26
  367. package/dist/managed-pages/feature.js +34 -34
  368. package/dist/managed-pages/handlers/by-slug.query.js +5 -6
  369. package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
  370. package/dist/managed-pages/handlers/set.write.js +5 -7
  371. package/dist/managed-pages/screens/page-screens.js +11 -11
  372. package/dist/managed-pages/seeding.js +8 -8
  373. package/dist/managed-pages/table.js +13 -12
  374. package/dist/managed-pages/web/client-plugin.d.ts +1 -1
  375. package/dist/managed-pages/web/client-plugin.js +5 -5
  376. package/dist/managed-pages/web/i18n.js +1 -1
  377. package/dist/notes-history/entity.js +4 -4
  378. package/dist/notes-history/feature.d.ts +2 -2
  379. package/dist/notes-history-user-data/hooks.js +1 -1
  380. package/dist/page-render/layout.js +9 -9
  381. package/dist/page-render/markdown.js +11 -11
  382. package/dist/page-render/security-headers.js +7 -6
  383. package/dist/personal-access-tokens/feature.d.ts +1 -1
  384. package/dist/personal-access-tokens/feature.js +9 -5
  385. package/dist/personal-access-tokens/roles.js +2 -2
  386. package/dist/readiness/handlers/status.query.js +3 -3
  387. package/dist/renderer-foundation/api.js +12 -13
  388. package/dist/renderer-foundation/constants.js +2 -2
  389. package/dist/renderer-foundation/feature.js +7 -7
  390. package/dist/renderer-pdf/render-table-pdf.d.ts +1 -1
  391. package/dist/renderer-pdf/render-table-pdf.js +22 -10
  392. package/dist/secrets/feature.js +9 -9
  393. package/dist/secrets/web/constants.js +2 -2
  394. package/dist/seo/feature.js +3 -3
  395. package/dist/sessions/constants.d.ts +1 -1
  396. package/dist/sessions/constants.js +1 -1
  397. package/dist/sessions/feature.d.ts +2 -2
  398. package/dist/sessions/feature.js +12 -8
  399. package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
  400. package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
  401. package/dist/sessions/handlers/revoke.write.js +1 -1
  402. package/dist/sessions/schema/user-session.js +4 -4
  403. package/dist/sessions/screens.js +2 -2
  404. package/dist/sessions/session-callbacks.js +2 -2
  405. package/dist/sessions/session-revoked-event.js +2 -2
  406. package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
  407. package/dist/shared/decrypt-stored-pii.d.ts +1 -0
  408. package/dist/shared/decrypt-stored-pii.js +7 -2
  409. package/dist/shared/encrypt-for-direct-write.js +1 -1
  410. package/dist/shared/index.d.ts +1 -1
  411. package/dist/shared/index.js +1 -1
  412. package/dist/shared/mail-template-body.d.ts +6 -2
  413. package/dist/shared/mail-template-body.js +7 -4
  414. package/dist/shared/map-with-concurrency.js +5 -4
  415. package/dist/shared/parent-visibility.js +2 -2
  416. package/dist/shared/password-hashing.js +1 -1
  417. package/dist/shared/signup-handover.js +1 -2
  418. package/dist/shared/single-use-token-store.js +1 -1
  419. package/dist/step-dispatcher/feature.js +1 -0
  420. package/dist/subscription-dodo/client.d.ts +17 -0
  421. package/dist/subscription-dodo/client.js +31 -0
  422. package/dist/subscription-dodo/constants.d.ts +12 -0
  423. package/dist/subscription-dodo/constants.js +19 -0
  424. package/dist/subscription-dodo/feature.d.ts +37 -0
  425. package/dist/subscription-dodo/feature.js +144 -0
  426. package/dist/subscription-dodo/index.d.ts +2 -0
  427. package/dist/subscription-dodo/index.js +4 -0
  428. package/dist/subscription-dodo/plugin-methods.d.ts +23 -0
  429. package/dist/subscription-dodo/plugin-methods.js +260 -0
  430. package/dist/subscription-dodo/runtime.d.ts +27 -0
  431. package/dist/subscription-dodo/runtime.js +89 -0
  432. package/dist/subscription-dodo/verify-webhook.d.ts +37 -0
  433. package/dist/subscription-dodo/verify-webhook.js +189 -0
  434. package/dist/subscription-mollie/constants.js +15 -17
  435. package/dist/subscription-mollie/feature.d.ts +17 -18
  436. package/dist/subscription-mollie/feature.js +24 -24
  437. package/dist/subscription-mollie/index.js +3 -3
  438. package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
  439. package/dist/subscription-mollie/plugin-methods.js +15 -14
  440. package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
  441. package/dist/subscription-mollie/verify-webhook.js +27 -27
  442. package/dist/subscription-stripe/constants.js +4 -6
  443. package/dist/subscription-stripe/feature.d.ts +14 -14
  444. package/dist/subscription-stripe/feature.js +36 -34
  445. package/dist/subscription-stripe/index.js +6 -6
  446. package/dist/subscription-stripe/plugin-methods.js +18 -18
  447. package/dist/subscription-stripe/runtime.d.ts +1 -1
  448. package/dist/subscription-stripe/runtime.js +8 -7
  449. package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
  450. package/dist/subscription-stripe/verify-webhook.js +59 -61
  451. package/dist/tags/feature.d.ts +3 -3
  452. package/dist/tags/screens.js +1 -1
  453. package/dist/template-resolver/api.d.ts +3 -2
  454. package/dist/template-resolver/api.js +34 -12
  455. package/dist/template-resolver/compile-document-body.js +1 -0
  456. package/dist/template-resolver/feature.js +2 -2
  457. package/dist/template-resolver/handlers/bundle-import.js +3 -3
  458. package/dist/template-resolver/handlers/copy-locale.write.d.ts +5 -1
  459. package/dist/template-resolver/handlers/copy-locale.write.js +22 -7
  460. package/dist/template-resolver/handlers/diff-to-system.query.js +3 -2
  461. package/dist/template-resolver/handlers/document-base.js +3 -2
  462. package/dist/template-resolver/handlers/find-by-id.query.js +8 -7
  463. package/dist/template-resolver/handlers/list.query.js +6 -7
  464. package/dist/template-resolver/handlers/overview.query.d.ts +3 -0
  465. package/dist/template-resolver/handlers/overview.query.js +6 -3
  466. package/dist/template-resolver/handlers/shared.js +2 -2
  467. package/dist/template-resolver/handlers/template-write.js +3 -3
  468. package/dist/template-resolver/handlers/tenant-override-counts.query.js +1 -3
  469. package/dist/template-resolver/handlers/tenant-override-selection.d.ts +2 -1
  470. package/dist/template-resolver/handlers/tenant-overrides.query.js +28 -5
  471. package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
  472. package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
  473. package/dist/template-resolver/handlers/usage.query.d.ts +2 -1
  474. package/dist/template-resolver/handlers/usage.query.js +26 -16
  475. package/dist/template-resolver/handlers/validate.query.js +7 -2
  476. package/dist/template-resolver/seeding.js +30 -14
  477. package/dist/template-resolver/store-template-resource.d.ts +1 -0
  478. package/dist/template-resolver/store-template-resource.js +19 -4
  479. package/dist/template-resolver/table.js +10 -11
  480. package/dist/template-resolver/template-delivery-policy.d.ts +0 -5
  481. package/dist/template-resolver/template-delivery-policy.js +0 -6
  482. package/dist/template-resolver/template-meta.js +7 -4
  483. package/dist/template-resolver/template-preview.js +4 -3
  484. package/dist/template-resolver/web/client-plugin.js +2 -2
  485. package/dist/template-resolver/web/constants.d.ts +2 -2
  486. package/dist/template-resolver/web/constants.js +3 -3
  487. package/dist/template-resolver/web/index.d.ts +1 -0
  488. package/dist/template-resolver/web/index.js +1 -0
  489. package/dist/template-resolver/web/mail-layout-constants.d.ts +5 -0
  490. package/dist/template-resolver/web/mail-layout-constants.js +7 -0
  491. package/dist/tenant/feature.js +7 -7
  492. package/dist/tenant/handlers/member-directory.query.d.ts +1 -0
  493. package/dist/tenant/handlers/member-directory.query.js +11 -4
  494. package/dist/tenant/handlers/members.query.js +1 -1
  495. package/dist/tenant/handlers/team-list.query.js +1 -1
  496. package/dist/tenant/handlers/tenant-directory.query.d.ts +1 -0
  497. package/dist/tenant/handlers/tenant-directory.query.js +9 -5
  498. package/dist/tenant/invitation-table.js +37 -40
  499. package/dist/tenant/membership-table.js +3 -3
  500. package/dist/tenant/schema/tenant.js +7 -9
  501. package/dist/tenant/screens.js +1 -1
  502. package/dist/tenant/seeding.d.ts +6 -5
  503. package/dist/tenant/seeding.js +12 -12
  504. package/dist/tenant/testing.js +5 -6
  505. package/dist/tenant/web/constants.js +2 -2
  506. package/dist/tenant-handover/events.js +5 -7
  507. package/dist/tenant-handover/feature.js +1 -1
  508. package/dist/tenant-handover/grant.js +1 -1
  509. package/dist/tenant-handover/handlers/claim.write.js +1 -1
  510. package/dist/tenant-handover/move-entity-graph.js +8 -9
  511. package/dist/tenant-handover/signup-handover-provider.js +1 -2
  512. package/dist/tenant-handover/transfer-graph.js +4 -5
  513. package/dist/tenant-lifecycle/boot-checks.js +1 -1
  514. package/dist/tenant-lifecycle/constants.d.ts +1 -0
  515. package/dist/tenant-lifecycle/constants.js +4 -0
  516. package/dist/tenant-lifecycle/feature.js +1 -1
  517. package/dist/tenant-lifecycle/run-tenant-destroy.js +2 -2
  518. package/dist/tenant-settings/constants.js +1 -1
  519. package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
  520. package/dist/tenant-settings/tenant-defaults.js +9 -2
  521. package/dist/tier-engine/aggregate-id.d.ts +11 -11
  522. package/dist/tier-engine/aggregate-id.js +15 -16
  523. package/dist/tier-engine/compose-app.d.ts +14 -14
  524. package/dist/tier-engine/compose-app.js +1 -1
  525. package/dist/tier-engine/entity.js +18 -19
  526. package/dist/tier-engine/feature.d.ts +19 -17
  527. package/dist/tier-engine/feature.js +68 -69
  528. package/dist/tier-engine/handlers/active-tier.query.js +6 -7
  529. package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
  530. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +7 -8
  531. package/dist/tier-engine/handlers/set-tenant-tier.write.js +7 -4
  532. package/dist/tier-engine/tier-resolver.js +2 -2
  533. package/dist/tier-engine/trial.js +8 -8
  534. package/dist/tier-engine/web/constants.js +2 -2
  535. package/dist/tier-engine/web/index.js +4 -4
  536. package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
  537. package/dist/user/handlers/create.write.js +4 -4
  538. package/dist/user/schema/user.d.ts +11 -11
  539. package/dist/user/schema/user.js +45 -44
  540. package/dist/user/seeding.d.ts +15 -15
  541. package/dist/user/seeding.js +28 -28
  542. package/dist/user/testing.js +3 -3
  543. package/dist/user-data-rights/audit-download.d.ts +8 -8
  544. package/dist/user-data-rights/audit-download.js +19 -20
  545. package/dist/user-data-rights/boot-checks.js +1 -1
  546. package/dist/user-data-rights/deletion-token.js +1 -1
  547. package/dist/user-data-rights/feature.d.ts +49 -50
  548. package/dist/user-data-rights/feature.js +54 -53
  549. package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
  550. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
  551. package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
  552. package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
  553. package/dist/user-data-rights/handlers/export-status.query.js +8 -9
  554. package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
  555. package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
  556. package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
  557. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
  558. package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
  559. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
  560. package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
  561. package/dist/user-data-rights/handlers/request-export.write.js +42 -41
  562. package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
  563. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
  564. package/dist/user-data-rights/index.js +8 -10
  565. package/dist/user-data-rights/lib/default-mailers.js +3 -3
  566. package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
  567. package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
  568. package/dist/user-data-rights/run-export-jobs.js +130 -237
  569. package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
  570. package/dist/user-data-rights/run-forget-cleanup.js +65 -83
  571. package/dist/user-data-rights/run-user-export.d.ts +34 -33
  572. package/dist/user-data-rights/run-user-export.js +55 -57
  573. package/dist/user-data-rights/schema/download-attempt.js +11 -11
  574. package/dist/user-data-rights/schema/download-token.js +37 -41
  575. package/dist/user-data-rights/schema/export-job.d.ts +4 -4
  576. package/dist/user-data-rights/schema/export-job.js +65 -67
  577. package/dist/user-data-rights/token-helpers.d.ts +8 -9
  578. package/dist/user-data-rights/token-helpers.js +21 -25
  579. package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
  580. package/dist/user-data-rights/web/client-plugin.js +1 -1
  581. package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
  582. package/dist/user-data-rights/web/constants.js +1 -1
  583. package/dist/user-data-rights/web/index.js +5 -5
  584. package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
  585. package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
  586. package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
  587. package/dist/user-data-rights/zip-path.d.ts +15 -15
  588. package/dist/user-data-rights/zip-path.js +41 -40
  589. package/dist/user-data-rights-defaults/feature.js +15 -15
  590. package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
  591. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
  592. package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
  593. package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
  594. package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
  595. package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
  596. package/dist/user-profile/handlers/change-email.write.js +13 -13
  597. package/dist/user-profile/index.js +3 -3
  598. package/dist/user-profile/web/client-plugin.js +1 -1
  599. package/dist/user-profile/web/constants.js +1 -1
  600. package/dist/user-profile/web/profile-screen.js +1 -1
  601. package/dist/waitlist/handlers/export-purge.write.js +2 -1
  602. package/dist/waitlist/handlers/submit.write.js +5 -5
  603. package/dist/waitlist/import.d.ts +1 -0
  604. package/dist/waitlist/import.js +4 -0
  605. package/dist/waitlist/legacy-migrate.js +17 -6
  606. package/dist/waitlist/link-on-signup.js +18 -6
  607. package/dist/waitlist/options.d.ts +3 -0
  608. package/dist/workflow-runner/aggregate-id.d.ts +1 -1
  609. package/dist/workflow-runner/aggregate-id.js +1 -1
  610. package/dist/workflow-runner/event-subscriber.js +4 -5
  611. package/dist/workflow-runner/event-trigger.js +4 -17
  612. package/dist/workflow-runner/feature.js +2 -2
  613. package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
  614. package/dist/workflow-runner/pending-projection.js +6 -7
  615. package/dist/workflow-runner/runner.js +6 -6
  616. package/dist/workflow-runner/tables.js +6 -6
  617. package/dist/workflow-runner/workflow-registry.js +1 -1
  618. package/package.json +20 -10
  619. package/src/agent-tools/changes.json +6 -0
  620. package/src/audit/changes.json +12 -0
  621. package/src/auth-mfa/changes.json +6 -0
  622. package/src/billing-foundation/changes.json +55 -0
  623. package/src/cap-counter/changes.json +18 -0
  624. package/src/channel-email/changes.json +6 -0
  625. package/src/config/changes.json +12 -0
  626. package/src/crypto-shredding/changes.json +6 -0
  627. package/src/delivery/changes.json +30 -0
  628. package/src/form-draft/changes.json +6 -0
  629. package/src/host-routing/changes.json +6 -0
  630. package/src/inbound-mail-foundation/changes.json +18 -0
  631. package/src/jobs/changes.json +13 -0
  632. package/src/mail-foundation/changes.json +6 -0
  633. package/src/renderer-pdf/changes.json +6 -0
  634. package/src/step-dispatcher/changes.json +6 -0
  635. package/src/subscription-dodo/changes.json +14 -0
  636. package/src/subscription-stripe/changes.json +12 -0
  637. package/src/template-resolver/changes.json +48 -0
  638. package/src/tenant/changes.json +6 -0
  639. package/src/tenant-lifecycle/changes.json +6 -0
  640. package/src/tier-engine/changes.json +6 -0
  641. package/src/waitlist/changes.json +18 -0
  642. package/dist/billing-foundation/consumer-protection/stored-user-email.d.ts +0 -1
  643. package/dist/billing-foundation/consumer-protection/stored-user-email.js +0 -8
@@ -1,22 +1,21 @@
1
- // Test-Helper für compliance-profiles. Legt einen Profile-Eintrag direkt
2
- // über den Event-Store-Executor an — gleicher Pfad wie der echte
3
- // set-profile-Handler, aber ohne Zod-Schema-Engung (akzeptiert
4
- // minimal-no-region für Migration-Edge-Case-Tests) und ohne Access-
5
- // Check. Default ifExists="skip": nur fehlende Profile anlegen.
1
+ // Test helper for compliance-profiles. Creates a profile entry directly
2
+ // through the Event Store executor—the same path as the real
3
+ // set-profile handler, but without Zod schema restrictions (accepts
4
+ // minimal-no-region for migration edge-case tests) and without an access
5
+ // check. Default ifExists="skip": creates only missing profiles.
6
6
  //
7
- // Sprint 2 user-data-rights nutzt das fuer Test-Setup ("user kann
8
- // Daten exportieren mit profile X" — pro Test ein frischer Tenant +
9
- // Profile-Wahl in einem Helper-Call).
7
+ // user-data-rights uses this for test setup ("user can export data with
8
+ // profile X": a fresh tenant and profile selection per test in one helper
9
+ // call).
10
10
  //
11
- // Pattern matched seedTextBlock aus text-content.
11
+ // The pattern matches seedTextBlock in template-resolver/seeding.ts.
12
12
  import { createEventStoreExecutor, createTenantDb, fetchOne, } from "@cosmicdrift/kumiko-framework/db";
13
13
  import { runEventStoreSeed, TestUsers, } from "@cosmicdrift/kumiko-framework/seeding";
14
14
  import { tenantComplianceProfileEntity, tenantComplianceProfileTable, } from "./schema/profile-selection.js";
15
15
  const executor = createEventStoreExecutor(tenantComplianceProfileTable, tenantComplianceProfileEntity, { entityName: "tenant-compliance-profile" });
16
16
  export async function seedComplianceProfile(db, opts) {
17
- // user.tenantId muss === opts.tenantId sein damit Event-Store-Stream
18
- // + Projection im selben Tenant-Bucket landen (Memory:
19
- // feedback_event_store_tenant_consistency).
17
+ // user.tenantId must equal opts.tenantId so the Event Store stream
18
+ // and projection remain in the same tenant bucket.
20
19
  const by = opts.by ?? { ...TestUsers.systemAdmin, tenantId: opts.tenantId };
21
20
  const tdb = createTenantDb({ db, tenantId: opts.tenantId, mode: "system" });
22
21
  const overrideJson = opts.override !== undefined ? JSON.stringify(opts.override) : null;
@@ -35,9 +34,9 @@ export async function seedComplianceProfile(db, opts) {
35
34
  if (!result.isSuccess) {
36
35
  throw new Error(`seedComplianceProfile create failed: ${JSON.stringify(result)}`);
37
36
  }
38
- // @cast-boundary db-row: executor.create result.data ist die
39
- // inserted Projection-Row (Record<string, unknown>); id ist nach
40
- // INSERT garantiert (Runtime-Check direkt darunter).
37
+ // @cast-boundary db-row: executor.create result.data is the
38
+ // inserted projection row (Record<string, unknown>); id is guaranteed
39
+ // after INSERT (runtime check directly below).
41
40
  const data = result.data;
42
41
  if (data.id === undefined) {
43
42
  throw new Error("seedComplianceProfile: executor.create did not return an id");
@@ -4,12 +4,12 @@ import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import * as z from "zod";
5
5
  import { tenantComplianceProfileTable } from "../../compliance-profiles/index.js";
6
6
  import { decryptTenantNames, tenantTable } from "../../tenant/index.js";
7
- // SystemAdmin platform-wide counterpart to needs-profile (#2089).
7
+ // SystemAdmin platform-wide counterpart to needs-profile.
8
8
  //
9
- // #2084 stopped needs-profile from nagging a TenantAdmin who can no longer
9
+ // The change stopped needs-profile from nagging a TenantAdmin who can no longer
10
10
  // reach a picker narrowed to access.systemAdmin — correct, but it left no
11
11
  // one else able to notice: needs-profile stays TenantAdmin-only on purpose
12
- // (widening its call-access was explicitly rejected in #2084), so a
12
+ // (widening its call-access was explicitly rejected), so a
13
13
  // SystemAdmin who owns the platform-only picker has no way to see which
14
14
  // tenants still run on minimal-no-region. This query fills that gap
15
15
  // instead of touching needs-profile: every enabled tenant that has no row
@@ -1,8 +1,8 @@
1
1
  // compliance-profiles-ops — platform-wide SystemAdmin visibility into
2
- // tenants missing a compliance-profile selection (#2089).
2
+ // tenants missing a compliance-profile selection.
3
3
  //
4
4
  // needs-profile (compliance-profiles) tells a TenantAdmin they must pick a
5
- // profile, but stays TenantAdmin-only by design (#2084) — a SystemAdmin who
5
+ // profile, but stays TenantAdmin-only by design — a SystemAdmin who
6
6
  // owns a picker narrowed to access.systemAdmin has no query at all. Kept as
7
7
  // a separate feature (mirrors folders-user-data/notes-history-user-data)
8
8
  // rather than folded into compliance-profiles: this is the one genuinely
@@ -2,4 +2,9 @@ import { type ConfigCascade } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import * as z from "zod";
3
3
  export declare const cascadeQuery: import("@cosmicdrift/kumiko-types/define-handler").QueryHandlerDefinition<"cascade", z.ZodObject<{
4
4
  keys: z.ZodOptional<z.ZodArray<z.ZodString>>;
5
+ scope: z.ZodOptional<z.ZodEnum<{
6
+ system: "system";
7
+ tenant: "tenant";
8
+ user: "user";
9
+ }>>;
5
10
  }, z.core.$strip>, Record<string, ConfigCascade>, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
@@ -1,13 +1,14 @@
1
- import { defineQueryHandler, isEncryptedAtRest, } from "@cosmicdrift/kumiko-framework/engine";
1
+ import { ConfigScopes, defineQueryHandler, isEncryptedAtRest, } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import * as z from "zod";
3
3
  import { requireConfigResolver, requireSystemDb } from "../feature.js";
4
4
  import { MASKED, redactInheritedCascade, shouldRedactInherited } from "../read-redaction.js";
5
- import { hasConfigAccess } from "../write-helpers.js";
5
+ import { hasConfigAccess, keyDefAtScope } from "../write-helpers.js";
6
6
  export const cascadeQuery = defineQueryHandler({
7
7
  name: "cascade",
8
8
  description: "Shows, per config key the caller may read, the value at every cascade level (user, tenant, system, app override, default) and which level won; use it to explain where a setting's current value comes from.",
9
9
  schema: z.object({
10
10
  keys: z.array(z.string()).optional(),
11
+ scope: z.enum([ConfigScopes.system, ConfigScopes.tenant, ConfigScopes.user]).optional(),
11
12
  }),
12
13
  access: {
13
14
  openToAll: {
@@ -34,7 +35,7 @@ export const cascadeQuery = defineQueryHandler({
34
35
  continue;
35
36
  if (!hasConfigAccess(keyDef.access.read, query.user.roles))
36
37
  continue;
37
- keyDefs.set(key, keyDef);
38
+ keyDefs.set(key, keyDefAtScope(keyDef, query.payload.scope, query.user.roles));
38
39
  filteredKeys.push(key);
39
40
  }
40
41
  const cascades = await resolver.getCascadeBatch(filteredKeys, keyDefs, query.user.tenantId, query.user.id, db, ctx.secrets);
@@ -9,10 +9,10 @@ export type ReadinessMissingKey = {
9
9
  export type RequiredKeyGate = (qualifiedName: string) => boolean;
10
10
  export declare function buildProviderSelectionGate(ctx: HandlerContext, callerQn: string, user: SessionUser, db: TenantDb): Promise<RequiredKeyGate>;
11
11
  export declare function collectMissingRequiredConfig(ctx: HandlerContext, callerQn: string, user: SessionUser, db: TenantDb, gate?: RequiredKeyGate, options?: {
12
- /** Verdict-Pfade (Rollup, selbst role-gated) MÜSSEN ungefiltert zählen:
13
- * der Per-Key-read-Filter ist Info-Disclosure-Schutz für den
14
- * openToAll-Handler — im Verdict droppte er SystemAdmin-gated
15
- * required-Keys still und meldete ready:true trotz Lücke. */
12
+ /** Verdict paths (rollup, themselves role-gated) MUST count without filtering:
13
+ * the per-key read filter protects the openToAll handler from information
14
+ * disclosure, but in the verdict it dropped SystemAdmin-gated required keys
15
+ * and incorrectly reported ready:true despite the gap. */
16
16
  readonly skipAccessFilter?: boolean;
17
17
  }): Promise<ReadinessMissingKey[]>;
18
18
  export declare const readinessQuery: import("@cosmicdrift/kumiko-types/define-handler").QueryHandlerDefinition<"readiness", z.ZodObject<{}, z.core.$strip>, {
@@ -95,7 +95,7 @@ export const readinessQuery = defineQueryHandler({
95
95
  const db = requireSystemDb(ctx, "config:query:readiness", query.user.tenantId);
96
96
  const missing = await collectMissingRequiredConfig(ctx, "config:query:readiness", query.user, db);
97
97
  // Additive, display-ready fields for the admin-shell dashboard stat
98
- // panel (fw#2312) — `missing` itself stays untouched for existing
98
+ // panel — `missing` itself stays untouched for existing
99
99
  // consumers that read the array directly.
100
100
  return {
101
101
  missing,
@@ -16,8 +16,8 @@
16
16
  // the NEW envelope: after a full run even a from-scratch rebuild only
17
17
  // ever sees the current-KEK envelope.
18
18
  //
19
- // systemScope() fail-closed pattern (framework#2056): the initial scan is
20
- // intentionally cross-tenant (system-wide key rotation), acknowledged via
19
+ // systemScope() fail-closed pattern: the initial scan is intentionally
20
+ // cross-tenant (system-wide key rotation), acknowledged via
21
21
  // UncheckedSystemDb.acknowledgeCrossTenant(). Rows are bucketed by tenant,
22
22
  // and assertRowsTenant() re-verifies each row against its bucket's tenant
23
23
  // right before the write — both checks are built locally from the exported
@@ -163,9 +163,8 @@ export const reencryptJob = async (rawPayload, ctx) => {
163
163
  return "failed";
164
164
  }
165
165
  // Re-verify the row's own tenantId against the bucket it was scanned
166
- // into, right before the write (framework#2072) — a mismatch here
167
- // fails this row only (via onRowError below), it does not abort the
168
- // whole job.
166
+ // into, right before the write — a mismatch here fails this row only
167
+ // (via onRowError below), it does not abort the whole job.
169
168
  sdbFor(tenantId).assertRowsTenant([row], "tenantId");
170
169
  const plaintext = await cipher.decrypt(row.value, { tenantId });
171
170
  const reencrypted = await cipher.encrypt(plaintext, { tenantId });
@@ -45,7 +45,8 @@ export const setWrite = defineWriteHandler({
45
45
  // rejected), but an admin override write can still target scope=
46
46
  // "system" for a tenant/user-scoped key (validateScope allows any
47
47
  // requestedScope <= definedScope) — system-row has no subject.
48
- if (keyDef.piiEncrypted && scope === ConfigScopes.system) {
48
+ const piiScope = keyDef.piiEncrypted && scope !== ConfigScopes.system ? scope : undefined;
49
+ if (keyDef.piiEncrypted && piiScope === undefined) {
49
50
  return writeFailure(new UnprocessableError("invalid_scope", {
50
51
  i18nKey: "config.errors.invalidScope",
51
52
  details: { key: event.payload.key, definedScope: keyDef.scope, requestedScope: scope },
@@ -110,7 +111,7 @@ export const setWrite = defineWriteHandler({
110
111
  const cipher = requireConfigEncryption(ctx, "config:write:set");
111
112
  serialized = await cipher.encrypt(serialized, { tenantId });
112
113
  }
113
- else if (keyDef.piiEncrypted) {
114
+ else if (piiScope !== undefined) {
114
115
  const kms = configuredPiiSubjectKms();
115
116
  if (!kms) {
116
117
  throw new InternalError({
@@ -119,8 +120,7 @@ export const setWrite = defineWriteHandler({
119
120
  `configurePiiSubjectKms(adapter) at boot.`,
120
121
  });
121
122
  }
122
- // scope="system" was already rejected above — narrow accordingly.
123
- const subject = resolvePiiSubject(scope, tenantId, userId);
123
+ const subject = resolvePiiSubject(piiScope, tenantId, userId);
124
124
  const kmsCtx = {
125
125
  requestId: requestContext.get()?.requestId ?? "config:write:set",
126
126
  tenantId,
@@ -2,6 +2,11 @@ import { type ConfigScope, type ConfigValueSource } from "@cosmicdrift/kumiko-fr
2
2
  import * as z from "zod";
3
3
  export declare const valuesQuery: import("@cosmicdrift/kumiko-types/define-handler").QueryHandlerDefinition<"values", z.ZodObject<{
4
4
  keys: z.ZodOptional<z.ZodArray<z.ZodString>>;
5
+ scope: z.ZodOptional<z.ZodEnum<{
6
+ system: "system";
7
+ tenant: "tenant";
8
+ user: "user";
9
+ }>>;
5
10
  }, z.core.$strip>, Record<string, {
6
11
  value: string | number | boolean | undefined;
7
12
  scope: ConfigScope;
@@ -1,13 +1,14 @@
1
- import { defineQueryHandler, isEncryptedAtRest, } from "@cosmicdrift/kumiko-framework/engine";
1
+ import { ConfigScopes, defineQueryHandler, isEncryptedAtRest, } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import * as z from "zod";
3
3
  import { requireConfigResolver, requireSystemDb } from "../feature.js";
4
4
  import { MASKED, redactInheritedCascade, shouldRedactInherited } from "../read-redaction.js";
5
- import { hasConfigAccess } from "../write-helpers.js";
5
+ import { hasConfigAccess, keyDefAtScope } from "../write-helpers.js";
6
6
  export const valuesQuery = defineQueryHandler({
7
7
  name: "values",
8
8
  description: "Returns the effective value, scope and winning source for every config key the caller may read (optionally narrowed to `keys`), with encrypted and secret-backed values masked; use it to inspect the current settings.",
9
9
  schema: z.object({
10
10
  keys: z.array(z.string()).optional(),
11
+ scope: z.enum([ConfigScopes.system, ConfigScopes.tenant, ConfigScopes.user]).optional(),
11
12
  }),
12
13
  // Per-key read access enforced via hasConfigAccess inside the handler.
13
14
  access: {
@@ -34,7 +35,7 @@ export const valuesQuery = defineQueryHandler({
34
35
  continue;
35
36
  if (!hasConfigAccess(keyDef.access.read, query.user.roles))
36
37
  continue;
37
- keyDefs.set(qualifiedKey, keyDef);
38
+ keyDefs.set(qualifiedKey, keyDefAtScope(keyDef, query.payload.scope, query.user.roles));
38
39
  filteredKeys.push(qualifiedKey);
39
40
  }
40
41
  // Resolve through the full cascade (rows → app-override → computed →
@@ -402,10 +402,10 @@ export function validateAppOverrides(registry, overrides) {
402
402
  if (keyDef.computed) {
403
403
  throw new Error(`App-Boot-Override for "${key}": this key has a computed resolver (plan-based / derived). App-overrides would silently bypass that logic — remove the override, or remove the computed resolver if a flat deploy-default is intended.`);
404
404
  }
405
- // Per keyDef.type narrow value inline — TS narrowt nicht durch
406
- // `typeof value !== typeForKey(...)` (typeForKey returnt string,
407
- // kein discriminator). Das vermeidet `value as string|number` casts
408
- // unten, weil value innerhalb des Branches schon typed ist.
405
+ // Narrow by keyDef.type inline because TypeScript cannot narrow through
406
+ // `typeof value !== typeForKey(...)`, whose return type is string rather
407
+ // than a discriminator. This avoids `value as string|number` casts below;
408
+ // value is correctly typed within each branch.
409
409
  if (keyDef.type === "number") {
410
410
  if (typeof value !== "number") {
411
411
  throw new Error(`App-Boot-Override for "${key}": expected number, got ${typeof value}`);
@@ -2,19 +2,19 @@ import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { createEntity, createTextField } from "@cosmicdrift/kumiko-framework/engine";
3
3
  // Config values are event-sourced. Each (key, scope) is its own aggregate
4
4
  // stream — lifecycle events `configValue.created / .updated / .deleted`
5
- // flow through createEventStoreExecutor, which writes the stream + this
6
- // projection in one TX. Reads stay O(1) against the projection.
5
+ // flow through createEventStoreExecutor, which writes the stream and this
6
+ // projection in one TX. Reads remain O(1) against the projection.
7
7
  //
8
8
  // System-scope rows use SYSTEM_TENANT_ID (not null) — buildBaseColumns
9
- // (via buildEntityTable) forces tenant_id NOT NULL, so die pre-ES "NULL
10
- // means system" convention is replaced with a fixed sentinel. Der unique
11
- // index über (key, tenant_id, user_id) prevent duplicate writes at the DB
12
- // level — deklariert via entity.indexes.
9
+ // (via buildEntityTable) forces tenant_id NOT NULL, so the pre-ES "NULL
10
+ // means system" convention is replaced with a fixed sentinel. The unique
11
+ // index on (key, tenant_id, user_id) prevents duplicate writes at the DB
12
+ // level — declared via entity.indexes.
13
13
  //
14
- // Single-Source-of-Truth: `configValueEntity`. Die DB-Tabelle wird über
15
- // buildEntityTable aus der EntityDefinition abgeleitet, der unique-Index
16
- // ist via entity.indexes deklariert. Plural-Re-Export `configValuesTable`
17
- // dient handlers (`reset.write.ts` etc.) als typisierte Drizzle-Table-Ref.
14
+ // Single source of truth: `configValueEntity`. The DB table is derived from
15
+ // the EntityDefinition through buildEntityTable, and the unique index is
16
+ // declared via entity.indexes. The plural re-export `configValuesTable`
17
+ // provides handlers (`reset.write.ts` etc.) with a typed Drizzle table ref.
18
18
  export const configValueEntity = createEntity({
19
19
  table: "read_config_values",
20
20
  fields: {
@@ -35,6 +35,7 @@ export declare function checkWriteAccess(keyDef: ConfigKeyDefinition, userRoles:
35
35
  */
36
36
  export declare function checkScopeWriteAccess(scope: ConfigScope, userRoles: readonly string[]): KumikoError | null;
37
37
  export declare function validateScope(requestedScope: ConfigScope, definedScope: ConfigScope, key: string): KumikoError | null;
38
+ export declare function keyDefAtScope(keyDef: ConfigKeyDefinition, readScope: ConfigScope | undefined, roles: readonly string[]): ConfigKeyDefinition;
38
39
  export declare function resolveScopeIds(scope: ConfigScope, tenantId: TenantId, userId: string): {
39
40
  tenantId: TenantId;
40
41
  userId: string | null;
@@ -33,10 +33,9 @@ export async function findConfigRow(db, key, tenantId, userId) {
33
33
  export async function configRowHoldsValue(row, keyDef, cipher, qualifiedKey, serializedValue) {
34
34
  if (row?.value === null || row?.value === undefined)
35
35
  return false;
36
- if (!keyDef?.encrypted && !keyDef?.piiEncrypted)
36
+ if (keyDef === undefined || (!keyDef.encrypted && !keyDef.piiEncrypted)) {
37
37
  return row.value === serializedValue;
38
- if (!keyDef)
39
- return false;
38
+ }
40
39
  try {
41
40
  return (await decryptStoredValue(row.value, keyDef, cipher, qualifiedKey)) === serializedValue;
42
41
  }
@@ -112,12 +111,7 @@ export function checkScopeWriteAccess(scope, userRoles) {
112
111
  });
113
112
  }
114
113
  export function validateScope(requestedScope, definedScope, key) {
115
- const levels = {
116
- [ConfigScopes.system]: 0,
117
- [ConfigScopes.tenant]: 1,
118
- [ConfigScopes.user]: 2,
119
- };
120
- if (levels[requestedScope] > levels[definedScope]) {
114
+ if (SCOPE_LEVEL[requestedScope] > SCOPE_LEVEL[definedScope]) {
121
115
  return new UnprocessableError("invalid_scope", {
122
116
  i18nKey: "config.errors.invalidScope",
123
117
  details: { key, definedScope, requestedScope },
@@ -125,6 +119,21 @@ export function validateScope(requestedScope, definedScope, key) {
125
119
  }
126
120
  return null;
127
121
  }
122
+ const SCOPE_LEVEL = {
123
+ [ConfigScopes.system]: 0,
124
+ [ConfigScopes.tenant]: 1,
125
+ [ConfigScopes.user]: 2,
126
+ };
127
+ // Reads a tenant/user key at a narrower scope, e.g. system for a system-level screen.
128
+ // Only a SystemAdmin may widen the read to the platform level; everyone else keeps the normal cascade.
129
+ export function keyDefAtScope(keyDef, readScope, roles) {
130
+ if (readScope === undefined ||
131
+ !roles.includes("SystemAdmin") ||
132
+ SCOPE_LEVEL[readScope] >= SCOPE_LEVEL[keyDef.scope]) {
133
+ return keyDef;
134
+ }
135
+ return { ...keyDef, scope: readScope };
136
+ }
128
137
  export function resolveScopeIds(scope, tenantId, userId) {
129
138
  switch (scope) {
130
139
  case ConfigScopes.system:
@@ -138,7 +147,7 @@ export function resolveScopeIds(scope, tenantId, userId) {
138
147
  }
139
148
  }
140
149
  // The subject a piiEncrypted config value is encrypted under, for the scope
141
- // actually written to (kumiko-platform#231/#459). Pure — no I/O — so a bug
150
+ // actually written to. Pure — no I/O — so a bug
142
151
  // here (e.g. picking the writer's identity instead of the row's target,
143
152
  // see entity fields' explicit userOwned.ownerField for why that
144
153
  // distinction matters) is caught by a fast unit test, not only the DB-
@@ -7,7 +7,7 @@ export declare const forgetSubjectSchema: z.ZodObject<{
7
7
  userId: z.ZodUUID;
8
8
  }, z.core.$strip>, z.ZodObject<{
9
9
  kind: z.ZodLiteral<"tenant">;
10
- tenantId: z.ZodPipe<z.ZodUUID, z.ZodTransform<string, string>>;
10
+ tenantId: z.ZodUUID;
11
11
  }, z.core.$strip>, z.ZodObject<{
12
12
  kind: z.ZodLiteral<"record">;
13
13
  entity: z.ZodString;
@@ -39,7 +39,7 @@ export declare const forgetSubjectWrite: import("@cosmicdrift/kumiko-types/defin
39
39
  userId: z.ZodUUID;
40
40
  }, z.core.$strip>, z.ZodObject<{
41
41
  kind: z.ZodLiteral<"tenant">;
42
- tenantId: z.ZodPipe<z.ZodUUID, z.ZodTransform<string, string>>;
42
+ tenantId: z.ZodUUID;
43
43
  }, z.core.$strip>, z.ZodObject<{
44
44
  kind: z.ZodLiteral<"record">;
45
45
  entity: z.ZodString;
@@ -54,7 +54,7 @@ function subjectAggregateId(raw) {
54
54
  }
55
55
  }
56
56
  // The record subject names its own entity — resolve it against the registry
57
- // instead of trusting the payload straight into resolveTableName/SQL (#2786).
57
+ // instead of trusting the payload straight into resolveTableName/SQL.
58
58
  function findRegisteredEntity(features, entityName) {
59
59
  for (const feature of features.values()) {
60
60
  const entity = feature.entities?.[entityName];
@@ -63,7 +63,7 @@ function findRegisteredEntity(features, entityName) {
63
63
  }
64
64
  return undefined;
65
65
  }
66
- // Tenant-scope guard (mh#349): DataProtectionOfficer is a tenant-scoped role,
66
+ // Tenant-scope guard: DataProtectionOfficer is a tenant-scoped role,
67
67
  // but the handler otherwise erases ANY subject cross-tenant on a raw
68
68
  // (un-scoped) client — a Tenant-A DPO who learns a Tenant-B subject id
69
69
  // (export, support ticket, log line) could destroy it. SystemAdmin
@@ -111,7 +111,7 @@ async function resolveTenantScopeDenial(db, features, user, raw) {
111
111
  const ownedInTenant = await subjectRowExistsInTenant(db, features, raw.userId, user.tenantId);
112
112
  return ownedInTenant ? undefined : memberDenied;
113
113
  }
114
- // fw#2789/#2805: blockDelete (legally mandated physical retention, e.g.
114
+ // blockDelete (legally mandated physical retention, e.g.
115
115
  // ledger/invoice text) means this command must refuse, not silently
116
116
  // anonymize or proceed. Refused when the host entity itself declares
117
117
  // blockDelete OR the owning tenant's effective data-retention policy
@@ -162,8 +162,8 @@ function denialReasonOf(failure) {
162
162
  }
163
163
  return failure.error.code;
164
164
  }
165
- // Denied cross-tenant probes must still leave an audit trail (fw#2348).
166
- // Appended outside the handler tx (fw#2592): the caller's
165
+ // Denied cross-tenant probes must still leave an audit trail.
166
+ // Appended outside the handler tx: the caller's
167
167
  // `return tenantScopeDenial` rolls that tx back.
168
168
  async function appendDenialAuditEvent(ctx, event, subjectKey, subjectKind, denialCode, denialAuditRunner) {
169
169
  if (!denialAuditRunner) {
@@ -195,7 +195,7 @@ async function appendDenialAuditEvent(ctx, event, subjectKey, subjectKind, denia
195
195
  registry: ctx.registry,
196
196
  db: denialAuditRunner,
197
197
  // MUST be event.user.tenantId, never SYSTEM_TENANT_ID — unsafeRaw
198
- // bypasses TenantDb's scoping, so this is the only guard against a cross-tenant denial event (fw#2452).
198
+ // bypasses TenantDb's scoping, so this is the only guard against a cross-tenant denial event.
199
199
  tenantId: event.user.tenantId,
200
200
  userId: String(event.user.id),
201
201
  callSiteLabel: "forget-subject denial audit",
@@ -224,7 +224,6 @@ function sweepErrorLabel(err) {
224
224
  // Each step runs in its own savepoint: a database error must not abort the handler
225
225
  // transaction, and one failing step must not skip or roll back the others.
226
226
  async function sweepDerivedSubjectData(ctx, subject, subjectKey, crossTenantRunner, audit, rawSubject) {
227
- const recordTenantId = await owningTenantOfRecordSubject(crossTenantRunner, ctx.registry.features, rawSubject);
228
227
  const failureLabels = [];
229
228
  const runStep = async (step) => {
230
229
  try {
@@ -235,10 +234,10 @@ async function sweepDerivedSubjectData(ctx, subject, subjectKey, crossTenantRunn
235
234
  }
236
235
  };
237
236
  await runStep(async (crossTenantSubjectRunner) => {
238
- // Blind-index sweep (#818): nulls bidx columns now so the deterministic
237
+ // Blind-index sweep: nulls bidx columns now so the deterministic
239
238
  // HMAC doesn't stay equality-matchable; raw because the ciphertext prefix addresses the subject across tenants.
240
239
  await nullBlindIndexesForSubject(crossTenantSubjectRunner, ctx.registry.features, subjectKey);
241
- // Derived search index still holds plaintext (#1610) — purge next to the
240
+ // Derived search index still holds plaintext — purge next to the
242
241
  // blind-index sweep. No adapter → no-op (apps without search).
243
242
  if (ctx.searchAdapter) {
244
243
  await purgeSearchDocumentsForSubject(crossTenantSubjectRunner, ctx.registry.features, ctx.searchAdapter, subjectKey, subject);
@@ -254,15 +253,19 @@ async function sweepDerivedSubjectData(ctx, subject, subjectKey, crossTenantRunn
254
253
  }
255
254
  });
256
255
  // File columns hold only the fileRef id, so the key erase never reaches the bytes.
257
- await runStep((crossTenantSubjectRunner) => purgeFilesReachingSubject({
258
- registry: ctx.registry,
259
- db: crossTenantSubjectRunner,
260
- subject,
261
- subjectKey,
262
- ...(recordTenantId !== undefined && { recordTenantId }),
263
- resolveDeleteBytes: resolveFileBytesDeleter(ctx),
264
- missingStorage: { mode: "fail" },
265
- }));
256
+ await runStep(async (crossTenantSubjectRunner) => {
257
+ // Inside the step: a failing owner lookup must land in the audit label, not abort the handler.
258
+ const recordTenantId = await owningTenantOfRecordSubject(crossTenantSubjectRunner, ctx.registry.features, rawSubject);
259
+ await purgeFilesReachingSubject({
260
+ registry: ctx.registry,
261
+ db: crossTenantSubjectRunner,
262
+ subject,
263
+ subjectKey,
264
+ ...(recordTenantId !== undefined && { recordTenantId }),
265
+ resolveDeleteBytes: resolveFileBytesDeleter(ctx),
266
+ missingStorage: { mode: "fail" },
267
+ });
268
+ });
266
269
  return failureLabels[0];
267
270
  }
268
271
  // Email subscribers and other non-user entities use user-style subject keys
@@ -310,7 +313,8 @@ async function appendSubjectForgotten(ctx, event, aggregateId, payload, outsideR
310
313
  await appendDomainEventCore({
311
314
  registry: ctx.registry,
312
315
  db: outsideRunner,
313
- // MUST be event.user.tenantId, never SYSTEM_TENANT_ID — unsafeRaw bypasses TenantDb's scoping (fw#2452).
316
+ // MUST be event.user.tenantId, never SYSTEM_TENANT_ID — unsafeRaw bypasses TenantDb's
317
+ // scoping.
314
318
  tenantId: event.user.tenantId,
315
319
  userId: String(event.user.id),
316
320
  callSiteLabel: "forget-subject audit",
@@ -331,7 +335,7 @@ async function appendSubjectForgotten(ctx, event, aggregateId, payload, outsideR
331
335
  // The automated Art.-17 path (user-data-rights forget-cleanup) calls
332
336
  // kms.eraseKey directly inside its per-user sub-tx; this command is the
333
337
  // standalone trigger for cases outside that pipeline (authority requests,
334
- // tenant-destroy in Sprint 5, operator recovery).
338
+ // tenant-destroy, operator recovery).
335
339
  export const forgetSubjectWrite = defineWriteHandler({
336
340
  name: "forget-subject",
337
341
  schema: forgetSubjectSchema,
@@ -393,7 +397,7 @@ export const forgetSubjectWrite = defineWriteHandler({
393
397
  // callable. Mirror of the automated Art.-17 path (userDeleteHook:
394
398
  // status=Deleted; apiTokenDeleteHook: revoke):
395
399
  // - user.updated as lifecycle event (updateUserLifecycle), so a
396
- // read_users rebuild doesn't wipe the flip (#494)
400
+ // read_users rebuild doesn't wipe the flip
397
401
  // - sessions don't need active revocation — session-callbacks
398
402
  // re-validate user.status on every request (isPrincipalBlocked
399
403
  // blocks Deleted).
@@ -1,19 +1,18 @@
1
1
  /**
2
- * Deterministic aggregate-id für ein fieldDefinition-Aggregate aus dem
3
- * Tripel (tenantId, entityName, fieldKey). Pro (Tenant|System, Entity,
4
- * FieldKey) existiert genau ein Aggregate.
2
+ * Deterministic aggregate ID for a fieldDefinition aggregate from the tuple
3
+ * (tenantId, entityName, fieldKey). Exactly one aggregate exists per
4
+ * (Tenant|System, Entity, FieldKey).
5
5
  *
6
- * **Scope-Semantik:**
7
- * - System-Scope: `tenantId = SYSTEM_TENANT_ID` → die fieldDefinition
8
- * gilt für alle Tenants (vendor-defined).
9
- * - Tenant-Scope: `tenantId = <tenant-uuid>` → pro Tenant eigene
6
+ * **Scope semantics:**
7
+ * - System scope: `tenantId = SYSTEM_TENANT_ID` → the fieldDefinition applies
8
+ * to all tenants (vendor-defined).
9
+ * - Tenant scope: `tenantId = <tenant-uuid>` → each tenant has its own
10
10
  * fieldDefinition.
11
11
  *
12
- * **Conflict-Rule** (durchgesetzt im write-handler, NICHT via DB-constraint):
13
- * Pro (entityName, fieldKey) darf nur EINE Definition existieren — entweder
14
- * system oder tenant, nicht beide. Wenn system `customer.internalNumber`
15
- * definiert, kann Tenant kein eigenes `customer.internalNumber` mehr
16
- * definieren (422 `fieldKey_conflict`). Verhindert Resolution-Ambiguität
17
- * beim Read.
12
+ * **Conflict rule** (enforced in the write handler, NOT via a DB constraint):
13
+ * Only ONE definition may exist per (entityName, fieldKey)—system or tenant,
14
+ * but not both. If system defines `customer.internalNumber`, a tenant cannot
15
+ * define its own `customer.internalNumber` (422 `fieldKey_conflict`). This
16
+ * prevents ambiguity when resolving the field during reads.
18
17
  */
19
18
  export declare function fieldDefinitionAggregateId(tenantId: string, entityName: string, fieldKey: string): string;
@@ -1,26 +1,25 @@
1
1
  import { v5 as uuidv5 } from "uuid";
2
- // Fixed UUID-namespace für custom-field-definition aggregate-id-Ableitung.
3
- // Generiert einmalig (2026-05-22), in Stein gemeißelt: ein Wechsel würde
4
- // jeden existing fieldDefinition-Stream re-keyen → kaputter event-replay,
5
- // kaputte definition-history. Drift-Pin in __tests__/drift.test.ts.
2
+ // Fixed UUID namespace for deriving custom-field definition aggregate IDs.
3
+ // Generated once; changing it would re-key every existing fieldDefinition stream,
4
+ // breaking event replay and definition history. Drift is pinned in
5
+ // __tests__/drift.test.ts.
6
6
  const FIELD_DEFINITION_NAMESPACE = "f1d3b2c7-4e5a-4b9c-8d1f-2a3b4c5d6e7f";
7
7
  /**
8
- * Deterministic aggregate-id für ein fieldDefinition-Aggregate aus dem
9
- * Tripel (tenantId, entityName, fieldKey). Pro (Tenant|System, Entity,
10
- * FieldKey) existiert genau ein Aggregate.
8
+ * Deterministic aggregate ID for a fieldDefinition aggregate from the tuple
9
+ * (tenantId, entityName, fieldKey). Exactly one aggregate exists per
10
+ * (Tenant|System, Entity, FieldKey).
11
11
  *
12
- * **Scope-Semantik:**
13
- * - System-Scope: `tenantId = SYSTEM_TENANT_ID` → die fieldDefinition
14
- * gilt für alle Tenants (vendor-defined).
15
- * - Tenant-Scope: `tenantId = <tenant-uuid>` → pro Tenant eigene
12
+ * **Scope semantics:**
13
+ * - System scope: `tenantId = SYSTEM_TENANT_ID` → the fieldDefinition applies
14
+ * to all tenants (vendor-defined).
15
+ * - Tenant scope: `tenantId = <tenant-uuid>` → each tenant has its own
16
16
  * fieldDefinition.
17
17
  *
18
- * **Conflict-Rule** (durchgesetzt im write-handler, NICHT via DB-constraint):
19
- * Pro (entityName, fieldKey) darf nur EINE Definition existieren — entweder
20
- * system oder tenant, nicht beide. Wenn system `customer.internalNumber`
21
- * definiert, kann Tenant kein eigenes `customer.internalNumber` mehr
22
- * definieren (422 `fieldKey_conflict`). Verhindert Resolution-Ambiguität
23
- * beim Read.
18
+ * **Conflict rule** (enforced in the write handler, NOT via a DB constraint):
19
+ * Only ONE definition may exist per (entityName, fieldKey)—system or tenant,
20
+ * but not both. If system defines `customer.internalNumber`, a tenant cannot
21
+ * define its own `customer.internalNumber` (422 `fieldKey_conflict`). This
22
+ * prevents ambiguity when resolving the field during reads.
24
23
  */
25
24
  // @wrapper-known uuid-domain
26
25
  export function fieldDefinitionAggregateId(tenantId, entityName, fieldKey) {