@cosmicdrift/kumiko-bundled-features 0.385.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 (470) hide show
  1. package/LICENSE +21 -57
  2. package/dist/agent-tools/tool-catalog.js +1 -1
  3. package/dist/agent-tools/tool-dispatch.js +0 -2
  4. package/dist/audit/screens.js +1 -1
  5. package/dist/auth-email-password/feature.js +1 -1
  6. package/dist/auth-email-password/handlers/change-password.write.js +3 -3
  7. package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
  8. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
  9. package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
  10. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  11. package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
  12. package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
  13. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
  14. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  15. package/dist/auth-email-password/handlers/login.write.js +1 -1
  16. package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
  17. package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
  18. package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
  19. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  20. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
  21. package/dist/auth-email-password/index.js +5 -5
  22. package/dist/auth-email-password/lockout-store.js +1 -1
  23. package/dist/auth-email-password/seeding.d.ts +42 -45
  24. package/dist/auth-email-password/seeding.js +51 -53
  25. package/dist/auth-email-password/signup-token-store.js +8 -8
  26. package/dist/auth-email-password/testing.js +3 -3
  27. package/dist/auth-email-password/web/auth-client.d.ts +2 -2
  28. package/dist/auth-email-password/web/auth-client.js +36 -37
  29. package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
  30. package/dist/auth-email-password/web/auth-gate.js +15 -16
  31. package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
  32. package/dist/auth-email-password/web/client-plugin.js +4 -5
  33. package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
  34. package/dist/auth-email-password/web/constants.js +3 -3
  35. package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
  36. package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
  37. package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
  38. package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
  39. package/dist/auth-email-password/web/index.js +5 -5
  40. package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
  41. package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
  42. package/dist/auth-email-password/web/login-screen.d.ts +1 -1
  43. package/dist/auth-email-password/web/login-screen.js +2 -3
  44. package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
  45. package/dist/auth-email-password/web/reset-password-screen.js +12 -13
  46. package/dist/auth-email-password/web/session.d.ts +10 -9
  47. package/dist/auth-email-password/web/session.js +28 -29
  48. package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
  49. package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
  50. package/dist/auth-email-password/web/signup-screen.js +13 -13
  51. package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
  52. package/dist/auth-email-password/web/tenant-switcher.js +21 -22
  53. package/dist/auth-email-password/web/use-shell-user.js +12 -13
  54. package/dist/auth-email-password/web/user-menu.d.ts +4 -4
  55. package/dist/auth-email-password/web/user-menu.js +12 -13
  56. package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
  57. package/dist/auth-email-password/web/verify-email-screen.js +9 -10
  58. package/dist/auth-foundation/boot-checks.js +4 -4
  59. package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
  60. package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
  61. package/dist/auth-foundation/types.js +2 -2
  62. package/dist/auth-mfa/handlers/disable.write.js +3 -3
  63. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
  64. package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
  65. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
  66. package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
  67. package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
  68. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  69. package/dist/auth-mfa/token-secrets.js +1 -1
  70. package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
  71. package/dist/auth-mfa/web/client-plugin.js +1 -1
  72. package/dist/auth-mfa/web/i18n.js +3 -3
  73. package/dist/auth-mfa/web/index.js +4 -4
  74. package/dist/auth-mfa/web/mfa-client.js +17 -16
  75. package/dist/auth-mfa/web/mfa-verify-screen.js +6 -6
  76. package/dist/billing-foundation/aggregate-id.d.ts +5 -5
  77. package/dist/billing-foundation/aggregate-id.js +10 -11
  78. package/dist/billing-foundation/entities.js +27 -27
  79. package/dist/billing-foundation/events.js +18 -17
  80. package/dist/billing-foundation/feature.js +42 -43
  81. package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
  82. package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
  83. package/dist/billing-foundation/handlers/create-checkout-session.write.js +18 -17
  84. package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
  85. package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
  86. package/dist/billing-foundation/handlers/process-event.write.js +20 -20
  87. package/dist/billing-foundation/projection.d.ts +15 -11
  88. package/dist/billing-foundation/projection.js +38 -37
  89. package/dist/billing-foundation/subscription-tier-sync.js +3 -3
  90. package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
  91. package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
  92. package/dist/billing-foundation/types.d.ts +40 -41
  93. package/dist/billing-foundation/types.js +20 -20
  94. package/dist/billing-foundation/web/billing-plans-panel.js +4 -4
  95. package/dist/cap-counter/aggregate-id.js +8 -9
  96. package/dist/cap-counter/constants.js +11 -12
  97. package/dist/cap-counter/enforce-cap.d.ts +59 -62
  98. package/dist/cap-counter/enforce-cap.js +47 -48
  99. package/dist/cap-counter/entity.js +29 -29
  100. package/dist/cap-counter/feature.js +34 -35
  101. package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
  102. package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
  103. package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
  104. package/dist/cap-counter/stock-cap-guard.js +1 -1
  105. package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
  106. package/dist/channel-email/smtp-transport.d.ts +18 -17
  107. package/dist/channel-email/smtp-transport.js +24 -21
  108. package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
  109. package/dist/compliance-profiles/feature.js +4 -4
  110. package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
  111. package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
  112. package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
  113. package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
  114. package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
  115. package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
  116. package/dist/compliance-profiles/schema/profile-selection.js +18 -23
  117. package/dist/compliance-profiles/seeding.js +14 -15
  118. package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
  119. package/dist/compliance-profiles-ops/index.js +2 -2
  120. package/dist/config/handlers/readiness.query.d.ts +4 -4
  121. package/dist/config/handlers/readiness.query.js +1 -1
  122. package/dist/config/handlers/reencrypt.job.js +4 -5
  123. package/dist/config/handlers/set.write.js +4 -4
  124. package/dist/config/resolver.js +4 -4
  125. package/dist/config/table.js +10 -10
  126. package/dist/config/write-helpers.js +1 -1
  127. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
  128. package/dist/crypto-shredding/handlers/forget-subject.write.js +12 -11
  129. package/dist/custom-fields/aggregate-id.d.ts +12 -13
  130. package/dist/custom-fields/aggregate-id.js +16 -17
  131. package/dist/custom-fields/entity.js +49 -47
  132. package/dist/custom-fields/events.js +7 -8
  133. package/dist/custom-fields/feature.d.ts +14 -14
  134. package/dist/custom-fields/feature.js +53 -54
  135. package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
  136. package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
  137. package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
  138. package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
  139. package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
  140. package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
  141. package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
  142. package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
  143. package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
  144. package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
  145. package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
  146. package/dist/custom-fields/lib/field-access.js +2 -2
  147. package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
  148. package/dist/custom-fields/lib/quota.js +1 -1
  149. package/dist/custom-fields/lib/value-schema.js +10 -12
  150. package/dist/custom-fields/run-retention.js +3 -3
  151. package/dist/custom-fields/schemas.js +14 -14
  152. package/dist/custom-fields/web/client-plugin.js +2 -5
  153. package/dist/custom-fields/web/constants.js +2 -2
  154. package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
  155. package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
  156. package/dist/custom-fields/wire-for-entity.js +65 -67
  157. package/dist/custom-fields/wire-user-data-rights.js +3 -3
  158. package/dist/data-retention/_internal/parse-override.js +2 -3
  159. package/dist/data-retention/feature.js +11 -18
  160. package/dist/data-retention/handlers/policy-for.query.js +6 -6
  161. package/dist/data-retention/keep-for.d.ts +7 -7
  162. package/dist/data-retention/keep-for.js +15 -15
  163. package/dist/data-retention/override-schema.d.ts +3 -4
  164. package/dist/data-retention/override-schema.js +13 -15
  165. package/dist/data-retention/presets.d.ts +4 -5
  166. package/dist/data-retention/presets.js +18 -23
  167. package/dist/data-retention/resolve-tenant-preset.js +17 -16
  168. package/dist/data-retention/resolver.d.ts +12 -12
  169. package/dist/data-retention/resolver.js +24 -23
  170. package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
  171. package/dist/data-retention/run-retention-cleanup.js +61 -51
  172. package/dist/data-retention/schema/tenant-retention-override.js +13 -11
  173. package/dist/delivery/feature.js +2 -2
  174. package/dist/delivery/handlers/log.query.js +1 -1
  175. package/dist/delivery/tables.js +9 -8
  176. package/dist/delivery/unsubscribe.js +4 -4
  177. package/dist/document-ingest-foundation/entity.js +4 -4
  178. package/dist/document-ingest-foundation/events.js +2 -2
  179. package/dist/document-ingest-foundation/feature.js +2 -2
  180. package/dist/document-ingest-foundation/pages.js +1 -1
  181. package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
  182. package/dist/feature-toggles/compose-tier-resolver.js +1 -1
  183. package/dist/feature-toggles/feature.js +1 -1
  184. package/dist/feature-toggles/global-feature-state-table.js +1 -1
  185. package/dist/feature-toggles/handlers/registered.query.js +5 -5
  186. package/dist/feature-toggles/toggle-sync-signal.js +1 -1
  187. package/dist/feature-toggles/web/constants.js +1 -1
  188. package/dist/file-derivatives/feature.d.ts +1 -1
  189. package/dist/file-derivatives/feature.js +1 -1
  190. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  191. package/dist/file-derivatives/presets.js +1 -1
  192. package/dist/file-foundation/feature.js +6 -6
  193. package/dist/file-provider-inmemory/feature.d.ts +1 -1
  194. package/dist/file-provider-inmemory/feature.js +16 -16
  195. package/dist/file-provider-s3/feature.js +16 -16
  196. package/dist/file-provider-s3/lib/s3-provider.js +6 -6
  197. package/dist/files/feature.js +6 -6
  198. package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
  199. package/dist/files-tenant-data/hooks.js +24 -26
  200. package/dist/files-tenant-data/index.js +1 -1
  201. package/dist/folders/feature.d.ts +1 -1
  202. package/dist/folders/web/folder-manager.js +2 -2
  203. package/dist/folders/web/tree.js +5 -5
  204. package/dist/form-draft/db/queries/cleanup.js +1 -1
  205. package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
  206. package/dist/form-draft/entity.js +3 -3
  207. package/dist/form-draft/feature.js +4 -5
  208. package/dist/form-draft/handlers/discard.write.js +1 -1
  209. package/dist/form-draft/release-file-refs.js +6 -6
  210. package/dist/form-draft/schemas.js +3 -3
  211. package/dist/form-draft/web/constants.js +0 -2
  212. package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
  213. package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
  214. package/dist/inbound-mail-foundation/connect-routes.js +4 -3
  215. package/dist/inbound-mail-foundation/constants.d.ts +22 -24
  216. package/dist/inbound-mail-foundation/constants.js +30 -33
  217. package/dist/inbound-mail-foundation/entities.d.ts +12 -12
  218. package/dist/inbound-mail-foundation/entities.js +47 -48
  219. package/dist/inbound-mail-foundation/events.d.ts +4 -3
  220. package/dist/inbound-mail-foundation/events.js +50 -47
  221. package/dist/inbound-mail-foundation/feature.js +39 -39
  222. package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
  223. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
  224. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
  225. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
  226. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
  227. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
  228. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
  229. package/dist/inbound-mail-foundation/handlers/update-account.write.js +11 -11
  230. package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
  231. package/dist/inbound-mail-foundation/oauth-state.js +11 -10
  232. package/dist/inbound-mail-foundation/projection.d.ts +4 -4
  233. package/dist/inbound-mail-foundation/projection.js +31 -29
  234. package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
  235. package/dist/inbound-mail-foundation/provider-factory.js +9 -9
  236. package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
  237. package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
  238. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
  239. package/dist/inbound-mail-foundation/types.d.ts +45 -46
  240. package/dist/inbound-mail-foundation/types.js +21 -21
  241. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
  242. package/dist/inbound-mail-foundation/watch-supervisor.js +57 -56
  243. package/dist/inbound-provider-imap/credential-document.js +13 -13
  244. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  245. package/dist/inbound-provider-imap/feature.js +42 -40
  246. package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
  247. package/dist/inbound-provider-imap/imap-client.js +20 -19
  248. package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
  249. package/dist/inbound-provider-inmemory/feature.js +19 -19
  250. package/dist/jobs/db/queries/retention.js +2 -2
  251. package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
  252. package/dist/jobs/events.js +1 -1
  253. package/dist/jobs/feature.js +5 -6
  254. package/dist/jobs/handlers/detail.query.js +4 -4
  255. package/dist/jobs/handlers/list.query.js +1 -1
  256. package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
  257. package/dist/jobs/handlers/reindex-entity.job.js +1 -1
  258. package/dist/jobs/handlers/retry.write.js +1 -1
  259. package/dist/jobs/job-instant.js +1 -1
  260. package/dist/jobs/job-run-logger.js +10 -11
  261. package/dist/jobs/job-run-table.js +3 -3
  262. package/dist/jobs/screens.js +1 -1
  263. package/dist/jobs/tenant-job-failure-table.js +1 -1
  264. package/dist/jobs/tenant-job-run-table.js +1 -1
  265. package/dist/ledger/entity.js +5 -5
  266. package/dist/ledger/feature.js +3 -3
  267. package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
  268. package/dist/ledger/recurring.js +12 -12
  269. package/dist/ledger/schemas.js +1 -1
  270. package/dist/ledger/web/constants.js +2 -2
  271. package/dist/ledger/web/index.js +7 -7
  272. package/dist/legal-pages/feature.d.ts +4 -4
  273. package/dist/legal-pages/feature.js +25 -26
  274. package/dist/legal-pages/markdown.js +3 -3
  275. package/dist/legal-pages/web/client-plugin.js +23 -24
  276. package/dist/legal-pages/web/index.js +0 -1
  277. package/dist/mail-foundation/feature.d.ts +2 -2
  278. package/dist/mail-foundation/feature.js +24 -25
  279. package/dist/mail-transport-inmemory/feature.d.ts +4 -4
  280. package/dist/mail-transport-inmemory/feature.js +27 -28
  281. package/dist/mail-transport-smtp/feature.js +20 -20
  282. package/dist/managed-pages/branding.js +6 -6
  283. package/dist/managed-pages/feature.d.ts +26 -26
  284. package/dist/managed-pages/feature.js +34 -34
  285. package/dist/managed-pages/handlers/by-slug.query.js +5 -6
  286. package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
  287. package/dist/managed-pages/handlers/set.write.js +5 -7
  288. package/dist/managed-pages/screens/page-screens.js +11 -11
  289. package/dist/managed-pages/seeding.js +8 -8
  290. package/dist/managed-pages/table.js +13 -12
  291. package/dist/managed-pages/web/client-plugin.d.ts +1 -1
  292. package/dist/managed-pages/web/client-plugin.js +5 -5
  293. package/dist/managed-pages/web/i18n.js +1 -1
  294. package/dist/notes-history/entity.js +4 -4
  295. package/dist/notes-history/feature.d.ts +2 -2
  296. package/dist/notes-history-user-data/hooks.js +1 -1
  297. package/dist/page-render/layout.js +9 -9
  298. package/dist/page-render/markdown.js +11 -11
  299. package/dist/page-render/security-headers.js +7 -6
  300. package/dist/personal-access-tokens/feature.js +5 -5
  301. package/dist/personal-access-tokens/roles.js +2 -2
  302. package/dist/readiness/handlers/status.query.js +3 -3
  303. package/dist/renderer-foundation/api.js +12 -13
  304. package/dist/renderer-foundation/constants.js +2 -2
  305. package/dist/renderer-foundation/feature.js +7 -7
  306. package/dist/secrets/feature.js +9 -9
  307. package/dist/secrets/web/constants.js +2 -2
  308. package/dist/seo/feature.js +3 -3
  309. package/dist/sessions/constants.d.ts +1 -1
  310. package/dist/sessions/constants.js +1 -1
  311. package/dist/sessions/feature.js +8 -8
  312. package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
  313. package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
  314. package/dist/sessions/handlers/revoke.write.js +1 -1
  315. package/dist/sessions/schema/user-session.js +4 -4
  316. package/dist/sessions/screens.js +2 -2
  317. package/dist/sessions/session-callbacks.js +2 -2
  318. package/dist/sessions/session-revoked-event.js +2 -2
  319. package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
  320. package/dist/shared/decrypt-stored-pii.js +1 -1
  321. package/dist/shared/encrypt-for-direct-write.js +1 -1
  322. package/dist/shared/map-with-concurrency.js +5 -4
  323. package/dist/shared/parent-visibility.js +2 -2
  324. package/dist/shared/password-hashing.js +1 -1
  325. package/dist/shared/signup-handover.js +1 -2
  326. package/dist/shared/single-use-token-store.js +1 -1
  327. package/dist/subscription-mollie/constants.js +15 -17
  328. package/dist/subscription-mollie/feature.d.ts +17 -18
  329. package/dist/subscription-mollie/feature.js +24 -24
  330. package/dist/subscription-mollie/index.js +3 -3
  331. package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
  332. package/dist/subscription-mollie/plugin-methods.js +15 -14
  333. package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
  334. package/dist/subscription-mollie/verify-webhook.js +27 -27
  335. package/dist/subscription-stripe/constants.js +4 -6
  336. package/dist/subscription-stripe/feature.d.ts +14 -14
  337. package/dist/subscription-stripe/feature.js +35 -34
  338. package/dist/subscription-stripe/index.js +6 -6
  339. package/dist/subscription-stripe/plugin-methods.js +18 -18
  340. package/dist/subscription-stripe/runtime.d.ts +1 -1
  341. package/dist/subscription-stripe/runtime.js +1 -1
  342. package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
  343. package/dist/subscription-stripe/verify-webhook.js +59 -61
  344. package/dist/tags/feature.d.ts +3 -3
  345. package/dist/tags/screens.js +1 -1
  346. package/dist/template-resolver/api.js +10 -10
  347. package/dist/template-resolver/handlers/find-by-id.query.js +5 -5
  348. package/dist/template-resolver/handlers/list.query.js +1 -1
  349. package/dist/template-resolver/handlers/shared.js +2 -2
  350. package/dist/template-resolver/handlers/template-write.js +3 -3
  351. package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
  352. package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
  353. package/dist/template-resolver/seeding.js +4 -4
  354. package/dist/template-resolver/table.js +10 -11
  355. package/dist/template-resolver/web/client-plugin.js +2 -2
  356. package/dist/tenant/feature.js +7 -7
  357. package/dist/tenant/handlers/member-directory.query.js +1 -1
  358. package/dist/tenant/handlers/members.query.js +1 -1
  359. package/dist/tenant/handlers/team-list.query.js +1 -1
  360. package/dist/tenant/handlers/tenant-directory.query.js +1 -1
  361. package/dist/tenant/invitation-table.js +37 -40
  362. package/dist/tenant/membership-table.js +3 -3
  363. package/dist/tenant/schema/tenant.js +7 -9
  364. package/dist/tenant/screens.js +1 -1
  365. package/dist/tenant/seeding.d.ts +6 -5
  366. package/dist/tenant/seeding.js +12 -12
  367. package/dist/tenant/testing.js +5 -6
  368. package/dist/tenant/web/constants.js +2 -2
  369. package/dist/tenant-handover/events.js +5 -7
  370. package/dist/tenant-handover/feature.js +1 -1
  371. package/dist/tenant-handover/grant.js +1 -1
  372. package/dist/tenant-handover/handlers/claim.write.js +1 -1
  373. package/dist/tenant-handover/move-entity-graph.js +8 -9
  374. package/dist/tenant-handover/signup-handover-provider.js +1 -2
  375. package/dist/tenant-handover/transfer-graph.js +4 -5
  376. package/dist/tenant-lifecycle/boot-checks.js +1 -1
  377. package/dist/tenant-lifecycle/feature.js +1 -1
  378. package/dist/tenant-settings/constants.js +1 -1
  379. package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
  380. package/dist/tenant-settings/tenant-defaults.js +9 -2
  381. package/dist/tier-engine/aggregate-id.d.ts +11 -11
  382. package/dist/tier-engine/aggregate-id.js +15 -16
  383. package/dist/tier-engine/compose-app.d.ts +14 -14
  384. package/dist/tier-engine/compose-app.js +1 -1
  385. package/dist/tier-engine/entity.js +18 -19
  386. package/dist/tier-engine/feature.d.ts +19 -17
  387. package/dist/tier-engine/feature.js +68 -69
  388. package/dist/tier-engine/handlers/active-tier.query.js +6 -7
  389. package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
  390. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +5 -5
  391. package/dist/tier-engine/handlers/set-tenant-tier.write.js +3 -3
  392. package/dist/tier-engine/tier-resolver.js +2 -2
  393. package/dist/tier-engine/trial.js +8 -8
  394. package/dist/tier-engine/web/index.js +4 -4
  395. package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
  396. package/dist/user/handlers/create.write.js +4 -4
  397. package/dist/user/schema/user.d.ts +11 -11
  398. package/dist/user/schema/user.js +45 -44
  399. package/dist/user/seeding.d.ts +15 -15
  400. package/dist/user/seeding.js +28 -28
  401. package/dist/user/testing.js +3 -3
  402. package/dist/user-data-rights/audit-download.d.ts +8 -8
  403. package/dist/user-data-rights/audit-download.js +19 -20
  404. package/dist/user-data-rights/boot-checks.js +1 -1
  405. package/dist/user-data-rights/deletion-token.js +1 -1
  406. package/dist/user-data-rights/feature.d.ts +49 -50
  407. package/dist/user-data-rights/feature.js +54 -53
  408. package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
  409. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
  410. package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
  411. package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
  412. package/dist/user-data-rights/handlers/export-status.query.js +8 -9
  413. package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
  414. package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
  415. package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
  416. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
  417. package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
  418. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
  419. package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
  420. package/dist/user-data-rights/handlers/request-export.write.js +42 -41
  421. package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
  422. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
  423. package/dist/user-data-rights/index.js +8 -10
  424. package/dist/user-data-rights/lib/default-mailers.js +3 -3
  425. package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
  426. package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
  427. package/dist/user-data-rights/run-export-jobs.js +127 -233
  428. package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
  429. package/dist/user-data-rights/run-forget-cleanup.js +63 -82
  430. package/dist/user-data-rights/run-user-export.d.ts +34 -33
  431. package/dist/user-data-rights/run-user-export.js +55 -57
  432. package/dist/user-data-rights/schema/download-attempt.js +11 -11
  433. package/dist/user-data-rights/schema/download-token.js +37 -41
  434. package/dist/user-data-rights/schema/export-job.d.ts +4 -4
  435. package/dist/user-data-rights/schema/export-job.js +65 -67
  436. package/dist/user-data-rights/token-helpers.d.ts +8 -9
  437. package/dist/user-data-rights/token-helpers.js +21 -25
  438. package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
  439. package/dist/user-data-rights/web/client-plugin.js +1 -1
  440. package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
  441. package/dist/user-data-rights/web/constants.js +1 -1
  442. package/dist/user-data-rights/web/index.js +5 -5
  443. package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
  444. package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
  445. package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
  446. package/dist/user-data-rights/zip-path.d.ts +15 -15
  447. package/dist/user-data-rights/zip-path.js +41 -40
  448. package/dist/user-data-rights-defaults/feature.js +15 -15
  449. package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
  450. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
  451. package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
  452. package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
  453. package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
  454. package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
  455. package/dist/user-profile/handlers/change-email.write.js +13 -13
  456. package/dist/user-profile/index.js +3 -3
  457. package/dist/user-profile/web/client-plugin.js +1 -1
  458. package/dist/user-profile/web/constants.js +1 -1
  459. package/dist/user-profile/web/profile-screen.js +1 -1
  460. package/dist/workflow-runner/aggregate-id.d.ts +1 -1
  461. package/dist/workflow-runner/aggregate-id.js +1 -1
  462. package/dist/workflow-runner/event-subscriber.js +4 -5
  463. package/dist/workflow-runner/event-trigger.js +4 -17
  464. package/dist/workflow-runner/feature.js +2 -2
  465. package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
  466. package/dist/workflow-runner/pending-projection.js +6 -7
  467. package/dist/workflow-runner/runner.js +6 -6
  468. package/dist/workflow-runner/tables.js +6 -6
  469. package/dist/workflow-runner/workflow-registry.js +1 -1
  470. package/package.json +10 -10
@@ -1,6 +1,6 @@
1
1
  // Generic tier-resolver factory. Extracted from the near-identical
2
- // tier-resolver.ts app copies in show-pony and publicstatus (infra#446) — the
3
- // only per-app variables were the TierName union and its caps/defaults, so
2
+ // tier-resolver.ts app copies in show-pony and publicstatus — the only
3
+ // per-app variables were the TierName union and its caps/defaults, so
4
4
  // both are now factory parameters.
5
5
  import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
6
6
  import { tierAssignmentEntity } from "./entity.js";
@@ -1,11 +1,11 @@
1
- // Trial-Phase: ein neuer Tenant bekommt für eine Karenzzeit ab seinem
2
- // Anlage-Datum (inserted_at der tier-assignment-Row — rebuild-stabil aus dem
3
- // Create-Event) zusätzlich die Features eines höheren Tiers, unabhängig vom
4
- // gespeicherten Tier. Rein zeit-abgeleitet: kein Stored-Flag, kein Scheduler,
5
- // automatischer Ablauf. Die App definiert die Policy (welcher Tier, wie lange);
6
- // die tier-engine wendet sie im Resolver an.
7
- // Reine Millis-Arithmetik auf epochMilliseconds (die beide Seiten — Projektions-
8
- // Row und Now — liefern). Kein Date, keine TZ.
1
+ // Trial phase: a new tenant receives the features of a higher tier for a grace
2
+ // period starting at its creation date (`inserted_at` of the tier-assignment Row —
3
+ // stable across rebuilds because it comes from the Create Event), regardless of
4
+ // the stored tier. It is derived solely from time: no stored flag, no scheduler,
5
+ // and automatic expiration. The app defines the policy (which tier, how long);
6
+ // the tier-engine applies it in the resolver.
7
+ // Pure millisecond arithmetic on epochMilliseconds, which both sides—the
8
+ // projection Row and Now—provide. No Date and no time zone.
9
9
  export function isTrialActive(startedAtEpochMs, nowEpochMs, durationHours) {
10
10
  return nowEpochMs < startedAtEpochMs + durationHours * 3_600_000;
11
11
  }
@@ -1,5 +1,5 @@
1
- // Public exports für die Browser-Seite des tier-engine Features. Konsumiert
2
- // über `@cosmicdrift/kumiko-bundled-features/tier-engine/web` — die
3
- // Server-Seite (createTierEngineFeature) lebt unter
4
- // `@cosmicdrift/kumiko-bundled-features/tier-engine` und hat keine React-Deps.
1
+ // Public exports for the browser side of the tier-engine feature. Import via
2
+ // `@cosmicdrift/kumiko-bundled-features/tier-engine/web` — the server side
3
+ // (createTierEngineFeature) is under
4
+ // `@cosmicdrift/kumiko-bundled-features/tier-engine` and has no React deps.
5
5
  export { tierEngineClient } from "./client-plugin.js";
@@ -1,11 +1,11 @@
1
- // #762 — one-time migration tooling for pre-#497 user event streams.
1
+ // One-time migration tooling for older user event streams.
2
2
  //
3
- // #497 made `user` a systemStream entity: every executor op addresses the
3
+ // Making `user` a systemStream entity means every executor op addresses the
4
4
  // stream on SYSTEM_TENANT_ID. Streams created before that live on whichever
5
- // tenant created them ("scattered"), so post-#497 writes version-conflict
6
- // against the empty SYSTEM stream. The raw UPDATE documented in the #497
7
- // changeset breaks as soon as an aggregate has BOTH a legacy stream and
8
- // post-#497 SYSTEM events (split stream — e.g. a skipOptimisticLock
5
+ // tenant created them ("scattered"), so newer writes version-conflict
6
+ // against the empty SYSTEM stream. The raw UPDATE breaks as soon as an
7
+ // aggregate has BOTH a legacy stream and newer SYSTEM events
8
+ // (split stream — e.g. a skipOptimisticLock
9
9
  // lifecycle write appended v1 on SYSTEM while v1..n live on the old
10
10
  // tenant): retenanting then trips events_aggregate_version_uq.
11
11
  //
@@ -54,12 +54,12 @@ async function migrateAggregate(db, aggregateId) {
54
54
  WHERE "aggregate_type" = 'user' AND "aggregate_id" = $1::uuid
55
55
  ORDER BY "id" ASC
56
56
  FOR UPDATE`, [aggregateId]);
57
- // Phase 1: negative interim versions — real versions are always >= 1, so
57
+ // Negative interim versions — real versions are always >= 1, so
58
58
  // nothing can collide with events_aggregate_version_uq mid-migration.
59
59
  for (const [i, ev] of events.entries()) {
60
60
  await raw.unsafe(`UPDATE "kumiko_events" SET "tenant_id" = $1::uuid, "version" = $2 WHERE "id" = $3`, [SYSTEM_TENANT_ID, -(i + 1), ev.id]);
61
61
  }
62
- // Phase 2: final contiguous 1..n.
62
+ // Final contiguous 1..n.
63
63
  for (const [i, ev] of events.entries()) {
64
64
  await raw.unsafe(`UPDATE "kumiko_events" SET "version" = $1 WHERE "id" = $2`, [i + 1, ev.id]);
65
65
  }
@@ -11,14 +11,14 @@ import { UserErrors } from "../web/constants.js";
11
11
  const crud = createEventStoreExecutor(userTable, userEntity, { entityName: "user" });
12
12
  // Only the Auth features (running as SYSTEM) or a SystemAdmin may create users.
13
13
  //
14
- // Email uniqueness has two layers (fw#2134):
14
+ // Email uniqueness has two layers:
15
15
  // 1. A pre-flight fetchOne — fast-fails with a friendly error on the
16
16
  // common case, but is race-prone on its own: two concurrent requests
17
17
  // can both see "no duplicate" and both proceed to crud.create.
18
18
  // 2. The real guard is the unique index over email's blind-index column
19
19
  // (schema/user.ts). A losing concurrent create hits that constraint
20
- // and crud.create returns a UniqueViolationError (framework's F8
21
- // pg-23505 mapping) instead of throwing — remapped below to the same
20
+ // and crud.create returns a UniqueViolationError (framework's pg-23505
21
+ // mapping) instead of throwing — remapped below to the same
22
22
  // emailAlreadyExists shape the pre-flight path returns, so callers see
23
23
  // one consistent error regardless of which layer caught the race.
24
24
  export const createWrite = defineWriteHandler({
@@ -89,7 +89,7 @@ export const createWrite = defineWriteHandler({
89
89
  // schema/user.ts's `read_users_email_unique` (+ its generated `_bidx`
90
90
  // pendant) is the actual race-safety net behind the pre-flight check
91
91
  // above — a losing concurrent create surfaces here as a generic
92
- // UniqueViolationError (framework F8 pg-23505 mapping). Only the email
92
+ // UniqueViolationError (framework pg-23505 mapping). Only the email
93
93
  // constraint gets remapped; any other unique_violation on this entity
94
94
  // passes through unchanged.
95
95
  function isRecord(value) {
@@ -1,8 +1,7 @@
1
1
  /**
2
- * User-Lifecycle-Status (S2.U1). Single source of truth — Auth-Middleware
3
- * (S2.U6), Forget-Job (S2.U5) und Restriction-Handler nutzen diese
4
- * Constants statt Magic-Strings (Memory feedback_role_naming_drift —
5
- * gleiches Pattern wie ROLES.SystemAdmin).
2
+ * User lifecycle status. This is the single source of truth used by the
3
+ * auth middleware, forget job, and restriction handler instead of duplicated
4
+ * magic strings, following the same pattern as ROLES.SystemAdmin.
6
5
  */
7
6
  export declare const USER_STATUS: {
8
7
  readonly Active: "active";
@@ -12,17 +11,18 @@ export declare const USER_STATUS: {
12
11
  };
13
12
  export type UserStatus = (typeof USER_STATUS)[keyof typeof USER_STATUS];
14
13
  /**
15
- * Anonymize-Display-Strings fuer userDeleteHook (S2.H1). Constants statt
16
- * Magic-Strings damit i18n-Mapping moeglich + drift-fest. Default-DE,
17
- * App-Author kann via i18n-System uebersetzen wenn gewuenscht.
14
+ * Display strings anonymized by userDeleteHook. Constants keep i18n mapping
15
+ * possible and prevent drift. The default is German; app authors can
16
+ * translate it through the i18n system if desired.
18
17
  */
19
18
  export declare const USER_DELETED_DISPLAY_NAME = "[Geloescht]";
20
19
  export declare const USER_ANONYMIZED_DISPLAY_NAME = "[Anonymisiert]";
21
20
  /**
22
- * Email-Pseudonyme nach Forget. `<prefix>-<userId>@anonymized.invalid`
23
- * — der userId-Suffix ist als Pseudo-Audit-Marker fuer Operator
24
- * (Tracing-fall) erlaubt; user-id selbst ist UUID, kein PII.
25
- * `.invalid`-TLD ist RFC2606-reserviert — niemals deliverbare Email.
21
+ * Email pseudonyms used after forgetting. `<prefix>-<userId>@anonymized.invalid`
22
+ * — the userId suffix is permitted as a pseudo-audit marker for operator
23
+ * tracing; the user ID itself is a UUID, not PII.
24
+ * The `.invalid` TLD is reserved by RFC2606, so the address can never be
25
+ * delivered.
26
26
  */
27
27
  export declare const USER_DELETED_EMAIL_PREFIX = "deleted";
28
28
  export declare const USER_ANONYMIZED_EMAIL_PREFIX = "anonymized";
@@ -2,10 +2,9 @@ import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { access, createBooleanField, createDerivedField, createEntity, createMultiSelectField, createSelectField, createTextField, createTimestampField, createTzField, } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { GLOBAL_ROLE_OPTIONS } from "../web/constants.js";
4
4
  /**
5
- * User-Lifecycle-Status (S2.U1). Single source of truth — Auth-Middleware
6
- * (S2.U6), Forget-Job (S2.U5) und Restriction-Handler nutzen diese
7
- * Constants statt Magic-Strings (Memory feedback_role_naming_drift —
8
- * gleiches Pattern wie ROLES.SystemAdmin).
5
+ * User lifecycle status. This is the single source of truth used by the
6
+ * auth middleware, forget job, and restriction handler instead of duplicated
7
+ * magic strings, following the same pattern as ROLES.SystemAdmin.
9
8
  */
10
9
  export const USER_STATUS = {
11
10
  Active: "active",
@@ -14,24 +13,25 @@ export const USER_STATUS = {
14
13
  Deleted: "deleted",
15
14
  };
16
15
  /**
17
- * Anonymize-Display-Strings fuer userDeleteHook (S2.H1). Constants statt
18
- * Magic-Strings damit i18n-Mapping moeglich + drift-fest. Default-DE,
19
- * App-Author kann via i18n-System uebersetzen wenn gewuenscht.
16
+ * Display strings anonymized by userDeleteHook. Constants keep i18n mapping
17
+ * possible and prevent drift. The default is German; app authors can
18
+ * translate it through the i18n system if desired.
20
19
  */
21
20
  export const USER_DELETED_DISPLAY_NAME = "[Geloescht]";
22
21
  export const USER_ANONYMIZED_DISPLAY_NAME = "[Anonymisiert]";
23
22
  /**
24
- * Email-Pseudonyme nach Forget. `<prefix>-<userId>@anonymized.invalid`
25
- * — der userId-Suffix ist als Pseudo-Audit-Marker fuer Operator
26
- * (Tracing-fall) erlaubt; user-id selbst ist UUID, kein PII.
27
- * `.invalid`-TLD ist RFC2606-reserviert — niemals deliverbare Email.
23
+ * Email pseudonyms used after forgetting. `<prefix>-<userId>@anonymized.invalid`
24
+ * — the userId suffix is permitted as a pseudo-audit marker for operator
25
+ * tracing; the user ID itself is a UUID, not PII.
26
+ * The `.invalid` TLD is reserved by RFC2606, so the address can never be
27
+ * delivered.
28
28
  */
29
29
  export const USER_DELETED_EMAIL_PREFIX = "deleted";
30
30
  export const USER_ANONYMIZED_EMAIL_PREFIX = "anonymized";
31
31
  export const USER_ANONYMIZED_EMAIL_DOMAIN = "anonymized.invalid";
32
- // Tuple form fuer createSelectField (erfordert non-empty readonly tuple).
33
- // Object.values(USER_STATUS) waere string[] — statisches Tuple ist
34
- // type-sicher.
32
+ // Tuple form for createSelectField (requires a non-empty readonly tuple).
33
+ // Object.values(USER_STATUS) would be string[]; the static tuple preserves
34
+ // type safety.
35
35
  const USER_STATUS_OPTIONS = [
36
36
  USER_STATUS.Active,
37
37
  USER_STATUS.Restricted,
@@ -45,10 +45,10 @@ export const userEntity = createEntity({
45
45
  table: "read_users",
46
46
  softDelete: true,
47
47
  // Tenant-independent identity aggregate — its event stream lives on
48
- // SYSTEM_TENANT_ID instead of whichever tenant happened to create it (#497).
48
+ // SYSTEM_TENANT_ID instead of whichever tenant happened to create it.
49
49
  systemStream: true,
50
50
  // Every row lives on SYSTEM_TENANT_ID; writes with another tenantId are
51
- // rejected (fw#2858).
51
+ // rejected.
52
52
  tenancy: "global",
53
53
  fields: {
54
54
  // Identity — anyone who can see the user can read the email, but only
@@ -81,17 +81,17 @@ export const userEntity = createEntity({
81
81
  reason: "credential_hash_read_without_decrypt",
82
82
  }),
83
83
  // Profile — user-editable. Real name in most apps → PII. Searchable via
84
- // the derived Meili index; events/projection stay ciphertext (#1610).
84
+ // the derived Meili index; events/projection stay ciphertext.
85
85
  displayName: createTextField({
86
86
  required: true,
87
87
  maxLength: 100,
88
88
  personal: "self",
89
89
  find: "fuzzy",
90
90
  }),
91
- // No default here — tenant-settings owns the app-wide locale default; see #1637.
91
+ // No default here — tenant-settings owns the app-wide locale default.
92
92
  locale: createTextField({ maxLength: 10, personal: false, reason: "technical_reference" }),
93
93
  // No default here — mirrors locale: ctx.tz falls back to tenant.timezone
94
- // (then "UTC") when unset, see buildHandlerContext (fw#1636).
94
+ // (then "UTC") when unset, see buildHandlerContext.
95
95
  timezone: createTzField(),
96
96
  // Which tenant should this user land in on next login. Set by the login
97
97
  // handler (SYSTEM), read by the login flow + UI for deep-linking.
@@ -121,21 +121,22 @@ export const userEntity = createEntity({
121
121
  default: [],
122
122
  access: { write: access.privileged },
123
123
  }),
124
- // S2.U1: User-Lifecycle-Status für user-data-rights (Sprint 2).
125
- // - "active": Normaler State, alle Operationen erlaubt
126
- // - "restricted": Art. 18 Restriction — Login blockiert + jede
127
- // Live-Session wird vom sessionChecker abgewiesen
124
+ // User lifecycle status for user-data-rights.
125
+ // - "active": Normal state; all operations are allowed.
126
+ // - "restricted": Art. 18 restriction — login is blocked and every
127
+ // live session is rejected by sessionChecker
128
128
  // ("blocked"). Recovery via lift-restriction
129
- // (openToAll, session-unabhängig).
130
- // - "deletionRequested": delete-account aufgerufen, gracePeriodEnd gesetzt,
131
- // Login blockiert. Bestehende Session bleibt LIVE
132
- // (reversibel) — User kann via cancel-deletion
133
- // zurück auf "active".
134
- // - "deleted": Forget executed nach Grace, Row anonymisiert via
135
- // softDelete. Login blockiert + Session "blocked".
129
+ // (openToAll, independent of the session).
130
+ // - "deletionRequested": delete-account was called and gracePeriodEnd set;
131
+ // login is blocked. Existing sessions remain LIVE
132
+ // (reversible), so the user can return to "active"
133
+ // via cancel-deletion.
134
+ // - "deleted": Forget was executed after the grace period; the row
135
+ // was anonymized via softDelete. Login is blocked and
136
+ // the session is "blocked".
136
137
  //
137
- // Schreibrecht privileged: nur die request-deletion / restrict / lift /
138
- // execute-forget-Handler (alle SYSTEM-context) duerfen status flippen.
138
+ // Write access is privileged: only the request-deletion / restrict / lift /
139
+ // execute-forget handlers (all in SYSTEM context) may change the status.
139
140
  status: createSelectField({
140
141
  required: true,
141
142
  default: USER_STATUS.Active,
@@ -143,21 +144,21 @@ export const userEntity = createEntity({
143
144
  sortable: true,
144
145
  access: { write: access.privileged },
145
146
  }),
146
- // Wann darf der pending-Forget tatsaechlich ausgefuehrt werden?
147
- // Cron-Job in user-data-rights checkt taeglich gracePeriodEnd < now()
148
- // und triggert dann die EXT_USER_DATA-Hooks. NULL solange kein
149
- // Forget pending — wird beim delete-account-Call gesetzt
150
- // (= now() + Compliance-Profile.userRights.gracePeriod), beim
151
- // cancel-deletion zurueckgesetzt.
147
+ // When a pending forget may actually be executed.
148
+ // The user-data-rights cron job checks daily whether gracePeriodEnd < now()
149
+ // and then triggers the EXT_USER_DATA hooks. NULL means no forget is pending;
150
+ // delete-account sets it to
151
+ // (= now() + Compliance-Profile.userRights.gracePeriod), and
152
+ // cancel-deletion resets it.
152
153
  gracePeriodEnd: createTimestampField({
153
154
  access: { write: access.privileged },
154
155
  }),
155
- // Replay-Schutz für den anonymen email-Token-Deletion-Flow (#354/1).
156
- // Gesetzt von request-deletion-by-email (eine UUID pro Mail-Antrag),
157
- // genullt von cancel-deletion. confirm-deletion-by-token faltet diese ID
158
- // in die HMAC-Purpose des Tokens — ein nach einem Cancel nachgespieltes
159
- // (noch TTL-gültiges) Token verifiziert gegen die genullte/erneuerte ID
160
- // nicht mehr. NULL solange kein email-Antrag offen ist.
156
+ // Replay protection for the anonymous email-token deletion flow.
157
+ // request-deletion-by-email sets one UUID per email request, and
158
+ // cancel-deletion clears it. confirm-deletion-by-token incorporates this ID
159
+ // into the token's HMAC purpose, so a token replayed after cancellation
160
+ // (while still within its TTL) no longer verifies against the cleared or
161
+ // renewed ID. NULL means no email request is pending.
161
162
  pendingDeletionRequestId: createTextField({
162
163
  maxLength: 36,
163
164
  access: { write: access.privileged },
@@ -4,28 +4,28 @@ import { type SeedTenantHooks } from "../tenant/seeding.ts";
4
4
  export type SeedUserOptions = {
5
5
  readonly email: string;
6
6
  readonly displayName: string;
7
- /** Optional bereits-gehashtes Passwort. Für plain-password-Tests
8
- * besser den Convenience-Wrapper aus
9
- * `@cosmicdrift/kumiko-bundled-features/auth-email-password/seeding` nutzen,
10
- * der argon2-Hashing übernimmt. */
7
+ /** Optional pre-hashed password. For plain-password tests, prefer the
8
+ * convenience wrapper from
9
+ * `@cosmicdrift/kumiko-bundled-features/auth-email-password/seeding`,
10
+ * which performs argon2 hashing. */
11
11
  readonly passwordHash?: string;
12
12
  readonly locale?: string;
13
- /** Global roles — land in users.roles as jsonb string[].
14
- * Werden vom login-handler in die Session-Roles parallel zu tenant-
15
- * membership-roles gemerged. Default: leer-array. Typisches Beispiel:
16
- * `["SystemAdmin"]` für den Plattform-Operator. */
13
+ /** Global roles—stored in users.roles as jsonb string[].
14
+ * The login handler merges them into the session roles alongside tenant-
15
+ * membership roles. Default: empty array. Typical example:
16
+ * `["SystemAdmin"]` for the platform operator. */
17
17
  readonly roles?: readonly string[];
18
- /** Initial-State für emailVerified. Default false (Pflicht-Verify-Flow
19
- * muss explizit "true" setzen wenn Email-Ownership schon bewiesen ist —
20
- * z.B. Magic-Link-Signup, wo der User den Mail-Link klicken musste
21
- * bevor sein Account überhaupt entsteht). */
18
+ /** Initial state for emailVerified. Default: false. The required
19
+ * verification flow must explicitly set "true" when email ownership has
20
+ * already been proven—for example, in a Magic-Link signup where the user
21
+ * clicked the email link before the account was created. */
22
22
  readonly emailVerified?: boolean;
23
23
  readonly by?: SessionUser;
24
24
  };
25
25
  /**
26
- * Seed a user. Returns the userId (existing oder neu angelegt).
27
- * Idempotent add-only über die `email`-Spalte: wenn ein User mit dieser
28
- * Email existiert, kommt seine ID zurück ohne neuen Insert.
26
+ * Seeds a user. Returns the userId (existing or newly created).
27
+ * Idempotent and add-only via the `email` column: if a user with this
28
+ * email exists, its ID is returned without a new insert.
29
29
  */
30
30
  export declare function seedUser(db: DbConnection, options: SeedUserOptions, hooks?: SeedTenantHooks): Promise<{
31
31
  id: string;
@@ -1,40 +1,40 @@
1
- // Testing-Helper fürs user-Feature. `seedUser` legt einen User direkt
2
- // über den Event-Store-Executor an — gleicher Pfad wie der echte
3
- // `UserHandlers.create`, aber ohne Access-Check und ohne ConflictError
4
- // bei Duplikaten. Idempotent add-only über die `email`-Spalte: ein
5
- // existierender User → return ohne Event. Kein update-Pfad — Profilfelder
6
- // ändern läuft über den regulären Handler.
1
+ // Testing helper for the user feature. `seedUser` creates a user directly
2
+ // through the event-store executor—the same path as the real
3
+ // `UserHandlers.create`, but without access checks or ConflictError on
4
+ // duplicates. It is idempotent and add-only via the `email` column: an
5
+ // existing user returns without emitting an event. There is no update path;
6
+ // profile changes go through the regular handler.
7
7
  //
8
- // Warum nicht direkt `db.insert(userTable)`: das würde den Event-Store
9
- // umgehen, also kein `user.created`-Event und keine MSP-Konsumenten
10
- // (audit, search-index) sehen den Seed. Der Executor-Pfad emittiert
11
- // das Event UND schreibt die Projection-Zeile in einer TX.
8
+ // Directly calling `db.insert(userTable)` would bypass the event store, so no
9
+ // `user.created` event would be emitted and no MSP consumers (audit,
10
+ // search-index) would see the seed. The executor path emits the event and
11
+ // writes the projection row in one transaction.
12
12
  import { computeBlindIndex, configuredBlindIndexKey } from "@cosmicdrift/kumiko-framework/crypto";
13
13
  import { createEventStoreExecutor, createTenantDb, fetchOne, } from "@cosmicdrift/kumiko-framework/db";
14
14
  import { TestUsers } from "@cosmicdrift/kumiko-framework/seeding";
15
- // kumiko-lint-ignore cross-feature-import shares the postSave-hooks fixture contract with tenant/seeding (#1478)
15
+ // kumiko-lint-ignore cross-feature-import shares the postSave-hooks fixture contract with tenant/seeding
16
16
  import { fireEntityPostSave } from "../tenant/seeding.js";
17
17
  import { userEntity, userTable } from "./schema/user.js";
18
18
  const userExecutor = createEventStoreExecutor(userTable, userEntity, { entityName: "user" });
19
19
  /**
20
- * Seed a user. Returns the userId (existing oder neu angelegt).
21
- * Idempotent add-only über die `email`-Spalte: wenn ein User mit dieser
22
- * Email existiert, kommt seine ID zurück ohne neuen Insert.
20
+ * Seeds a user. Returns the userId (existing or newly created).
21
+ * Idempotent and add-only via the `email` column: if a user with this
22
+ * email exists, its ID is returned without a new insert.
23
23
  */
24
24
  export async function seedUser(db, options,
25
25
  // Optional, append-only — same rationale as tenant/seeding's seedTenant
26
- // hooks param (#1478): fires user's postSave hooks (e.g. a Welcome-
26
+ // hooks param: fires user's postSave hooks (e.g. a Welcome-
27
27
  // notification hook keyed off `allOf: "user"`) for fixtures/self-signup
28
28
  // that opt in. Omit to keep today's hook-less behavior.
29
29
  hooks) {
30
30
  const by = options.by ?? TestUsers.systemAdmin;
31
- // executor.create erwartet eine TenantDb (mit .insert()-API). User
32
- // ist zwar tenant-agnostic (kein tenant_id-Spalte), aber das runtime-
33
- // Interface braucht den Wrap.
31
+ // executor.create expects a TenantDb (with an .insert() API). Although
32
+ // User is tenant-agnostic (it has no tenant_id column), the runtime
33
+ // interface requires this wrapper.
34
34
  const tdb = createTenantDb({ db, tenantId: by.tenantId, mode: "system" });
35
35
  const existing = await fetchOne(db, userTable, { email: options.email, isDeleted: false });
36
- // @cast-boundary db-row: users.id ist uuid-Spalte (string), fetchOne
37
- // liefert die Projection-Row als Record<string, unknown>.
36
+ // @cast-boundary db-row: users.id is a uuid column (string), and fetchOne
37
+ // returns the projection row as Record<string, unknown>.
38
38
  if (existing) {
39
39
  const id = existing["id"];
40
40
  if (options.emailVerified === true) {
@@ -57,13 +57,13 @@ hooks) {
57
57
  return { id: extractId(result.data, "seedUser") };
58
58
  }
59
59
  // A re-run seed onto a row created before emailVerified flipped to true must
60
- // still set it (#1687) — via the executor, so it lands as a real `.updated` event.
60
+ // still set it — via the executor, so it lands as a real `.updated` event.
61
61
  export async function reconcileSeededUserEmailVerified(db, existingRow, by) {
62
62
  // skip: already verified, nothing to reconcile
63
63
  if (existingRow["emailVerified"] === true)
64
64
  return;
65
- // @cast-boundary db-row: users.id ist uuid-Spalte (string), fetchOne
66
- // liefert die Projection-Row als Record<string, unknown>.
65
+ // @cast-boundary db-row: users.id is a uuid column (string), and fetchOne
66
+ // returns the projection row as Record<string, unknown>.
67
67
  const id = existingRow["id"];
68
68
  const tdb = createTenantDb({ db, tenantId: by.tenantId, mode: "system" });
69
69
  const result = await userExecutor.update({ id, version: existingRow["version"], changes: { emailVerified: true } }, by, tdb);
@@ -111,11 +111,11 @@ export async function rewriteSeededUserEmail(db, existingRow, email, by) {
111
111
  throw new Error(`rewriteSeededUserEmail failed: ${result.error.code} — ${JSON.stringify(result.error.details ?? {})}`);
112
112
  }
113
113
  }
114
- // Extrahiert die `id`-Spalte aus dem executor.create-Result. Der
115
- // Executor liefert ein Record<string, unknown> (die Projection-Row), in
116
- // das die DB die Aggregat-id reinschreibt — wir prüfen runtime statt
117
- // blindem `as { id: string }`-Cast, damit ein API-Vertragsbruch sofort
118
- // als ehrlicher Throw rauskommt statt downstream als undefined-Bug.
114
+ // Extracts the `id` column from the executor.create result. The executor
115
+ // returns a Record<string, unknown> (the projection row), into which the DB
116
+ // writes the aggregate ID. We validate it at runtime instead of using a
117
+ // blind `as { id: string }` cast, so an API contract violation throws an
118
+ // explicit error rather than surfacing downstream as an undefined-value bug.
119
119
  function extractId(data, who) {
120
120
  if (typeof data === "object" && data !== null && "id" in data) {
121
121
  const id = data.id; // @cast-boundary engine-bridge
@@ -1,4 +1,4 @@
1
- // /testing re-exportiert /seeding. Siehe ../tenant/testing.ts für die
2
- // Begründung — Helpers sind shared zwischen Tests und Dev-Server-
3
- // Bootstrap, /seeding ist die stabile Heimat.
1
+ // /testing re-exports /seeding. See ../tenant/testing.ts for the
2
+ // reason: helpers are shared between tests and Dev-Server bootstrap,
3
+ // and /seeding is the stable home.
4
4
  export * from "./seeding.js";
@@ -8,11 +8,11 @@ export interface RecordDownloadUseArgs {
8
8
  readonly tokenVersion: number;
9
9
  readonly tokenUseCount: number;
10
10
  /**
11
- * Tenant fuer die system-mode-TenantDb. ExportDownloadToken ist
12
- * tenant-agnostisch (1:1 zum tenant-agnostic Job), aber der event-
13
- * store-Stream-Lookup braucht einen Tenant-Context. Wir nutzen
14
- * job.requestedFromTenantId — dieselbe Identitaet wie beim
15
- * Token-Create im Worker (Atom 4a).
11
+ * Tenant for the system-mode TenantDb. ExportDownloadToken is
12
+ * tenant-agnostic (1:1 with the tenant-agnostic job), but the event-store
13
+ * stream lookup requires a tenant context. We use
14
+ * job.requestedFromTenantId — the same identity used when creating the
15
+ * token in the worker.
16
16
  */
17
17
  readonly tenantId: TenantId;
18
18
  readonly now: Instant;
@@ -20,9 +20,9 @@ export interface RecordDownloadUseArgs {
20
20
  readonly userAgent: string | null;
21
21
  }
22
22
  /**
23
- * Audit-Update: useCount, lastUsedAt, IP, UA. Best-effort —
24
- * version-conflicts (parallel-downloads) werden swallowed, Download
25
- * succeeded trotzdem.
23
+ * Audit update: useCount, lastUsedAt, IP, and UA. Best-effort —
24
+ * version conflicts (parallel downloads) are swallowed, so the download
25
+ * still succeeds.
26
26
  */
27
27
  export declare function recordDownloadUse(args: RecordDownloadUseArgs): Promise<void>;
28
28
  export type DownloadAttemptResult = "notFound" | "expired" | "failed" | "signedUrlNotSupported";
@@ -1,19 +1,18 @@
1
- // Audit-Helper fuer Download-Endpoint (S2.U3 Atom 4b).
1
+ // Audit helper for the download endpoint.
2
2
  //
3
- // Beim Download (Token-Pfad oder Job-Pfad) werden Audit-Felder am
4
- // Token-Row aktualisiert:
3
+ // During a download (token path or job path), audit fields on the token row
4
+ // are updated:
5
5
  // - useCount + 1
6
6
  // - lastUsedAt = now
7
- // - lastUsedFromIp = caller-IP (X-Forwarded-For oder Connection-IP)
8
- // - lastUsedUserAgent = UA-Header
7
+ // - lastUsedFromIp = caller IP (X-Forwarded-For or connection IP)
8
+ // - lastUsedUserAgent = UA header
9
9
  //
10
- // **Best-Effort-Update:** version-conflicts (zwei parallel-Downloads
11
- // raceen um den update) werden silent geswallowt — Audit ist "letzter
12
- // Use", nicht "alle Uses". Der zweite Download succeeded trotzdem
13
- // (kein download-block bei race).
10
+ // **Best-effort update:** version conflicts (two downloads racing to update)
11
+ // are silently swallowed — the audit records the "last use", not "all uses".
12
+ // The second download still succeeds (a race does not block the download).
14
13
  //
15
- // **ES via tokenCrud.update:** kein direct-UPDATE. Memory
16
- // `feedback_no_fake_dispatcher` + `feedback_event_store_tenant_consistency`.
14
+ // **ES via tokenCrud.update:** no direct UPDATE, so the event-store and tenant
15
+ // consistency rules remain in effect.
17
16
  import { createEventStoreExecutor, createTenantDb } from "@cosmicdrift/kumiko-framework/db";
18
17
  import { createSystemUser } from "@cosmicdrift/kumiko-framework/engine";
19
18
  import { tokenCrud } from "./run-export-jobs.js";
@@ -22,9 +21,9 @@ const attemptCrud = createEventStoreExecutor(downloadAttemptsTable, downloadAtte
22
21
  entityName: "download-attempt",
23
22
  });
24
23
  /**
25
- * Audit-Update: useCount, lastUsedAt, IP, UA. Best-effort —
26
- * version-conflicts (parallel-downloads) werden swallowed, Download
27
- * succeeded trotzdem.
24
+ * Audit update: useCount, lastUsedAt, IP, and UA. Best-effort —
25
+ * version conflicts (parallel downloads) are swallowed, so the download
26
+ * still succeeds.
28
27
  */
29
28
  export async function recordDownloadUse(args) {
30
29
  const { db, tokenId, tokenVersion, tokenUseCount, tenantId, now, ip, userAgent } = args;
@@ -42,14 +41,14 @@ export async function recordDownloadUse(args) {
42
41
  },
43
42
  }, executor, tdb)
44
43
  .catch(() => {
45
- // version-conflict bei parallelen Downloads → der erste hat
46
- // bereits useCount inkrementiert. Wir behalten den Audit-Eintrag
47
- // des ersten Downloads (lastUsedAt etc.). Kein download-block.
44
+ // A version conflict means a parallel download already incremented
45
+ // useCount. Keep the first download's audit entry (lastUsedAt, etc.);
46
+ // do not block the download.
48
47
  });
49
48
  }
50
- // Best-effort INSERT in read_download_attempts. Throws im Audit-Pfad
51
- // duerfen den Download-Endpoint nicht killen (User soll seinen 404
52
- // bekommen, nicht 500); failures werden silent geswallowt.
49
+ // Best-effort INSERT into read_download_attempts. Errors in the audit path
50
+ // must not kill the download endpoint: the user should receive their 404,
51
+ // not a 500; failures are silently swallowed.
53
52
  export async function recordInvalidAttempt(args) {
54
53
  const { db, tenantId, now } = args;
55
54
  const executor = createSystemUser(tenantId);
@@ -7,7 +7,7 @@ import { entitiesOf } from "../shared/index.js";
7
7
  // only; runtime no-ops (a delete hook that silently skips) are not detectable
8
8
  // here — those are covered by the export/forget integration tests.
9
9
  //
10
- // Registered as an `r.bootCheck()` by this feature (#1314) — EXT_USER_DATA is
10
+ // Registered as an `r.bootCheck()` by this feature — EXT_USER_DATA is
11
11
  // owned by user-data-rights (r.extendsRegistrar(EXT_USER_DATA, {})), so any
12
12
  // r.useExtension(EXT_USER_DATA, ...) usage across the app already requires
13
13
  // user-data-rights to be mounted (boot-validator's extension-provider check
@@ -2,7 +2,7 @@
2
2
  // subject is the user, the anchor is the pending request id stored on the
3
3
  // user row. Minting and verification both run through
4
4
  // shared/row-bound-grant, so a token from a cancelled cycle (id nulled) or a
5
- // superseded one (row holds a newer id) fails verification — see #354/1.
5
+ // superseded one (row holds a newer id) fails verification.
6
6
  //
7
7
  // The purpose string and the anchoring are unchanged from the hand-rolled
8
8
  // version this replaced, so tokens stay byte-compatible.