@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.388.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (643) hide show
  1. package/LICENSE +21 -57
  2. package/dist/agent-tools/tool-catalog.js +1 -1
  3. package/dist/agent-tools/tool-dispatch.d.ts +7 -7
  4. package/dist/agent-tools/tool-dispatch.js +9 -9
  5. package/dist/audit/handlers/audit-events.js +1 -1
  6. package/dist/audit/screens.js +1 -1
  7. package/dist/auth-email-password/feature.js +1 -1
  8. package/dist/auth-email-password/handlers/change-password.write.js +3 -3
  9. package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
  10. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
  11. package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
  12. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  13. package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
  14. package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
  15. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
  16. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  17. package/dist/auth-email-password/handlers/login.write.js +1 -1
  18. package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
  19. package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
  20. package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
  21. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  22. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
  23. package/dist/auth-email-password/index.js +5 -5
  24. package/dist/auth-email-password/lockout-store.js +1 -1
  25. package/dist/auth-email-password/seeding.d.ts +42 -45
  26. package/dist/auth-email-password/seeding.js +51 -53
  27. package/dist/auth-email-password/signup-token-store.js +8 -8
  28. package/dist/auth-email-password/testing.js +3 -3
  29. package/dist/auth-email-password/web/auth-client.d.ts +2 -2
  30. package/dist/auth-email-password/web/auth-client.js +36 -37
  31. package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
  32. package/dist/auth-email-password/web/auth-gate.js +15 -16
  33. package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
  34. package/dist/auth-email-password/web/client-plugin.js +4 -5
  35. package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
  36. package/dist/auth-email-password/web/constants.js +3 -3
  37. package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
  38. package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
  39. package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
  40. package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
  41. package/dist/auth-email-password/web/index.js +5 -5
  42. package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
  43. package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
  44. package/dist/auth-email-password/web/login-screen.d.ts +1 -1
  45. package/dist/auth-email-password/web/login-screen.js +2 -3
  46. package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
  47. package/dist/auth-email-password/web/reset-password-screen.js +12 -13
  48. package/dist/auth-email-password/web/session.d.ts +10 -9
  49. package/dist/auth-email-password/web/session.js +28 -29
  50. package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
  51. package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
  52. package/dist/auth-email-password/web/signup-screen.js +13 -13
  53. package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
  54. package/dist/auth-email-password/web/tenant-switcher.js +21 -22
  55. package/dist/auth-email-password/web/use-shell-user.js +12 -13
  56. package/dist/auth-email-password/web/user-menu.d.ts +4 -4
  57. package/dist/auth-email-password/web/user-menu.js +12 -13
  58. package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
  59. package/dist/auth-email-password/web/verify-email-screen.js +9 -10
  60. package/dist/auth-foundation/boot-checks.js +4 -4
  61. package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
  62. package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
  63. package/dist/auth-foundation/types.js +2 -2
  64. package/dist/auth-mfa/feature-exports.d.ts +2 -2
  65. package/dist/auth-mfa/feature.js +8 -0
  66. package/dist/auth-mfa/handlers/disable.write.js +3 -3
  67. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
  68. package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
  69. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
  70. package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
  71. package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
  72. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  73. package/dist/auth-mfa/token-secrets.js +1 -1
  74. package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
  75. package/dist/auth-mfa/web/client-plugin.js +1 -1
  76. package/dist/auth-mfa/web/i18n.js +8 -4
  77. package/dist/auth-mfa/web/index.js +4 -4
  78. package/dist/auth-mfa/web/mfa-client.js +17 -16
  79. package/dist/auth-mfa/web/mfa-code-or-recovery-field.d.ts +11 -0
  80. package/dist/auth-mfa/web/mfa-code-or-recovery-field.js +12 -0
  81. package/dist/auth-mfa/web/mfa-disable-dialog.js +14 -3
  82. package/dist/auth-mfa/web/mfa-regenerate-recovery-dialog.js +14 -3
  83. package/dist/auth-mfa/web/mfa-setup-preauth-screen.js +10 -5
  84. package/dist/auth-mfa/web/mfa-verify-screen.js +32 -11
  85. package/dist/billing-foundation/aggregate-id.d.ts +5 -5
  86. package/dist/billing-foundation/aggregate-id.js +10 -11
  87. package/dist/billing-foundation/checkout-core.d.ts +9 -14
  88. package/dist/billing-foundation/checkout-core.js +24 -39
  89. package/dist/billing-foundation/consumer-protection/confirmation-mail.js +8 -2
  90. package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +1 -0
  91. package/dist/billing-foundation/consumer-protection/consent-gate.js +1 -0
  92. package/dist/billing-foundation/consumer-protection/issue-confirmation.js +9 -3
  93. package/dist/billing-foundation/consumer-protection/mail-notifications.js +3 -1
  94. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.d.ts +4 -2
  95. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.js +6 -5
  96. package/dist/billing-foundation/consumer-protection/termination-record.d.ts +5 -1
  97. package/dist/billing-foundation/consumer-protection/termination-record.js +27 -17
  98. package/dist/billing-foundation/consumer-protection/termination-request.js +12 -7
  99. package/dist/billing-foundation/consumer-protection/termination-revoke.js +12 -7
  100. package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +1 -1
  101. package/dist/billing-foundation/consumer-protection/termination-texts.js +3 -0
  102. package/dist/billing-foundation/consumer-protection/withdrawal-period.d.ts +5 -2
  103. package/dist/billing-foundation/consumer-protection/withdrawal-period.js +8 -9
  104. package/dist/billing-foundation/entities.js +27 -27
  105. package/dist/billing-foundation/events.d.ts +1 -0
  106. package/dist/billing-foundation/events.js +19 -17
  107. package/dist/billing-foundation/feature.js +45 -44
  108. package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
  109. package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
  110. package/dist/billing-foundation/handlers/billing-plans.query.js +35 -5
  111. package/dist/billing-foundation/handlers/create-checkout-session.write.js +19 -17
  112. package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
  113. package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
  114. package/dist/billing-foundation/handlers/plan-switch-preview.query.d.ts +13 -0
  115. package/dist/billing-foundation/handlers/plan-switch-preview.query.js +48 -0
  116. package/dist/billing-foundation/handlers/process-event.write.d.ts +6 -0
  117. package/dist/billing-foundation/handlers/process-event.write.js +28 -22
  118. package/dist/billing-foundation/handlers/start-plan-checkout.write.js +32 -5
  119. package/dist/billing-foundation/handlers/switch-plan.write.d.ts +2 -2
  120. package/dist/billing-foundation/handlers/switch-plan.write.js +56 -64
  121. package/dist/billing-foundation/handlers/sync-subscription.write.js +12 -1
  122. package/dist/billing-foundation/i18n.js +22 -0
  123. package/dist/billing-foundation/index.d.ts +1 -1
  124. package/dist/billing-foundation/plan-catalog.d.ts +21 -5
  125. package/dist/billing-foundation/plan-catalog.js +25 -16
  126. package/dist/billing-foundation/plan-switch.d.ts +12 -0
  127. package/dist/billing-foundation/plan-switch.js +60 -0
  128. package/dist/billing-foundation/projection.d.ts +15 -11
  129. package/dist/billing-foundation/projection.js +38 -37
  130. package/dist/billing-foundation/subscription-tier-sync.js +3 -3
  131. package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
  132. package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
  133. package/dist/billing-foundation/types.d.ts +97 -42
  134. package/dist/billing-foundation/types.js +29 -20
  135. package/dist/billing-foundation/validate-options.js +17 -0
  136. package/dist/billing-foundation/web/billing-plans-panel.js +82 -36
  137. package/dist/billing-foundation/web/checkout-consent-dialog.d.ts +17 -3
  138. package/dist/billing-foundation/web/checkout-consent-dialog.js +14 -10
  139. package/dist/billing-foundation/web/constants.d.ts +4 -0
  140. package/dist/billing-foundation/web/constants.js +4 -0
  141. package/dist/billing-foundation/web/plan-price.d.ts +15 -0
  142. package/dist/billing-foundation/web/plan-price.js +32 -0
  143. package/dist/billing-foundation/web/plan-switch-confirm-dialog.d.ts +15 -0
  144. package/dist/billing-foundation/web/plan-switch-confirm-dialog.js +66 -0
  145. package/dist/cap-counter/aggregate-id.js +8 -9
  146. package/dist/cap-counter/cap-reservation.js +5 -1
  147. package/dist/cap-counter/constants.js +11 -12
  148. package/dist/cap-counter/enforce-cap.d.ts +59 -62
  149. package/dist/cap-counter/enforce-cap.js +49 -49
  150. package/dist/cap-counter/entity.js +29 -29
  151. package/dist/cap-counter/feature.js +34 -35
  152. package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
  153. package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
  154. package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
  155. package/dist/cap-counter/stock-cap-guard.js +8 -2
  156. package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
  157. package/dist/channel-email/feature.js +1 -1
  158. package/dist/channel-email/smtp-transport.d.ts +18 -17
  159. package/dist/channel-email/smtp-transport.js +24 -21
  160. package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
  161. package/dist/compliance-profiles/feature.js +4 -4
  162. package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
  163. package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
  164. package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
  165. package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
  166. package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
  167. package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
  168. package/dist/compliance-profiles/schema/profile-selection.js +18 -23
  169. package/dist/compliance-profiles/seeding.js +14 -15
  170. package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
  171. package/dist/compliance-profiles-ops/index.js +2 -2
  172. package/dist/config/handlers/cascade.query.d.ts +5 -0
  173. package/dist/config/handlers/cascade.query.js +4 -3
  174. package/dist/config/handlers/readiness.query.d.ts +4 -4
  175. package/dist/config/handlers/readiness.query.js +1 -1
  176. package/dist/config/handlers/reencrypt.job.js +4 -5
  177. package/dist/config/handlers/set.write.js +4 -4
  178. package/dist/config/handlers/values.query.d.ts +5 -0
  179. package/dist/config/handlers/values.query.js +4 -3
  180. package/dist/config/resolver.js +4 -4
  181. package/dist/config/table.js +10 -10
  182. package/dist/config/write-helpers.d.ts +1 -0
  183. package/dist/config/write-helpers.js +19 -10
  184. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
  185. package/dist/crypto-shredding/handlers/forget-subject.write.js +25 -21
  186. package/dist/custom-fields/aggregate-id.d.ts +12 -13
  187. package/dist/custom-fields/aggregate-id.js +16 -17
  188. package/dist/custom-fields/entity.js +49 -47
  189. package/dist/custom-fields/events.js +7 -8
  190. package/dist/custom-fields/feature.d.ts +14 -14
  191. package/dist/custom-fields/feature.js +53 -54
  192. package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
  193. package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
  194. package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
  195. package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
  196. package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
  197. package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
  198. package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
  199. package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
  200. package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
  201. package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
  202. package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
  203. package/dist/custom-fields/lib/field-access.js +2 -2
  204. package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
  205. package/dist/custom-fields/lib/quota.js +1 -1
  206. package/dist/custom-fields/lib/value-schema.js +10 -12
  207. package/dist/custom-fields/run-retention.js +3 -3
  208. package/dist/custom-fields/schemas.js +14 -14
  209. package/dist/custom-fields/web/client-plugin.js +2 -5
  210. package/dist/custom-fields/web/constants.js +2 -2
  211. package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
  212. package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
  213. package/dist/custom-fields/wire-for-entity.js +65 -67
  214. package/dist/custom-fields/wire-user-data-rights.js +3 -3
  215. package/dist/data-retention/_internal/parse-override.js +2 -3
  216. package/dist/data-retention/feature.js +11 -18
  217. package/dist/data-retention/handlers/policy-for.query.js +6 -6
  218. package/dist/data-retention/keep-for.d.ts +7 -7
  219. package/dist/data-retention/keep-for.js +15 -15
  220. package/dist/data-retention/override-schema.d.ts +3 -4
  221. package/dist/data-retention/override-schema.js +13 -15
  222. package/dist/data-retention/presets.d.ts +4 -5
  223. package/dist/data-retention/presets.js +18 -23
  224. package/dist/data-retention/resolve-tenant-preset.js +17 -16
  225. package/dist/data-retention/resolver.d.ts +12 -12
  226. package/dist/data-retention/resolver.js +24 -23
  227. package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
  228. package/dist/data-retention/run-retention-cleanup.js +61 -51
  229. package/dist/data-retention/schema/tenant-retention-override.js +13 -11
  230. package/dist/delivery/channel-context.js +6 -3
  231. package/dist/delivery/db/queries/preferences.js +2 -2
  232. package/dist/delivery/delivery-service.js +22 -7
  233. package/dist/delivery/feature.js +2 -2
  234. package/dist/delivery/handlers/log.query.js +1 -1
  235. package/dist/delivery/handlers/preferences.query.d.ts +1 -1
  236. package/dist/delivery/handlers/preferences.query.js +20 -1
  237. package/dist/delivery/handlers/unsubscribe-page-chrome.query.js +1 -1
  238. package/dist/delivery/tables.js +9 -8
  239. package/dist/delivery/unsubscribe-link.d.ts +3 -1
  240. package/dist/delivery/unsubscribe-page-strings.d.ts +1 -0
  241. package/dist/delivery/unsubscribe-page-strings.js +1 -0
  242. package/dist/delivery/unsubscribe-page.d.ts +2 -0
  243. package/dist/delivery/unsubscribe-page.js +5 -0
  244. package/dist/delivery/unsubscribe.js +29 -11
  245. package/dist/document-ingest-foundation/entity.js +4 -4
  246. package/dist/document-ingest-foundation/events.js +2 -2
  247. package/dist/document-ingest-foundation/feature.js +2 -2
  248. package/dist/document-ingest-foundation/pages.js +1 -1
  249. package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
  250. package/dist/feature-toggles/compose-tier-resolver.js +1 -1
  251. package/dist/feature-toggles/feature.js +1 -1
  252. package/dist/feature-toggles/global-feature-state-table.js +1 -1
  253. package/dist/feature-toggles/handlers/registered.query.js +5 -5
  254. package/dist/feature-toggles/toggle-sync-signal.js +1 -1
  255. package/dist/feature-toggles/web/constants.js +1 -1
  256. package/dist/file-derivatives/feature.d.ts +1 -1
  257. package/dist/file-derivatives/feature.js +1 -1
  258. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  259. package/dist/file-derivatives/presets.js +1 -1
  260. package/dist/file-foundation/feature.js +6 -6
  261. package/dist/file-foundation/index.d.ts +1 -1
  262. package/dist/file-foundation/index.js +1 -1
  263. package/dist/file-foundation/read-file-ref-content.d.ts +3 -0
  264. package/dist/file-foundation/read-file-ref-content.js +6 -1
  265. package/dist/file-provider-inmemory/feature.d.ts +1 -1
  266. package/dist/file-provider-inmemory/feature.js +16 -16
  267. package/dist/file-provider-s3/env-named-feature.d.ts +0 -2
  268. package/dist/file-provider-s3/feature.js +16 -16
  269. package/dist/file-provider-s3/lib/s3-provider.js +6 -6
  270. package/dist/files/feature.js +6 -6
  271. package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
  272. package/dist/files-tenant-data/hooks.js +24 -26
  273. package/dist/files-tenant-data/index.js +1 -1
  274. package/dist/folders/feature.d.ts +1 -1
  275. package/dist/folders/web/folder-manager.js +2 -2
  276. package/dist/folders/web/tree.js +5 -5
  277. package/dist/form-draft/db/queries/cleanup.js +3 -3
  278. package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
  279. package/dist/form-draft/decrypt-draft.js +5 -1
  280. package/dist/form-draft/entity.js +3 -3
  281. package/dist/form-draft/feature.js +4 -5
  282. package/dist/form-draft/handlers/discard.write.js +1 -1
  283. package/dist/form-draft/release-file-refs.js +6 -6
  284. package/dist/form-draft/schemas.js +3 -3
  285. package/dist/form-draft/web/constants.js +0 -2
  286. package/dist/host-routing/dispatch.js +11 -20
  287. package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
  288. package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
  289. package/dist/inbound-mail-foundation/connect-routes.js +4 -3
  290. package/dist/inbound-mail-foundation/constants.d.ts +22 -24
  291. package/dist/inbound-mail-foundation/constants.js +30 -33
  292. package/dist/inbound-mail-foundation/entities.d.ts +12 -12
  293. package/dist/inbound-mail-foundation/entities.js +47 -48
  294. package/dist/inbound-mail-foundation/events.d.ts +4 -3
  295. package/dist/inbound-mail-foundation/events.js +50 -47
  296. package/dist/inbound-mail-foundation/feature.js +39 -39
  297. package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
  298. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
  299. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
  300. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
  301. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
  302. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
  303. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
  304. package/dist/inbound-mail-foundation/handlers/update-account.write.d.ts +2 -2
  305. package/dist/inbound-mail-foundation/handlers/update-account.write.js +22 -14
  306. package/dist/inbound-mail-foundation/i18n.js +0 -1
  307. package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
  308. package/dist/inbound-mail-foundation/oauth-state.js +11 -10
  309. package/dist/inbound-mail-foundation/projection.d.ts +4 -4
  310. package/dist/inbound-mail-foundation/projection.js +31 -29
  311. package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
  312. package/dist/inbound-mail-foundation/provider-factory.js +9 -9
  313. package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
  314. package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
  315. package/dist/inbound-mail-foundation/screens.js +0 -3
  316. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
  317. package/dist/inbound-mail-foundation/types.d.ts +49 -49
  318. package/dist/inbound-mail-foundation/types.js +21 -21
  319. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
  320. package/dist/inbound-mail-foundation/watch-supervisor.js +85 -67
  321. package/dist/inbound-provider-imap/credential-document.js +13 -13
  322. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  323. package/dist/inbound-provider-imap/feature.js +42 -40
  324. package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
  325. package/dist/inbound-provider-imap/imap-client.js +20 -19
  326. package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
  327. package/dist/inbound-provider-inmemory/feature.js +19 -19
  328. package/dist/jobs/db/queries/retention.js +2 -2
  329. package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
  330. package/dist/jobs/events.js +1 -1
  331. package/dist/jobs/feature.d.ts +1 -0
  332. package/dist/jobs/feature.js +13 -10
  333. package/dist/jobs/handlers/detail.query.js +4 -4
  334. package/dist/jobs/handlers/list.query.js +1 -1
  335. package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
  336. package/dist/jobs/handlers/reindex-entity.job.js +1 -1
  337. package/dist/jobs/handlers/retry.write.js +1 -1
  338. package/dist/jobs/handlers/tenant-failures.query.d.ts +1 -1
  339. package/dist/jobs/handlers/tenant-failures.query.js +45 -41
  340. package/dist/jobs/handlers/tenant-runs.query.d.ts +1 -1
  341. package/dist/jobs/handlers/tenant-runs.query.js +54 -50
  342. package/dist/jobs/job-instant.js +1 -1
  343. package/dist/jobs/job-run-logger.js +15 -15
  344. package/dist/jobs/job-run-table.js +3 -3
  345. package/dist/jobs/screens.js +1 -1
  346. package/dist/jobs/tenant-job-failure-table.js +1 -1
  347. package/dist/jobs/tenant-job-run-table.js +1 -1
  348. package/dist/ledger/entity.js +5 -5
  349. package/dist/ledger/feature.js +3 -3
  350. package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
  351. package/dist/ledger/recurring.js +12 -12
  352. package/dist/ledger/schemas.js +1 -1
  353. package/dist/ledger/web/constants.js +2 -2
  354. package/dist/ledger/web/index.js +7 -7
  355. package/dist/legal-pages/feature.d.ts +4 -4
  356. package/dist/legal-pages/feature.js +25 -26
  357. package/dist/legal-pages/markdown.js +3 -3
  358. package/dist/legal-pages/web/client-plugin.js +23 -24
  359. package/dist/legal-pages/web/index.js +0 -1
  360. package/dist/mail-foundation/feature.d.ts +5 -5
  361. package/dist/mail-foundation/feature.js +27 -25
  362. package/dist/mail-transport-inmemory/feature.d.ts +4 -4
  363. package/dist/mail-transport-inmemory/feature.js +27 -28
  364. package/dist/mail-transport-smtp/feature.js +20 -20
  365. package/dist/managed-pages/branding.js +6 -6
  366. package/dist/managed-pages/feature.d.ts +26 -26
  367. package/dist/managed-pages/feature.js +34 -34
  368. package/dist/managed-pages/handlers/by-slug.query.js +5 -6
  369. package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
  370. package/dist/managed-pages/handlers/set.write.js +5 -7
  371. package/dist/managed-pages/screens/page-screens.js +11 -11
  372. package/dist/managed-pages/seeding.js +8 -8
  373. package/dist/managed-pages/table.js +13 -12
  374. package/dist/managed-pages/web/client-plugin.d.ts +1 -1
  375. package/dist/managed-pages/web/client-plugin.js +5 -5
  376. package/dist/managed-pages/web/i18n.js +1 -1
  377. package/dist/notes-history/entity.js +4 -4
  378. package/dist/notes-history/feature.d.ts +2 -2
  379. package/dist/notes-history-user-data/hooks.js +1 -1
  380. package/dist/page-render/layout.js +9 -9
  381. package/dist/page-render/markdown.js +11 -11
  382. package/dist/page-render/security-headers.js +7 -6
  383. package/dist/personal-access-tokens/feature.d.ts +1 -1
  384. package/dist/personal-access-tokens/feature.js +9 -5
  385. package/dist/personal-access-tokens/roles.js +2 -2
  386. package/dist/readiness/handlers/status.query.js +3 -3
  387. package/dist/renderer-foundation/api.js +12 -13
  388. package/dist/renderer-foundation/constants.js +2 -2
  389. package/dist/renderer-foundation/feature.js +7 -7
  390. package/dist/renderer-pdf/render-table-pdf.d.ts +1 -1
  391. package/dist/renderer-pdf/render-table-pdf.js +22 -10
  392. package/dist/secrets/feature.js +9 -9
  393. package/dist/secrets/web/constants.js +2 -2
  394. package/dist/seo/feature.js +3 -3
  395. package/dist/sessions/constants.d.ts +1 -1
  396. package/dist/sessions/constants.js +1 -1
  397. package/dist/sessions/feature.d.ts +2 -2
  398. package/dist/sessions/feature.js +12 -8
  399. package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
  400. package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
  401. package/dist/sessions/handlers/revoke.write.js +1 -1
  402. package/dist/sessions/schema/user-session.js +4 -4
  403. package/dist/sessions/screens.js +2 -2
  404. package/dist/sessions/session-callbacks.js +2 -2
  405. package/dist/sessions/session-revoked-event.js +2 -2
  406. package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
  407. package/dist/shared/decrypt-stored-pii.d.ts +1 -0
  408. package/dist/shared/decrypt-stored-pii.js +7 -2
  409. package/dist/shared/encrypt-for-direct-write.js +1 -1
  410. package/dist/shared/index.d.ts +1 -1
  411. package/dist/shared/index.js +1 -1
  412. package/dist/shared/mail-template-body.d.ts +6 -2
  413. package/dist/shared/mail-template-body.js +7 -4
  414. package/dist/shared/map-with-concurrency.js +5 -4
  415. package/dist/shared/parent-visibility.js +2 -2
  416. package/dist/shared/password-hashing.js +1 -1
  417. package/dist/shared/signup-handover.js +1 -2
  418. package/dist/shared/single-use-token-store.js +1 -1
  419. package/dist/step-dispatcher/feature.js +1 -0
  420. package/dist/subscription-dodo/client.d.ts +17 -0
  421. package/dist/subscription-dodo/client.js +31 -0
  422. package/dist/subscription-dodo/constants.d.ts +12 -0
  423. package/dist/subscription-dodo/constants.js +19 -0
  424. package/dist/subscription-dodo/feature.d.ts +37 -0
  425. package/dist/subscription-dodo/feature.js +144 -0
  426. package/dist/subscription-dodo/index.d.ts +2 -0
  427. package/dist/subscription-dodo/index.js +4 -0
  428. package/dist/subscription-dodo/plugin-methods.d.ts +23 -0
  429. package/dist/subscription-dodo/plugin-methods.js +260 -0
  430. package/dist/subscription-dodo/runtime.d.ts +27 -0
  431. package/dist/subscription-dodo/runtime.js +89 -0
  432. package/dist/subscription-dodo/verify-webhook.d.ts +37 -0
  433. package/dist/subscription-dodo/verify-webhook.js +189 -0
  434. package/dist/subscription-mollie/constants.js +15 -17
  435. package/dist/subscription-mollie/feature.d.ts +17 -18
  436. package/dist/subscription-mollie/feature.js +24 -24
  437. package/dist/subscription-mollie/index.js +3 -3
  438. package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
  439. package/dist/subscription-mollie/plugin-methods.js +15 -14
  440. package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
  441. package/dist/subscription-mollie/verify-webhook.js +27 -27
  442. package/dist/subscription-stripe/constants.js +4 -6
  443. package/dist/subscription-stripe/feature.d.ts +14 -14
  444. package/dist/subscription-stripe/feature.js +36 -34
  445. package/dist/subscription-stripe/index.js +6 -6
  446. package/dist/subscription-stripe/plugin-methods.js +18 -18
  447. package/dist/subscription-stripe/runtime.d.ts +1 -1
  448. package/dist/subscription-stripe/runtime.js +8 -7
  449. package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
  450. package/dist/subscription-stripe/verify-webhook.js +59 -61
  451. package/dist/tags/feature.d.ts +3 -3
  452. package/dist/tags/screens.js +1 -1
  453. package/dist/template-resolver/api.d.ts +3 -2
  454. package/dist/template-resolver/api.js +34 -12
  455. package/dist/template-resolver/compile-document-body.js +1 -0
  456. package/dist/template-resolver/feature.js +2 -2
  457. package/dist/template-resolver/handlers/bundle-import.js +3 -3
  458. package/dist/template-resolver/handlers/copy-locale.write.d.ts +5 -1
  459. package/dist/template-resolver/handlers/copy-locale.write.js +22 -7
  460. package/dist/template-resolver/handlers/diff-to-system.query.js +3 -2
  461. package/dist/template-resolver/handlers/document-base.js +3 -2
  462. package/dist/template-resolver/handlers/find-by-id.query.js +8 -7
  463. package/dist/template-resolver/handlers/list.query.js +6 -7
  464. package/dist/template-resolver/handlers/overview.query.d.ts +3 -0
  465. package/dist/template-resolver/handlers/overview.query.js +6 -3
  466. package/dist/template-resolver/handlers/shared.js +2 -2
  467. package/dist/template-resolver/handlers/template-write.js +3 -3
  468. package/dist/template-resolver/handlers/tenant-override-counts.query.js +1 -3
  469. package/dist/template-resolver/handlers/tenant-override-selection.d.ts +2 -1
  470. package/dist/template-resolver/handlers/tenant-overrides.query.js +28 -5
  471. package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
  472. package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
  473. package/dist/template-resolver/handlers/usage.query.d.ts +2 -1
  474. package/dist/template-resolver/handlers/usage.query.js +26 -16
  475. package/dist/template-resolver/handlers/validate.query.js +7 -2
  476. package/dist/template-resolver/seeding.js +30 -14
  477. package/dist/template-resolver/store-template-resource.d.ts +1 -0
  478. package/dist/template-resolver/store-template-resource.js +19 -4
  479. package/dist/template-resolver/table.js +10 -11
  480. package/dist/template-resolver/template-delivery-policy.d.ts +0 -5
  481. package/dist/template-resolver/template-delivery-policy.js +0 -6
  482. package/dist/template-resolver/template-meta.js +7 -4
  483. package/dist/template-resolver/template-preview.js +4 -3
  484. package/dist/template-resolver/web/client-plugin.js +2 -2
  485. package/dist/template-resolver/web/constants.d.ts +2 -2
  486. package/dist/template-resolver/web/constants.js +3 -3
  487. package/dist/template-resolver/web/index.d.ts +1 -0
  488. package/dist/template-resolver/web/index.js +1 -0
  489. package/dist/template-resolver/web/mail-layout-constants.d.ts +5 -0
  490. package/dist/template-resolver/web/mail-layout-constants.js +7 -0
  491. package/dist/tenant/feature.js +7 -7
  492. package/dist/tenant/handlers/member-directory.query.d.ts +1 -0
  493. package/dist/tenant/handlers/member-directory.query.js +11 -4
  494. package/dist/tenant/handlers/members.query.js +1 -1
  495. package/dist/tenant/handlers/team-list.query.js +1 -1
  496. package/dist/tenant/handlers/tenant-directory.query.d.ts +1 -0
  497. package/dist/tenant/handlers/tenant-directory.query.js +9 -5
  498. package/dist/tenant/invitation-table.js +37 -40
  499. package/dist/tenant/membership-table.js +3 -3
  500. package/dist/tenant/schema/tenant.js +7 -9
  501. package/dist/tenant/screens.js +1 -1
  502. package/dist/tenant/seeding.d.ts +6 -5
  503. package/dist/tenant/seeding.js +12 -12
  504. package/dist/tenant/testing.js +5 -6
  505. package/dist/tenant/web/constants.js +2 -2
  506. package/dist/tenant-handover/events.js +5 -7
  507. package/dist/tenant-handover/feature.js +1 -1
  508. package/dist/tenant-handover/grant.js +1 -1
  509. package/dist/tenant-handover/handlers/claim.write.js +1 -1
  510. package/dist/tenant-handover/move-entity-graph.js +8 -9
  511. package/dist/tenant-handover/signup-handover-provider.js +1 -2
  512. package/dist/tenant-handover/transfer-graph.js +4 -5
  513. package/dist/tenant-lifecycle/boot-checks.js +1 -1
  514. package/dist/tenant-lifecycle/constants.d.ts +1 -0
  515. package/dist/tenant-lifecycle/constants.js +4 -0
  516. package/dist/tenant-lifecycle/feature.js +1 -1
  517. package/dist/tenant-lifecycle/run-tenant-destroy.js +2 -2
  518. package/dist/tenant-settings/constants.js +1 -1
  519. package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
  520. package/dist/tenant-settings/tenant-defaults.js +9 -2
  521. package/dist/tier-engine/aggregate-id.d.ts +11 -11
  522. package/dist/tier-engine/aggregate-id.js +15 -16
  523. package/dist/tier-engine/compose-app.d.ts +14 -14
  524. package/dist/tier-engine/compose-app.js +1 -1
  525. package/dist/tier-engine/entity.js +18 -19
  526. package/dist/tier-engine/feature.d.ts +19 -17
  527. package/dist/tier-engine/feature.js +68 -69
  528. package/dist/tier-engine/handlers/active-tier.query.js +6 -7
  529. package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
  530. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +7 -8
  531. package/dist/tier-engine/handlers/set-tenant-tier.write.js +7 -4
  532. package/dist/tier-engine/tier-resolver.js +2 -2
  533. package/dist/tier-engine/trial.js +8 -8
  534. package/dist/tier-engine/web/constants.js +2 -2
  535. package/dist/tier-engine/web/index.js +4 -4
  536. package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
  537. package/dist/user/handlers/create.write.js +4 -4
  538. package/dist/user/schema/user.d.ts +11 -11
  539. package/dist/user/schema/user.js +45 -44
  540. package/dist/user/seeding.d.ts +15 -15
  541. package/dist/user/seeding.js +28 -28
  542. package/dist/user/testing.js +3 -3
  543. package/dist/user-data-rights/audit-download.d.ts +8 -8
  544. package/dist/user-data-rights/audit-download.js +19 -20
  545. package/dist/user-data-rights/boot-checks.js +1 -1
  546. package/dist/user-data-rights/deletion-token.js +1 -1
  547. package/dist/user-data-rights/feature.d.ts +49 -50
  548. package/dist/user-data-rights/feature.js +54 -53
  549. package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
  550. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
  551. package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
  552. package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
  553. package/dist/user-data-rights/handlers/export-status.query.js +8 -9
  554. package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
  555. package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
  556. package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
  557. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
  558. package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
  559. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
  560. package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
  561. package/dist/user-data-rights/handlers/request-export.write.js +42 -41
  562. package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
  563. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
  564. package/dist/user-data-rights/index.js +8 -10
  565. package/dist/user-data-rights/lib/default-mailers.js +3 -3
  566. package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
  567. package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
  568. package/dist/user-data-rights/run-export-jobs.js +130 -237
  569. package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
  570. package/dist/user-data-rights/run-forget-cleanup.js +65 -83
  571. package/dist/user-data-rights/run-user-export.d.ts +34 -33
  572. package/dist/user-data-rights/run-user-export.js +55 -57
  573. package/dist/user-data-rights/schema/download-attempt.js +11 -11
  574. package/dist/user-data-rights/schema/download-token.js +37 -41
  575. package/dist/user-data-rights/schema/export-job.d.ts +4 -4
  576. package/dist/user-data-rights/schema/export-job.js +65 -67
  577. package/dist/user-data-rights/token-helpers.d.ts +8 -9
  578. package/dist/user-data-rights/token-helpers.js +21 -25
  579. package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
  580. package/dist/user-data-rights/web/client-plugin.js +1 -1
  581. package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
  582. package/dist/user-data-rights/web/constants.js +1 -1
  583. package/dist/user-data-rights/web/index.js +5 -5
  584. package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
  585. package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
  586. package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
  587. package/dist/user-data-rights/zip-path.d.ts +15 -15
  588. package/dist/user-data-rights/zip-path.js +41 -40
  589. package/dist/user-data-rights-defaults/feature.js +15 -15
  590. package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
  591. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
  592. package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
  593. package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
  594. package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
  595. package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
  596. package/dist/user-profile/handlers/change-email.write.js +13 -13
  597. package/dist/user-profile/index.js +3 -3
  598. package/dist/user-profile/web/client-plugin.js +1 -1
  599. package/dist/user-profile/web/constants.js +1 -1
  600. package/dist/user-profile/web/profile-screen.js +1 -1
  601. package/dist/waitlist/handlers/export-purge.write.js +2 -1
  602. package/dist/waitlist/handlers/submit.write.js +5 -5
  603. package/dist/waitlist/import.d.ts +1 -0
  604. package/dist/waitlist/import.js +4 -0
  605. package/dist/waitlist/legacy-migrate.js +17 -6
  606. package/dist/waitlist/link-on-signup.js +18 -6
  607. package/dist/waitlist/options.d.ts +3 -0
  608. package/dist/workflow-runner/aggregate-id.d.ts +1 -1
  609. package/dist/workflow-runner/aggregate-id.js +1 -1
  610. package/dist/workflow-runner/event-subscriber.js +4 -5
  611. package/dist/workflow-runner/event-trigger.js +4 -17
  612. package/dist/workflow-runner/feature.js +2 -2
  613. package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
  614. package/dist/workflow-runner/pending-projection.js +6 -7
  615. package/dist/workflow-runner/runner.js +6 -6
  616. package/dist/workflow-runner/tables.js +6 -6
  617. package/dist/workflow-runner/workflow-registry.js +1 -1
  618. package/package.json +20 -10
  619. package/src/agent-tools/changes.json +6 -0
  620. package/src/audit/changes.json +12 -0
  621. package/src/auth-mfa/changes.json +6 -0
  622. package/src/billing-foundation/changes.json +55 -0
  623. package/src/cap-counter/changes.json +18 -0
  624. package/src/channel-email/changes.json +6 -0
  625. package/src/config/changes.json +12 -0
  626. package/src/crypto-shredding/changes.json +6 -0
  627. package/src/delivery/changes.json +30 -0
  628. package/src/form-draft/changes.json +6 -0
  629. package/src/host-routing/changes.json +6 -0
  630. package/src/inbound-mail-foundation/changes.json +18 -0
  631. package/src/jobs/changes.json +13 -0
  632. package/src/mail-foundation/changes.json +6 -0
  633. package/src/renderer-pdf/changes.json +6 -0
  634. package/src/step-dispatcher/changes.json +6 -0
  635. package/src/subscription-dodo/changes.json +14 -0
  636. package/src/subscription-stripe/changes.json +12 -0
  637. package/src/template-resolver/changes.json +48 -0
  638. package/src/tenant/changes.json +6 -0
  639. package/src/tenant-lifecycle/changes.json +6 -0
  640. package/src/tier-engine/changes.json +6 -0
  641. package/src/waitlist/changes.json +18 -0
  642. package/dist/billing-foundation/consumer-protection/stored-user-email.d.ts +0 -1
  643. package/dist/billing-foundation/consumer-protection/stored-user-email.js +0 -8
@@ -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
  };
@@ -1,31 +1,32 @@
1
- // Domain-events für inbound-mail-foundation.
1
+ // Domain events for inbound-mail-foundation.
2
2
  //
3
- // **Pattern:** event-sourced — jede eingehende Mail und jeder Account-
4
- // Lifecycle-Übergang wird zu einem domain-event. Read-models =
5
- // inline projections (read_mail_accounts / read_inbound_messages /
6
- // read_mail_threads). Future-consumer (Business-Prozesse: Ticket-
7
- // Anlage, Beleg-Erkennung, Auto-Antwort) listenen direkt auf
8
- // `inbound-message-received` und können via extendEntityProjection
9
- // die KOMPLETTE Historie rückwirkend replayen.
3
+ // **Pattern:** event-sourced — each incoming mail and account-lifecycle
4
+ // transition becomes a domain event. Read models = inline projections
5
+ // (read_mail_accounts / read_inbound_messages / read_mail_threads).
6
+ // Future consumers (business processes: ticket creation, receipt
7
+ // recognition, auto-replies) listen directly to `inbound-message-received`
8
+ // and can replay the COMPLETE history retroactively via
9
+ // extendEntityProjection.
10
10
  //
11
- // **Payload-Disziplin (Events sind forever):**
12
- // - domain-clean + generisch: keine App-Begriffe (kein solon), keine
13
- // provider-raw-Strukturen im payload — raw lebt in metadata.headers.
14
- // - KEINE Bodies: bodyRef zeigt auf file-foundation-Storage. Der
15
- // Event-Store ist kein Blob-Store.
16
- // - PII (address/from/to/cc/subject/snippet) steht als Ciphertext im
17
- // payload (`kumiko-pii:v1:...`), encrypted VOR dem append im
18
- // write-handler — Subject-Key ist der Tenant, tenant-destroy's
19
- // eraseSubjectKeys macht Event-Log UND Projection unlesbar
20
- // (crypto-shredding, Muster billing-foundation #800).
11
+ // **Payload discipline (events are forever):**
12
+ // - Domain-clean and generic: no app-specific terms (no solon), and no
13
+ // provider-raw structures in the payload — raw data lives in
14
+ // metadata.headers.
15
+ // - NO bodies: bodyRef points to file-foundation storage. The event store
16
+ // is not a blob store.
17
+ // - PII (address/from/to/cc/subject/snippet) is stored as ciphertext in
18
+ // the payload (`kumiko-pii:v1:...`), encrypted BEFORE append in the
19
+ // write handler — the subject key is the tenant, and tenant destruction's
20
+ // eraseSubjectKeys makes both the event log and projection unreadable
21
+ // (crypto-shredding, the billing-foundation pattern).
21
22
  import * as z from "zod";
22
23
  import { INBOUND_MAIL_FOUNDATION_FEATURE, InboundMailAccountStatuses } from "./constants.js";
23
- // Aggregate-types für den event-store.
24
+ // Aggregate types for the event store.
24
25
  export const MAIL_ACCOUNT_AGGREGATE_TYPE = "mail-account";
25
26
  export const INBOUND_MESSAGE_AGGREGATE_TYPE = "inbound-message";
26
27
  export const MAIL_THREAD_AGGREGATE_TYPE = "mail-thread";
27
- // Event-name-Konstanten — short-form (für r.defineEvent) + qualifizierte
28
- // FQN (für ctx.unsafeAppendEvent + projection-apply-keys).
28
+ // Event-name constants — short forms (for r.defineEvent) and qualified
29
+ // FQNs (for ctx.unsafeAppendEvent and projection-apply keys).
29
30
  export const MAIL_ACCOUNT_CONNECTED_EVENT_SHORT = "mail-account-connected";
30
31
  export const MAIL_ACCOUNT_UPDATED_EVENT_SHORT = "mail-account-updated";
31
32
  export const MAIL_ACCOUNT_DISCONNECTED_EVENT_SHORT = "mail-account-disconnected";
@@ -43,46 +44,48 @@ const accountStatusEnum = z.enum([
43
44
  InboundMailAccountStatuses.disconnected,
44
45
  ]);
45
46
  // ============================================================================
46
- // mail-account-Stream — connected / updated / disconnected
47
+ // mail-account stream — connected / updated / disconnected
47
48
  // ============================================================================
48
49
  //
49
- // Ein Stream pro Postfach (aggregateId = accountId, random uuid beim
50
- // connect). address ist PII → maxLength 1000 wegen Ciphertext-Blowup
51
- // (ein 200-char-Plaintext wird ~460+ chars JSON-envelope, siehe
52
- // billing-foundation events.ts).
50
+ // One stream per mailbox (aggregateId = accountId, random UUID on connect).
51
+ // address is PII, so maxLength is 1000 to allow for ciphertext expansion
52
+ // (a 200-character plaintext becomes ~460+ characters in a JSON envelope;
53
+ // see billing-foundation events.ts).
53
54
  export const mailAccountEventPayloadSchema = z.object({
54
55
  provider: z.string().min(1).max(50),
55
- /** "password" | "xoauth2" | "oauth" (InboundMailAuthMethods) — bewusst
56
- * string statt enum: neue Auth-Methoden ohne Event-Upcaster. */
56
+ /** "password" | "xoauth2" | "oauth" (InboundMailAuthMethods) — deliberately
57
+ * a string rather than an enum, so new auth methods require no event
58
+ * upcaster. */
57
59
  authMethod: z.string().min(1).max(30),
58
- /** null = tenant-geteilt, sonst persönliches Postfach dieses Users. */
60
+ /** null = shared by the tenant; otherwise, this user's personal mailbox. */
59
61
  ownerUserId: z.string().max(36).nullable(),
60
62
  displayName: z.string().max(200),
61
63
  address: z.string().min(1).max(1000),
62
64
  status: accountStatusEnum,
63
- /** Provider-agnostischer Watch-Zustand ("idle", "watching",
64
- * "backoff:3", ...) — reines Ops-Signal, kein PII. */
65
+ /** Provider-agnostic watch state ("idle", "watching", "backoff:3", ...)
66
+ * — an operational signal only, not PII. */
65
67
  watchState: z.string().max(100),
66
68
  });
67
69
  // ============================================================================
68
- // inbound-message-Stream — genau EIN received-Event pro Message
70
+ // inbound-message stream — exactly ONE received event per message
69
71
  // ============================================================================
70
72
  //
71
73
  // aggregateId = inboundMessageAggregateId(accountId, providerMessageId)
72
- // → deterministic, Provider-Replays kollidieren auf demselben Stream.
74
+ // → deterministic, so provider replays collide on the same stream.
73
75
  //
74
- // PII-Felder (from/to/cc/subject/snippet): Ciphertext, maxLength großzügig.
75
- // to/cc als JSON-stringified string[] VOR encryption — im Payload steht
76
- // der Ciphertext-String, nicht das Array (primitives only, upcaster-safe).
76
+ // PII fields (from/to/cc/subject/snippet): ciphertext with generous
77
+ // maximum lengths. to/cc are JSON-stringified string[] BEFORE encryption;
78
+ // the payload contains the ciphertext string, not the array (primitives only,
79
+ // upcaster-safe).
77
80
  export const inboundMessageEventPayloadSchema = z.object({
78
81
  accountId: z.uuid(),
79
- /** Scope-Vererbung vom Account (Ingest-Zeitpunkt). */
82
+ /** Scope inherited from the account at ingest time. */
80
83
  ownerUserId: z.string().max(36).nullable(),
81
- /** RFC-5322 Message-ID-Header (normalisiert, ohne <>) — NICHT PII-
82
- * encrypted: Idempotency/Threading-Anchor, opaque technical id. */
84
+ /** RFC-5322 Message-ID header (normalized, without <>) — NOT PII-encrypted:
85
+ * idempotency/threading anchor and opaque technical ID. */
83
86
  messageIdHeader: z.string().min(1).max(500),
84
- /** Normalisierter Thread-Schlüssel (References-Chain-Root bzw.
85
- * Provider-Thread-ID, provider-präfixed). */
87
+ /** Normalized thread key (References-chain root or provider thread ID,
88
+ * prefixed by the provider). */
86
89
  threadKey: z.string().min(1).max(500),
87
90
  from: z.string().min(1).max(2000),
88
91
  /** JSON-stringified string[], dann PII-encrypted. */
@@ -91,14 +94,14 @@ export const inboundMessageEventPayloadSchema = z.object({
91
94
  cc: z.string().max(8000),
92
95
  subject: z.string().max(4000),
93
96
  snippet: z.string().max(4000),
94
- /** ISO-Instant — Empfangszeit laut Provider (INTERNALDATE bzw.
95
- * receivedDateTime), nicht Ingest-Zeit. */
97
+ /** ISO instant — receipt time reported by the provider (INTERNALDATE or
98
+ * receivedDateTime), not ingest time. */
96
99
  receivedAtIso: z.string().min(1),
97
- /** file-foundation-Referenz auf den raw-Body (MIME). Leer wenn die
98
- * App ohne Body-Persistenz mounted (snippet-only-Mode). */
100
+ /** file-foundation reference to the raw body (MIME). Empty when the app
101
+ * is mounted without body persistence (snippet-only mode). */
99
102
  bodyRef: z.string().max(500),
100
- /** Fachlicher Scope-Hint für nachgelagerte Business-Prozesse —
101
- * generisch ("inbox", Folder-Name), KEINE App-Semantik. */
103
+ /** Domain scope hint for downstream business processes — generic
104
+ * ("inbox", folder name), with NO app-specific semantics. */
102
105
  scope: z.string().max(200),
103
106
  });
104
107
  // ============================================================================
@@ -1,44 +1,44 @@
1
1
  // kumiko-feature-version: 1
2
2
  //
3
- // inbound-mail-foundation — Plugin-Host für eingehende E-Mail
4
- // (Inbox-Föderation). Gegenstück zu mail-foundation (outbound): getrennte
5
- // Extension-Points, getrennter State — Architektur-Vorbild ist
6
- // file-foundation (Foundation besitzt State), nicht mail-transport.
3
+ // inbound-mail-foundation — Plugin host for inbound e-mail
4
+ // (inbox federation). Counterpart to mail-foundation (outbound): separate
5
+ // extension points, separate state — architectural model is
6
+ // file-foundation (the foundation owns state), not mail-transport.
7
7
  //
8
- // **Multi-Provider von Tag 1** (wie billing-foundation): KEIN globaler
9
- // `provider`-config-key. Ein Tenant verbindet parallel IMAP- und (später)
10
- // M365-/Gmail-Postfächer; der Provider steht pro MailAccount.
8
+ // **Multi-provider from day one** (as with billing-foundation): NO global
9
+ // `provider` config key. A tenant can connect IMAP and (later) M365/Gmail
10
+ // mailboxes in parallel; the provider is specified per MailAccount.
11
11
  //
12
- // **Was diese Foundation liefert:**
13
- // 1. **Plugin-API** für Inbound-Provider via r.extendsRegistrar
12
+ // **What this foundation provides:**
13
+ // 1. **Plugin API** for inbound providers via r.extendsRegistrar
14
14
  // ("inboundMailProvider"): verify/fetch/oauth?/watch? (types.ts).
15
- // 2. **3 event-sourced Streams** — mail-account (Lifecycle),
16
- // inbound-message (genau EIN received-Event pro Mail, deterministic
17
- // aggregateId ⇒ exactly-once trotz at-least-once-Ingest),
18
- // mail-thread (Rollup). Volle Historie replay-fähig für spätere
19
- // Consumer (Business-Prozesse: Ticket, Beleg, Auto-Antwort).
20
- // 3. **Inline-Projections** auf read_mail_accounts /
15
+ // 2. **3 event-sourced streams** — mail-account (lifecycle),
16
+ // inbound-message (exactly ONE received event per message, deterministic
17
+ // aggregateId ⇒ exactly-once despite at-least-once ingest),
18
+ // mail-thread (rollup). Full replayable history for later
19
+ // consumers (business processes: ticket, receipt, auto-reply).
20
+ // 3. **Inline projections** into read_mail_accounts /
21
21
  // read_inbound_messages / read_mail_threads (read-your-own-write).
22
- // 4. **Write-/Query-Handler**: connect/update/disconnect-account,
22
+ // 4. **Write/query handlers**: connect/update/disconnect-account,
23
23
  // ingest-message (programmatic, SystemAdmin), account:list +
24
- // message:list (PII-decrypted, scope-gefiltert).
25
- // 5. **createInboundMailConnectRoutes**: OAuth-Connect + anonymer
26
- // Callback (außerhalb /api/*), state HMAC-signiert.
27
- // 6. **createInboundMailSupervisor**: app-verdrahteter Watch-(IDLE)-
28
- // Supervisor mit Backoff + Reconciliation-Poll.
24
+ // message:list (PII-decrypted, scope-filtered).
25
+ // 5. **createInboundMailConnectRoutes**: OAuth connect + anonymous
26
+ // callback (outside /api/*), with HMAC-signed state.
27
+ // 6. **createInboundMailSupervisor**: app-wired watch (IDLE)
28
+ // supervisor with backoff + reconciliation poll.
29
29
  //
30
- // **Was diese Foundation NICHT macht:**
31
- // - Keine Business-Semantik (Intent, Ticket, Zuweisung, gelesen/
32
- // erledigt) — das gehört dem App-Consumer (z.B. via Event-Job auf
33
- // inbound-message-received + eigener Projection).
34
- // - Kein Body-Blob im Event-Store: rawMime → file-foundation via
35
- // Supervisor-storeBody-Hook, Event trägt nur bodyRef.
36
- // - Kein IMAP-Flag-Write-back (V1) — Inbox-Status lebt beim Consumer.
30
+ // **What this foundation does NOT do:**
31
+ // - No business semantics (intent, ticket, assignment, read/
32
+ // completed) — those belong to the app consumer (for example, via an
33
+ // event job on inbound-message-received + its own projection).
34
+ // - No body blob in the event store: rawMime → file-foundation via
35
+ // the Supervisor-storeBody-Hook; the event carries only bodyRef.
36
+ // - No IMAP flag write-back (V1) — inbox status belongs to the consumer.
37
37
  //
38
38
  // **PII/GDPR:** address/from/to/cc/subject/snippet are `personal: "tenant"`
39
39
  // — encrypted BEFORE every event append (the only write path), event log AND
40
40
  // projections carry ciphertext; tenant-destroy shreds the subject key
41
- // (crypto-shredding, same pattern as billing-foundation #800). The destroy
41
+ // (crypto-shredding, the same pattern as billing-foundation). The destroy
42
42
  // hook additionally archives all streams + deletes the rows.
43
43
  import { defineFeature, EXT_TENANT_DATA } from "@cosmicdrift/kumiko-framework/engine";
44
44
  import { createFileProviderForTenant, } from "@cosmicdrift/kumiko-framework/files";
@@ -64,7 +64,7 @@ export function createInboundMailFoundationFeature() {
64
64
  category: "notifications",
65
65
  recommended: false,
66
66
  });
67
- // EXT_TENANT_DATA-Hook braucht den tenant-lifecycle-Host.
67
+ // The EXT_TENANT_DATA hook requires the tenant-lifecycle host.
68
68
  r.requires({ features: ["tenant-lifecycle"] });
69
69
  // 5 fine-grained domain-events (Payload-Schemas: events.ts).
70
70
  // piiFields: "none" — address/subject/snippet are already ciphertext under the tenant subject key before append (see events.ts).
@@ -86,7 +86,7 @@ export function createInboundMailFoundationFeature() {
86
86
  r.defineEvent(MAIL_THREAD_UPDATED_EVENT_SHORT, mailThreadEventPayloadSchema, {
87
87
  piiFields: "none",
88
88
  });
89
- // Inline projections — apply in derselben TX wie der Append.
89
+ // Inline projections — apply in the same transaction as the append.
90
90
  r.projection({
91
91
  name: "mail-account",
92
92
  source: MAIL_ACCOUNT_AGGREGATE_TYPE,
@@ -126,7 +126,7 @@ export function createInboundMailFoundationFeature() {
126
126
  });
127
127
  // Sync machinery: high-frequency tick state, deliberately NOT
128
128
  // event-sourced — r.storeTable keeps the migration DDL but excludes the
129
- // tables from the projection rebuild (#494/#498 class).
129
+ // tables from the projection rebuild.
130
130
  r.storeTable(syncCursorTable, {
131
131
  reason: "read_side.mail_sync_cursors_direct_write",
132
132
  });
@@ -148,8 +148,8 @@ export function createInboundMailFoundationFeature() {
148
148
  r.screen(mailAccountListScreen);
149
149
  r.screen(mailAccountEditScreen);
150
150
  r.translations({ keys: INBOUND_MAIL_FOUNDATION_I18N });
151
- // Entity-genaue GDPR-Destroy-Hooks — der gdpr-storage-Boot-Validator
152
- // prueft die EXT_TENANT_DATA-Registrierung pro tenant-subject-Entity.
151
+ // Entity-specific GDPR destroy hooks — the gdpr-storage boot validator
152
+ // checks the EXT_TENANT_DATA registration for each tenant-subject entity.
153
153
  r.useExtension(EXT_TENANT_DATA, "mail-account", {
154
154
  destroy: mailAccountTenantDestroyHook,
155
155
  escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
@@ -162,7 +162,7 @@ export function createInboundMailFoundationFeature() {
162
162
  destroy: mailThreadTenantDestroyHook,
163
163
  escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
164
164
  });
165
- // Data-Retention (#957) — perTenant fan-out (one run per tenant, like
165
+ // Data-Retention — perTenant fan-out (one run per tenant, like
166
166
  // data-retention:retention-cleanup): runInboundMailRetention's raw query
167
167
  // helpers need the unfiltered runner, so the handler declares escapeHatch
168
168
  // and reaches for ctx.db.unsafeRaw(). Without this cron, read_inbound_messages
@@ -185,10 +185,10 @@ export function createInboundMailFoundationFeature() {
185
185
  }
186
186
  const T = (await import("@cosmicdrift/kumiko-framework/time")).getTemporal();
187
187
  const retentionDb = ctx.db.unsafeRaw(); // @cast-boundary db-operator — jobs never run inside a DbTx
188
- // Body-Objekte liegen in file-foundation. Provider lazy + memoized —
189
- // heute schreibt der Ingest kein bodyRef (storeBody-Hook ungebunden),
190
- // der Provider wird also nie gebaut. Sobald storeBody wired ist, raeumt
191
- // die Retention die Bodies mit ab.
188
+ // Body objects are stored in file-foundation. The provider is lazy and memoized —
189
+ // ingest currently writes no bodyRef (the storeBody hook is not wired),
190
+ // so the provider is never built. Once storeBody is wired, retention
191
+ // also cleans up the bodies.
192
192
  let providerPromise = null;
193
193
  const deleteBodyObject = async (bodyRef) => {
194
194
  if (!providerPromise) {
@@ -1,13 +1,13 @@
1
- // Geteilter State-Loader für update-account / disconnect-account.
1
+ // Shared state loader for update-account / disconnect-account.
2
2
  //
3
- // Die mail-account-Events sind full-snapshots (Muster billing-foundation:
4
- // "Alle nutzen denselben payload-shape, der event-type taggt was
5
- // passiert ist") — ein Übergangs-Handler lädt den letzten Snapshot,
6
- // merged seine Delta-Felder rein und appendet den neuen Snapshot.
3
+ // mail-account events are full snapshots (following the billing-foundation
4
+ // pattern: "All events use the same payload shape; the event-type identifies
5
+ // what happened") — a transitional handler loads the latest snapshot, merges
6
+ // its delta fields into it, and appends the new snapshot.
7
7
  //
8
- // **PII-Disziplin:** `address` steht im geladenen Payload bereits als
9
- // Ciphertext und wird 1:1 durchkopiert — NIE re-encrypten (würde bei
10
- // fehlendem KMS decrypt erzwingen bzw. Double-Encryption produzieren).
8
+ // **PII discipline:** `address` is already ciphertext in the loaded payload
9
+ // and is copied byte-for-byte — NEVER re-encrypt it (that would require KMS
10
+ // decryption when unavailable or produce double encryption).
11
11
  export async function loadCurrentMailAccountPayload(ctx, accountId) {
12
12
  const events = await ctx.loadAggregate(accountId);
13
13
  const last = events[events.length - 1];
@@ -1,17 +1,16 @@
1
- // connect-account — Tenant-Admin verbindet ein Postfach. Legt den
2
- // mail-account-Stream an (aggregateId = random uuid = accountId =
3
- // Secret-Slot-Key für IMAP-Passwort/OAuth-Refresh-Token).
1
+ // connect-account — A tenant admin connects a mailbox. Creates the
2
+ // mail-account stream (aggregateId = random uuid = accountId =
3
+ // secret-slot key for the IMAP password/OAuth refresh token).
4
4
  //
5
- // **Was hier NICHT passiert:**
6
- // - Kein Secret-Write: IMAP-Credentials laufen über den secrets-Pfad,
7
- // OAuth-Tokens über die generischen /inbound-mail/oauth-Routen —
8
- // beides VOR bzw. NACH diesem Call, nie durch den Handler-Payload
9
- // (Plain-Passwörter gehören nicht in einen Write-Payload, der im
10
- // Dispatcher-Log landen kann).
11
- // - Kein Verbindungs-Test: der Watch-Supervisor probiert den ersten
12
- // fetch und schaltet bei Fehler via update-account auf auth_error —
13
- // der Connect bleibt schnell und offline-fähig (Test-Ergebnis kommt
14
- // asynchron als Status-Übergang).
5
+ // **What does NOT happen here:**
6
+ // - No secret write: IMAP credentials use the secrets path, and OAuth
7
+ // tokens use the generic /inbound-mail/oauth routes—both before or
8
+ // after this call, never in the handler payload (plain passwords must
9
+ // not enter a write payload that can appear in the dispatcher log).
10
+ // - No connection test: the watch supervisor attempts the first fetch
11
+ // and switches to auth_error via update-account on failure—the connect
12
+ // stays fast and offline-capable (the test result arrives asynchronously
13
+ // as a status transition).
15
14
  import { configuredPiiSubjectKms, encryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
16
15
  import { failUnprocessable } from "@cosmicdrift/kumiko-framework/errors";
17
16
  import * as z from "zod";
@@ -19,7 +18,7 @@ import { InboundMailAccountStatuses, InboundMailAuthMethods } from "../constants
19
18
  import { MAIL_ACCOUNT_PII_FIELDS, mailAccountEntity } from "../entities.js";
20
19
  import { MAIL_ACCOUNT_AGGREGATE_TYPE, MAIL_ACCOUNT_CONNECTED_EVENT_QN, } from "../events.js";
21
20
  export const connectAccountSchema = z.object({
22
- /** Provider-Key wie an der Extension registriert ("imap",
21
+ /** Provider key registered with the extension ("imap",
23
22
  * "m365-graph", "gmail-rest"). */
24
23
  provider: z.string().min(1).max(50),
25
24
  authMethod: z.enum([
@@ -28,16 +27,16 @@ export const connectAccountSchema = z.object({
28
27
  InboundMailAuthMethods.oauth,
29
28
  ]),
30
29
  displayName: z.string().max(200),
31
- /** Postfach-Adresse, Plaintext — wird hier encrypted. */
30
+ /** Mailbox address in plaintext; it is encrypted here. */
32
31
  address: z.string().min(1).max(320),
33
- /** "shared" = tenant-geteilt (info@) · "user" = persönliches Postfach
34
- * des Callers (ownerUserId wird aus der Session gezogen, nie aus dem
35
- * Payload — kein Fremd-Claiming). */
32
+ /** "shared" = shared across the tenant (info@) · "user" = the caller's
33
+ * personal mailbox (ownerUserId is taken from the session, never from
34
+ * the payload—preventing claims on another user's mailbox). */
36
35
  scope: z.enum(["shared", "user"]),
37
- /** NUR für den programmatic OAuth-Callback-Pfad (SystemAdmin): dort
38
- * ist der Dispatcher-User ein SystemUser, der echte Owner steht im
39
- * HMAC-verifizierten state. Tenant-Caller dürfen das Feld nicht
40
- * setzen (Fremd-Claiming-Sperre im Handler). */
36
+ /** Only for the programmatic OAuth callback path (SystemAdmin): there,
37
+ * the dispatcher user is a SystemUser and the actual owner is in the
38
+ * HMAC-verified state. Tenant callers must not set this field (the
39
+ * handler prevents claims on another user's mailbox). */
41
40
  ownerUserIdOverride: z.string().max(36).nullable().optional(),
42
41
  });
43
42
  export const connectAccountHandler = {
@@ -58,8 +57,8 @@ export const connectAccountHandler = {
58
57
  : payload.scope === "user"
59
58
  ? event.user.id
60
59
  : null;
61
- // PII-Encrypt der Adresse vor dem append — einziger Write-Pfad auf
62
- // den Stream, deckt Event-Log UND Projection ab (#800-Muster).
60
+ // PII-encrypt the address before the append. This is the only write path to
61
+ // the stream, so it covers both the event log and the projection.
63
62
  const piiKms = configuredPiiSubjectKms();
64
63
  const plainPii = { tenantId, address: payload.address };
65
64
  const encryptedFields = piiKms
@@ -71,8 +70,8 @@ export const connectAccountHandler = {
71
70
  ownerUserId,
72
71
  displayName: payload.displayName,
73
72
  address: encryptedFields.address,
74
- // active ab Connect — der Supervisor greift den Account beim
75
- // nächsten Tick auf und degradiert ihn bei Credential-Fehlern.
73
+ // The account is active upon connection; the supervisor picks it up on
74
+ // the next tick and downgrades it when credentials fail.
76
75
  status: InboundMailAccountStatuses.active,
77
76
  watchState: "idle",
78
77
  };
@@ -1,11 +1,11 @@
1
- // disconnect-account — Tenant-Admin trennt ein Postfach. Stream bleibt
2
- // (Audit-Historie), Status wird disconnected, der Watch-Supervisor
3
- // überspringt den Account ab dem nächsten Tick. Secret-Cleanup (IMAP-
4
- // Passwort/Refresh-Token im Slot accountId) macht der Aufrufer-Flow —
5
- // der Handler fasst den secrets-Pfad nicht an.
1
+ // disconnect-account — A TenantAdmin disconnects a mailbox. The stream is retained
2
+ // for audit history, the status becomes disconnected, and the watch supervisor
3
+ // skips the account starting with the next tick. Secret cleanup (IMAP password/
4
+ // refresh token in the accountId slot) is handled by the caller flow; this handler
5
+ // does not touch the secrets path.
6
6
  //
7
- // Idempotent: disconnect auf bereits disconnected Account ist ein
8
- // success-no-op (kein zweites Event) — Doppelklick-/Retry-freundlich.
7
+ // Idempotent: disconnecting an already disconnected account is a success no-op
8
+ // with no second event, making double-clicks and retries safe.
9
9
  import { failNotFound } from "@cosmicdrift/kumiko-framework/errors";
10
10
  import * as z from "zod";
11
11
  import { InboundMailAccountStatuses } from "../constants.js";