@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.387.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 (469) hide show
  1. package/LICENSE +21 -57
  2. package/dist/agent-tools/tool-catalog.js +1 -1
  3. package/dist/audit/screens.js +1 -1
  4. package/dist/auth-email-password/feature.js +1 -1
  5. package/dist/auth-email-password/handlers/change-password.write.js +3 -3
  6. package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
  7. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
  8. package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
  9. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  10. package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
  11. package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
  12. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
  13. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  14. package/dist/auth-email-password/handlers/login.write.js +1 -1
  15. package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
  16. package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
  17. package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
  18. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  19. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
  20. package/dist/auth-email-password/index.js +5 -5
  21. package/dist/auth-email-password/lockout-store.js +1 -1
  22. package/dist/auth-email-password/seeding.d.ts +42 -45
  23. package/dist/auth-email-password/seeding.js +51 -53
  24. package/dist/auth-email-password/signup-token-store.js +8 -8
  25. package/dist/auth-email-password/testing.js +3 -3
  26. package/dist/auth-email-password/web/auth-client.d.ts +2 -2
  27. package/dist/auth-email-password/web/auth-client.js +36 -37
  28. package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
  29. package/dist/auth-email-password/web/auth-gate.js +15 -16
  30. package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
  31. package/dist/auth-email-password/web/client-plugin.js +4 -5
  32. package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
  33. package/dist/auth-email-password/web/constants.js +3 -3
  34. package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
  35. package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
  36. package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
  37. package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
  38. package/dist/auth-email-password/web/index.js +5 -5
  39. package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
  40. package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
  41. package/dist/auth-email-password/web/login-screen.d.ts +1 -1
  42. package/dist/auth-email-password/web/login-screen.js +2 -3
  43. package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
  44. package/dist/auth-email-password/web/reset-password-screen.js +12 -13
  45. package/dist/auth-email-password/web/session.d.ts +10 -9
  46. package/dist/auth-email-password/web/session.js +28 -29
  47. package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
  48. package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
  49. package/dist/auth-email-password/web/signup-screen.js +13 -13
  50. package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
  51. package/dist/auth-email-password/web/tenant-switcher.js +21 -22
  52. package/dist/auth-email-password/web/use-shell-user.js +12 -13
  53. package/dist/auth-email-password/web/user-menu.d.ts +4 -4
  54. package/dist/auth-email-password/web/user-menu.js +12 -13
  55. package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
  56. package/dist/auth-email-password/web/verify-email-screen.js +9 -10
  57. package/dist/auth-foundation/boot-checks.js +4 -4
  58. package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
  59. package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
  60. package/dist/auth-foundation/types.js +2 -2
  61. package/dist/auth-mfa/handlers/disable.write.js +3 -3
  62. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
  63. package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
  64. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
  65. package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
  66. package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
  67. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  68. package/dist/auth-mfa/token-secrets.js +1 -1
  69. package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
  70. package/dist/auth-mfa/web/client-plugin.js +1 -1
  71. package/dist/auth-mfa/web/i18n.js +3 -3
  72. package/dist/auth-mfa/web/index.js +4 -4
  73. package/dist/auth-mfa/web/mfa-client.js +17 -16
  74. package/dist/auth-mfa/web/mfa-verify-screen.js +6 -6
  75. package/dist/billing-foundation/aggregate-id.d.ts +5 -5
  76. package/dist/billing-foundation/aggregate-id.js +10 -11
  77. package/dist/billing-foundation/entities.js +27 -27
  78. package/dist/billing-foundation/events.js +18 -17
  79. package/dist/billing-foundation/feature.js +42 -43
  80. package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
  81. package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
  82. package/dist/billing-foundation/handlers/create-checkout-session.write.js +18 -17
  83. package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
  84. package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
  85. package/dist/billing-foundation/handlers/process-event.write.js +20 -20
  86. package/dist/billing-foundation/projection.d.ts +15 -11
  87. package/dist/billing-foundation/projection.js +38 -37
  88. package/dist/billing-foundation/subscription-tier-sync.js +3 -3
  89. package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
  90. package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
  91. package/dist/billing-foundation/types.d.ts +40 -41
  92. package/dist/billing-foundation/types.js +20 -20
  93. package/dist/billing-foundation/web/billing-plans-panel.js +4 -4
  94. package/dist/cap-counter/aggregate-id.js +8 -9
  95. package/dist/cap-counter/constants.js +11 -12
  96. package/dist/cap-counter/enforce-cap.d.ts +59 -62
  97. package/dist/cap-counter/enforce-cap.js +47 -48
  98. package/dist/cap-counter/entity.js +29 -29
  99. package/dist/cap-counter/feature.js +34 -35
  100. package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
  101. package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
  102. package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
  103. package/dist/cap-counter/stock-cap-guard.js +1 -1
  104. package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
  105. package/dist/channel-email/smtp-transport.d.ts +18 -17
  106. package/dist/channel-email/smtp-transport.js +24 -21
  107. package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
  108. package/dist/compliance-profiles/feature.js +4 -4
  109. package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
  110. package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
  111. package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
  112. package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
  113. package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
  114. package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
  115. package/dist/compliance-profiles/schema/profile-selection.js +18 -23
  116. package/dist/compliance-profiles/seeding.js +14 -15
  117. package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
  118. package/dist/compliance-profiles-ops/index.js +2 -2
  119. package/dist/config/handlers/readiness.query.d.ts +4 -4
  120. package/dist/config/handlers/readiness.query.js +1 -1
  121. package/dist/config/handlers/reencrypt.job.js +4 -5
  122. package/dist/config/handlers/set.write.js +4 -4
  123. package/dist/config/resolver.js +4 -4
  124. package/dist/config/table.js +10 -10
  125. package/dist/config/write-helpers.js +1 -1
  126. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
  127. package/dist/crypto-shredding/handlers/forget-subject.write.js +12 -11
  128. package/dist/custom-fields/aggregate-id.d.ts +12 -13
  129. package/dist/custom-fields/aggregate-id.js +16 -17
  130. package/dist/custom-fields/entity.js +49 -47
  131. package/dist/custom-fields/events.js +7 -8
  132. package/dist/custom-fields/feature.d.ts +14 -14
  133. package/dist/custom-fields/feature.js +53 -54
  134. package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
  135. package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
  136. package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
  137. package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
  138. package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
  139. package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
  140. package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
  141. package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
  142. package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
  143. package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
  144. package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
  145. package/dist/custom-fields/lib/field-access.js +2 -2
  146. package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
  147. package/dist/custom-fields/lib/quota.js +1 -1
  148. package/dist/custom-fields/lib/value-schema.js +10 -12
  149. package/dist/custom-fields/run-retention.js +3 -3
  150. package/dist/custom-fields/schemas.js +14 -14
  151. package/dist/custom-fields/web/client-plugin.js +2 -5
  152. package/dist/custom-fields/web/constants.js +2 -2
  153. package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
  154. package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
  155. package/dist/custom-fields/wire-for-entity.js +65 -67
  156. package/dist/custom-fields/wire-user-data-rights.js +3 -3
  157. package/dist/data-retention/_internal/parse-override.js +2 -3
  158. package/dist/data-retention/feature.js +11 -18
  159. package/dist/data-retention/handlers/policy-for.query.js +6 -6
  160. package/dist/data-retention/keep-for.d.ts +7 -7
  161. package/dist/data-retention/keep-for.js +15 -15
  162. package/dist/data-retention/override-schema.d.ts +3 -4
  163. package/dist/data-retention/override-schema.js +13 -15
  164. package/dist/data-retention/presets.d.ts +4 -5
  165. package/dist/data-retention/presets.js +18 -23
  166. package/dist/data-retention/resolve-tenant-preset.js +17 -16
  167. package/dist/data-retention/resolver.d.ts +12 -12
  168. package/dist/data-retention/resolver.js +24 -23
  169. package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
  170. package/dist/data-retention/run-retention-cleanup.js +61 -51
  171. package/dist/data-retention/schema/tenant-retention-override.js +13 -11
  172. package/dist/delivery/feature.js +2 -2
  173. package/dist/delivery/handlers/log.query.js +1 -1
  174. package/dist/delivery/tables.js +9 -8
  175. package/dist/delivery/unsubscribe.js +4 -4
  176. package/dist/document-ingest-foundation/entity.js +4 -4
  177. package/dist/document-ingest-foundation/events.js +2 -2
  178. package/dist/document-ingest-foundation/feature.js +2 -2
  179. package/dist/document-ingest-foundation/pages.js +1 -1
  180. package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
  181. package/dist/feature-toggles/compose-tier-resolver.js +1 -1
  182. package/dist/feature-toggles/feature.js +1 -1
  183. package/dist/feature-toggles/global-feature-state-table.js +1 -1
  184. package/dist/feature-toggles/handlers/registered.query.js +5 -5
  185. package/dist/feature-toggles/toggle-sync-signal.js +1 -1
  186. package/dist/feature-toggles/web/constants.js +1 -1
  187. package/dist/file-derivatives/feature.d.ts +1 -1
  188. package/dist/file-derivatives/feature.js +1 -1
  189. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  190. package/dist/file-derivatives/presets.js +1 -1
  191. package/dist/file-foundation/feature.js +6 -6
  192. package/dist/file-provider-inmemory/feature.d.ts +1 -1
  193. package/dist/file-provider-inmemory/feature.js +16 -16
  194. package/dist/file-provider-s3/feature.js +16 -16
  195. package/dist/file-provider-s3/lib/s3-provider.js +6 -6
  196. package/dist/files/feature.js +6 -6
  197. package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
  198. package/dist/files-tenant-data/hooks.js +24 -26
  199. package/dist/files-tenant-data/index.js +1 -1
  200. package/dist/folders/feature.d.ts +1 -1
  201. package/dist/folders/web/folder-manager.js +2 -2
  202. package/dist/folders/web/tree.js +5 -5
  203. package/dist/form-draft/db/queries/cleanup.js +1 -1
  204. package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
  205. package/dist/form-draft/entity.js +3 -3
  206. package/dist/form-draft/feature.js +4 -5
  207. package/dist/form-draft/handlers/discard.write.js +1 -1
  208. package/dist/form-draft/release-file-refs.js +6 -6
  209. package/dist/form-draft/schemas.js +3 -3
  210. package/dist/form-draft/web/constants.js +0 -2
  211. package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
  212. package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
  213. package/dist/inbound-mail-foundation/connect-routes.js +4 -3
  214. package/dist/inbound-mail-foundation/constants.d.ts +22 -24
  215. package/dist/inbound-mail-foundation/constants.js +30 -33
  216. package/dist/inbound-mail-foundation/entities.d.ts +12 -12
  217. package/dist/inbound-mail-foundation/entities.js +47 -48
  218. package/dist/inbound-mail-foundation/events.d.ts +4 -3
  219. package/dist/inbound-mail-foundation/events.js +50 -47
  220. package/dist/inbound-mail-foundation/feature.js +39 -39
  221. package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
  222. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
  223. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
  224. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
  225. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
  226. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
  227. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
  228. package/dist/inbound-mail-foundation/handlers/update-account.write.js +11 -11
  229. package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
  230. package/dist/inbound-mail-foundation/oauth-state.js +11 -10
  231. package/dist/inbound-mail-foundation/projection.d.ts +4 -4
  232. package/dist/inbound-mail-foundation/projection.js +31 -29
  233. package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
  234. package/dist/inbound-mail-foundation/provider-factory.js +9 -9
  235. package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
  236. package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
  237. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
  238. package/dist/inbound-mail-foundation/types.d.ts +45 -46
  239. package/dist/inbound-mail-foundation/types.js +21 -21
  240. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
  241. package/dist/inbound-mail-foundation/watch-supervisor.js +57 -56
  242. package/dist/inbound-provider-imap/credential-document.js +13 -13
  243. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  244. package/dist/inbound-provider-imap/feature.js +42 -40
  245. package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
  246. package/dist/inbound-provider-imap/imap-client.js +20 -19
  247. package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
  248. package/dist/inbound-provider-inmemory/feature.js +19 -19
  249. package/dist/jobs/db/queries/retention.js +2 -2
  250. package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
  251. package/dist/jobs/events.js +1 -1
  252. package/dist/jobs/feature.js +5 -6
  253. package/dist/jobs/handlers/detail.query.js +4 -4
  254. package/dist/jobs/handlers/list.query.js +1 -1
  255. package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
  256. package/dist/jobs/handlers/reindex-entity.job.js +1 -1
  257. package/dist/jobs/handlers/retry.write.js +1 -1
  258. package/dist/jobs/job-instant.js +1 -1
  259. package/dist/jobs/job-run-logger.js +10 -11
  260. package/dist/jobs/job-run-table.js +3 -3
  261. package/dist/jobs/screens.js +1 -1
  262. package/dist/jobs/tenant-job-failure-table.js +1 -1
  263. package/dist/jobs/tenant-job-run-table.js +1 -1
  264. package/dist/ledger/entity.js +5 -5
  265. package/dist/ledger/feature.js +3 -3
  266. package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
  267. package/dist/ledger/recurring.js +12 -12
  268. package/dist/ledger/schemas.js +1 -1
  269. package/dist/ledger/web/constants.js +2 -2
  270. package/dist/ledger/web/index.js +7 -7
  271. package/dist/legal-pages/feature.d.ts +4 -4
  272. package/dist/legal-pages/feature.js +25 -26
  273. package/dist/legal-pages/markdown.js +3 -3
  274. package/dist/legal-pages/web/client-plugin.js +23 -24
  275. package/dist/legal-pages/web/index.js +0 -1
  276. package/dist/mail-foundation/feature.d.ts +2 -2
  277. package/dist/mail-foundation/feature.js +24 -25
  278. package/dist/mail-transport-inmemory/feature.d.ts +4 -4
  279. package/dist/mail-transport-inmemory/feature.js +27 -28
  280. package/dist/mail-transport-smtp/feature.js +20 -20
  281. package/dist/managed-pages/branding.js +6 -6
  282. package/dist/managed-pages/feature.d.ts +26 -26
  283. package/dist/managed-pages/feature.js +34 -34
  284. package/dist/managed-pages/handlers/by-slug.query.js +5 -6
  285. package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
  286. package/dist/managed-pages/handlers/set.write.js +5 -7
  287. package/dist/managed-pages/screens/page-screens.js +11 -11
  288. package/dist/managed-pages/seeding.js +8 -8
  289. package/dist/managed-pages/table.js +13 -12
  290. package/dist/managed-pages/web/client-plugin.d.ts +1 -1
  291. package/dist/managed-pages/web/client-plugin.js +5 -5
  292. package/dist/managed-pages/web/i18n.js +1 -1
  293. package/dist/notes-history/entity.js +4 -4
  294. package/dist/notes-history/feature.d.ts +2 -2
  295. package/dist/notes-history-user-data/hooks.js +1 -1
  296. package/dist/page-render/layout.js +9 -9
  297. package/dist/page-render/markdown.js +11 -11
  298. package/dist/page-render/security-headers.js +7 -6
  299. package/dist/personal-access-tokens/feature.js +5 -5
  300. package/dist/personal-access-tokens/roles.js +2 -2
  301. package/dist/readiness/handlers/status.query.js +3 -3
  302. package/dist/renderer-foundation/api.js +12 -13
  303. package/dist/renderer-foundation/constants.js +2 -2
  304. package/dist/renderer-foundation/feature.js +7 -7
  305. package/dist/secrets/feature.js +9 -9
  306. package/dist/secrets/web/constants.js +2 -2
  307. package/dist/seo/feature.js +3 -3
  308. package/dist/sessions/constants.d.ts +1 -1
  309. package/dist/sessions/constants.js +1 -1
  310. package/dist/sessions/feature.js +8 -8
  311. package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
  312. package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
  313. package/dist/sessions/handlers/revoke.write.js +1 -1
  314. package/dist/sessions/schema/user-session.js +4 -4
  315. package/dist/sessions/screens.js +2 -2
  316. package/dist/sessions/session-callbacks.js +2 -2
  317. package/dist/sessions/session-revoked-event.js +2 -2
  318. package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
  319. package/dist/shared/decrypt-stored-pii.js +1 -1
  320. package/dist/shared/encrypt-for-direct-write.js +1 -1
  321. package/dist/shared/map-with-concurrency.js +5 -4
  322. package/dist/shared/parent-visibility.js +2 -2
  323. package/dist/shared/password-hashing.js +1 -1
  324. package/dist/shared/signup-handover.js +1 -2
  325. package/dist/shared/single-use-token-store.js +1 -1
  326. package/dist/subscription-mollie/constants.js +15 -17
  327. package/dist/subscription-mollie/feature.d.ts +17 -18
  328. package/dist/subscription-mollie/feature.js +24 -24
  329. package/dist/subscription-mollie/index.js +3 -3
  330. package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
  331. package/dist/subscription-mollie/plugin-methods.js +15 -14
  332. package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
  333. package/dist/subscription-mollie/verify-webhook.js +27 -27
  334. package/dist/subscription-stripe/constants.js +4 -6
  335. package/dist/subscription-stripe/feature.d.ts +14 -14
  336. package/dist/subscription-stripe/feature.js +35 -34
  337. package/dist/subscription-stripe/index.js +6 -6
  338. package/dist/subscription-stripe/plugin-methods.js +18 -18
  339. package/dist/subscription-stripe/runtime.d.ts +1 -1
  340. package/dist/subscription-stripe/runtime.js +1 -1
  341. package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
  342. package/dist/subscription-stripe/verify-webhook.js +59 -61
  343. package/dist/tags/feature.d.ts +3 -3
  344. package/dist/tags/screens.js +1 -1
  345. package/dist/template-resolver/api.js +10 -10
  346. package/dist/template-resolver/handlers/find-by-id.query.js +5 -5
  347. package/dist/template-resolver/handlers/list.query.js +1 -1
  348. package/dist/template-resolver/handlers/shared.js +2 -2
  349. package/dist/template-resolver/handlers/template-write.js +3 -3
  350. package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
  351. package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
  352. package/dist/template-resolver/seeding.js +4 -4
  353. package/dist/template-resolver/table.js +10 -11
  354. package/dist/template-resolver/web/client-plugin.js +2 -2
  355. package/dist/tenant/feature.js +7 -7
  356. package/dist/tenant/handlers/member-directory.query.js +1 -1
  357. package/dist/tenant/handlers/members.query.js +1 -1
  358. package/dist/tenant/handlers/team-list.query.js +1 -1
  359. package/dist/tenant/handlers/tenant-directory.query.js +1 -1
  360. package/dist/tenant/invitation-table.js +37 -40
  361. package/dist/tenant/membership-table.js +3 -3
  362. package/dist/tenant/schema/tenant.js +7 -9
  363. package/dist/tenant/screens.js +1 -1
  364. package/dist/tenant/seeding.d.ts +6 -5
  365. package/dist/tenant/seeding.js +12 -12
  366. package/dist/tenant/testing.js +5 -6
  367. package/dist/tenant/web/constants.js +2 -2
  368. package/dist/tenant-handover/events.js +5 -7
  369. package/dist/tenant-handover/feature.js +1 -1
  370. package/dist/tenant-handover/grant.js +1 -1
  371. package/dist/tenant-handover/handlers/claim.write.js +1 -1
  372. package/dist/tenant-handover/move-entity-graph.js +8 -9
  373. package/dist/tenant-handover/signup-handover-provider.js +1 -2
  374. package/dist/tenant-handover/transfer-graph.js +4 -5
  375. package/dist/tenant-lifecycle/boot-checks.js +1 -1
  376. package/dist/tenant-lifecycle/feature.js +1 -1
  377. package/dist/tenant-settings/constants.js +1 -1
  378. package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
  379. package/dist/tenant-settings/tenant-defaults.js +9 -2
  380. package/dist/tier-engine/aggregate-id.d.ts +11 -11
  381. package/dist/tier-engine/aggregate-id.js +15 -16
  382. package/dist/tier-engine/compose-app.d.ts +14 -14
  383. package/dist/tier-engine/compose-app.js +1 -1
  384. package/dist/tier-engine/entity.js +18 -19
  385. package/dist/tier-engine/feature.d.ts +19 -17
  386. package/dist/tier-engine/feature.js +68 -69
  387. package/dist/tier-engine/handlers/active-tier.query.js +6 -7
  388. package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
  389. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +5 -5
  390. package/dist/tier-engine/handlers/set-tenant-tier.write.js +3 -3
  391. package/dist/tier-engine/tier-resolver.js +2 -2
  392. package/dist/tier-engine/trial.js +8 -8
  393. package/dist/tier-engine/web/index.js +4 -4
  394. package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
  395. package/dist/user/handlers/create.write.js +4 -4
  396. package/dist/user/schema/user.d.ts +11 -11
  397. package/dist/user/schema/user.js +45 -44
  398. package/dist/user/seeding.d.ts +15 -15
  399. package/dist/user/seeding.js +28 -28
  400. package/dist/user/testing.js +3 -3
  401. package/dist/user-data-rights/audit-download.d.ts +8 -8
  402. package/dist/user-data-rights/audit-download.js +19 -20
  403. package/dist/user-data-rights/boot-checks.js +1 -1
  404. package/dist/user-data-rights/deletion-token.js +1 -1
  405. package/dist/user-data-rights/feature.d.ts +49 -50
  406. package/dist/user-data-rights/feature.js +54 -53
  407. package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
  408. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
  409. package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
  410. package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
  411. package/dist/user-data-rights/handlers/export-status.query.js +8 -9
  412. package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
  413. package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
  414. package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
  415. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
  416. package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
  417. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
  418. package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
  419. package/dist/user-data-rights/handlers/request-export.write.js +42 -41
  420. package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
  421. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
  422. package/dist/user-data-rights/index.js +8 -10
  423. package/dist/user-data-rights/lib/default-mailers.js +3 -3
  424. package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
  425. package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
  426. package/dist/user-data-rights/run-export-jobs.js +127 -233
  427. package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
  428. package/dist/user-data-rights/run-forget-cleanup.js +63 -82
  429. package/dist/user-data-rights/run-user-export.d.ts +34 -33
  430. package/dist/user-data-rights/run-user-export.js +55 -57
  431. package/dist/user-data-rights/schema/download-attempt.js +11 -11
  432. package/dist/user-data-rights/schema/download-token.js +37 -41
  433. package/dist/user-data-rights/schema/export-job.d.ts +4 -4
  434. package/dist/user-data-rights/schema/export-job.js +65 -67
  435. package/dist/user-data-rights/token-helpers.d.ts +8 -9
  436. package/dist/user-data-rights/token-helpers.js +21 -25
  437. package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
  438. package/dist/user-data-rights/web/client-plugin.js +1 -1
  439. package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
  440. package/dist/user-data-rights/web/constants.js +1 -1
  441. package/dist/user-data-rights/web/index.js +5 -5
  442. package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
  443. package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
  444. package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
  445. package/dist/user-data-rights/zip-path.d.ts +15 -15
  446. package/dist/user-data-rights/zip-path.js +41 -40
  447. package/dist/user-data-rights-defaults/feature.js +15 -15
  448. package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
  449. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
  450. package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
  451. package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
  452. package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
  453. package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
  454. package/dist/user-profile/handlers/change-email.write.js +13 -13
  455. package/dist/user-profile/index.js +3 -3
  456. package/dist/user-profile/web/client-plugin.js +1 -1
  457. package/dist/user-profile/web/constants.js +1 -1
  458. package/dist/user-profile/web/profile-screen.js +1 -1
  459. package/dist/workflow-runner/aggregate-id.d.ts +1 -1
  460. package/dist/workflow-runner/aggregate-id.js +1 -1
  461. package/dist/workflow-runner/event-subscriber.js +4 -5
  462. package/dist/workflow-runner/event-trigger.js +4 -17
  463. package/dist/workflow-runner/feature.js +2 -2
  464. package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
  465. package/dist/workflow-runner/pending-projection.js +6 -7
  466. package/dist/workflow-runner/runner.js +6 -6
  467. package/dist/workflow-runner/tables.js +6 -6
  468. package/dist/workflow-runner/workflow-registry.js +1 -1
  469. package/package.json +10 -10
@@ -1,22 +1,21 @@
1
- // increment-rolling — Rolling-Window-Counter-Increment via Custom-
2
- // Event statt CRUD/projection. Designed für Caps deren Wert sich
3
- // kontinuierlich erneuern soll (KI-Tokens-7-Tage, Egress pro 24h).
1
+ // increment-rolling — Rolling-window counter increment via a custom
2
+ // event instead of CRUD/projection. Designed for caps whose values
3
+ // continuously renew (AI tokens over 7 days, egress over 24 hours).
4
4
  //
5
- // **Warum kein r.entity / CRUD wie der Calendar-Counter:** Der
6
- // Calendar-Counter speichert den kumulierten value in seiner
7
- // projection-row. Beim Period-Rollover wechselt die aggregate-id auf
8
- // den neuen Period-Start, das ist der "Reset". Bei Rolling-Window
9
- // gibt es keinen Rollover-Punkt — der Counter "rollt" kontinuierlich
10
- // raus. Ein einzelner kumulativer value wäre falsch (würde monoton
11
- // wachsen ohne Expiration). Die korrekte Read-Semantik ist: SUM aller
12
- // Increment-Amounts der letzten N Tage. Dafür brauchen wir die
13
- // einzelnen Increments als separate Events mit ihrem eigenen
14
- // `amount`-Feld; CRUD-Events tragen nur den kumulativen value.
5
+ // **Why not r.entity / CRUD like the calendar counter:** The calendar
6
+ // counter stores the cumulative value in its projection row. At the
7
+ // period rollover, the aggregate ID changes to the new period start;
8
+ // that is the "reset". A rolling window has no rollover point—the
9
+ // counter continuously rolls out. A single cumulative value would be
10
+ // incorrect because it would grow monotonically without expiration.
11
+ // The correct read semantics are SUM of all increment amounts from the
12
+ // last N days. Therefore, each increment must be a separate event with
13
+ // its own `amount` field; CRUD events carry only the cumulative value.
15
14
  //
16
- // **Aggregate-Stream:** ein Stream pro (tenant, capName) — siehe
17
- // `rollingCapAggregateId`. Alle Increments hängen am selben Stream
18
- // in monoton-steigender version. enforceRollingCap liest die letzten
19
- // N Tage aus diesem Stream.
15
+ // **Aggregate stream:** one stream per (tenant, capName)—see
16
+ // `rollingCapAggregateId`. All increments use the same stream in
17
+ // monotonically increasing version order. enforceRollingCap reads the
18
+ // last N days from this stream.
20
19
  import * as z from "zod";
21
20
  import { rollingCapAggregateId } from "../aggregate-id.js";
22
21
  import { CAP_COUNTER_ROLLING_AGGREGATE_TYPE, ROLLING_INCREMENTED_EVENT_QN } from "../constants.js";
@@ -28,8 +27,8 @@ const incrementRollingSchema = z.object({
28
27
  * Window-Sum is exact. */
29
28
  amount: z.number().int().positive().default(1),
30
29
  });
31
- /** Schema des emittierten Custom-Events. Identisch zum Input-Schema:
32
- * der Caller zahlt amount, wir hängen es 1:1 an den Stream. */
30
+ /** Schema of the emitted custom event. Identical to the input schema:
31
+ * the caller supplies amount, which we append unchanged to the stream. */
33
32
  export const rollingIncrementedSchema = incrementRollingSchema;
34
33
  /** Payload of the event that gives a reserved rolling amount back. */
35
34
  export const rollingReleasedSchema = incrementRollingSchema.extend({
@@ -37,27 +36,28 @@ export const rollingReleasedSchema = incrementRollingSchema.extend({
37
36
  /** When the released increment was booked; absent on events written before it was recorded. */
38
37
  incrementedAt: z.string().optional(),
39
38
  });
40
- // Rolling-Increment-Handler — append-only. Race-frei: zwei parallele
41
- // Increments für (tenant, cap) hängen sich am selben aggregate-stream
42
- // in unterschiedlichen versions auf, das event-store ordert.
39
+ // Rolling-increment handler — append-only. Race-free: two parallel
40
+ // increments for (tenant, cap) attach to the same aggregate stream at
41
+ // different versions, and the event store orders them.
43
42
  //
44
- // **Kein version_conflict-Pfad** wie beim Calendar-Counter: hier
45
- // liest niemand den projection-state vor dem Schreiben. Der
46
- // expectedVersion ist implizit "next-after-current", was der event-
47
- // store atomar ermittelt.
43
+ // **No version_conflict path** as with the calendar counter: nothing
44
+ // reads projection state before writing. The expectedVersion is
45
+ // implicitly "next-after-current", which the event store determines
46
+ // atomically.
48
47
  export const incrementRollingCapHandler = {
49
48
  name: "increment-rolling",
50
49
  agent: { expose: false },
51
50
  schema: incrementRollingSchema,
52
- // Internal handler — System-Caller (Plattform-foundations nach
53
- // erfolgreichem Side-Effect) ruft das auf. Tenant-end-users niemals
54
- // direkt. Audit-row zeigt welche subsystem-call-site zugehängt hat.
51
+ // Internal handler — a system caller (platform foundations after a
52
+ // successful side effect) invokes it. Tenant end users must never
53
+ // call it directly. The audit row shows which subsystem call site
54
+ // attached the operation.
55
55
  access: { roles: ["SystemAdmin"] },
56
56
  handler: async (event, ctx) => {
57
57
  // @cast-boundary engine-payload — dispatcher hands handler the
58
58
  // already-Zod-validated payload as `unknown`; cast to the typed
59
- // shape we declared via incrementRollingSchema. Mirror der
60
- // existing increment.write.ts-Cast — gleiche dispatcher-boundary.
59
+ // shape declared via incrementRollingSchema. Mirror the cast in
60
+ // existing increment.write.ts—the same dispatcher boundary.
61
61
  const payload = event.payload;
62
62
  const aggregateId = rollingCapAggregateId(event.user.tenantId, payload.capName);
63
63
  // unsafeAppendEvent: the strict appendEvent is bound to an app's own event map, which
@@ -2,12 +2,11 @@ import * as z from "zod";
2
2
  import { markCapSoftWarned } from "../book-cap-usage.js";
3
3
  // mark-soft-warned — sets lastSoftWarnedAt on the counter so subsequent
4
4
  // soft-cap-hits in the same period don't re-trigger notifications.
5
- // Anti-Notification-Storm-Schutz aus Memory `project_pricing_byok_caps`.
5
+ // This prevents notification storms.
6
6
  //
7
- // **Caller-Pattern:** enforceCap-Helper checks if value crosses the
8
- // soft threshold AND lastSoftWarnedAt is null → calls this handler →
9
- // emits whatever notification (delivery-feature, ops-alert, etc.). The
10
- // emit-side is app-specific; this handler only sets the flag.
7
+ // **Caller pattern:** enforceCap-Helper checks whether the value crosses the
8
+ // soft threshold while lastSoftWarnedAt is null, then calls this handler and
9
+ // emits the application-specific notification. This handler only sets the flag.
11
10
  const markSoftWarnedSchema = z.object({
12
11
  capName: z.string().min(1).max(100),
13
12
  periodStartIso: z.string().min(1),
@@ -1,5 +1,5 @@
1
1
  // Generic stock-cap write-guard factory. Extracted from the near-identical
2
- // cap-guard.ts app copies in show-pony and publicstatus (infra#446) — the
2
+ // cap-guard.ts app copies in show-pony and publicstatus — the
3
3
  // only per-app variable was the Caps shape and how to resolve it for a
4
4
  // tenant, so both are now factory parameters.
5
5
  import { UnprocessableError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
@@ -1,11 +1,9 @@
1
1
  import type { HandlerContext, WriteEvent, WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import { type CapToleranceProfileName, type SoftHitNotifier } from "./enforce-cap.ts";
3
3
  /**
4
- * Pro-call dynamische Cap-Definition. Wird vor jedem Handler-Aufruf
5
- * neu evaluiert — typischer Caller liest hier den Tenant-Tier aus
6
- * dem ctx, mappt ihn auf einen Limit-Wert. `amount` default 1 (count-
7
- * events); für byte/token-cap übergibt der Caller die Größe aus
8
- * `event.payload`.
4
+ * Dynamic cap definition resolved for each handler invocation. A typical caller reads the tenant
5
+ * tier from `ctx` and maps it to a limit. `amount` defaults to 1 (counting events); for byte or
6
+ * token caps, the caller supplies the size from `event.payload`.
9
7
  */
10
8
  export type CalendarCapDef = {
11
9
  readonly capName: string;
@@ -1,16 +1,16 @@
1
1
  import type { EmailTransport } from "./types.ts";
2
2
  export type SmtpTransportOptions = {
3
- /** SMTP-Server-Host (z.B. "smtp.gmail.com", "in-v3.mailjet.com",
4
- * "localhost" für Mailhog/MailCatcher in dev). */
3
+ /** SMTP server host (for example, "smtp.gmail.com", "in-v3.mailjet.com",
4
+ * or "localhost" for Mailhog/MailCatcher in development). */
5
5
  readonly host: string;
6
- /** Default 587 (STARTTLS). 465 für implicit-TLS, 25 für unencrypted
7
- * (nur lokal/intern, nie public). */
6
+ /** Default 587 (STARTTLS). 465 uses implicit TLS; 25 is unencrypted
7
+ * (for local/internal use only, never public). */
8
8
  readonly port?: number;
9
- /** TLS-Mode: true = implicit TLS auf port 465, false = STARTTLS auf
10
- * 587 (oder plain auf 25). Default false (STARTTLS standard). */
9
+ /** TLS mode: true = implicit TLS on port 465, false = STARTTLS on
10
+ * 587 (or plain on 25). The default is false (STARTTLS). */
11
11
  readonly secure?: boolean;
12
- /** Optional auth — manche internal-relays nehmen IP-whitelisting statt
13
- * Login. Wenn gesetzt, beide felder pflicht. */
12
+ /** Optional authentication — some internal relays use IP allowlisting
13
+ * instead of login. When set, both fields are required. */
14
14
  readonly auth?: {
15
15
  readonly user: string;
16
16
  readonly pass: string;
@@ -28,8 +28,8 @@ export type SmtpTransportOptions = {
28
28
  readonly servername?: string;
29
29
  };
30
30
  export declare function createSmtpTransport(options: SmtpTransportOptions): EmailTransport;
31
- /** Env-Felder die `createSmtpTransportFromEnv` liest. Apps die SMTP
32
- * nutzen extenden ihr env-Schema um genau diese Keys. */
31
+ /** Environment fields read by `createSmtpTransportFromEnv`. Apps that use
32
+ * SMTP should extend their environment schema with exactly these keys. */
33
33
  export type SmtpEnv = {
34
34
  readonly SMTP_HOST?: string;
35
35
  readonly SMTP_PORT?: string;
@@ -39,14 +39,15 @@ export type SmtpEnv = {
39
39
  readonly SMTP_FROM?: string;
40
40
  };
41
41
  /**
42
- * Boot-Time-Transport aus env. Ohne `SMTP_HOST` → `null` (Caller behandelt
43
- * das als "kein Mail-Versand", statt zu crashen). Port wird zu Number
44
- * gecoerced (default 587), `secure` ist `SMTP_SECURE === "true"`, auth nur
45
- * wenn user UND pass gesetzt sind.
42
+ * Creates a transport at boot time from the environment. Without
43
+ * `SMTP_HOST`, returns `null` so the caller can treat this as no mail
44
+ * delivery instead of crashing. The port is coerced to a number (default
45
+ * 587); `secure` is `SMTP_SECURE === "true"`; authentication is included
46
+ * only when both the user and password are set.
46
47
  *
47
- * Ersetzt den identischen `env.SMTP_HOST ? createSmtpTransport({...}) : null`
48
- * Block den jede App in bin/main.ts + bin/server.ts hand-rollte — nur die
49
- * From-Default (`fallbackFrom`) variiert pro App.
48
+ * Replaces the repeated `env.SMTP_HOST ? createSmtpTransport({...}) : null`
49
+ * block that each app previously implemented in bin/main.ts and
50
+ * bin/server.ts. Only the From default (`fallbackFrom`) varies by app.
50
51
  */
51
52
  export declare function createSmtpTransportFromEnv(env: SmtpEnv, opts: {
52
53
  readonly fallbackFrom: string;
@@ -1,20 +1,22 @@
1
- // SMTP-Transport für EmailTransport-Interface. nodemailer-basiert
2
- // (battle-tested, TLS-AUTH-Pool-Reconnect handled). Universaler default
3
- // für apps die keinen Vendor-spezifischen Sender wollen — funktioniert
4
- // gegen jeden SMTP-Server (Gmail, eigener Postfix, Brevo-SMTP-relay,
5
- // Office 365, Mailhog für lokales testing).
1
+ // SMTP transport for the EmailTransport interface, based on nodemailer
2
+ // (battle-tested, handles TLS, auth and pool reconnects). It is the universal
3
+ // default for apps that do not need a vendor-specific sender and works with
4
+ // any SMTP server (Gmail, a private
5
+ // Postfix server, a Brevo SMTP relay, Office 365, or Mailhog for local
6
+ // testing).
6
7
  //
7
- // Why SMTP statt Vendor-API als default:
8
- // 1. EU-Story: kein Daten an US-Vendor, App-Owner wählt Server.
9
- // 2. Self-Hosting: Customer kann eigenen Mailserver nutzen, kein
8
+ // Why SMTP instead of a vendor API as the default:
9
+ // 1. EU data control: the app owner chooses the server instead of sending
10
+ // data to a US vendor.
11
+ // 2. Self-hosting: customers can use their own mail server without an
10
12
  // external account.
11
- // 3. Universalität: jeder Vendor (Brevo, Resend, Mailgun, Postmark)
12
- // bietet auch SMTP — wer Brevo will, setzt Brevos SMTP-Credentials.
13
+ // 3. Universality: every vendor (Brevo, Resend, Mailgun, Postmark) also
14
+ // offers SMTP, so Brevo users can provide Brevo SMTP credentials.
13
15
  //
14
- // Transport-Pool: nodemailer.createTransport({pool: true}) hält bis zu
15
- // 5 Verbindungen offen + reused. Bei kleinen Apps reicht das; für High-
16
- // Volume-Apps muss der Caller eine eigene Implementation mit
17
- // dedizierter Queue (BullMQ + retry) drüberlegen.
16
+ // The transport pool (createTransport({ pool: true })) keeps up to 5
17
+ // connections open and reuses them. That is enough for small apps; for
18
+ // high-volume apps the caller must layer its own implementation with a
19
+ // dedicated queue (BullMQ + retry) on top.
18
20
  import { createTransport } from "nodemailer";
19
21
  import addressparser from "nodemailer/lib/addressparser";
20
22
  function isControlCharacter(char) {
@@ -80,14 +82,15 @@ export function createSmtpTransport(options) {
80
82
  };
81
83
  }
82
84
  /**
83
- * Boot-Time-Transport aus env. Ohne `SMTP_HOST` → `null` (Caller behandelt
84
- * das als "kein Mail-Versand", statt zu crashen). Port wird zu Number
85
- * gecoerced (default 587), `secure` ist `SMTP_SECURE === "true"`, auth nur
86
- * wenn user UND pass gesetzt sind.
85
+ * Creates a transport at boot time from the environment. Without
86
+ * `SMTP_HOST`, returns `null` so the caller can treat this as no mail
87
+ * delivery instead of crashing. The port is coerced to a number (default
88
+ * 587); `secure` is `SMTP_SECURE === "true"`; authentication is included
89
+ * only when both the user and password are set.
87
90
  *
88
- * Ersetzt den identischen `env.SMTP_HOST ? createSmtpTransport({...}) : null`
89
- * Block den jede App in bin/main.ts + bin/server.ts hand-rollte — nur die
90
- * From-Default (`fallbackFrom`) variiert pro App.
91
+ * Replaces the repeated `env.SMTP_HOST ? createSmtpTransport({...}) : null`
92
+ * block that each app previously implemented in bin/main.ts and
93
+ * bin/server.ts. Only the From default (`fallbackFrom`) varies by app.
91
94
  */
92
95
  export function createSmtpTransportFromEnv(env, opts) {
93
96
  if (!env.SMTP_HOST)
@@ -13,10 +13,9 @@ export const unreadCountQuery = defineQueryHandler({
13
13
  },
14
14
  description: "Counts the calling user's unread in-app notification messages; use it for an inbox badge or to check whether a user has pending notifications.",
15
15
  handler: async (query, ctx) => {
16
- // The query helpers in db/query.ts have no aggregate helper — selectMany alle matching rows,
17
- // count() in JS. Pragma: unread-counts sind low-cardinality (user-
18
- // scoped, max ~hunderte rows). Wenn das wachsen sollte: raw .unsafe()
19
- // mit COUNT(*).
16
+ // The query helpers in db/query.ts have no aggregate helper, so selectMany returns all matching
17
+ // rows and count() runs in JS. This is acceptable because unread counts are low-cardinality and
18
+ // user-scoped, with at most a few hundred rows; use raw .unsafe() with COUNT(*) if that grows.
20
19
  const rows = await selectMany(ctx.db, inAppMessagesTable, {
21
20
  userId: query.user.id,
22
21
  isRead: false,
@@ -18,10 +18,10 @@ export function createComplianceProfilesFeature(options) {
18
18
  category: "compliance",
19
19
  recommended: false,
20
20
  });
21
- // Standalone — kein r.requires noetig: tenantId kommt aus dem User-
22
- // Context, Profile-Selection ist eigene Entity, sub-processor-Liste
23
- // sind Constants. Wenn S1.4+ Cross-Feature-Reads dazukommen, kommt
24
- // r.requires hier rein.
21
+ // Standalone — r.requires is not needed: tenantId comes from the user
22
+ // context, profile selection is a separate entity, and the sub-processor
23
+ // list consists of constants. Add r.requires if cross-feature reads are
24
+ // introduced.
25
25
  r.entity({ name: "tenant-compliance-profile", ...tenantComplianceProfileEntity });
26
26
  r.exposesApi("compliance.forTenant");
27
27
  const handlers = {
@@ -4,13 +4,10 @@ import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
4
4
  import * as z from "zod";
5
5
  import { parseComplianceProfileOverride } from "../_internal/parse-override.js";
6
6
  import { tenantComplianceProfileTable } from "../schema/profile-selection.js";
7
- // Liefert das effektive Compliance-Profile fuer den aktuellen Tenant.
8
- // Macht den exposesApi-Marker aus feature.ts mit echtem Inhalt.
7
+ // Returns the effective compliance profile for the current tenant.
9
8
  //
10
- // Default-Verhalten (Edge-Case-Decision aus S1.1): kein Profile-
11
- // Eintrag → minimal-no-region + warning="no-profile-selected".
12
- // Caller (z.B. user-data-rights in Sprint 2) sieht das warning und
13
- // kann Onboarding-Banner triggern.
9
+ // If no profile is selected, returns minimal-no-region with
10
+ // warning="no-profile-selected" so callers can trigger an onboarding banner.
14
11
  export const forTenantQuery = defineQueryHandler({
15
12
  name: "for-tenant",
16
13
  schema: z.object({}),
@@ -1,12 +1,12 @@
1
1
  import { COMPLIANCE_PROFILES, SELECTABLE_PROFILE_KEYS, } from "@cosmicdrift/kumiko-framework/compliance";
2
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
- // Liefert alle waehlbaren Compliance-Profile fuer das Tenant-Onboarding.
5
- // Pure In-Memory-Read der Constants — keine DB-Abfrage. Kein Caching
6
- // noetig (modulo Pre-Boot bereits aufgeloest).
4
+ // Returns all selectable compliance profiles for tenant onboarding.
5
+ // Pure in-memory read of the constants—no database query or caching is needed
6
+ // because they are already resolved before boot.
7
7
  //
8
- // Filtert minimal-no-region raus — das ist Default-Fallback, nicht
9
- // auswählbar (Production soll explizite Wahl treffen).
8
+ // Excludes minimal-no-region because it is the default fallback, not selectable;
9
+ // production must make an explicit choice.
10
10
  export const listProfilesQuery = defineQueryHandler({
11
11
  name: "list-profiles",
12
12
  schema: z.object({}),
@@ -5,7 +5,7 @@ import * as z from "zod";
5
5
  import { tenantComplianceProfileTable } from "../schema/profile-selection.js";
6
6
  // Onboarding banner trigger for tenant admin.
7
7
  //
8
- // Sprint 1.5 — minimal API endpoint, the UI banner comes in a later UI
8
+ // Minimal API endpoint, the UI banner comes in a later UI
9
9
  // sprint. Pure read query: does an entry exist in tenantComplianceProfile
10
10
  // for the current tenant?
11
11
  //
@@ -18,7 +18,7 @@ import { tenantComplianceProfileTable } from "../schema/profile-selection.js";
18
18
  // option of createComplianceProfilesFeature) — passing the option through
19
19
  // would widen call access by default to all three access.admin roles
20
20
  // (including SystemAdmin). Instead the handler takes `pickerReachableRoles`
21
- // and deliberately resolves the #2063 special case: if the *caller's*
21
+ // and deliberately resolves the special case: if the *caller's*
22
22
  // roles no longer intersect the picker's `access` option, the query stops
23
23
  // reporting needsSelection — otherwise a tenant admin would be told to
24
24
  // open a screen they can't reach.
@@ -33,8 +33,8 @@ export function createNeedsProfileQuery(pickerReachableRoles) {
33
33
  tenantId: query.user.tenantId,
34
34
  })); // @cast-boundary db-runner
35
35
  if (row) {
36
- // S1.7 X1: minimal-no-region is no longer settable via set-profile
37
- // (Zod). If Sprint 2 ships a seedComplianceProfile helper that
36
+ // Minimal-no-region is no longer settable via set-profile
37
+ // (Zod). If a seedComplianceProfile helper ships that
38
38
  // reintroduces the migration edge case, a defensive path belongs
39
39
  // here again — until then, every existing entry is a deliberately
40
40
  // chosen production profile.
@@ -8,10 +8,10 @@ import { tenantComplianceProfileEntity, tenantComplianceProfileTable, } from "..
8
8
  const crud = createEventStoreExecutor(tenantComplianceProfileTable, tenantComplianceProfileEntity, {
9
9
  entityName: "tenant-compliance-profile",
10
10
  });
11
- // Schema engt sich auf die 3 oeffentlich waehlbaren Profile (Sprint 1.7
12
- // X1) — minimal-no-region ist Default-Fallback fuer "noch keine Wahl",
13
- // nicht eine waehlbare Production-Option. Symmetrisch zu
14
- // SELECTABLE_PROFILE_KEYS aus der framework/compliance-Liste.
11
+ // The schema is limited to the three publicly selectable profiles.
12
+ // `minimal-no-region` is the default fallback while no choice has been
13
+ // made yet, not a selectable production option. This mirrors
14
+ // SELECTABLE_PROFILE_KEYS from the framework/compliance list.
15
15
  const profileKeySchema = z.enum(SELECTABLE_PROFILE_KEYS);
16
16
  // Upsert: the first call inserts, later calls update, so repeating the same values
17
17
  // is idempotent apart from the extra audit events.
@@ -30,22 +30,21 @@ export const setProfileWrite = defineWriteHandler({
30
30
  override: z.string().nullable().optional(),
31
31
  tenantIdOverride: z.string().min(1).optional(),
32
32
  }),
33
- // SystemAdmin kann Profile fuer Customer-Setup setzen (Plattform-
34
- // Operator-Pfad). TenantAdmin nur fuer eigenen Tenant.
33
+ // SystemAdmin can set profiles for customer setup through the platform-
34
+ // operator path; TenantAdmin can set them only for their own tenant.
35
35
  access: { roles: access.admin },
36
36
  description: "Sets or replaces a tenant's compliance profile key plus an optional JSON override, for onboarding or a later region change; a system admin may target a different tenant through tenantIdOverride.",
37
37
  handler: async (event, ctx) => {
38
38
  const tenantId = (event.payload.tenantIdOverride ?? event.user.tenantId); // @cast-boundary engine-payload
39
39
  const { db, streamTenantId } = requireForTenant(ctx, tenantId);
40
- // Override-Validation: muss parseables JSON-Object sein UND dem
41
- // ComplianceProfileOverride-Schema entsprechen (S1.9 Z3 — strict-Zod
42
- // mit Top-Level + Sub-Level-Whitelist via .strict()). Tippfehler
43
- // wie `{ userRights: { weeks: 3 } }` werden hier rejected statt vom
44
- // deepMerge silent ins Profile gespliced.
40
+ // The override must be parseable JSON representing an object and must
41
+ // conform to the ComplianceProfileOverride schema. The strict Zod
42
+ // top-level and nested allowlists reject typos such as
43
+ // `{ userRights: { weeks: 3 } }` instead of silently letting
44
+ // deepMerge splice them into the profile.
45
45
  //
46
- // Errors via writeFailure + Kumiko-Error-Klassen (S1.10 M3) statt
47
- // throw — landen so mit Path-Detail im response-body statt als
48
- // generic internal_error.
46
+ // writeFailure and Kumiko error classes preserve path details in the
47
+ // response body instead of producing a generic internal_error.
49
48
  if (event.payload.override) {
50
49
  let parsed;
51
50
  try {
@@ -2,19 +2,17 @@ import { getActiveSubProcessors, getPlannedSubProcessors, KUMIKO_SUB_PROCESSORS,
2
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
4
4
  import * as z from "zod";
5
- // Public Sub-Processor-Liste — anonymous accessible (Memory:
6
- // project_anonymous_access). Matched die DSGVO Art. 28(2) Pflicht
7
- // dass die Liste der Auftragsverarbeiter oeffentlich einsehbar ist
8
- // (typisch verlinkt aus Datenschutzerklaerung + AVV).
5
+ // Public sub-processor list, accessible anonymously. This satisfies the GDPR Art. 28(2) requirement
6
+ // that the list of processors be publicly accessible, typically linked from
7
+ // the privacy policy and data-processing agreement.
9
8
  //
10
- // Format: JSON mit getrennten active/planned-Sektionen. Tenant-Admins
11
- // kriegen Notification ueber Aenderungen via Cron-Job (Sprint 1.5+
12
- // oder S9 compliance-as-product). RSS-Feed kommt in S9.
9
+ // Format: JSON with separate active/planned sections. Tenant admins receive
10
+ // change notifications via a cron job.
13
11
  //
14
- // Zwei Auflistungen statt einer flachen Liste:
15
- // - `active`: aktuell eingesetzte Sub-Processors
16
- // - `planned`: bekannte zukünftige Sub-Processors (Tenant-Admin-
17
- // Lead-Time bevor sie aktiv werden — typisch bei AI/Stripe)
12
+ // Two lists are used instead of one flat list:
13
+ // - `active`: sub-processors currently in use
14
+ // - `planned`: known future sub-processors, giving tenant admins lead time
15
+ // before activation, as is typical for AI and Stripe providers.
18
16
  export const subProcessorsQuery = defineQueryHandler({
19
17
  name: "sub-processors",
20
18
  schema: z.object({}),
@@ -1,12 +1,12 @@
1
- // Direkter Resolver-Helper fuer Bulk-Iteration ohne dispatcher-Roundtrip.
1
+ // Direct resolver helper for bulk iteration without a dispatcher round trip.
2
2
  //
3
- // `for-tenant`-Query (handlers/for-tenant.query.ts) ist die Cross-Feature-
4
- // API fuer Handler-Pfade. Worker (S2.U3 Atom 3b) lebt im JobContext
5
- // ohne `queryAs` — braucht direkten DB-Lookup + resolveComplianceProfile.
3
+ // The `for-tenant` query (handlers/for-tenant.query.ts) is the cross-feature
4
+ // API for handler paths. Workers run in JobContext (without `queryAs`), so
5
+ // they need a direct database lookup followed by `resolveComplianceProfile`.
6
6
  //
7
- // Pattern matched data-retention's `resolveRetentionPolicyForTenant`.
8
- // Beide Pfade nutzen `resolveComplianceProfile` aus framework/compliance,
9
- // also kein Drift zwischen Query-API und Worker-Pfad.
7
+ // This follows data-retention's `resolveRetentionPolicyForTenant` pattern.
8
+ // Both paths use `resolveComplianceProfile` from framework/compliance, keeping
9
+ // the query API and worker path consistent.
10
10
  import { resolveComplianceProfile, } from "@cosmicdrift/kumiko-framework/compliance";
11
11
  import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
12
12
  import { isTenantDb } from "../shared/index.js";
@@ -1,23 +1,18 @@
1
1
  import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { createEntity, createLongTextField, createSelectField, } from "@cosmicdrift/kumiko-framework/engine";
3
- // Tenant-1-zu-1: Pro Tenant genau eine Profile-Wahl.
3
+ // One-to-one relationship: each tenant has exactly one profile selection.
4
4
  //
5
- // Architektur-Entscheidung (2026-05-06): Profile-Selection lebt als
6
- // separate Entity im compliance-profiles-Feature, NICHT als config-key
7
- // im tenant-Feature. Begruendung:
8
- // (a) override ist strukturiertes JSON, config-key-Pattern (timezone/
9
- // locale) ist key-value-flach
10
- // (b) Profile-Wechsel ist audit-relevant — Event-Store gibt das
11
- // automatisch fuer Entity-Writes
12
- // (c) Plan-Files in docs/plans/datenschutz/compliance-profiles.md
13
- // nennen sie explizit als tenantComplianceProfile-Entity
5
+ // Profile selection is a separate entity in the compliance-profiles feature,
6
+ // not a config key in the tenant feature, because:
7
+ // (a) override is structured JSON, while the config-key pattern
8
+ // (timezone/locale) is flat key-value data
9
+ // (b) profile changes are audit-relevant, which the event store handles
10
+ // automatically for entity writes
14
11
  //
15
- // Wer in 6 Monaten zweifelt warum nicht config-key: siehe oben.
16
- //
17
- // override als JSON-String in longText: kein dedizierter jsonField-Typ
18
- // im Framework; embedded hat festes Schema, das hier dynamisch ist.
19
- // Zod-Validation beim set-profile-Handler stellt Schema-Konformitaet
20
- // sicher.
12
+ // override is stored as a JSON string in longText because the framework has
13
+ // no dedicated jsonField type; embedded has a fixed schema, while this schema
14
+ // is dynamic. Zod validation in the set-profile handler ensures schema
15
+ // conformity.
21
16
  export const tenantComplianceProfileEntity = createEntity({
22
17
  table: "read_tenant_compliance_profiles",
23
18
  fields: {
@@ -25,19 +20,19 @@ export const tenantComplianceProfileEntity = createEntity({
25
20
  required: true,
26
21
  options: ["eu-dsgvo", "swiss-dsg", "de-hr-dsgvo-hgb", "minimal-no-region"],
27
22
  }),
28
- // override: JSON-String mit Partial-ComplianceProfile. NULL/leer
29
- // bedeutet "Default-Profile, keine Override". Validiert beim
30
- // set-profile-Handler via Zod.
23
+ // override: JSON string containing a partial ComplianceProfile. NULL/empty
24
+ // means "default profile, no override". Validated by the
25
+ // set-profile handler via Zod.
31
26
  override: createLongTextField({
32
27
  personal: false,
33
28
  reason: "is_business_data",
34
29
  }),
35
30
  },
36
31
  indexes: [
37
- // Pro Tenant nur EIN Profile-Datensatz. Boot-Validator-Comment in
38
- // EntityIndexDef warnt vor single-column-tenantId-Index als redundant
39
- // — UNIQUE-Constraint ist hier aber semantisch noetig (1:1-Relation)
40
- // und nicht nur Performance-Hint, daher explizit deklariert.
32
+ // Only one profile record is allowed per tenant. Although the boot validator
33
+ // warns that a single-column tenantId index is redundant, the UNIQUE
34
+ // constraint is semantically required here for the one-to-one relationship,
35
+ // not merely a performance hint, so it is declared explicitly.
41
36
  { unique: true, columns: ["tenantId"] },
42
37
  ],
43
38
  });
@@ -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