@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.388.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (643) hide show
  1. package/LICENSE +21 -57
  2. package/dist/agent-tools/tool-catalog.js +1 -1
  3. package/dist/agent-tools/tool-dispatch.d.ts +7 -7
  4. package/dist/agent-tools/tool-dispatch.js +9 -9
  5. package/dist/audit/handlers/audit-events.js +1 -1
  6. package/dist/audit/screens.js +1 -1
  7. package/dist/auth-email-password/feature.js +1 -1
  8. package/dist/auth-email-password/handlers/change-password.write.js +3 -3
  9. package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
  10. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
  11. package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
  12. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  13. package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
  14. package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
  15. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
  16. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  17. package/dist/auth-email-password/handlers/login.write.js +1 -1
  18. package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
  19. package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
  20. package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
  21. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  22. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
  23. package/dist/auth-email-password/index.js +5 -5
  24. package/dist/auth-email-password/lockout-store.js +1 -1
  25. package/dist/auth-email-password/seeding.d.ts +42 -45
  26. package/dist/auth-email-password/seeding.js +51 -53
  27. package/dist/auth-email-password/signup-token-store.js +8 -8
  28. package/dist/auth-email-password/testing.js +3 -3
  29. package/dist/auth-email-password/web/auth-client.d.ts +2 -2
  30. package/dist/auth-email-password/web/auth-client.js +36 -37
  31. package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
  32. package/dist/auth-email-password/web/auth-gate.js +15 -16
  33. package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
  34. package/dist/auth-email-password/web/client-plugin.js +4 -5
  35. package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
  36. package/dist/auth-email-password/web/constants.js +3 -3
  37. package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
  38. package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
  39. package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
  40. package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
  41. package/dist/auth-email-password/web/index.js +5 -5
  42. package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
  43. package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
  44. package/dist/auth-email-password/web/login-screen.d.ts +1 -1
  45. package/dist/auth-email-password/web/login-screen.js +2 -3
  46. package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
  47. package/dist/auth-email-password/web/reset-password-screen.js +12 -13
  48. package/dist/auth-email-password/web/session.d.ts +10 -9
  49. package/dist/auth-email-password/web/session.js +28 -29
  50. package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
  51. package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
  52. package/dist/auth-email-password/web/signup-screen.js +13 -13
  53. package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
  54. package/dist/auth-email-password/web/tenant-switcher.js +21 -22
  55. package/dist/auth-email-password/web/use-shell-user.js +12 -13
  56. package/dist/auth-email-password/web/user-menu.d.ts +4 -4
  57. package/dist/auth-email-password/web/user-menu.js +12 -13
  58. package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
  59. package/dist/auth-email-password/web/verify-email-screen.js +9 -10
  60. package/dist/auth-foundation/boot-checks.js +4 -4
  61. package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
  62. package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
  63. package/dist/auth-foundation/types.js +2 -2
  64. package/dist/auth-mfa/feature-exports.d.ts +2 -2
  65. package/dist/auth-mfa/feature.js +8 -0
  66. package/dist/auth-mfa/handlers/disable.write.js +3 -3
  67. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
  68. package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
  69. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
  70. package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
  71. package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
  72. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  73. package/dist/auth-mfa/token-secrets.js +1 -1
  74. package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
  75. package/dist/auth-mfa/web/client-plugin.js +1 -1
  76. package/dist/auth-mfa/web/i18n.js +8 -4
  77. package/dist/auth-mfa/web/index.js +4 -4
  78. package/dist/auth-mfa/web/mfa-client.js +17 -16
  79. package/dist/auth-mfa/web/mfa-code-or-recovery-field.d.ts +11 -0
  80. package/dist/auth-mfa/web/mfa-code-or-recovery-field.js +12 -0
  81. package/dist/auth-mfa/web/mfa-disable-dialog.js +14 -3
  82. package/dist/auth-mfa/web/mfa-regenerate-recovery-dialog.js +14 -3
  83. package/dist/auth-mfa/web/mfa-setup-preauth-screen.js +10 -5
  84. package/dist/auth-mfa/web/mfa-verify-screen.js +32 -11
  85. package/dist/billing-foundation/aggregate-id.d.ts +5 -5
  86. package/dist/billing-foundation/aggregate-id.js +10 -11
  87. package/dist/billing-foundation/checkout-core.d.ts +9 -14
  88. package/dist/billing-foundation/checkout-core.js +24 -39
  89. package/dist/billing-foundation/consumer-protection/confirmation-mail.js +8 -2
  90. package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +1 -0
  91. package/dist/billing-foundation/consumer-protection/consent-gate.js +1 -0
  92. package/dist/billing-foundation/consumer-protection/issue-confirmation.js +9 -3
  93. package/dist/billing-foundation/consumer-protection/mail-notifications.js +3 -1
  94. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.d.ts +4 -2
  95. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.js +6 -5
  96. package/dist/billing-foundation/consumer-protection/termination-record.d.ts +5 -1
  97. package/dist/billing-foundation/consumer-protection/termination-record.js +27 -17
  98. package/dist/billing-foundation/consumer-protection/termination-request.js +12 -7
  99. package/dist/billing-foundation/consumer-protection/termination-revoke.js +12 -7
  100. package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +1 -1
  101. package/dist/billing-foundation/consumer-protection/termination-texts.js +3 -0
  102. package/dist/billing-foundation/consumer-protection/withdrawal-period.d.ts +5 -2
  103. package/dist/billing-foundation/consumer-protection/withdrawal-period.js +8 -9
  104. package/dist/billing-foundation/entities.js +27 -27
  105. package/dist/billing-foundation/events.d.ts +1 -0
  106. package/dist/billing-foundation/events.js +19 -17
  107. package/dist/billing-foundation/feature.js +45 -44
  108. package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
  109. package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
  110. package/dist/billing-foundation/handlers/billing-plans.query.js +35 -5
  111. package/dist/billing-foundation/handlers/create-checkout-session.write.js +19 -17
  112. package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
  113. package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
  114. package/dist/billing-foundation/handlers/plan-switch-preview.query.d.ts +13 -0
  115. package/dist/billing-foundation/handlers/plan-switch-preview.query.js +48 -0
  116. package/dist/billing-foundation/handlers/process-event.write.d.ts +6 -0
  117. package/dist/billing-foundation/handlers/process-event.write.js +28 -22
  118. package/dist/billing-foundation/handlers/start-plan-checkout.write.js +32 -5
  119. package/dist/billing-foundation/handlers/switch-plan.write.d.ts +2 -2
  120. package/dist/billing-foundation/handlers/switch-plan.write.js +56 -64
  121. package/dist/billing-foundation/handlers/sync-subscription.write.js +12 -1
  122. package/dist/billing-foundation/i18n.js +22 -0
  123. package/dist/billing-foundation/index.d.ts +1 -1
  124. package/dist/billing-foundation/plan-catalog.d.ts +21 -5
  125. package/dist/billing-foundation/plan-catalog.js +25 -16
  126. package/dist/billing-foundation/plan-switch.d.ts +12 -0
  127. package/dist/billing-foundation/plan-switch.js +60 -0
  128. package/dist/billing-foundation/projection.d.ts +15 -11
  129. package/dist/billing-foundation/projection.js +38 -37
  130. package/dist/billing-foundation/subscription-tier-sync.js +3 -3
  131. package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
  132. package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
  133. package/dist/billing-foundation/types.d.ts +97 -42
  134. package/dist/billing-foundation/types.js +29 -20
  135. package/dist/billing-foundation/validate-options.js +17 -0
  136. package/dist/billing-foundation/web/billing-plans-panel.js +82 -36
  137. package/dist/billing-foundation/web/checkout-consent-dialog.d.ts +17 -3
  138. package/dist/billing-foundation/web/checkout-consent-dialog.js +14 -10
  139. package/dist/billing-foundation/web/constants.d.ts +4 -0
  140. package/dist/billing-foundation/web/constants.js +4 -0
  141. package/dist/billing-foundation/web/plan-price.d.ts +15 -0
  142. package/dist/billing-foundation/web/plan-price.js +32 -0
  143. package/dist/billing-foundation/web/plan-switch-confirm-dialog.d.ts +15 -0
  144. package/dist/billing-foundation/web/plan-switch-confirm-dialog.js +66 -0
  145. package/dist/cap-counter/aggregate-id.js +8 -9
  146. package/dist/cap-counter/cap-reservation.js +5 -1
  147. package/dist/cap-counter/constants.js +11 -12
  148. package/dist/cap-counter/enforce-cap.d.ts +59 -62
  149. package/dist/cap-counter/enforce-cap.js +49 -49
  150. package/dist/cap-counter/entity.js +29 -29
  151. package/dist/cap-counter/feature.js +34 -35
  152. package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
  153. package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
  154. package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
  155. package/dist/cap-counter/stock-cap-guard.js +8 -2
  156. package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
  157. package/dist/channel-email/feature.js +1 -1
  158. package/dist/channel-email/smtp-transport.d.ts +18 -17
  159. package/dist/channel-email/smtp-transport.js +24 -21
  160. package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
  161. package/dist/compliance-profiles/feature.js +4 -4
  162. package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
  163. package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
  164. package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
  165. package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
  166. package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
  167. package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
  168. package/dist/compliance-profiles/schema/profile-selection.js +18 -23
  169. package/dist/compliance-profiles/seeding.js +14 -15
  170. package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
  171. package/dist/compliance-profiles-ops/index.js +2 -2
  172. package/dist/config/handlers/cascade.query.d.ts +5 -0
  173. package/dist/config/handlers/cascade.query.js +4 -3
  174. package/dist/config/handlers/readiness.query.d.ts +4 -4
  175. package/dist/config/handlers/readiness.query.js +1 -1
  176. package/dist/config/handlers/reencrypt.job.js +4 -5
  177. package/dist/config/handlers/set.write.js +4 -4
  178. package/dist/config/handlers/values.query.d.ts +5 -0
  179. package/dist/config/handlers/values.query.js +4 -3
  180. package/dist/config/resolver.js +4 -4
  181. package/dist/config/table.js +10 -10
  182. package/dist/config/write-helpers.d.ts +1 -0
  183. package/dist/config/write-helpers.js +19 -10
  184. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
  185. package/dist/crypto-shredding/handlers/forget-subject.write.js +25 -21
  186. package/dist/custom-fields/aggregate-id.d.ts +12 -13
  187. package/dist/custom-fields/aggregate-id.js +16 -17
  188. package/dist/custom-fields/entity.js +49 -47
  189. package/dist/custom-fields/events.js +7 -8
  190. package/dist/custom-fields/feature.d.ts +14 -14
  191. package/dist/custom-fields/feature.js +53 -54
  192. package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
  193. package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
  194. package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
  195. package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
  196. package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
  197. package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
  198. package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
  199. package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
  200. package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
  201. package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
  202. package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
  203. package/dist/custom-fields/lib/field-access.js +2 -2
  204. package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
  205. package/dist/custom-fields/lib/quota.js +1 -1
  206. package/dist/custom-fields/lib/value-schema.js +10 -12
  207. package/dist/custom-fields/run-retention.js +3 -3
  208. package/dist/custom-fields/schemas.js +14 -14
  209. package/dist/custom-fields/web/client-plugin.js +2 -5
  210. package/dist/custom-fields/web/constants.js +2 -2
  211. package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
  212. package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
  213. package/dist/custom-fields/wire-for-entity.js +65 -67
  214. package/dist/custom-fields/wire-user-data-rights.js +3 -3
  215. package/dist/data-retention/_internal/parse-override.js +2 -3
  216. package/dist/data-retention/feature.js +11 -18
  217. package/dist/data-retention/handlers/policy-for.query.js +6 -6
  218. package/dist/data-retention/keep-for.d.ts +7 -7
  219. package/dist/data-retention/keep-for.js +15 -15
  220. package/dist/data-retention/override-schema.d.ts +3 -4
  221. package/dist/data-retention/override-schema.js +13 -15
  222. package/dist/data-retention/presets.d.ts +4 -5
  223. package/dist/data-retention/presets.js +18 -23
  224. package/dist/data-retention/resolve-tenant-preset.js +17 -16
  225. package/dist/data-retention/resolver.d.ts +12 -12
  226. package/dist/data-retention/resolver.js +24 -23
  227. package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
  228. package/dist/data-retention/run-retention-cleanup.js +61 -51
  229. package/dist/data-retention/schema/tenant-retention-override.js +13 -11
  230. package/dist/delivery/channel-context.js +6 -3
  231. package/dist/delivery/db/queries/preferences.js +2 -2
  232. package/dist/delivery/delivery-service.js +22 -7
  233. package/dist/delivery/feature.js +2 -2
  234. package/dist/delivery/handlers/log.query.js +1 -1
  235. package/dist/delivery/handlers/preferences.query.d.ts +1 -1
  236. package/dist/delivery/handlers/preferences.query.js +20 -1
  237. package/dist/delivery/handlers/unsubscribe-page-chrome.query.js +1 -1
  238. package/dist/delivery/tables.js +9 -8
  239. package/dist/delivery/unsubscribe-link.d.ts +3 -1
  240. package/dist/delivery/unsubscribe-page-strings.d.ts +1 -0
  241. package/dist/delivery/unsubscribe-page-strings.js +1 -0
  242. package/dist/delivery/unsubscribe-page.d.ts +2 -0
  243. package/dist/delivery/unsubscribe-page.js +5 -0
  244. package/dist/delivery/unsubscribe.js +29 -11
  245. package/dist/document-ingest-foundation/entity.js +4 -4
  246. package/dist/document-ingest-foundation/events.js +2 -2
  247. package/dist/document-ingest-foundation/feature.js +2 -2
  248. package/dist/document-ingest-foundation/pages.js +1 -1
  249. package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
  250. package/dist/feature-toggles/compose-tier-resolver.js +1 -1
  251. package/dist/feature-toggles/feature.js +1 -1
  252. package/dist/feature-toggles/global-feature-state-table.js +1 -1
  253. package/dist/feature-toggles/handlers/registered.query.js +5 -5
  254. package/dist/feature-toggles/toggle-sync-signal.js +1 -1
  255. package/dist/feature-toggles/web/constants.js +1 -1
  256. package/dist/file-derivatives/feature.d.ts +1 -1
  257. package/dist/file-derivatives/feature.js +1 -1
  258. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  259. package/dist/file-derivatives/presets.js +1 -1
  260. package/dist/file-foundation/feature.js +6 -6
  261. package/dist/file-foundation/index.d.ts +1 -1
  262. package/dist/file-foundation/index.js +1 -1
  263. package/dist/file-foundation/read-file-ref-content.d.ts +3 -0
  264. package/dist/file-foundation/read-file-ref-content.js +6 -1
  265. package/dist/file-provider-inmemory/feature.d.ts +1 -1
  266. package/dist/file-provider-inmemory/feature.js +16 -16
  267. package/dist/file-provider-s3/env-named-feature.d.ts +0 -2
  268. package/dist/file-provider-s3/feature.js +16 -16
  269. package/dist/file-provider-s3/lib/s3-provider.js +6 -6
  270. package/dist/files/feature.js +6 -6
  271. package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
  272. package/dist/files-tenant-data/hooks.js +24 -26
  273. package/dist/files-tenant-data/index.js +1 -1
  274. package/dist/folders/feature.d.ts +1 -1
  275. package/dist/folders/web/folder-manager.js +2 -2
  276. package/dist/folders/web/tree.js +5 -5
  277. package/dist/form-draft/db/queries/cleanup.js +3 -3
  278. package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
  279. package/dist/form-draft/decrypt-draft.js +5 -1
  280. package/dist/form-draft/entity.js +3 -3
  281. package/dist/form-draft/feature.js +4 -5
  282. package/dist/form-draft/handlers/discard.write.js +1 -1
  283. package/dist/form-draft/release-file-refs.js +6 -6
  284. package/dist/form-draft/schemas.js +3 -3
  285. package/dist/form-draft/web/constants.js +0 -2
  286. package/dist/host-routing/dispatch.js +11 -20
  287. package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
  288. package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
  289. package/dist/inbound-mail-foundation/connect-routes.js +4 -3
  290. package/dist/inbound-mail-foundation/constants.d.ts +22 -24
  291. package/dist/inbound-mail-foundation/constants.js +30 -33
  292. package/dist/inbound-mail-foundation/entities.d.ts +12 -12
  293. package/dist/inbound-mail-foundation/entities.js +47 -48
  294. package/dist/inbound-mail-foundation/events.d.ts +4 -3
  295. package/dist/inbound-mail-foundation/events.js +50 -47
  296. package/dist/inbound-mail-foundation/feature.js +39 -39
  297. package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
  298. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
  299. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
  300. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
  301. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
  302. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
  303. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
  304. package/dist/inbound-mail-foundation/handlers/update-account.write.d.ts +2 -2
  305. package/dist/inbound-mail-foundation/handlers/update-account.write.js +22 -14
  306. package/dist/inbound-mail-foundation/i18n.js +0 -1
  307. package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
  308. package/dist/inbound-mail-foundation/oauth-state.js +11 -10
  309. package/dist/inbound-mail-foundation/projection.d.ts +4 -4
  310. package/dist/inbound-mail-foundation/projection.js +31 -29
  311. package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
  312. package/dist/inbound-mail-foundation/provider-factory.js +9 -9
  313. package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
  314. package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
  315. package/dist/inbound-mail-foundation/screens.js +0 -3
  316. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
  317. package/dist/inbound-mail-foundation/types.d.ts +49 -49
  318. package/dist/inbound-mail-foundation/types.js +21 -21
  319. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
  320. package/dist/inbound-mail-foundation/watch-supervisor.js +85 -67
  321. package/dist/inbound-provider-imap/credential-document.js +13 -13
  322. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  323. package/dist/inbound-provider-imap/feature.js +42 -40
  324. package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
  325. package/dist/inbound-provider-imap/imap-client.js +20 -19
  326. package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
  327. package/dist/inbound-provider-inmemory/feature.js +19 -19
  328. package/dist/jobs/db/queries/retention.js +2 -2
  329. package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
  330. package/dist/jobs/events.js +1 -1
  331. package/dist/jobs/feature.d.ts +1 -0
  332. package/dist/jobs/feature.js +13 -10
  333. package/dist/jobs/handlers/detail.query.js +4 -4
  334. package/dist/jobs/handlers/list.query.js +1 -1
  335. package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
  336. package/dist/jobs/handlers/reindex-entity.job.js +1 -1
  337. package/dist/jobs/handlers/retry.write.js +1 -1
  338. package/dist/jobs/handlers/tenant-failures.query.d.ts +1 -1
  339. package/dist/jobs/handlers/tenant-failures.query.js +45 -41
  340. package/dist/jobs/handlers/tenant-runs.query.d.ts +1 -1
  341. package/dist/jobs/handlers/tenant-runs.query.js +54 -50
  342. package/dist/jobs/job-instant.js +1 -1
  343. package/dist/jobs/job-run-logger.js +15 -15
  344. package/dist/jobs/job-run-table.js +3 -3
  345. package/dist/jobs/screens.js +1 -1
  346. package/dist/jobs/tenant-job-failure-table.js +1 -1
  347. package/dist/jobs/tenant-job-run-table.js +1 -1
  348. package/dist/ledger/entity.js +5 -5
  349. package/dist/ledger/feature.js +3 -3
  350. package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
  351. package/dist/ledger/recurring.js +12 -12
  352. package/dist/ledger/schemas.js +1 -1
  353. package/dist/ledger/web/constants.js +2 -2
  354. package/dist/ledger/web/index.js +7 -7
  355. package/dist/legal-pages/feature.d.ts +4 -4
  356. package/dist/legal-pages/feature.js +25 -26
  357. package/dist/legal-pages/markdown.js +3 -3
  358. package/dist/legal-pages/web/client-plugin.js +23 -24
  359. package/dist/legal-pages/web/index.js +0 -1
  360. package/dist/mail-foundation/feature.d.ts +5 -5
  361. package/dist/mail-foundation/feature.js +27 -25
  362. package/dist/mail-transport-inmemory/feature.d.ts +4 -4
  363. package/dist/mail-transport-inmemory/feature.js +27 -28
  364. package/dist/mail-transport-smtp/feature.js +20 -20
  365. package/dist/managed-pages/branding.js +6 -6
  366. package/dist/managed-pages/feature.d.ts +26 -26
  367. package/dist/managed-pages/feature.js +34 -34
  368. package/dist/managed-pages/handlers/by-slug.query.js +5 -6
  369. package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
  370. package/dist/managed-pages/handlers/set.write.js +5 -7
  371. package/dist/managed-pages/screens/page-screens.js +11 -11
  372. package/dist/managed-pages/seeding.js +8 -8
  373. package/dist/managed-pages/table.js +13 -12
  374. package/dist/managed-pages/web/client-plugin.d.ts +1 -1
  375. package/dist/managed-pages/web/client-plugin.js +5 -5
  376. package/dist/managed-pages/web/i18n.js +1 -1
  377. package/dist/notes-history/entity.js +4 -4
  378. package/dist/notes-history/feature.d.ts +2 -2
  379. package/dist/notes-history-user-data/hooks.js +1 -1
  380. package/dist/page-render/layout.js +9 -9
  381. package/dist/page-render/markdown.js +11 -11
  382. package/dist/page-render/security-headers.js +7 -6
  383. package/dist/personal-access-tokens/feature.d.ts +1 -1
  384. package/dist/personal-access-tokens/feature.js +9 -5
  385. package/dist/personal-access-tokens/roles.js +2 -2
  386. package/dist/readiness/handlers/status.query.js +3 -3
  387. package/dist/renderer-foundation/api.js +12 -13
  388. package/dist/renderer-foundation/constants.js +2 -2
  389. package/dist/renderer-foundation/feature.js +7 -7
  390. package/dist/renderer-pdf/render-table-pdf.d.ts +1 -1
  391. package/dist/renderer-pdf/render-table-pdf.js +22 -10
  392. package/dist/secrets/feature.js +9 -9
  393. package/dist/secrets/web/constants.js +2 -2
  394. package/dist/seo/feature.js +3 -3
  395. package/dist/sessions/constants.d.ts +1 -1
  396. package/dist/sessions/constants.js +1 -1
  397. package/dist/sessions/feature.d.ts +2 -2
  398. package/dist/sessions/feature.js +12 -8
  399. package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
  400. package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
  401. package/dist/sessions/handlers/revoke.write.js +1 -1
  402. package/dist/sessions/schema/user-session.js +4 -4
  403. package/dist/sessions/screens.js +2 -2
  404. package/dist/sessions/session-callbacks.js +2 -2
  405. package/dist/sessions/session-revoked-event.js +2 -2
  406. package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
  407. package/dist/shared/decrypt-stored-pii.d.ts +1 -0
  408. package/dist/shared/decrypt-stored-pii.js +7 -2
  409. package/dist/shared/encrypt-for-direct-write.js +1 -1
  410. package/dist/shared/index.d.ts +1 -1
  411. package/dist/shared/index.js +1 -1
  412. package/dist/shared/mail-template-body.d.ts +6 -2
  413. package/dist/shared/mail-template-body.js +7 -4
  414. package/dist/shared/map-with-concurrency.js +5 -4
  415. package/dist/shared/parent-visibility.js +2 -2
  416. package/dist/shared/password-hashing.js +1 -1
  417. package/dist/shared/signup-handover.js +1 -2
  418. package/dist/shared/single-use-token-store.js +1 -1
  419. package/dist/step-dispatcher/feature.js +1 -0
  420. package/dist/subscription-dodo/client.d.ts +17 -0
  421. package/dist/subscription-dodo/client.js +31 -0
  422. package/dist/subscription-dodo/constants.d.ts +12 -0
  423. package/dist/subscription-dodo/constants.js +19 -0
  424. package/dist/subscription-dodo/feature.d.ts +37 -0
  425. package/dist/subscription-dodo/feature.js +144 -0
  426. package/dist/subscription-dodo/index.d.ts +2 -0
  427. package/dist/subscription-dodo/index.js +4 -0
  428. package/dist/subscription-dodo/plugin-methods.d.ts +23 -0
  429. package/dist/subscription-dodo/plugin-methods.js +260 -0
  430. package/dist/subscription-dodo/runtime.d.ts +27 -0
  431. package/dist/subscription-dodo/runtime.js +89 -0
  432. package/dist/subscription-dodo/verify-webhook.d.ts +37 -0
  433. package/dist/subscription-dodo/verify-webhook.js +189 -0
  434. package/dist/subscription-mollie/constants.js +15 -17
  435. package/dist/subscription-mollie/feature.d.ts +17 -18
  436. package/dist/subscription-mollie/feature.js +24 -24
  437. package/dist/subscription-mollie/index.js +3 -3
  438. package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
  439. package/dist/subscription-mollie/plugin-methods.js +15 -14
  440. package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
  441. package/dist/subscription-mollie/verify-webhook.js +27 -27
  442. package/dist/subscription-stripe/constants.js +4 -6
  443. package/dist/subscription-stripe/feature.d.ts +14 -14
  444. package/dist/subscription-stripe/feature.js +36 -34
  445. package/dist/subscription-stripe/index.js +6 -6
  446. package/dist/subscription-stripe/plugin-methods.js +18 -18
  447. package/dist/subscription-stripe/runtime.d.ts +1 -1
  448. package/dist/subscription-stripe/runtime.js +8 -7
  449. package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
  450. package/dist/subscription-stripe/verify-webhook.js +59 -61
  451. package/dist/tags/feature.d.ts +3 -3
  452. package/dist/tags/screens.js +1 -1
  453. package/dist/template-resolver/api.d.ts +3 -2
  454. package/dist/template-resolver/api.js +34 -12
  455. package/dist/template-resolver/compile-document-body.js +1 -0
  456. package/dist/template-resolver/feature.js +2 -2
  457. package/dist/template-resolver/handlers/bundle-import.js +3 -3
  458. package/dist/template-resolver/handlers/copy-locale.write.d.ts +5 -1
  459. package/dist/template-resolver/handlers/copy-locale.write.js +22 -7
  460. package/dist/template-resolver/handlers/diff-to-system.query.js +3 -2
  461. package/dist/template-resolver/handlers/document-base.js +3 -2
  462. package/dist/template-resolver/handlers/find-by-id.query.js +8 -7
  463. package/dist/template-resolver/handlers/list.query.js +6 -7
  464. package/dist/template-resolver/handlers/overview.query.d.ts +3 -0
  465. package/dist/template-resolver/handlers/overview.query.js +6 -3
  466. package/dist/template-resolver/handlers/shared.js +2 -2
  467. package/dist/template-resolver/handlers/template-write.js +3 -3
  468. package/dist/template-resolver/handlers/tenant-override-counts.query.js +1 -3
  469. package/dist/template-resolver/handlers/tenant-override-selection.d.ts +2 -1
  470. package/dist/template-resolver/handlers/tenant-overrides.query.js +28 -5
  471. package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
  472. package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
  473. package/dist/template-resolver/handlers/usage.query.d.ts +2 -1
  474. package/dist/template-resolver/handlers/usage.query.js +26 -16
  475. package/dist/template-resolver/handlers/validate.query.js +7 -2
  476. package/dist/template-resolver/seeding.js +30 -14
  477. package/dist/template-resolver/store-template-resource.d.ts +1 -0
  478. package/dist/template-resolver/store-template-resource.js +19 -4
  479. package/dist/template-resolver/table.js +10 -11
  480. package/dist/template-resolver/template-delivery-policy.d.ts +0 -5
  481. package/dist/template-resolver/template-delivery-policy.js +0 -6
  482. package/dist/template-resolver/template-meta.js +7 -4
  483. package/dist/template-resolver/template-preview.js +4 -3
  484. package/dist/template-resolver/web/client-plugin.js +2 -2
  485. package/dist/template-resolver/web/constants.d.ts +2 -2
  486. package/dist/template-resolver/web/constants.js +3 -3
  487. package/dist/template-resolver/web/index.d.ts +1 -0
  488. package/dist/template-resolver/web/index.js +1 -0
  489. package/dist/template-resolver/web/mail-layout-constants.d.ts +5 -0
  490. package/dist/template-resolver/web/mail-layout-constants.js +7 -0
  491. package/dist/tenant/feature.js +7 -7
  492. package/dist/tenant/handlers/member-directory.query.d.ts +1 -0
  493. package/dist/tenant/handlers/member-directory.query.js +11 -4
  494. package/dist/tenant/handlers/members.query.js +1 -1
  495. package/dist/tenant/handlers/team-list.query.js +1 -1
  496. package/dist/tenant/handlers/tenant-directory.query.d.ts +1 -0
  497. package/dist/tenant/handlers/tenant-directory.query.js +9 -5
  498. package/dist/tenant/invitation-table.js +37 -40
  499. package/dist/tenant/membership-table.js +3 -3
  500. package/dist/tenant/schema/tenant.js +7 -9
  501. package/dist/tenant/screens.js +1 -1
  502. package/dist/tenant/seeding.d.ts +6 -5
  503. package/dist/tenant/seeding.js +12 -12
  504. package/dist/tenant/testing.js +5 -6
  505. package/dist/tenant/web/constants.js +2 -2
  506. package/dist/tenant-handover/events.js +5 -7
  507. package/dist/tenant-handover/feature.js +1 -1
  508. package/dist/tenant-handover/grant.js +1 -1
  509. package/dist/tenant-handover/handlers/claim.write.js +1 -1
  510. package/dist/tenant-handover/move-entity-graph.js +8 -9
  511. package/dist/tenant-handover/signup-handover-provider.js +1 -2
  512. package/dist/tenant-handover/transfer-graph.js +4 -5
  513. package/dist/tenant-lifecycle/boot-checks.js +1 -1
  514. package/dist/tenant-lifecycle/constants.d.ts +1 -0
  515. package/dist/tenant-lifecycle/constants.js +4 -0
  516. package/dist/tenant-lifecycle/feature.js +1 -1
  517. package/dist/tenant-lifecycle/run-tenant-destroy.js +2 -2
  518. package/dist/tenant-settings/constants.js +1 -1
  519. package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
  520. package/dist/tenant-settings/tenant-defaults.js +9 -2
  521. package/dist/tier-engine/aggregate-id.d.ts +11 -11
  522. package/dist/tier-engine/aggregate-id.js +15 -16
  523. package/dist/tier-engine/compose-app.d.ts +14 -14
  524. package/dist/tier-engine/compose-app.js +1 -1
  525. package/dist/tier-engine/entity.js +18 -19
  526. package/dist/tier-engine/feature.d.ts +19 -17
  527. package/dist/tier-engine/feature.js +68 -69
  528. package/dist/tier-engine/handlers/active-tier.query.js +6 -7
  529. package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
  530. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +7 -8
  531. package/dist/tier-engine/handlers/set-tenant-tier.write.js +7 -4
  532. package/dist/tier-engine/tier-resolver.js +2 -2
  533. package/dist/tier-engine/trial.js +8 -8
  534. package/dist/tier-engine/web/constants.js +2 -2
  535. package/dist/tier-engine/web/index.js +4 -4
  536. package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
  537. package/dist/user/handlers/create.write.js +4 -4
  538. package/dist/user/schema/user.d.ts +11 -11
  539. package/dist/user/schema/user.js +45 -44
  540. package/dist/user/seeding.d.ts +15 -15
  541. package/dist/user/seeding.js +28 -28
  542. package/dist/user/testing.js +3 -3
  543. package/dist/user-data-rights/audit-download.d.ts +8 -8
  544. package/dist/user-data-rights/audit-download.js +19 -20
  545. package/dist/user-data-rights/boot-checks.js +1 -1
  546. package/dist/user-data-rights/deletion-token.js +1 -1
  547. package/dist/user-data-rights/feature.d.ts +49 -50
  548. package/dist/user-data-rights/feature.js +54 -53
  549. package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
  550. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
  551. package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
  552. package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
  553. package/dist/user-data-rights/handlers/export-status.query.js +8 -9
  554. package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
  555. package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
  556. package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
  557. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
  558. package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
  559. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
  560. package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
  561. package/dist/user-data-rights/handlers/request-export.write.js +42 -41
  562. package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
  563. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
  564. package/dist/user-data-rights/index.js +8 -10
  565. package/dist/user-data-rights/lib/default-mailers.js +3 -3
  566. package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
  567. package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
  568. package/dist/user-data-rights/run-export-jobs.js +130 -237
  569. package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
  570. package/dist/user-data-rights/run-forget-cleanup.js +65 -83
  571. package/dist/user-data-rights/run-user-export.d.ts +34 -33
  572. package/dist/user-data-rights/run-user-export.js +55 -57
  573. package/dist/user-data-rights/schema/download-attempt.js +11 -11
  574. package/dist/user-data-rights/schema/download-token.js +37 -41
  575. package/dist/user-data-rights/schema/export-job.d.ts +4 -4
  576. package/dist/user-data-rights/schema/export-job.js +65 -67
  577. package/dist/user-data-rights/token-helpers.d.ts +8 -9
  578. package/dist/user-data-rights/token-helpers.js +21 -25
  579. package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
  580. package/dist/user-data-rights/web/client-plugin.js +1 -1
  581. package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
  582. package/dist/user-data-rights/web/constants.js +1 -1
  583. package/dist/user-data-rights/web/index.js +5 -5
  584. package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
  585. package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
  586. package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
  587. package/dist/user-data-rights/zip-path.d.ts +15 -15
  588. package/dist/user-data-rights/zip-path.js +41 -40
  589. package/dist/user-data-rights-defaults/feature.js +15 -15
  590. package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
  591. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
  592. package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
  593. package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
  594. package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
  595. package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
  596. package/dist/user-profile/handlers/change-email.write.js +13 -13
  597. package/dist/user-profile/index.js +3 -3
  598. package/dist/user-profile/web/client-plugin.js +1 -1
  599. package/dist/user-profile/web/constants.js +1 -1
  600. package/dist/user-profile/web/profile-screen.js +1 -1
  601. package/dist/waitlist/handlers/export-purge.write.js +2 -1
  602. package/dist/waitlist/handlers/submit.write.js +5 -5
  603. package/dist/waitlist/import.d.ts +1 -0
  604. package/dist/waitlist/import.js +4 -0
  605. package/dist/waitlist/legacy-migrate.js +17 -6
  606. package/dist/waitlist/link-on-signup.js +18 -6
  607. package/dist/waitlist/options.d.ts +3 -0
  608. package/dist/workflow-runner/aggregate-id.d.ts +1 -1
  609. package/dist/workflow-runner/aggregate-id.js +1 -1
  610. package/dist/workflow-runner/event-subscriber.js +4 -5
  611. package/dist/workflow-runner/event-trigger.js +4 -17
  612. package/dist/workflow-runner/feature.js +2 -2
  613. package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
  614. package/dist/workflow-runner/pending-projection.js +6 -7
  615. package/dist/workflow-runner/runner.js +6 -6
  616. package/dist/workflow-runner/tables.js +6 -6
  617. package/dist/workflow-runner/workflow-registry.js +1 -1
  618. package/package.json +20 -10
  619. package/src/agent-tools/changes.json +6 -0
  620. package/src/audit/changes.json +12 -0
  621. package/src/auth-mfa/changes.json +6 -0
  622. package/src/billing-foundation/changes.json +55 -0
  623. package/src/cap-counter/changes.json +18 -0
  624. package/src/channel-email/changes.json +6 -0
  625. package/src/config/changes.json +12 -0
  626. package/src/crypto-shredding/changes.json +6 -0
  627. package/src/delivery/changes.json +30 -0
  628. package/src/form-draft/changes.json +6 -0
  629. package/src/host-routing/changes.json +6 -0
  630. package/src/inbound-mail-foundation/changes.json +18 -0
  631. package/src/jobs/changes.json +13 -0
  632. package/src/mail-foundation/changes.json +6 -0
  633. package/src/renderer-pdf/changes.json +6 -0
  634. package/src/step-dispatcher/changes.json +6 -0
  635. package/src/subscription-dodo/changes.json +14 -0
  636. package/src/subscription-stripe/changes.json +12 -0
  637. package/src/template-resolver/changes.json +48 -0
  638. package/src/tenant/changes.json +6 -0
  639. package/src/tenant-lifecycle/changes.json +6 -0
  640. package/src/tier-engine/changes.json +6 -0
  641. package/src/waitlist/changes.json +18 -0
  642. package/dist/billing-foundation/consumer-protection/stored-user-email.d.ts +0 -1
  643. package/dist/billing-foundation/consumer-protection/stored-user-email.js +0 -8
@@ -1,24 +1,24 @@
1
- // ingest-message — programmatic entry-point für Provider-Plugins
2
- // (watch-callback + fetchSince-Sync). Nimmt eine normalisierte
3
- // RawInboundMessage und macht atomic in EINER TX:
1
+ // ingest-message — programmatic entry point for provider plugins
2
+ // (watch callback + fetchSince sync). Accepts a normalized
3
+ // RawInboundMessage and performs atomically in ONE TX:
4
4
  //
5
- // 1. Idempotency-Check (cheap: store_mail_seen_messages; Defense-in-
6
- // depth: Stream-Existenz auf der deterministic aggregateId).
7
- // 2. threadKey-Normalisierung (Provider-Thread-ID bevorzugt, sonst
8
- // References-Chain-Root, sonst Message-ID = Single-Message-Thread).
9
- // 3. PII-Encrypt (from/to/cc/subject/snippet) VOR dem append —
10
- // Event-Log UND Projection tragen Ciphertext (#800-Muster).
11
- // 4. inbound-message-received-append (Inline-Projection schreibt
12
- // read_inbound_messages in derselben TX). Savepoint-scoped
5
+ // 1. Idempotency check (cheap: store_mail_seen_messages; defense in
6
+ // depth: stream existence check on the deterministic aggregateId).
7
+ // 2. threadKey normalization (provider thread ID preferred, otherwise
8
+ // References chain root, otherwise Message-ID = single-message thread).
9
+ // 3. PII encryption (from/to/cc/subject/snippet) BEFORE the append —
10
+ // both the event log AND projection contain ciphertext.
11
+ // 4. inbound-message-received append (inline projection writes
12
+ // read_inbound_messages in the same TX). Savepoint-scoped
13
13
  // (ctx.tryAppendEvent) — a losing concurrent ingest for the same
14
14
  // messageAggId returns { duplicate: true } instead of failing the TX.
15
- // 5. Thread-Rollup: mail-thread-updated-append mit neu berechnetem
16
- // Snapshot (count+1, max(lastMessageAt)) — die apply ist ein
17
- // dummer UPSERT.
18
- // 6. seen-message-Dedup-Anchor einfügen.
15
+ // 5. Thread rollup: mail-thread-updated append with a recalculated
16
+ // snapshot (count+1, max(lastMessageAt)) — the apply is a
17
+ // dumb UPSERT.
18
+ // 6. Insert the seen-message deduplication anchor.
19
19
  //
20
- // SystemAdmin-only: Aufrufer ist der Watch/Sync-Supervisor bzw. der
21
- // Poll-Cron mit programmatic SystemUser — nie ein Tenant-Request.
20
+ // SystemAdmin-only: the caller is the watch/sync supervisor or
21
+ // the poll cron with a programmatic SystemUser — never a tenant request.
22
22
  import { configuredPiiSubjectKms, encryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
23
23
  import { acquireNamespacedAdvisoryLock, countWhere } from "@cosmicdrift/kumiko-framework/db";
24
24
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
@@ -29,24 +29,24 @@ import { INBOUND_MESSAGE_PII_FIELDS, inboundMessageEntity, MAIL_THREAD_PII_FIELD
29
29
  import { INBOUND_MESSAGE_AGGREGATE_TYPE, INBOUND_MESSAGE_RECEIVED_EVENT_QN, MAIL_THREAD_AGGREGATE_TYPE, MAIL_THREAD_UPDATED_EVENT_QN, } from "../events.js";
30
30
  import { inboundMessagesProjectionTable } from "../projection.js";
31
31
  // =============================================================================
32
- // Input-Schema — der normalisierte Provider-Output (RawInboundMessage,
33
- // types.ts) + Envelope (accountId/providerName/providerCursor). rawMime
34
- // ist hier bewusst NICHT dabei: der Aufrufer persisted den Body VOR dem
35
- // ingest-Call nach file-foundation und übergibt nur bodyRef — der
36
- // Handler-Payload bleibt blob-frei (Event-Store-Disziplin).
32
+ // Input schema — the normalized provider output (RawInboundMessage,
33
+ // types.ts) plus the envelope (accountId/providerName/providerCursor). rawMime
34
+ // is intentionally excluded: the caller persists the body to
35
+ // file-foundation BEFORE the ingest call and passes only bodyRef — the
36
+ // handler payload remains blob-free (event-store discipline).
37
37
  // =============================================================================
38
38
  export const ingestMessageSchema = z.object({
39
39
  accountId: z.uuid(),
40
- /** Scope-Vererbung vom Account — der Supervisor kennt den
41
- * MailAccountRecord und reicht ownerUserId durch. */
40
+ /** Scope inherited from the account — the supervisor knows the
41
+ * MailAccountRecord and passes ownerUserId through. */
42
42
  ownerUserId: z.string().max(36).nullable(),
43
43
  providerName: z.string().min(1).max(50),
44
- /** Provider-native Message-ID — Idempotency-Anchor mit accountId. */
44
+ /** Provider-native Message-ID — idempotency anchor with accountId. */
45
45
  providerMessageId: z.string().min(1).max(500),
46
- /** RFC-5322 Message-ID ohne <>; null → deterministischer Ersatz. */
46
+ /** RFC-5322 Message-ID without <>; null → deterministic fallback. */
47
47
  messageIdHeader: z.string().min(1).max(500).nullable(),
48
48
  providerThreadId: z.string().min(1).max(500).nullable(),
49
- /** References/In-Reply-To-Chain, älteste zuerst. */
49
+ /** References/In-Reply-To chain, oldest first. */
50
50
  references: z.array(z.string().min(1).max(500)).max(200),
51
51
  from: z.string().min(1).max(2000),
52
52
  to: z.array(z.string().max(2000)).max(200),
@@ -57,18 +57,18 @@ export const ingestMessageSchema = z.object({
57
57
  /** file-foundation-Ref; leer im snippet-only-Mode. */
58
58
  bodyRef: z.string().max(500),
59
59
  scope: z.string().min(1).max(200),
60
- /** Cursor-Snapshot zum Ingest-Zeitpunkt — Debug/Replay, landet in
61
- * metadata.headers, nie im payload. */
60
+ /** Cursor snapshot at ingest time — used for debugging/replay and stored in
61
+ * metadata.headers, never in the payload. */
62
62
  providerCursor: z.string().max(2000),
63
63
  });
64
64
  /**
65
- * threadKey-Normalisierung (Plan §3.2):
66
- * 1. Provider-Thread-ID falls vorhanden — provider-präfixed, damit
67
- * IMAP-References-Keys und Graph-conversationIds nie kollidieren.
68
- * 2. Sonst Root der References-Chain (älteste Message-ID = der
69
- * Thread-Anker, den alle Replies teilen).
70
- * 3. Sonst die eigene Message-ID → Single-Message-Thread; ein späteres
71
- * Reply trägt sie als References-Root und landet im selben Thread.
65
+ * Normalizes threadKey:
66
+ * 1. Use the provider thread ID when present — prefix it with the provider
67
+ * so IMAP References keys and Graph conversationIds never collide.
68
+ * 2. Otherwise use the root of the References chain (the oldest Message-ID,
69
+ * which is the thread anchor shared by all replies).
70
+ * 3. Otherwise use the own Message-ID → single-message thread; a later
71
+ * reply carries it as the References root and joins the same thread.
72
72
  */
73
73
  function buildThreadKey(p, effectiveMessageIdHeader) {
74
74
  if (p.providerThreadId)
@@ -99,12 +99,12 @@ export const ingestMessageHandler = {
99
99
  const tenantId = event.user.tenantId;
100
100
  const messageAggId = inboundMessageAggregateId(payload.accountId, payload.providerMessageId);
101
101
  // ---------------------------------------------------------------
102
- // 1. Idempotency. Cheap path zuerst: Dedup-Anchor-Row. Der
103
- // Stream-Check dahinter ist Defense-in-depth für den Fall dass
104
- // ein früherer ingest NACH dem append aber VOR dem seen-insert
105
- // gestorben ist (kann in einer TX nicht passieren — aber der
106
- // Check ist billig und macht den Handler rebuild-robust falls
107
- // store_mail_seen_messages je getruncated wird).
102
+ // 1. Idempotency. Use the deduplication anchor row first because it is
103
+ // cheap. The stream check afterward provides defense in depth if
104
+ // an earlier ingest died AFTER the append but BEFORE the seen insert
105
+ // (this cannot happen within one TX, but the check is cheap and makes
106
+ // the handler robust to rebuilding if store_mail_seen_messages is
107
+ // ever truncated).
108
108
  // ---------------------------------------------------------------
109
109
  const seenRows = await ctx.db.selectMany(seenMessageTable, {
110
110
  accountId: payload.accountId,
@@ -137,11 +137,10 @@ export const ingestMessageHandler = {
137
137
  const threadKey = buildThreadKey(payload, effectiveMessageIdHeader);
138
138
  const threadAggId = mailThreadAggregateId(tenantId, threadKey);
139
139
  // ---------------------------------------------------------------
140
- // 3. PII-Encrypt. to/cc werden VOR encryption JSON-stringified —
141
- // im Payload steht der Ciphertext-String, nicht das Array
142
- // (primitives only, upcaster-safe). Kein KMS konfiguriert =
143
- // plaintext-passthrough (Engine-off-Verhalten, Muster
144
- // billing-foundation process-event #724/#800).
140
+ // 3. PII encryption. Serialize to/cc as JSON BEFORE encryption so the
141
+ // payload contains a ciphertext string rather than an array
142
+ // (primitives only, upcaster-safe). If no KMS is configured, pass
143
+ // through plaintext (engine-off behavior).
145
144
  // ---------------------------------------------------------------
146
145
  const piiKms = configuredPiiSubjectKms();
147
146
  const messagePlainPii = {
@@ -208,14 +207,14 @@ export const ingestMessageHandler = {
208
207
  // concurrent ingests on the same thread (Watch-Push vs.
209
208
  // Poll-Reconciliation overlap, or two different messages of the
210
209
  // same thread arriving at once) converge on the true count.
211
- // acquireNamespacedAdvisoryLock below (issue #2155) serializes this whole
210
+ // acquireNamespacedAdvisoryLock below serializes this whole
212
211
  // countWhere+append section per threadAggId — transaction-scoped,
213
212
  // so it survives tryAppendEvent's inner SAVEPOINT and releases at
214
213
  // the enclosing TX's commit/rollback. Without it, a concurrent
215
214
  // commit landing between countWhere and tryAppendEvent's own fresh
216
215
  // version-read makes the append succeed with a stale count instead
217
216
  // of a VersionConflictError, so the retry loop below never sees it
218
- // as a conflict to retry (#1229's original gap). Unlike step 4, a
217
+ // as a conflict to retry (the original gap). Unlike step 4, a
219
218
  // lost version-conflict race here must NOT be treated as a no-op
220
219
  // duplicate — skipping would leave this message's contribution to
221
220
  // messageCount/lastMessageAt out of the thread forever. Exhausting
@@ -264,8 +263,8 @@ export const ingestMessageHandler = {
264
263
  });
265
264
  }
266
265
  // ---------------------------------------------------------------
267
- // 6. Dedup-Anchor. Läuft in derselben TX wie die appends — stirbt
268
- // der Handler, rollt alles zusammen zurück.
266
+ // 6. Deduplication anchor. It runs in the same TX as the appends, so
267
+ // if the handler fails, everything is rolled back together.
269
268
  // ---------------------------------------------------------------
270
269
  await ctx.db.insertOne(seenMessageTable, {
271
270
  tenantId,
@@ -1,12 +1,12 @@
1
- // list-accounts — tenant-scoped Liste der verbundenen Postfächer fürs
2
- // Connect-/Settings-UI. PII (address) wird beim Read decrypted (Muster
3
- // billing-foundation list-subscriptions).
1
+ // list-accounts — tenant-scoped list of connected mailboxes for the
2
+ // Connect/Settings UI. PII (address) is decrypted on read, following the
3
+ // billing-foundation list-subscriptions pattern.
4
4
  //
5
- // **Scope-Sichtbarkeit (Plan Entscheidung 2):** shared-Postfächer
6
- // (ownerUserId=null) sieht jeder Berechtigte; persönliche nur der Owner
7
- // selbst + TenantAdmin/SystemAdmin (Compliance-Sicht). Filter läuft
8
- // in-memory nach dem tenant-scoped select — Volumen ist die Anzahl
9
- // verbundener Postfächer eines Tenants (einstellig bis zweistellig).
5
+ // **Scope visibility:** authorized users can see shared mailboxes
6
+ // (ownerUserId=null); personal mailboxes are visible only to their owner,
7
+ // TenantAdmin, or SystemAdmin for compliance access. Filtering runs in memory
8
+ // after the tenant-scoped select because a tenant has only a single- to
9
+ // double-digit number of connected mailboxes.
10
10
  import { configuredPiiSubjectKms, decryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
11
11
  import { MAX_LIST_LIMIT } from "@cosmicdrift/kumiko-framework/engine";
12
12
  import * as z from "zod";
@@ -1,12 +1,12 @@
1
- // list-messages — tenant-scoped Message-Liste (Inbox-Cockpit).
2
- // Optionale Filter: accountId (ein Postfach), threadKey (eine
3
- // Konversation), scope (Folder-Hint). PII (from/to/cc/subject/snippet)
4
- // wird beim Read decrypted; to/cc bleiben JSON-stringified strings —
5
- // der Client parsed sie (dokumentiert im Event-Payload).
1
+ // list-messages — tenant-scoped message list for the inbox cockpit.
2
+ // Optional filters: accountId (one mailbox), threadKey (one conversation),
3
+ // scope (folder hint). PII (from/to/cc/subject/snippet) is decrypted on read;
4
+ // to/cc remain JSON-stringified strings, which the client parses as documented
5
+ // in the event payload.
6
6
  //
7
- // Bewusst KEINE Pagination in V1: die Projection ist tenant-scoped und
8
- // das Inbox-Cockpit lädt begrenzte Zeiträume; ein `limit`-Feld ist
9
- // vorwärtskompatibel ergänzbar ohne den QN zu brechen.
7
+ // Deliberately no pagination in V1: the projection is tenant-scoped and the
8
+ // inbox cockpit loads bounded time ranges; a `limit` field can be added
9
+ // compatibly without breaking the QN.
10
10
  import { configuredPiiSubjectKms, decryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
11
11
  import * as z from "zod";
12
12
  import { INBOUND_MESSAGE_PII_FIELDS } from "../entities.js";
@@ -35,8 +35,8 @@ export const listMessagesQuery = {
35
35
  if (payload.scope)
36
36
  filter["scope"] = payload.scope;
37
37
  const allRows = await ctx.db.selectMany(inboundMessagesProjectionTable, filter);
38
- // Scope-Sichtbarkeit (Plan Entscheidung 2): Messages persönlicher
39
- // Postfächer nur für Owner + TenantAdmin/SystemAdmin.
38
+ // Scope visibility: messages in personal mailboxes are visible only to the
39
+ // owner or TenantAdmin/SystemAdmin.
40
40
  const rows = allRows.filter((row) => isVisibleToCaller(row, ctx.user));
41
41
  const piiKms = configuredPiiSubjectKms();
42
42
  if (!piiKms)
@@ -1,7 +1,6 @@
1
- // Scope-Sichtbarkeit (Plan Entscheidung 2): shared-Rows
2
- // (ownerUserId=null) sieht jeder Berechtigte; persönliche nur der Owner
3
- // selbst + TenantAdmin/SystemAdmin (Compliance-Sicht). Gilt identisch
4
- // für read_mail_accounts und read_inbound_messages (Scope-Vererbung).
1
+ // Scope visibility: shared rows (`ownerUserId=null`) are visible to any authorized caller;
2
+ // personal rows are visible only to the owner, `TenantAdmin`, or `SystemAdmin` for compliance.
3
+ // The same rule applies to `read_mail_accounts` and `read_inbound_messages`.
5
4
  export function isVisibleToCaller(row, user) {
6
5
  const owner = row["ownerUserId"];
7
6
  if (owner == null || owner === "")
@@ -1,4 +1,4 @@
1
- import type { WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
1
+ import { type WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import * as z from "zod";
3
3
  export declare const updateAccountSchema: z.ZodObject<{
4
4
  accountId: z.ZodUUID;
@@ -9,6 +9,6 @@ export declare const updateAccountSchema: z.ZodObject<{
9
9
  }>>;
10
10
  watchState: z.ZodOptional<z.ZodString>;
11
11
  displayName: z.ZodOptional<z.ZodString>;
12
- reason: z.ZodString;
12
+ reason: z.ZodOptional<z.ZodString>;
13
13
  }, z.core.$strip>;
14
14
  export declare const updateAccountHandler: WriteHandlerDef;
@@ -1,7 +1,9 @@
1
- // update-account — Account-Status-Übergänge: Watch-Supervisor meldet
2
- // error/backoff, OAuth-Refresh scheitert (auth_error), Tenant-Admin
3
- // re-enabled nach Credential-Fix. Full-snapshot-Event: lädt den letzten
4
- // Stand, merged die Delta-Felder, appendet den neuen Snapshot.
1
+ // update-account — Account status transitions: the watch supervisor reports
2
+ // error/backoff, OAuth refresh fails (auth_error), or a tenant admin re-enables
3
+ // the account after fixing its credentials. Full-snapshot event: loads the
4
+ // latest state, merges the delta fields, and appends the new snapshot.
5
+ import { ROLES } from "@cosmicdrift/kumiko-framework/auth";
6
+ import { SYSTEM_USER_ID, } from "@cosmicdrift/kumiko-framework/engine";
5
7
  import { failNotFound, failUnprocessable } from "@cosmicdrift/kumiko-framework/errors";
6
8
  import * as z from "zod";
7
9
  import { InboundMailAccountStatuses } from "../constants.js";
@@ -19,10 +21,16 @@ export const updateAccountSchema = z.object({
19
21
  /** Ops-Signal ("idle", "watching", "backoff:3", ...). */
20
22
  watchState: z.string().max(100).optional(),
21
23
  displayName: z.string().max(200).optional(),
22
- /** Audit-Grund für metadata.headers ("watch_supervisor",
23
- * "oauth_refresh", "tenant_admin"). */
24
- reason: z.string().min(1).max(100),
24
+ /** Audit reason for metadata.headers, honored for the system identity only
25
+ * ("watch_supervisor", "oauth_refresh"); user callers get a role-derived reason. */
26
+ reason: z.string().min(1).max(100).optional(),
25
27
  });
28
+ const SYSTEM_FALLBACK_REASON = "system";
29
+ function auditReasonFor(user, requestedReason) {
30
+ if (user.id === SYSTEM_USER_ID)
31
+ return requestedReason ?? SYSTEM_FALLBACK_REASON;
32
+ return user.roles.includes(ROLES.SystemAdmin) ? "system_admin" : "tenant_admin";
33
+ }
26
34
  export const updateAccountHandler = {
27
35
  name: "update-account",
28
36
  schema: updateAccountSchema,
@@ -36,14 +44,14 @@ export const updateAccountHandler = {
36
44
  return failNotFound("mail-account", payload.accountId);
37
45
  }
38
46
  if (current.status === InboundMailAccountStatuses.disconnected) {
39
- // Getrennte Accounts sind final — Re-Enable läuft über einen
40
- // frischen connect (neuer Stream, neuer Secret-Slot). Verhindert
41
- // dass ein nachzügelnder Supervisor-Tick einen disconnected
42
- // Account wieder auf active hebt (Race Disconnect vs. Poll).
47
+ // Disconnected accounts are final; re-enabling requires a fresh connect
48
+ // (new stream, new secret slot). This prevents a delayed supervisor tick
49
+ // from restoring a disconnected account to active (disconnect vs. poll
50
+ // race).
43
51
  return failUnprocessable("account_disconnected", { accountId: payload.accountId });
44
52
  }
45
- // Merge: address/provider/authMethod kommen 1:1 aus dem letzten
46
- // Snapshot (address bleibt Ciphertext — nie re-encrypten).
53
+ // address/provider/authMethod come unchanged from the latest snapshot
54
+ // (address remains ciphertext—never re-encrypt it).
47
55
  const eventPayload = {
48
56
  ...current,
49
57
  ...(payload.status !== undefined ? { status: payload.status } : {}),
@@ -52,7 +60,7 @@ export const updateAccountHandler = {
52
60
  };
53
61
  const headers = {
54
62
  providerName: current.provider,
55
- reason: payload.reason,
63
+ reason: auditReasonFor(event.user, payload.reason),
56
64
  };
57
65
  await ctx.unsafeAppendEvent({
58
66
  aggregateId: payload.accountId,
@@ -31,5 +31,4 @@ export const INBOUND_MAIL_FOUNDATION_I18N = {
31
31
  },
32
32
  [formFieldKey("accountId")]: { en: "Mailbox" },
33
33
  [formFieldKey("displayName")]: { en: "Name" },
34
- [formFieldKey("reason")]: { en: "Reason" },
35
34
  };
@@ -1,14 +1,14 @@
1
1
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
2
2
  export type OAuthStatePayload = {
3
3
  readonly tenantId: string;
4
- /** null = shared-Postfach, sonst persönliches Postfach dieses Users. */
4
+ /** null = shared mailbox; otherwise this user's personal mailbox. */
5
5
  readonly ownerUserId: string | null;
6
6
  readonly providerKey: string;
7
- /** Postfach-Adresse aus dem Connect-Request — landet nach dem
8
- * Token-Exchange im MailAccount. */
7
+ /** Mailbox address from the connect request; after token exchange, it is
8
+ * stored in the MailAccount. */
9
9
  readonly mailbox: string;
10
- /** Einmal-Nonce — macht jeden state einzigartig (kein Replay über
11
- * zwei parallele Connect-Flows hinweg). */
10
+ /** One-time nonce makes each state unique, preventing replay across
11
+ * two parallel connect flows. */
12
12
  readonly nonce: string;
13
13
  };
14
14
  export type VerifyOAuthStateResult = {
@@ -1,14 +1,15 @@
1
- // HMAC-signierter OAuth-`state`-Parameter für den Connect-Flow.
1
+ // HMAC-signed OAuth-`state` parameter for the connect flow.
2
2
  //
3
- // Bindet {tenantId, ownerUserId?, providerKey, mailbox, nonce} an den
4
- // Redirect: der anonyme Callback (außerhalb /api/*) vertraut NUR dem
5
- // verifizierten state — verhindert CSRF und Fremd-Claiming (ein
6
- // Angreifer kann den Callback nicht auf einen fremden Tenant/User
7
- // umbiegen, ohne die Signatur zu brechen).
3
+ // Binds {tenantId, ownerUserId?, providerKey, mailbox, nonce} to the
4
+ // redirect: the anonymous callback (outside /api/*) trusts only the
5
+ // verified state, preventing CSRF and cross-tenant or cross-user claiming
6
+ // because an attacker cannot redirect the callback to another tenant or
7
+ // user without breaking the signature.
8
8
  //
9
9
  // Format: <payload-base64url>.<expiresAtMs>.<hmac-base64url>
10
- // Muster: auth-email-password/signed-token.ts (HMAC-SHA256, purpose im
11
- // HMAC-Input, timing-safe compare, Expiry im Klartext-Segment).
10
+ // Patterned after auth-email-password/signed-token.ts (HMAC-SHA256, purpose
11
+ // in the HMAC input, timing-safe comparison, expiry in the clear-text
12
+ // segment).
12
13
  import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
13
14
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
14
15
  import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
@@ -40,8 +41,8 @@ export function verifyOAuthState(state, secret, now = Temporal.Now.instant()) {
40
41
  const expected = sign(hmacInput(payloadB64, expiresAtMs), secret);
41
42
  const expectedBuf = Buffer.from(expected, "base64url");
42
43
  const providedBuf = Buffer.from(providedSig, "base64url");
43
- // Length-check VOR timingSafeEqual — die würde bei Längen-Mismatch
44
- // werfen, und der Throw selbst leakt via Timing.
44
+ // Check the length before timingSafeEqual: it throws on a length mismatch,
45
+ // and the throw itself leaks information through timing.
45
46
  if (expectedBuf.length !== providedBuf.length)
46
47
  return { ok: false, reason: "bad_signature" };
47
48
  if (!timingSafeEqual(expectedBuf, providedBuf))
@@ -130,12 +130,12 @@ export declare const mailThreadsProjectionTable: import("@cosmicdrift/kumiko-fra
130
130
  }, "tenant">>;
131
131
  /** mail-account-connected → UPSERT full. */
132
132
  export declare const applyMailAccountConnected: import("@cosmicdrift/kumiko-types/projection").SingleStreamApplyFn;
133
- /** mail-account-updated → UPSERT full (status/watchState-Übergänge). */
133
+ /** mail-account-updated → full UPSERT for status/watchState transitions. */
134
134
  export declare const applyMailAccountUpdated: import("@cosmicdrift/kumiko-types/projection").SingleStreamApplyFn;
135
- /** mail-account-disconnected → UPSERT full (payload.status=disconnected).
136
- * Row bleibt (Audit-Sicht in der Account-Liste), Stream bleibt. */
135
+ /** mail-account-disconnected → full UPSERT (payload.status=disconnected).
136
+ * The row and stream remain for audit visibility in the account list. */
137
137
  export declare const applyMailAccountDisconnected: import("@cosmicdrift/kumiko-types/projection").SingleStreamApplyFn;
138
138
  /** inbound-message-received → INSERT ... ON CONFLICT DO NOTHING. */
139
139
  export declare const applyInboundMessageReceived: import("@cosmicdrift/kumiko-types/projection").SingleStreamApplyFn;
140
- /** mail-thread-updated → UPSERT full mit dem Payload-Snapshot. */
140
+ /** mail-thread-updated → full UPSERT with the payload snapshot. */
141
141
  export declare const applyMailThreadUpdated: import("@cosmicdrift/kumiko-types/projection").SingleStreamApplyFn;
@@ -1,26 +1,27 @@
1
- // Inline-projections für die drei event-sourced Streams:
1
+ // Inline projections for the three event-sourced streams:
2
2
  // mail-account → read_mail_accounts (UPSERT, current state)
3
3
  // inbound-message → read_inbound_messages (INSERT-ignore, append-only)
4
- // mail-thread → read_mail_threads (UPSERT, Rollup)
4
+ // mail-thread → read_mail_threads (UPSERT, rollup)
5
5
  //
6
- // Apply läuft in derselben TX wie ctx.unsafeAppendEvent — read-your-
7
- // own-write ohne dispatcher-tick (Muster billing-foundation).
6
+ // Apply runs in the same transaction as ctx.unsafeAppendEvent, providing
7
+ // read-your-own-write without waiting for a dispatcher tick (as in
8
+ // billing-foundation).
8
9
  //
9
- // **Production-deployment caveat** (gleich wie billing-foundation):
10
- // die Tables sind als raw drizzle-pgTable in r.projection registriert,
11
- // NICHT als r.entity — Apps müssen sie in ihre drizzle/generate.ts
12
- // aufnehmen (via *-ProjectionTable-Imports). setupTestStack pusht sie
13
- // automatisch via r.projection.table.
10
+ // **Production-deployment caveat** (same as billing-foundation):
11
+ // The tables are registered as raw drizzle-pgTable instances in r.projection,
12
+ // NOT as r.entity. Apps must include them in their drizzle/generate.ts
13
+ // (via *-ProjectionTable imports). setupTestStack pushes them automatically
14
+ // via r.projection.table.
14
15
  //
15
- // **PII:** die Payload-Felder (address/from/to/cc/subject/snippet)
16
- // kommen bereits als Ciphertext an — encrypted VOR dem append im
17
- // write-handler. Die applies kopieren nur durch; decrypted wird erst
18
- // in den list-queries.
16
+ // **PII:** The payload fields (address/from/to/cc/subject/snippet) already
17
+ // arrive as ciphertext because they are encrypted BEFORE the append in the
18
+ // write handler. The applies only copy them through; decryption happens only
19
+ // in the list queries.
19
20
  import { buildEntityTable, insertOnConflictDoNothing, requireEntityTableMeta, upsertOnConflict, } from "@cosmicdrift/kumiko-framework/db";
20
21
  import { defineApply } from "@cosmicdrift/kumiko-framework/engine";
21
22
  import { inboundMessageEntity, mailAccountEntity, mailThreadEntity } from "./entities.js";
22
- // Drizzle-table-instances aus den entity-shapes — geteilt zwischen
23
- // projection-applies und list-queries (ein column-namespace).
23
+ // Drizzle table instances derived from the entity shapes, shared between
24
+ // projection applies and list queries to provide one column namespace.
24
25
  export const mailAccountsProjectionTable = buildEntityTable("mail-account", mailAccountEntity);
25
26
  export const inboundMessagesProjectionTable = buildEntityTable("inbound-message", inboundMessageEntity);
26
27
  export const mailThreadsProjectionTable = buildEntityTable("mail-thread", mailThreadEntity);
@@ -30,9 +31,10 @@ const mailAccountsProjectionMeta = requireEntityTableMeta(mailAccountsProjection
30
31
  const inboundMessagesProjectionMeta = requireEntityTableMeta(inboundMessagesProjectionTable, "inbound-message");
31
32
  const mailThreadsProjectionMeta = requireEntityTableMeta(mailThreadsProjectionTable, "mail-thread");
32
33
  // =============================================================================
33
- // mail-account — connected/updated/disconnected teilen den payload-shape,
34
- // der event-type taggt was passiert ist. Alle drei UPSERT-full für
35
- // defensive consistency (rebuild-aus-dem-Nichts, out-of-order).
34
+ // mail-account — connected/updated/disconnected share the payload shape;
35
+ // the event type identifies what happened. All three perform a full UPSERT
36
+ // for defensive consistency during from-scratch rebuilds and out-of-order
37
+ // processing.
36
38
  // =============================================================================
37
39
  const applyMailAccountUpsert = defineApply(async (event, tx) => {
38
40
  const p = event.payload;
@@ -57,15 +59,15 @@ const applyMailAccountUpsert = defineApply(async (event, tx) => {
57
59
  });
58
60
  /** mail-account-connected → UPSERT full. */
59
61
  export const applyMailAccountConnected = applyMailAccountUpsert;
60
- /** mail-account-updated → UPSERT full (status/watchState-Übergänge). */
62
+ /** mail-account-updated → full UPSERT for status/watchState transitions. */
61
63
  export const applyMailAccountUpdated = applyMailAccountUpsert;
62
- /** mail-account-disconnected → UPSERT full (payload.status=disconnected).
63
- * Row bleibt (Audit-Sicht in der Account-Liste), Stream bleibt. */
64
+ /** mail-account-disconnected → full UPSERT (payload.status=disconnected).
65
+ * The row and stream remain for audit visibility in the account list. */
64
66
  export const applyMailAccountDisconnected = applyMailAccountUpsert;
65
67
  // =============================================================================
66
- // inbound-message — genau EIN received-event pro Stream (deterministic
67
- // aggregateId). INSERT-ignore: Replays no-op'en auf der PK statt zu
68
- // knallen; es gibt keinen update-Fall.
68
+ // inbound-message — exactly one received event per stream (deterministic
69
+ // aggregateId). INSERT-ignore makes replays no-ops on the primary key;
70
+ // there is no update case.
69
71
  // =============================================================================
70
72
  /** inbound-message-received → INSERT ... ON CONFLICT DO NOTHING. */
71
73
  export const applyInboundMessageReceived = defineApply(async (event, tx) => {
@@ -88,12 +90,12 @@ export const applyInboundMessageReceived = defineApply(async (event, tx) => {
88
90
  });
89
91
  });
90
92
  // =============================================================================
91
- // mail-thread — Rollup pro (tenantId, threadKey). Der write-handler
92
- // berechnet messageCount/lastMessageAt und appendet den updated-event
93
- // mit dem NEUEN Stand — die apply ist ein dummer UPSERT-full (kein
94
- // increment in der apply: Replays wären sonst nicht idempotent).
93
+ // mail-thread — rollup per (tenantId, threadKey). The write handler computes
94
+ // messageCount/lastMessageAt and appends the updated event with the NEW state.
95
+ // The apply performs a full UPSERT rather than incrementing, because
96
+ // replays would otherwise not be idempotent.
95
97
  // =============================================================================
96
- /** mail-thread-updated → UPSERT full mit dem Payload-Snapshot. */
98
+ /** mail-thread-updated → full UPSERT with the payload snapshot. */
97
99
  export const applyMailThreadUpdated = defineApply(async (event, tx) => {
98
100
  const p = event.payload;
99
101
  const mutable = {
@@ -1,7 +1,7 @@
1
1
  import { type InboundMailContext, type InboundMailProviderPlugin, type MailAccountRecord } from "./types.ts";
2
- /** Lookup per Provider-Key ("imap", "m365-graph", ...) — genutzt von den
3
- * OAuth-Connect-Routen, wo noch kein Account existiert. */
2
+ /** Looks up a provider by key ("imap", "m365-graph", ...); used by OAuth
3
+ * connect routes before an account exists. */
4
4
  export declare function resolveInboundProviderForKey(ctx: InboundMailContext, providerKey: string, handlerName?: string): InboundMailProviderPlugin;
5
- /** Lookup für einen konkreten Account — der Standard-Pfad in Poll-Job
6
- * und Watch-Supervisor. */
5
+ /** Looks up the provider for a specific account; the standard path for poll jobs
6
+ * and the watch supervisor. */
7
7
  export declare function resolveInboundProviderForAccount(ctx: InboundMailContext, account: MailAccountRecord, handlerName?: string): InboundMailProviderPlugin;
@@ -1,12 +1,12 @@
1
- // Provider-Factory — Mirror von mail-foundation's createTransportForTenant
2
- // inkl. der drei Fehlerpfade (kein registry / nicht registriert / falsche
3
- // Plugin-Shape). Abweichung zum Outbound-Muster (Plan §1.3): KEIN
4
- // per-Tenant-Config-Selector — der Provider steht pro MailAccount
5
- // (`account.provider`), ein Tenant kann mehrere Provider parallel nutzen.
1
+ // Provider factory — mirrors mail-foundation's createTransportForTenant, including
2
+ // the three error paths (missing registry, unregistered provider, invalid plugin
3
+ // shape). Unlike the outbound pattern, there is no per-tenant config selector:
4
+ // the provider is specified per MailAccount (`account.provider`), so a tenant can
5
+ // use multiple providers in parallel.
6
6
  import { INBOUND_MAIL_FOUNDATION_FEATURE, INBOUND_MAIL_PROVIDER_EXTENSION } from "./constants.js";
7
7
  import { isInboundMailProviderPlugin, } from "./types.js";
8
- /** Lookup per Provider-Key ("imap", "m365-graph", ...) — genutzt von den
9
- * OAuth-Connect-Routen, wo noch kein Account existiert. */
8
+ /** Looks up a provider by key ("imap", "m365-graph", ...); used by OAuth
9
+ * connect routes before an account exists. */
10
10
  export function resolveInboundProviderForKey(ctx, providerKey, handlerName = "inbound-mail-foundation:provider-factory") {
11
11
  if (!ctx.registry) {
12
12
  throw new Error(`${handlerName}: ctx.registry is missing — required to look up registered inbound-mail provider plugins`);
@@ -24,8 +24,8 @@ export function resolveInboundProviderForKey(ctx, providerKey, handlerName = "in
24
24
  }
25
25
  return usage.options;
26
26
  }
27
- /** Lookup für einen konkreten Account — der Standard-Pfad in Poll-Job
28
- * und Watch-Supervisor. */
27
+ /** Looks up the provider for a specific account; the standard path for poll jobs
28
+ * and the watch supervisor. */
29
29
  export function resolveInboundProviderForAccount(ctx, account, handlerName = "inbound-mail-foundation:provider-factory") {
30
30
  return resolveInboundProviderForKey(ctx, account.provider, handlerName);
31
31
  }
@@ -7,12 +7,14 @@ export declare const SEEN_RETENTION_DAYS = 90;
7
7
  export interface InboundRetentionArgs {
8
8
  readonly db: DbRunner;
9
9
  readonly tenantId: TenantId;
10
- /** Now-Injection — Tests pinnen den Wert ohne Date-Mock (Pattern keep-for.ts). */
10
+ /**
11
+ * Injects the current time so tests can pin it without a date mock (pattern from keep-for.ts).
12
+ */
11
13
  readonly now: Instant;
12
14
  readonly messageRetentionDays?: number;
13
15
  readonly seenRetentionDays?: number;
14
- /** Loescht ein file-storage-Body-Objekt per bodyRef-key. Vom Job lazy
15
- * verdrahtet (createFileProviderForTenant). Fehlt = kein Body-Delete. */
16
+ /** Deletes a file-storage body object by bodyRef key. Wired lazily by the job
17
+ * (createFileProviderForTenant); if absent, no body is deleted. */
16
18
  readonly deleteBodyObject?: (bodyRef: string) => Promise<void>;
17
19
  }
18
20
  export interface InboundRetentionReport {