@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
@@ -63,7 +63,7 @@ export const discardDraftWrite = defineWriteHandler({
63
63
  // Fail-closed erase of file_refs rows FIRST (outside the best-effort
64
64
  // storage-hygiene loop). releaseDraftFileRefs swallows per-key errors
65
65
  // by design — routing forget through it would report discarded:true
66
- // while leaving the row behind (#1922 / review #2009).
66
+ // while leaving the row behind.
67
67
  for (const ref of ownedRefs) {
68
68
  const forgetResult = await fileRefExecutor.forget({ id: ref.id }, event.user, ctx.db);
69
69
  if (!forgetResult.isSuccess)
@@ -1,5 +1,5 @@
1
1
  import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
2
- // The draft blob's `values` is free-form by design (issue #1889: form-draft
2
+ // The draft blob's `values` is free-form by design: form-draft
3
3
  // never knows the consuming form's field schema, only { values, stepIndex,
4
4
  // savedAt }). A FileRef pointer is therefore recognised purely by shape —
5
5
  // any object anywhere in `values` carrying a non-empty string `storageKey`
@@ -45,11 +45,11 @@ export function collectDraftFileRefKeys(draft) {
45
45
  //
46
46
  // Takes an already-decided key list, not the draft blob — callers must run
47
47
  // collectDraftFileRefKeys() output through db/queries' owned-storage-key
48
- // filter first. `values` is free-form, client-supplied JSON (issue #1889);
49
- // releasing a key straight out of it without verifying a real, owned
50
- // file_refs row exists would let a crafted `{ storageKey: "<victim's key>" }`
51
- // delete someone else's file — the same ownership check file-routes.ts runs
52
- // before every read/delete (loadFileForTenant + FileAccessGuard).
48
+ // filter first. `values` is free-form, client-supplied JSON; releasing a key
49
+ // straight out of it without verifying a real, owned file_refs row exists
50
+ // would let a crafted `{ storageKey: "<victim's key>" }` delete someone
51
+ // else's file — the same ownership check file-routes.ts runs before every
52
+ // read/delete (loadFileForTenant + FileAccessGuard).
53
53
  export async function releaseDraftFileRefs(keys, deleteBinary, log) {
54
54
  for (const key of keys) {
55
55
  try {
@@ -10,9 +10,9 @@ function jsonByteLength(value) {
10
10
  const draftValuesSchema = z
11
11
  .record(z.string(), z.unknown())
12
12
  .refine((values) => jsonByteLength(values) <= FORM_DRAFT_VALUES_MAX_BYTES, `values exceeds the ${FORM_DRAFT_VALUES_MAX_BYTES}-byte limit`);
13
- // The draft blob shape — fixed by issue #1889 here, not left for consumers
13
+ // The draft blob shape — fixed here, not left for consumers
14
14
  // to invent per-app. `stepIndex` is in from the start so wizard-mode resume
15
- // (kumiko-framework#1884) doesn't need a later migration.
15
+ // doesn't need a later migration.
16
16
  export const formDraftBlobSchema = z.object({
17
17
  values: z.record(z.string(), z.unknown()),
18
18
  stepIndex: z.number().int().min(0),
@@ -30,7 +30,7 @@ export const saveDraftPayloadSchema = z.object({
30
30
  // row right after the domain entity write already carries the same
31
31
  // storageKeys forward — releasing them here would destroy files the entity
32
32
  // now depends on. Only an actual abandon/abort flow should pass
33
- // releaseFiles: true (issue #1915's "explicit abort" case).
33
+ // releaseFiles: true (the "explicit abort" case).
34
34
  export const discardDraftPayloadSchema = z.object({
35
35
  draftKey: draftKeySchema,
36
36
  releaseFiles: z.boolean().optional(),
@@ -1,6 +1,4 @@
1
1
  // form-draft bundle constants — feature-name + qualified handler/query names.
2
- //
3
- // Part of CosmicDriftGameStudio/kumiko-framework#1883 (wizard mode), issue #1889.
4
2
  export const FORM_DRAFT_FEATURE_NAME = "form-draft";
5
3
  // Qualified handler/query names (QN format: scope:type:name). Clients
6
4
  // reference the object instead of magic strings.
@@ -1,20 +1,20 @@
1
1
  /**
2
- * Deterministic aggregate-id für eine inbound-message. Key ist
3
- * (accountId, providerMessageId): derselbe Provider-Fetch der zweimal
4
- * dieselbe Message liefert (IDLE-Doppel-Notify, Cursor-Overlap,
5
- * Watch-Restart-Replay) landet auf demselben Stream — der Idempotency-
6
- * Check im ingest-handler sieht den bereits appendeten Event.
2
+ * Deterministic aggregate ID for an inbound message. The key is
3
+ * (accountId, providerMessageId): if the provider delivers the same message
4
+ * twice (IDLE duplicate notification, cursor overlap, watch-restart replay),
5
+ * both deliveries use the same stream, so the idempotency check in the
6
+ * ingest handler sees the event that was already appended.
7
7
  *
8
- * accountId (nicht tenantId) im Key: zwei Accounts desselben Tenants
9
- * können dieselbe Mail empfangen (CC an beide Postfächer) — das sind
10
- * fachlich ZWEI inbound-messages.
8
+ * accountId, rather than tenantId, is part of the key because two accounts in
9
+ * the same tenant can receive the same email (CC'd to both inboxes); these
10
+ * are two distinct inbound messages.
11
11
  */
12
12
  export declare function inboundMessageAggregateId(accountId: string, providerMessageId: string): string;
13
13
  /**
14
- * Deterministic aggregate-id für einen mail-thread. Key ist
15
- * (tenantId, threadKey) — Threads sind tenant-weit, nicht account-weit:
16
- * eine Konversation die über zwei verbundene Postfächer läuft ist EIN
17
- * Thread. threadKey kommt normalisiert vom Provider (References/
18
- * In-Reply-To-Chain bzw. Provider-Thread-ID).
14
+ * Deterministic aggregate ID for a mail thread. The key is
15
+ * (tenantId, threadKey): threads are tenant-wide, not account-specific, so a
16
+ * conversation spanning two connected inboxes is one thread. threadKey is
17
+ * normalized by the provider (References/In-Reply-To chain or provider
18
+ * thread ID).
19
19
  */
20
20
  export declare function mailThreadAggregateId(tenantId: string, threadKey: string): string;
@@ -1,33 +1,33 @@
1
1
  import { v5 as uuidv5 } from "uuid";
2
- // Fixed UUID-namespaces für deterministic aggregate-id-Ableitung.
3
- // Generiert einmalig (2026-07-12), in Stein gemeißelt: ein Wechsel würde
4
- // jeden existing aggregate-Stream re-keyen → kaputte Message-Historie,
5
- // kaputte Idempotency. Drift-Pins in __tests__/feature.test.ts.
6
- /** Namespace für inbound-message-Streams. */
2
+ // Fixed UUID namespaces for deterministic aggregate-ID derivation.
3
+ // Generated once (2026-07-12) and immutable: changing one would re-key
4
+ // every existing aggregate stream, breaking message history and idempotency.
5
+ // Drift is pinned in __tests__/feature.test.ts.
6
+ /** Namespace for inbound-message streams. */
7
7
  const INBOUND_MESSAGE_NAMESPACE = "7f2a9c41-3d6b-4e0f-9c58-2b1e7a4d8f63";
8
- /** Namespace für mail-thread-Streams. */
8
+ /** Namespace for mail-thread streams. */
9
9
  const MAIL_THREAD_NAMESPACE = "b48d1e72-5c9a-4f36-8e0d-6a3f9b2c7e15";
10
10
  /**
11
- * Deterministic aggregate-id für eine inbound-message. Key ist
12
- * (accountId, providerMessageId): derselbe Provider-Fetch der zweimal
13
- * dieselbe Message liefert (IDLE-Doppel-Notify, Cursor-Overlap,
14
- * Watch-Restart-Replay) landet auf demselben Stream — der Idempotency-
15
- * Check im ingest-handler sieht den bereits appendeten Event.
11
+ * Deterministic aggregate ID for an inbound message. The key is
12
+ * (accountId, providerMessageId): if the provider delivers the same message
13
+ * twice (IDLE duplicate notification, cursor overlap, watch-restart replay),
14
+ * both deliveries use the same stream, so the idempotency check in the
15
+ * ingest handler sees the event that was already appended.
16
16
  *
17
- * accountId (nicht tenantId) im Key: zwei Accounts desselben Tenants
18
- * können dieselbe Mail empfangen (CC an beide Postfächer) — das sind
19
- * fachlich ZWEI inbound-messages.
17
+ * accountId, rather than tenantId, is part of the key because two accounts in
18
+ * the same tenant can receive the same email (CC'd to both inboxes); these
19
+ * are two distinct inbound messages.
20
20
  */
21
21
  // @wrapper-known uuid-domain
22
22
  export function inboundMessageAggregateId(accountId, providerMessageId) {
23
23
  return uuidv5(`${accountId}:${providerMessageId}`, INBOUND_MESSAGE_NAMESPACE);
24
24
  }
25
25
  /**
26
- * Deterministic aggregate-id für einen mail-thread. Key ist
27
- * (tenantId, threadKey) — Threads sind tenant-weit, nicht account-weit:
28
- * eine Konversation die über zwei verbundene Postfächer läuft ist EIN
29
- * Thread. threadKey kommt normalisiert vom Provider (References/
30
- * In-Reply-To-Chain bzw. Provider-Thread-ID).
26
+ * Deterministic aggregate ID for a mail thread. The key is
27
+ * (tenantId, threadKey): threads are tenant-wide, not account-specific, so a
28
+ * conversation spanning two connected inboxes is one thread. threadKey is
29
+ * normalized by the provider (References/In-Reply-To chain or provider
30
+ * thread ID).
31
31
  */
32
32
  // @wrapper-known uuid-domain
33
33
  export function mailThreadAggregateId(tenantId, threadKey) {
@@ -1,5 +1,5 @@
1
- // createInboundMailConnectRoutes — declarative extraRoutes (kumiko-
2
- // framework#3050) the app owner mounts via `extraRoutes` in buildServer.
1
+ // createInboundMailConnectRoutes — declarative extraRoutes the app owner mounts
2
+ // via `extraRoutes` in buildServer.
3
3
  //
4
4
  // GET /api/inbound-mail/connect (entry:"user" — signed-in caller)
5
5
  // GET /inbound-mail/oauth/callback (entry:"signature" — anonymous,
@@ -10,6 +10,7 @@
10
10
  // resolved via resolveInboundProviderForKey. The callback trusts ONLY the
11
11
  // HMAC-verified state (CSRF-/foreign-claiming lock, see oauth-state.ts).
12
12
  import { ExtraRouteRejection, signatureRoute } from "@cosmicdrift/kumiko-framework/api";
13
+ import { propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
13
14
  import { INBOUND_MAIL_FOUNDATION_FEATURE, InboundMailAuthMethods, InboundMailFoundationHandlers, inboundCredentialSecretKey, } from "./constants.js";
14
15
  import { inboundRefreshTokenSecretOptions, } from "./oauth-access-token.js";
15
16
  import { signOAuthState, verifyOAuthState } from "./oauth-state.js";
@@ -130,7 +131,7 @@ export function createInboundMailConnectRoutes(options) {
130
131
  if (!dispatched.isSuccess) {
131
132
  return errorJson(c, 502, "account_create_failed", JSON.stringify(dispatched.error ?? {}));
132
133
  }
133
- const accountId = dispatched.data?.accountId;
134
+ const accountId = propertyOf(dispatched.data, "accountId");
134
135
  if (typeof accountId !== "string") {
135
136
  return errorJson(c, 502, "account_create_failed", "connect-account returned no accountId");
136
137
  }
@@ -1,53 +1,51 @@
1
1
  export declare const INBOUND_MAIL_FOUNDATION_FEATURE: "inbound-mail-foundation";
2
2
  export declare const INBOUND_MAIL_PROVIDER_EXTENSION: "inboundMailProvider";
3
3
  export declare const InboundMailFoundationHandlers: {
4
- /** Programmatic entry-point für Provider-Plugins (watch-callback +
5
- * fetchSince-Sync): normalisierte Message rein, Idempotency +
6
- * PII-encrypt + event-append + Thread-Update atomic. */
4
+ /** Programmatic entry point for provider plugins (watch callback +
5
+ * fetchSince sync): accepts a normalized message and atomically performs
6
+ * idempotency handling, PII encryption, event append, and thread update. */
7
7
  readonly ingestMessage: "inbound-mail-foundation:write:ingest-message";
8
- /** Tenant-Admin verbindet ein Postfach (IMAP-Credentials via secrets
9
- * oder OAuth-Redirect via oauth-routes). Legt den mail-account-Stream
10
- * an. */
8
+ /** Tenant admin connects a mailbox (IMAP credentials via secrets or an
9
+ * OAuth redirect via oauth-routes). Creates the mail-account stream. */
11
10
  readonly connectAccount: "inbound-mail-foundation:write:connect-account";
12
- /** Account-Status-Übergänge (watch error/backoff, oauth-refresh
13
- * failed, re-enabled). */
11
+ /** Account status transitions (watch error/backoff, OAuth refresh
12
+ * failure, re-enabled). */
14
13
  readonly updateAccount: "inbound-mail-foundation:write:update-account";
15
- /** Tenant-Admin trennt ein Postfach. Stream bleibt (Audit), Status
16
- * wird disconnected, Watch stoppt. */
14
+ /** Tenant admin disconnects a mailbox. The stream remains for auditing;
15
+ * the status becomes disconnected and the watch stops. */
17
16
  readonly disconnectAccount: "inbound-mail-foundation:write:disconnect-account";
18
17
  };
19
18
  export declare const InboundMailFoundationQueries: {
20
- /** Tenant-scoped Liste der verbundenen Postfächer. */
19
+ /** Tenant-scoped list of connected mailboxes. */
21
20
  readonly listAccounts: "inbound-mail-foundation:query:account:list";
22
- /** Tenant-scoped Message-Liste (Inbox-Cockpit). PII wird beim Read
23
- * decrypted. */
21
+ /** Tenant-scoped message list (inbox cockpit). PII is decrypted on read.
22
+ */
24
23
  readonly listMessages: "inbound-mail-foundation:query:message:list";
25
24
  };
26
25
  export declare const InboundMailAccountStatuses: {
27
- /** Verbunden, Watch/Sync läuft (oder ist startbereit). */
26
+ /** Connected; watch/sync is running or ready to start. */
28
27
  readonly active: "active";
29
- /** Credentials/Token ungültig — Tenant-Admin muss re-connecten. */
28
+ /** Credentials or token are invalid; the tenant admin must reconnect. */
30
29
  readonly authError: "auth_error";
31
30
  /** Transienter Fehler, Supervisor backoff-retried. */
32
31
  readonly degraded: "degraded";
33
- /** Vom Tenant-Admin getrennt. Keine Syncs mehr. */
32
+ /** Disconnected by the tenant admin; no further syncs run. */
34
33
  readonly disconnected: "disconnected";
35
34
  };
36
35
  export type InboundMailAccountStatus = (typeof InboundMailAccountStatuses)[keyof typeof InboundMailAccountStatuses];
37
36
  /**
38
- * Tenant-Secret-Slot eines Accounts: IMAP-App-Passwort ODER OAuth-
39
- * Refresh-Token — der Provider interpretiert den Inhalt gemäß
40
- * `authMethod` (Plan §4). Dynamisches Keying pro Account ist vom
41
- * secrets-Feature gedeckt: SecretsContext.get/set nehmen beliebige
42
- * String-Keys (resolveKey in secrets-context.ts) — Plan-Risiko 4
43
- * verifiziert, kein Framework-Gap.
37
+ * Tenant secret slot for an account: IMAP app password OR OAuth refresh
38
+ * token. The provider interprets the contents according to `authMethod`.
39
+ * Dynamic per-account keying is supported by the secrets feature:
40
+ * SecretsContext.get/set accept arbitrary string keys (resolveKey in
41
+ * secrets-context.ts), so no framework change is required.
44
42
  */
45
43
  export declare function inboundCredentialSecretKey(accountId: string): string;
46
44
  export declare const InboundMailAuthMethods: {
47
45
  /** Formular-Connect: Config (host/port/secure) + Tenant-Secret. */
48
46
  readonly password: "password";
49
- /** SASL XOAUTH2 über IMAP — Fallback für M365/Gmail-Konten ohne
50
- * gemounteten Enterprise-Provider (gleicher Secret-Slot). */
47
+ /** SASL XOAUTH2 over IMAP — fallback for M365/Gmail accounts without a
48
+ * mounted enterprise provider (same secret slot). */
51
49
  readonly xoauth2: "xoauth2";
52
50
  /** Nativer OAuth-Provider (m365-graph, gmail-rest). */
53
51
  readonly oauth: "oauth";
@@ -1,69 +1,66 @@
1
1
  // Feature name
2
2
  export const INBOUND_MAIL_FOUNDATION_FEATURE = "inbound-mail-foundation";
3
- // Extension-point name für Provider-Plugins (inbound-provider-imap,
3
+ // Extension-point name for provider plugins (inbound-provider-imap,
4
4
  // inbound-provider-m365-graph, inbound-provider-gmail-rest, ...).
5
5
  export const INBOUND_MAIL_PROVIDER_EXTENSION = "inboundMailProvider";
6
6
  // Qualified write handler names (QN format: scope:type:name).
7
7
  export const InboundMailFoundationHandlers = {
8
- /** Programmatic entry-point für Provider-Plugins (watch-callback +
9
- * fetchSince-Sync): normalisierte Message rein, Idempotency +
10
- * PII-encrypt + event-append + Thread-Update atomic. */
8
+ /** Programmatic entry point for provider plugins (watch callback +
9
+ * fetchSince sync): accepts a normalized message and atomically performs
10
+ * idempotency handling, PII encryption, event append, and thread update. */
11
11
  ingestMessage: "inbound-mail-foundation:write:ingest-message",
12
- /** Tenant-Admin verbindet ein Postfach (IMAP-Credentials via secrets
13
- * oder OAuth-Redirect via oauth-routes). Legt den mail-account-Stream
14
- * an. */
12
+ /** Tenant admin connects a mailbox (IMAP credentials via secrets or an
13
+ * OAuth redirect via oauth-routes). Creates the mail-account stream. */
15
14
  connectAccount: "inbound-mail-foundation:write:connect-account",
16
- /** Account-Status-Übergänge (watch error/backoff, oauth-refresh
17
- * failed, re-enabled). */
15
+ /** Account status transitions (watch error/backoff, OAuth refresh
16
+ * failure, re-enabled). */
18
17
  updateAccount: "inbound-mail-foundation:write:update-account",
19
- /** Tenant-Admin trennt ein Postfach. Stream bleibt (Audit), Status
20
- * wird disconnected, Watch stoppt. */
18
+ /** Tenant admin disconnects a mailbox. The stream remains for auditing;
19
+ * the status becomes disconnected and the watch stops. */
21
20
  disconnectAccount: "inbound-mail-foundation:write:disconnect-account",
22
21
  };
23
22
  // Qualified query handler names.
24
23
  export const InboundMailFoundationQueries = {
25
- /** Tenant-scoped Liste der verbundenen Postfächer. */
24
+ /** Tenant-scoped list of connected mailboxes. */
26
25
  listAccounts: "inbound-mail-foundation:query:account:list",
27
- /** Tenant-scoped Message-Liste (Inbox-Cockpit). PII wird beim Read
28
- * decrypted. */
26
+ /** Tenant-scoped message list (inbox cockpit). PII is decrypted on read.
27
+ */
29
28
  listMessages: "inbound-mail-foundation:query:message:list",
30
29
  };
31
30
  // Normalized account status values — provider-agnostic.
32
31
  export const InboundMailAccountStatuses = {
33
- /** Verbunden, Watch/Sync läuft (oder ist startbereit). */
32
+ /** Connected; watch/sync is running or ready to start. */
34
33
  active: "active",
35
- /** Credentials/Token ungültig — Tenant-Admin muss re-connecten. */
34
+ /** Credentials or token are invalid; the tenant admin must reconnect. */
36
35
  authError: "auth_error",
37
36
  /** Transienter Fehler, Supervisor backoff-retried. */
38
37
  degraded: "degraded",
39
- /** Vom Tenant-Admin getrennt. Keine Syncs mehr. */
38
+ /** Disconnected by the tenant admin; no further syncs run. */
40
39
  disconnected: "disconnected",
41
40
  };
42
41
  /**
43
- * Tenant-Secret-Slot eines Accounts: IMAP-App-Passwort ODER OAuth-
44
- * Refresh-Token — der Provider interpretiert den Inhalt gemäß
45
- * `authMethod` (Plan §4). Dynamisches Keying pro Account ist vom
46
- * secrets-Feature gedeckt: SecretsContext.get/set nehmen beliebige
47
- * String-Keys (resolveKey in secrets-context.ts) — Plan-Risiko 4
48
- * verifiziert, kein Framework-Gap.
42
+ * Tenant secret slot for an account: IMAP app password OR OAuth refresh
43
+ * token. The provider interprets the contents according to `authMethod`.
44
+ * Dynamic per-account keying is supported by the secrets feature:
45
+ * SecretsContext.get/set accept arbitrary string keys (resolveKey in
46
+ * secrets-context.ts), so no framework change is required.
49
47
  */
50
48
  export function inboundCredentialSecretKey(accountId) {
51
49
  return `${INBOUND_MAIL_FOUNDATION_FEATURE}:inbound.credential.${accountId}`;
52
50
  }
53
- // Auth-Methode eines Accounts — vom connect-Flow gesetzt, von Providern
54
- // gelesen (imap unterscheidet hierüber Passwort-Formular vs. XOAUTH2-
55
- // Fallback, Plan §2).
51
+ // Authentication method for an account, set by the connect flow and read
52
+ // by providers (IMAP uses it to distinguish the password form from the
53
+ // XOAUTH2 fallback).
56
54
  export const InboundMailAuthMethods = {
57
55
  /** Formular-Connect: Config (host/port/secure) + Tenant-Secret. */
58
56
  password: "password",
59
- /** SASL XOAUTH2 über IMAP — Fallback für M365/Gmail-Konten ohne
60
- * gemounteten Enterprise-Provider (gleicher Secret-Slot). */
57
+ /** SASL XOAUTH2 over IMAP — fallback for M365/Gmail accounts without a
58
+ * mounted enterprise provider (same secret slot). */
61
59
  xoauth2: "xoauth2",
62
60
  /** Nativer OAuth-Provider (m365-graph, gmail-rest). */
63
61
  oauth: "oauth",
64
62
  };
65
- // **Multi-Provider von Tag 1:** KEIN globaler `provider`-config-key
66
- // (anders als mail-foundation, gleich wie billing-foundation). Ein Tenant
67
- // kann parallel ein IMAP-Postfach UND ein M365-Postfach verbinden — der
68
- // Provider steht pro MailAccount-Row (`provider`-Feld), gesetzt beim
69
- // connect-Flow.
63
+ // **Multi-provider:** no global `provider` config key
64
+ // (unlike mail-foundation, as with billing-foundation). A tenant can connect
65
+ // an IMAP mailbox and an M365 mailbox in parallel; the provider is stored per
66
+ // MailAccount row (`provider` field) and set by the connect flow.
@@ -1,5 +1,5 @@
1
- /** Ein verbundenes Postfach. Eine Row pro Account, PK = aggregateId
2
- * (= accountId, random uuid beim connect). */
1
+ /** A connected mailbox. One row per account, with PK = aggregateId
2
+ * (= accountId, random uuid on connect). */
3
3
  export declare const mailAccountEntity: import("@cosmicdrift/kumiko-types/fields").EntityDefinition<{
4
4
  readonly provider: import("@cosmicdrift/kumiko-types/fields").EntityTextFieldDef & {
5
5
  required: true;
@@ -38,8 +38,8 @@ export declare const mailAccountEntity: import("@cosmicdrift/kumiko-types/fields
38
38
  required: true;
39
39
  };
40
40
  }, "tenant">;
41
- /** Eine eingegangene Mail (Envelope + Snippet, KEIN Body — bodyRef
42
- * zeigt auf file-foundation). PK = aggregateId =
41
+ /** An incoming mail (envelope + snippet, NO body — bodyRef
42
+ * points to file-foundation). PK = aggregateId =
43
43
  * inboundMessageAggregateId(accountId, providerMessageId). */
44
44
  export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fields").EntityDefinition<{
45
45
  readonly accountId: import("@cosmicdrift/kumiko-types/fields").EntityTextFieldDef & {
@@ -138,10 +138,10 @@ export declare const mailThreadEntity: import("@cosmicdrift/kumiko-types/fields"
138
138
  export declare const MAIL_ACCOUNT_PII_FIELDS: readonly string[];
139
139
  export declare const INBOUND_MESSAGE_PII_FIELDS: readonly string[];
140
140
  export declare const MAIL_THREAD_PII_FIELDS: readonly string[];
141
- /** Provider-Cursor pro Account ("wo war ich?"): IMAP UIDVALIDITY:UIDNEXT,
142
- * Graph deltaLink, Gmail historyId. Eine Row pro (accountId, scope).
143
- * Write-locked auf privileged — nur Foundation-Handler/Supervisor
144
- * schreiben, kein Tenant-Request. */
141
+ /** Provider cursor per account ("where was I?"): IMAP UIDVALIDITY:UIDNEXT,
142
+ * Graph deltaLink, Gmail historyId. One row per (accountId, scope).
143
+ * Write-locked to privileged — only Foundation handlers/supervisors
144
+ * write it; tenant requests cannot. */
145
145
  export declare const syncCursorEntity: import("@cosmicdrift/kumiko-types/fields").EntityDefinition<{
146
146
  readonly accountId: import("@cosmicdrift/kumiko-types/fields").EntityTextFieldDef & {
147
147
  required: true;
@@ -168,10 +168,10 @@ export declare const syncCursorEntity: import("@cosmicdrift/kumiko-types/fields"
168
168
  required: true;
169
169
  };
170
170
  }, "tenant">;
171
- /** Dedup-Anchor für O(1)-Idempotency ohne Stream-Scan bei sehr langen
172
- * Message-Historien: (accountId, providerMessageId) UNIQUE. Der
173
- * ingest-handler prüft zuerst hier (cheap), der Stream-Scan bleibt
174
- * Defense-in-depth. */
171
+ /** Deduplication anchor for O(1) idempotency without scanning the stream
172
+ * for very long message histories: (accountId, providerMessageId) UNIQUE.
173
+ * The ingest handler checks here first (cheap); the stream scan remains
174
+ * defense-in-depth. */
175
175
  export declare const seenMessageEntity: import("@cosmicdrift/kumiko-types/fields").EntityDefinition<{
176
176
  readonly accountId: import("@cosmicdrift/kumiko-types/fields").EntityTextFieldDef & {
177
177
  required: true;
@@ -2,27 +2,26 @@ import { collectPiiSubjectFields } from "@cosmicdrift/kumiko-framework/crypto";
2
2
  import { deriveEntityTableMeta } from "@cosmicdrift/kumiko-framework/db";
3
3
  import { access, createEntity, createNumberField, createTextField, createTimestampField, } from "@cosmicdrift/kumiko-framework/engine";
4
4
  // ============================================================================
5
- // Read-Models der drei event-sourced Aggregates
5
+ // Read models for the three event-sourced aggregates
6
6
  // ============================================================================
7
7
  //
8
- // Inline-Projection-Targets. Geschrieben AUSSCHLIESSLICH von den
9
- // projection-applies (siehe feature.ts), nie direkt vom handler.
10
- // Source-of-truth sind die event-store-Streams `mail-account` /
11
- // `inbound-message` / `mail-thread` — die Tabellen sind rebuild-fähig.
8
+ // Inline projection targets. Written EXCLUSIVELY by projection applies
9
+ // (see feature.ts), never directly by the handler.
10
+ // The event-store streams `mail-account` / `inbound-message` / `mail-thread`
11
+ // are the source of truth, so these tables can be rebuilt.
12
12
  //
13
13
  // **PII convention:** `personal: "tenant"` (not `encrypted`): fields must
14
- // crypto-shred when eraseSubjectKeys deletes the tenant subject key on
15
- // tenant-destroy (#800 pattern from billing-foundation).
16
- // maxLength jeweils Ciphertext-budgetiert (`kumiko-pii:v1:<subject>:
17
- // <blob>` — Plaintext×~2.3 + Envelope-Overhead).
14
+ // be crypto-shredded when eraseSubjectKeys deletes the tenant subject key on
15
+ // tenant destruction (pattern from billing-foundation).
16
+ // maxLength is budgeted for ciphertext (`kumiko-pii:v1:<subject>:
17
+ // <blob>` — Plaintext×~2.3 + envelope overhead).
18
18
  //
19
- // **Offene Design-Frage aus dem Plan (§3.4):** PII-Subject einer
20
- // Inbound-Mail ist vorerst der TENANT (Postfach-Inhaber), nicht der
21
- // externe Absender — ein Absender-Forget-Flow bräuchte per-Sender-Keys
22
- // und ist bewusst NICHT Teil von Phase 1 (dokumentierte Entscheidung,
23
- // Erasure-Pfad ist tenant-destroy).
24
- /** Ein verbundenes Postfach. Eine Row pro Account, PK = aggregateId
25
- * (= accountId, random uuid beim connect). */
19
+ // **Design decision:** The PII subject of an inbound mail is currently the
20
+ // TENANT (mailbox owner), not the external sender. A sender-forget flow would
21
+ // require per-sender keys and is deliberately not included; the erasure path
22
+ // is tenant destruction.
23
+ /** A connected mailbox. One row per account, with PK = aggregateId
24
+ * (= accountId, random uuid on connect). */
26
25
  export const mailAccountEntity = createEntity({
27
26
  table: "read_mail_accounts",
28
27
  fields: {
@@ -38,10 +37,10 @@ export const mailAccountEntity = createEntity({
38
37
  personal: false,
39
38
  reason: "technical_reference",
40
39
  }),
41
- // null = tenant-geteiltes Postfach (info@), gesetzt = persönliches
42
- // Postfach dieses Users. Sichtbarkeits-Filter in den list-queries:
43
- // Owner + TenantAdmin (Compliance); KEIN Crypto-Subject-Wechsel in
44
- // V1 (Subject bleibt Tenant, siehe Header).
40
+ // null = tenant-shared mailbox (info@), set = this user's personal
41
+ // mailbox. Visibility filters in the list queries:
42
+ // Owner + TenantAdmin (compliance); NO crypto-subject change in
43
+ // V1 (subject remains Tenant, see header).
45
44
  ownerUserId: createTextField({ maxLength: 36, personal: false, reason: "pseudonymous_fk" }),
46
45
  // Tenant-authored mailbox label, not a person's name.
47
46
  displayName: createTextField({
@@ -49,7 +48,7 @@ export const mailAccountEntity = createEntity({
49
48
  personal: false,
50
49
  reason: "tenant_config_not_personal",
51
50
  }),
52
- // Postfach-Adresse — PII des Tenants.
51
+ // Mailbox address — tenant PII.
53
52
  address: createTextField({ required: true, maxLength: 1000, personal: "tenant", find: "none" }),
54
53
  status: createTextField({
55
54
  required: true,
@@ -61,8 +60,8 @@ export const mailAccountEntity = createEntity({
61
60
  connectedAt: createTimestampField({ required: true }),
62
61
  },
63
62
  });
64
- /** Eine eingegangene Mail (Envelope + Snippet, KEIN Body — bodyRef
65
- * zeigt auf file-foundation). PK = aggregateId =
63
+ /** An incoming mail (envelope + snippet, NO body — bodyRef
64
+ * points to file-foundation). PK = aggregateId =
66
65
  * inboundMessageAggregateId(accountId, providerMessageId). */
67
66
  export const inboundMessageEntity = createEntity({
68
67
  table: "read_inbound_messages",
@@ -73,9 +72,9 @@ export const inboundMessageEntity = createEntity({
73
72
  personal: false,
74
73
  reason: "technical_reference",
75
74
  }),
76
- // Scope-Vererbung vom Account zum Ingest-Zeitpunkt — Messages eines
77
- // persönlichen Postfachs sind nur für den Owner (+ TenantAdmin)
78
- // sichtbar, ohne Join auf read_mail_accounts.
75
+ // Scope is inherited from the account at ingest time: messages from a
76
+ // personal mailbox are visible only to the owner (+ TenantAdmin),
77
+ // without joining read_mail_accounts.
79
78
  ownerUserId: createTextField({ maxLength: 36, personal: false, reason: "pseudonymous_fk" }),
80
79
  messageIdHeader: createTextField({
81
80
  required: true,
@@ -116,27 +115,27 @@ export const mailThreadEntity = createEntity({
116
115
  messageCount: createNumberField({ required: true, integer: true }),
117
116
  },
118
117
  });
119
- // Single source of truth für die PII-Feld-Listen — encrypt (ingest/
120
- // connect-handler) und decrypt (list-queries) teilen dieselbe Liste,
121
- // damit ein künftiges weiteres tenantOwned-Feld nicht an einer der
122
- // Stellen vergessen wird (Muster billing-foundation entities.ts).
118
+ // Single source of truth for the PII field lists — encrypt (ingest/
119
+ // connect-handler) and decrypt (list-queries) share the same list,
120
+ // so a future tenantOwned field cannot be omitted in either location
121
+ // (pattern from billing-foundation entities.ts).
123
122
  export const MAIL_ACCOUNT_PII_FIELDS = collectPiiSubjectFields(mailAccountEntity);
124
123
  export const INBOUND_MESSAGE_PII_FIELDS = collectPiiSubjectFields(inboundMessageEntity);
125
124
  export const MAIL_THREAD_PII_FIELDS = collectPiiSubjectFields(mailThreadEntity);
126
125
  // ============================================================================
127
- // Unmanaged Direct-Write-Stores — Sync-Maschinerie, NICHT event-sourced
126
+ // Unmanaged direct-write stores — sync machinery, NOT event-sourced
128
127
  // ============================================================================
129
128
  //
130
- // SyncCursor + SeenMessage sind technischer Tick-State des Watch/Sync-
131
- // Loops: hochfrequente Writes ohne Business-Fakt-Charakter. Als r.entity
132
- // würden sie (a) das Event-Log fluten und (b) beim Projection-Rebuild
133
- // gewischt (Direct-Write ohne Event → Rebuild findet nichts, #494/#498-
134
- // Klasse). Deshalb r.unmanagedTable — Migration-DDL ja, Rebuild-Target
135
- // nein (Muster sessions/feature.ts).
136
- /** Provider-Cursor pro Account ("wo war ich?"): IMAP UIDVALIDITY:UIDNEXT,
137
- * Graph deltaLink, Gmail historyId. Eine Row pro (accountId, scope).
138
- * Write-locked auf privileged — nur Foundation-Handler/Supervisor
139
- * schreiben, kein Tenant-Request. */
129
+ // SyncCursor + SeenMessage are technical tick state for the watch/sync
130
+ // loops: high-frequency writes without business-fact semantics. As
131
+ // r.entity, they would (a) flood the event log and (b) be wiped during a
132
+ // projection rebuild (direct write without an event means the rebuild finds
133
+ // nothing). Therefore r.unmanagedTable — migration DDL, but not a rebuild
134
+ // target (pattern from sessions/feature.ts).
135
+ /** Provider cursor per account ("where was I?"): IMAP UIDVALIDITY:UIDNEXT,
136
+ * Graph deltaLink, Gmail historyId. One row per (accountId, scope).
137
+ * Write-locked to privileged — only Foundation handlers/supervisors
138
+ * write it; tenant requests cannot. */
140
139
  export const syncCursorEntity = createEntity({
141
140
  table: "store_mail_sync_cursors",
142
141
  softDelete: false,
@@ -168,10 +167,10 @@ export const syncCursorEntity = createEntity({
168
167
  }),
169
168
  },
170
169
  });
171
- /** Dedup-Anchor für O(1)-Idempotency ohne Stream-Scan bei sehr langen
172
- * Message-Historien: (accountId, providerMessageId) UNIQUE. Der
173
- * ingest-handler prüft zuerst hier (cheap), der Stream-Scan bleibt
174
- * Defense-in-depth. */
170
+ /** Deduplication anchor for O(1) idempotency without scanning the stream
171
+ * for very long message histories: (accountId, providerMessageId) UNIQUE.
172
+ * The ingest handler checks here first (cheap); the stream scan remains
173
+ * defense-in-depth. */
175
174
  export const seenMessageEntity = createEntity({
176
175
  table: "store_mail_seen_messages",
177
176
  softDelete: false,
@@ -196,9 +195,9 @@ export const seenMessageEntity = createEntity({
196
195
  }),
197
196
  },
198
197
  });
199
- // Plain EntityTableMeta (kein branded EntityTable) — unmanaged Direct-
200
- // Write-Stores, Handler schreiben via ctx.db (siehe user-session.ts-
201
- // Rationale).
198
+ // Plain EntityTableMeta (not a branded EntityTable) — unmanaged direct-
199
+ // write stores; handlers write via ctx.db (see user-session.ts-
200
+ // rationale).
202
201
  export const syncCursorTable = deriveEntityTableMeta("mail-sync-cursor", syncCursorEntity, {
203
202
  source: "unmanaged",
204
203
  });
@@ -52,13 +52,14 @@ export type MailThreadEventPayload = z.infer<typeof mailThreadEventPayloadSchema
52
52
  export type InboundMessageEventHeaders = {
53
53
  readonly providerMessageId: string;
54
54
  readonly providerName: string;
55
- /** Provider-Cursor-Snapshot zum Ingest-Zeitpunkt (UIDVALIDITY:UID,
56
- * deltaLink, historyId ...) — Debug/Replay-Hilfe, kein Payload. */
55
+ /** Provider cursor snapshot at ingest time (UIDVALIDITY:UID, deltaLink,
56
+ * historyId ...) — useful for debugging and replay, not part of the
57
+ * payload. */
57
58
  readonly providerCursor: string;
58
59
  };
59
60
  export type MailAccountEventHeaders = {
60
61
  readonly providerName: string;
61
- /** Was den Übergang ausgelöst hat ("connect_flow", "watch_supervisor",
62
+ /** What triggered the transition ("connect_flow", "watch_supervisor",
62
63
  * "oauth_refresh", "tenant_admin"). */
63
64
  readonly reason: string;
64
65
  };