@cosmicdrift/kumiko-samples 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 (530) hide show
  1. package/LICENSE +21 -57
  2. package/README.md +1 -1
  3. package/package.json +2 -2
  4. package/packages/bundled-features/package.json +9 -2
  5. package/packages/bundled-features/src/agent-tools/changes.json +6 -0
  6. package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
  7. package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +9 -9
  8. package/packages/bundled-features/src/audit/changes.json +12 -0
  9. package/packages/bundled-features/src/audit/handlers/audit-events.ts +1 -1
  10. package/packages/bundled-features/src/audit/screens.ts +1 -1
  11. package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
  12. package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
  13. package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
  14. package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
  15. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
  16. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
  17. package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
  18. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  19. package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
  20. package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
  21. package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
  22. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +34 -37
  23. package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
  24. package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
  25. package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
  26. package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
  27. package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
  28. package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
  29. package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
  30. package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
  31. package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
  32. package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
  33. package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
  34. package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
  35. package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
  36. package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
  37. package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
  38. package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
  39. package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
  40. package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
  41. package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
  42. package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
  43. package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
  44. package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
  45. package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
  46. package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
  47. package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
  48. package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
  49. package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
  50. package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
  51. package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
  52. package/packages/bundled-features/src/auth-mfa/changes.json +6 -0
  53. package/packages/bundled-features/src/auth-mfa/feature-exports.ts +2 -2
  54. package/packages/bundled-features/src/auth-mfa/feature.ts +6 -0
  55. package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
  56. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
  57. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
  58. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  59. package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
  60. package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
  61. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  62. package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
  63. package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
  64. package/packages/bundled-features/src/auth-mfa/web/i18n.ts +9 -4
  65. package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
  66. package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
  67. package/packages/bundled-features/src/auth-mfa/web/mfa-code-or-recovery-field.tsx +68 -0
  68. package/packages/bundled-features/src/auth-mfa/web/mfa-disable-dialog.tsx +23 -13
  69. package/packages/bundled-features/src/auth-mfa/web/mfa-regenerate-recovery-dialog.tsx +23 -13
  70. package/packages/bundled-features/src/auth-mfa/web/mfa-setup-preauth-screen.tsx +15 -6
  71. package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +71 -24
  72. package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
  73. package/packages/bundled-features/src/billing-foundation/changes.json +55 -0
  74. package/packages/bundled-features/src/billing-foundation/checkout-core.ts +32 -42
  75. package/packages/bundled-features/src/billing-foundation/consumer-protection/confirmation-mail.ts +8 -2
  76. package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-gate.ts +2 -0
  77. package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +14 -3
  78. package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +3 -4
  79. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-receipt-limit.ts +12 -6
  80. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +35 -19
  81. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +12 -8
  82. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-revoke.ts +14 -8
  83. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +5 -0
  84. package/packages/bundled-features/src/billing-foundation/consumer-protection/withdrawal-period.ts +8 -10
  85. package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
  86. package/packages/bundled-features/src/billing-foundation/events.ts +23 -21
  87. package/packages/bundled-features/src/billing-foundation/feature.ts +45 -44
  88. package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
  89. package/packages/bundled-features/src/billing-foundation/handlers/billing-plans.query.ts +71 -6
  90. package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +19 -17
  91. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
  92. package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
  93. package/packages/bundled-features/src/billing-foundation/handlers/plan-switch-preview.query.ts +65 -0
  94. package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +29 -22
  95. package/packages/bundled-features/src/billing-foundation/handlers/start-plan-checkout.write.ts +44 -8
  96. package/packages/bundled-features/src/billing-foundation/handlers/switch-plan.write.ts +72 -82
  97. package/packages/bundled-features/src/billing-foundation/handlers/sync-subscription.write.ts +14 -1
  98. package/packages/bundled-features/src/billing-foundation/i18n.ts +22 -0
  99. package/packages/bundled-features/src/billing-foundation/index.ts +2 -0
  100. package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +62 -27
  101. package/packages/bundled-features/src/billing-foundation/plan-switch.ts +84 -0
  102. package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
  103. package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
  104. package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
  105. package/packages/bundled-features/src/billing-foundation/types.ts +144 -66
  106. package/packages/bundled-features/src/billing-foundation/validate-options.ts +19 -0
  107. package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +123 -51
  108. package/packages/bundled-features/src/billing-foundation/web/checkout-consent-dialog.tsx +89 -42
  109. package/packages/bundled-features/src/billing-foundation/web/constants.ts +4 -0
  110. package/packages/bundled-features/src/billing-foundation/web/plan-price.ts +55 -0
  111. package/packages/bundled-features/src/billing-foundation/web/plan-switch-confirm-dialog.tsx +224 -0
  112. package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
  113. package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
  114. package/packages/bundled-features/src/cap-counter/cap-reservation.ts +5 -1
  115. package/packages/bundled-features/src/cap-counter/changes.json +18 -0
  116. package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
  117. package/packages/bundled-features/src/cap-counter/enforce-cap.ts +66 -68
  118. package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
  119. package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
  120. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
  121. package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
  122. package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +9 -2
  123. package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
  124. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
  125. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
  126. package/packages/bundled-features/src/channel-email/changes.json +6 -0
  127. package/packages/bundled-features/src/channel-email/feature.ts +1 -1
  128. package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
  129. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
  130. package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
  131. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
  132. package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
  133. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
  134. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
  135. package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
  136. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
  137. package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
  138. package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
  139. package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
  140. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
  141. package/packages/bundled-features/src/config/changes.json +12 -0
  142. package/packages/bundled-features/src/config/handlers/cascade.query.ts +4 -2
  143. package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
  144. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
  145. package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
  146. package/packages/bundled-features/src/config/handlers/values.query.ts +4 -2
  147. package/packages/bundled-features/src/config/resolver.ts +4 -4
  148. package/packages/bundled-features/src/config/table.ts +10 -10
  149. package/packages/bundled-features/src/config/write-helpers.ts +28 -9
  150. package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
  151. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +23 -21
  152. package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
  153. package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
  154. package/packages/bundled-features/src/custom-fields/events.ts +7 -8
  155. package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
  156. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
  157. package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
  158. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
  159. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
  160. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
  161. package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
  162. package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
  163. package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.ts +1 -1
  164. package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
  165. package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -12
  166. package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
  167. package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
  168. package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
  169. package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
  170. package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
  171. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
  172. package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
  173. package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
  174. package/packages/bundled-features/src/data-retention/feature.ts +11 -18
  175. package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
  176. package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
  177. package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
  178. package/packages/bundled-features/src/data-retention/presets.ts +18 -23
  179. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  180. package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
  181. package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
  182. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
  183. package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
  184. package/packages/bundled-features/src/delivery/changes.json +30 -0
  185. package/packages/bundled-features/src/delivery/channel-context.ts +9 -3
  186. package/packages/bundled-features/src/delivery/db/queries/preferences.ts +2 -2
  187. package/packages/bundled-features/src/delivery/delivery-service.ts +35 -5
  188. package/packages/bundled-features/src/delivery/feature.ts +3 -3
  189. package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
  190. package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +20 -1
  191. package/packages/bundled-features/src/delivery/handlers/unsubscribe-page-chrome.query.ts +1 -1
  192. package/packages/bundled-features/src/delivery/tables.ts +9 -8
  193. package/packages/bundled-features/src/delivery/unsubscribe-link.ts +3 -1
  194. package/packages/bundled-features/src/delivery/unsubscribe-page-strings.ts +1 -0
  195. package/packages/bundled-features/src/delivery/unsubscribe-page.ts +6 -0
  196. package/packages/bundled-features/src/delivery/unsubscribe.ts +40 -19
  197. package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
  198. package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
  199. package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
  200. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
  201. package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
  202. package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +4 -4
  203. package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
  204. package/packages/bundled-features/src/feature-toggles/feature.ts +1 -1
  205. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  206. package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
  207. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  208. package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
  209. package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
  210. package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
  211. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  212. package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
  213. package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
  214. package/packages/bundled-features/src/file-foundation/index.ts +1 -0
  215. package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +7 -1
  216. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
  217. package/packages/bundled-features/src/file-provider-s3/env-named-feature.ts +0 -2
  218. package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
  219. package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
  220. package/packages/bundled-features/src/files/README.md +1 -1
  221. package/packages/bundled-features/src/files/feature.ts +6 -6
  222. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
  223. package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
  224. package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
  225. package/packages/bundled-features/src/folders/feature.ts +1 -1
  226. package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
  227. package/packages/bundled-features/src/folders/web/tree.ts +5 -5
  228. package/packages/bundled-features/src/form-draft/changes.json +6 -0
  229. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +3 -3
  230. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
  231. package/packages/bundled-features/src/form-draft/decrypt-draft.ts +4 -1
  232. package/packages/bundled-features/src/form-draft/entity.ts +3 -3
  233. package/packages/bundled-features/src/form-draft/feature.ts +4 -5
  234. package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
  235. package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
  236. package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
  237. package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
  238. package/packages/bundled-features/src/host-routing/README.md +1 -1
  239. package/packages/bundled-features/src/host-routing/changes.json +6 -0
  240. package/packages/bundled-features/src/host-routing/dispatch.ts +16 -17
  241. package/packages/bundled-features/src/host-routing/options.ts +2 -1
  242. package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
  243. package/packages/bundled-features/src/inbound-mail-foundation/changes.json +18 -0
  244. package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
  245. package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
  246. package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
  247. package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
  248. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
  249. package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
  250. package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
  251. package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
  252. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
  253. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
  254. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
  255. package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
  256. package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +27 -15
  257. package/packages/bundled-features/src/inbound-mail-foundation/i18n.ts +0 -1
  258. package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
  259. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
  260. package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
  261. package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
  262. package/packages/bundled-features/src/inbound-mail-foundation/screens.ts +0 -3
  263. package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
  264. package/packages/bundled-features/src/inbound-mail-foundation/types.ts +70 -70
  265. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +101 -84
  266. package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
  267. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
  268. package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
  269. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
  270. package/packages/bundled-features/src/jobs/changes.json +13 -0
  271. package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
  272. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
  273. package/packages/bundled-features/src/jobs/events.ts +1 -1
  274. package/packages/bundled-features/src/jobs/feature.ts +20 -11
  275. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
  276. package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
  277. package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
  278. package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
  279. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  280. package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +45 -40
  281. package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +63 -59
  282. package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
  283. package/packages/bundled-features/src/jobs/job-run-logger.ts +19 -19
  284. package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
  285. package/packages/bundled-features/src/jobs/screens.ts +1 -1
  286. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  287. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  288. package/packages/bundled-features/src/ledger/entity.ts +5 -5
  289. package/packages/bundled-features/src/ledger/feature.ts +3 -3
  290. package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
  291. package/packages/bundled-features/src/ledger/recurring.ts +12 -12
  292. package/packages/bundled-features/src/ledger/schemas.ts +1 -1
  293. package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
  294. package/packages/bundled-features/src/ledger/web/index.ts +7 -7
  295. package/packages/bundled-features/src/legal-pages/README.md +1 -1
  296. package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
  297. package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
  298. package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
  299. package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
  300. package/packages/bundled-features/src/mail-foundation/changes.json +6 -0
  301. package/packages/bundled-features/src/mail-foundation/feature.ts +31 -30
  302. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
  303. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
  304. package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
  305. package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
  306. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
  307. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
  308. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
  309. package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
  310. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
  311. package/packages/bundled-features/src/managed-pages/table.ts +16 -15
  312. package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
  313. package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
  314. package/packages/bundled-features/src/notes-history/entity.ts +4 -4
  315. package/packages/bundled-features/src/notes-history/feature.ts +2 -2
  316. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  317. package/packages/bundled-features/src/page-render/layout.ts +9 -9
  318. package/packages/bundled-features/src/page-render/markdown.ts +11 -11
  319. package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
  320. package/packages/bundled-features/src/personal-access-tokens/feature.ts +9 -6
  321. package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
  322. package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
  323. package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
  324. package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
  325. package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
  326. package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
  327. package/packages/bundled-features/src/renderer-pdf/changes.json +6 -0
  328. package/packages/bundled-features/src/renderer-pdf/render-table-pdf.ts +27 -10
  329. package/packages/bundled-features/src/secrets/feature.ts +9 -9
  330. package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
  331. package/packages/bundled-features/src/seo/feature.ts +3 -3
  332. package/packages/bundled-features/src/sessions/constants.ts +1 -1
  333. package/packages/bundled-features/src/sessions/feature.ts +16 -11
  334. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
  335. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +2 -2
  336. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  337. package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
  338. package/packages/bundled-features/src/sessions/screens.ts +2 -2
  339. package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
  340. package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
  341. package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
  342. package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +11 -1
  343. package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
  344. package/packages/bundled-features/src/shared/index.ts +1 -1
  345. package/packages/bundled-features/src/shared/mail-template-body.ts +10 -3
  346. package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
  347. package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
  348. package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
  349. package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
  350. package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
  351. package/packages/bundled-features/src/step-dispatcher/changes.json +6 -0
  352. package/packages/bundled-features/src/step-dispatcher/feature.ts +1 -0
  353. package/packages/bundled-features/src/subscription-dodo/changes.json +14 -0
  354. package/packages/bundled-features/src/subscription-dodo/client.ts +45 -0
  355. package/packages/bundled-features/src/subscription-dodo/constants.ts +24 -0
  356. package/packages/bundled-features/src/subscription-dodo/feature.ts +207 -0
  357. package/packages/bundled-features/src/subscription-dodo/index.ts +16 -0
  358. package/packages/bundled-features/src/subscription-dodo/plugin-methods.ts +345 -0
  359. package/packages/bundled-features/src/subscription-dodo/runtime.ts +126 -0
  360. package/packages/bundled-features/src/subscription-dodo/verify-webhook.ts +262 -0
  361. package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
  362. package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
  363. package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
  364. package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
  365. package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
  366. package/packages/bundled-features/src/subscription-stripe/changes.json +12 -0
  367. package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
  368. package/packages/bundled-features/src/subscription-stripe/feature.ts +45 -43
  369. package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
  370. package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
  371. package/packages/bundled-features/src/subscription-stripe/runtime.ts +9 -8
  372. package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
  373. package/packages/bundled-features/src/tags/feature.ts +3 -3
  374. package/packages/bundled-features/src/tags/screens.ts +1 -1
  375. package/packages/bundled-features/src/template-resolver/api.ts +41 -14
  376. package/packages/bundled-features/src/template-resolver/changes.json +48 -0
  377. package/packages/bundled-features/src/template-resolver/compile-document-body.ts +1 -0
  378. package/packages/bundled-features/src/template-resolver/feature.ts +2 -2
  379. package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +3 -2
  380. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +27 -5
  381. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +3 -2
  382. package/packages/bundled-features/src/template-resolver/handlers/document-base.ts +3 -2
  383. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +8 -7
  384. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +19 -20
  385. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +15 -5
  386. package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
  387. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
  388. package/packages/bundled-features/src/template-resolver/handlers/tenant-override-counts.query.ts +9 -5
  389. package/packages/bundled-features/src/template-resolver/handlers/tenant-override-selection.ts +8 -6
  390. package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +44 -5
  391. package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
  392. package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
  393. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +37 -26
  394. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +7 -2
  395. package/packages/bundled-features/src/template-resolver/seeding.ts +36 -18
  396. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +22 -4
  397. package/packages/bundled-features/src/template-resolver/table.ts +13 -14
  398. package/packages/bundled-features/src/template-resolver/template-delivery-policy.ts +0 -11
  399. package/packages/bundled-features/src/template-resolver/template-meta.ts +12 -4
  400. package/packages/bundled-features/src/template-resolver/template-preview.ts +11 -3
  401. package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
  402. package/packages/bundled-features/src/template-resolver/web/constants.ts +7 -5
  403. package/packages/bundled-features/src/template-resolver/web/index.ts +7 -0
  404. package/packages/bundled-features/src/template-resolver/web/mail-layout-constants.ts +8 -0
  405. package/packages/bundled-features/src/tenant/changes.json +6 -0
  406. package/packages/bundled-features/src/tenant/feature.ts +7 -7
  407. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +10 -4
  408. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  409. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  410. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  411. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +8 -5
  412. package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
  413. package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
  414. package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
  415. package/packages/bundled-features/src/tenant/screens.ts +1 -1
  416. package/packages/bundled-features/src/tenant/seeding.ts +19 -18
  417. package/packages/bundled-features/src/tenant/testing.ts +5 -6
  418. package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
  419. package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
  420. package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
  421. package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
  422. package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
  423. package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
  424. package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
  425. package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
  426. package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
  427. package/packages/bundled-features/src/tenant-lifecycle/changes.json +6 -0
  428. package/packages/bundled-features/src/tenant-lifecycle/constants.ts +5 -0
  429. package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
  430. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +7 -3
  431. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
  432. package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
  433. package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
  434. package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
  435. package/packages/bundled-features/src/tier-engine/changes.json +6 -0
  436. package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
  437. package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
  438. package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
  439. package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
  440. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
  441. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +12 -9
  442. package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
  443. package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
  444. package/packages/bundled-features/src/tier-engine/web/constants.ts +3 -3
  445. package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
  446. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
  447. package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
  448. package/packages/bundled-features/src/user/schema/user.ts +45 -44
  449. package/packages/bundled-features/src/user/seeding.ts +40 -40
  450. package/packages/bundled-features/src/user/testing.ts +3 -3
  451. package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
  452. package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
  453. package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
  454. package/packages/bundled-features/src/user-data-rights/feature.ts +112 -113
  455. package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
  456. package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
  457. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
  458. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
  459. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
  460. package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
  461. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
  462. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +4 -4
  463. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
  464. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
  465. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
  466. package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
  467. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
  468. package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
  469. package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
  470. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
  471. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +169 -280
  472. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +87 -108
  473. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
  474. package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
  475. package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
  476. package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
  477. package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
  478. package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
  479. package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
  480. package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
  481. package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
  482. package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
  483. package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
  484. package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
  485. package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
  486. package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
  487. package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
  488. package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
  489. package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
  490. package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +1 -1
  491. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
  492. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
  493. package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
  494. package/packages/bundled-features/src/user-profile/index.ts +3 -3
  495. package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
  496. package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
  497. package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
  498. package/packages/bundled-features/src/waitlist/changes.json +18 -0
  499. package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +2 -1
  500. package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +5 -5
  501. package/packages/bundled-features/src/waitlist/import.ts +5 -0
  502. package/packages/bundled-features/src/waitlist/legacy-migrate.ts +22 -3
  503. package/packages/bundled-features/src/waitlist/link-on-signup.ts +20 -10
  504. package/packages/bundled-features/src/waitlist/options.ts +3 -0
  505. package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
  506. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
  507. package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
  508. package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
  509. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
  510. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
  511. package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
  512. package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
  513. package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
  514. package/samples/apps/styleguide/src/features/widgets/i18n.ts +11 -0
  515. package/samples/apps/styleguide/src/features/widgets/web/Widgets.tsx +24 -0
  516. package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-constants.ts +5 -0
  517. package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-features.ts +90 -15
  518. package/samples/apps/use-all-bundled/e2e-billing-gallery/server.ts +16 -6
  519. package/samples/apps/use-all-bundled/feature-manifest.json +120 -3
  520. package/samples/apps/use-all-bundled/src/run-config.ts +9 -3
  521. package/samples/recipes/auth-mfa/README.md +5 -0
  522. package/samples/recipes/auth-mfa/package.json +5 -2
  523. package/samples/recipes/auth-mfa/src/web/confirmation-code-step.tsx +49 -0
  524. package/samples/recipes/auth-mfa/tsconfig.json +8 -0
  525. package/samples/recipes/env-composition/README.md +3 -1
  526. package/samples/recipes/env-composition/src/env.ts +2 -0
  527. package/samples/recipes/legal-pages/README.md +1 -1
  528. package/samples/recipes/rate-limiting/README.md +18 -0
  529. package/samples/recipes/rate-limiting/src/feature.ts +12 -0
  530. package/packages/bundled-features/src/billing-foundation/consumer-protection/stored-user-email.ts +0 -12
@@ -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
 
23
23
  import {
24
24
  configuredPiiSubjectKms,
@@ -49,25 +49,25 @@ import {
49
49
  import { inboundMessagesProjectionTable } from "../projection.ts";
50
50
 
51
51
  // =============================================================================
52
- // Input-Schema — der normalisierte Provider-Output (RawInboundMessage,
53
- // types.ts) + Envelope (accountId/providerName/providerCursor). rawMime
54
- // ist hier bewusst NICHT dabei: der Aufrufer persisted den Body VOR dem
55
- // ingest-Call nach file-foundation und übergibt nur bodyRef — der
56
- // Handler-Payload bleibt blob-frei (Event-Store-Disziplin).
52
+ // Input schema — the normalized provider output (RawInboundMessage,
53
+ // types.ts) plus the envelope (accountId/providerName/providerCursor). rawMime
54
+ // is intentionally excluded: the caller persists the body to
55
+ // file-foundation BEFORE the ingest call and passes only bodyRef — the
56
+ // handler payload remains blob-free (event-store discipline).
57
57
  // =============================================================================
58
58
 
59
59
  export const ingestMessageSchema = z.object({
60
60
  accountId: z.uuid(),
61
- /** Scope-Vererbung vom Account — der Supervisor kennt den
62
- * MailAccountRecord und reicht ownerUserId durch. */
61
+ /** Scope inherited from the account — the supervisor knows the
62
+ * MailAccountRecord and passes ownerUserId through. */
63
63
  ownerUserId: z.string().max(36).nullable(),
64
64
  providerName: z.string().min(1).max(50),
65
- /** Provider-native Message-ID — Idempotency-Anchor mit accountId. */
65
+ /** Provider-native Message-ID — idempotency anchor with accountId. */
66
66
  providerMessageId: z.string().min(1).max(500),
67
- /** RFC-5322 Message-ID ohne <>; null → deterministischer Ersatz. */
67
+ /** RFC-5322 Message-ID without <>; null → deterministic fallback. */
68
68
  messageIdHeader: z.string().min(1).max(500).nullable(),
69
69
  providerThreadId: z.string().min(1).max(500).nullable(),
70
- /** References/In-Reply-To-Chain, älteste zuerst. */
70
+ /** References/In-Reply-To chain, oldest first. */
71
71
  references: z.array(z.string().min(1).max(500)).max(200),
72
72
  from: z.string().min(1).max(2000),
73
73
  to: z.array(z.string().max(2000)).max(200),
@@ -78,20 +78,20 @@ export const ingestMessageSchema = z.object({
78
78
  /** file-foundation-Ref; leer im snippet-only-Mode. */
79
79
  bodyRef: z.string().max(500),
80
80
  scope: z.string().min(1).max(200),
81
- /** Cursor-Snapshot zum Ingest-Zeitpunkt — Debug/Replay, landet in
82
- * metadata.headers, nie im payload. */
81
+ /** Cursor snapshot at ingest time — used for debugging/replay and stored in
82
+ * metadata.headers, never in the payload. */
83
83
  providerCursor: z.string().max(2000),
84
84
  });
85
85
  type IngestMessagePayload = z.infer<typeof ingestMessageSchema>;
86
86
 
87
87
  /**
88
- * threadKey-Normalisierung (Plan §3.2):
89
- * 1. Provider-Thread-ID falls vorhanden — provider-präfixed, damit
90
- * IMAP-References-Keys und Graph-conversationIds nie kollidieren.
91
- * 2. Sonst Root der References-Chain (älteste Message-ID = der
92
- * Thread-Anker, den alle Replies teilen).
93
- * 3. Sonst die eigene Message-ID → Single-Message-Thread; ein späteres
94
- * Reply trägt sie als References-Root und landet im selben Thread.
88
+ * Normalizes threadKey:
89
+ * 1. Use the provider thread ID when present — prefix it with the provider
90
+ * so IMAP References keys and Graph conversationIds never collide.
91
+ * 2. Otherwise use the root of the References chain (the oldest Message-ID,
92
+ * which is the thread anchor shared by all replies).
93
+ * 3. Otherwise use the own Message-ID → single-message thread; a later
94
+ * reply carries it as the References root and joins the same thread.
95
95
  */
96
96
  function buildThreadKey(p: IngestMessagePayload, effectiveMessageIdHeader: string): string {
97
97
  if (p.providerThreadId) return `${p.providerName}:${p.providerThreadId}`.slice(0, 500);
@@ -123,12 +123,12 @@ export const ingestMessageHandler: WriteHandlerDef = {
123
123
  const messageAggId = inboundMessageAggregateId(payload.accountId, payload.providerMessageId);
124
124
 
125
125
  // ---------------------------------------------------------------
126
- // 1. Idempotency. Cheap path zuerst: Dedup-Anchor-Row. Der
127
- // Stream-Check dahinter ist Defense-in-depth für den Fall dass
128
- // ein früherer ingest NACH dem append aber VOR dem seen-insert
129
- // gestorben ist (kann in einer TX nicht passieren — aber der
130
- // Check ist billig und macht den Handler rebuild-robust falls
131
- // store_mail_seen_messages je getruncated wird).
126
+ // 1. Idempotency. Use the deduplication anchor row first because it is
127
+ // cheap. The stream check afterward provides defense in depth if
128
+ // an earlier ingest died AFTER the append but BEFORE the seen insert
129
+ // (this cannot happen within one TX, but the check is cheap and makes
130
+ // the handler robust to rebuilding if store_mail_seen_messages is
131
+ // ever truncated).
132
132
  // ---------------------------------------------------------------
133
133
  const seenRows = await ctx.db.selectMany(seenMessageTable, {
134
134
  accountId: payload.accountId,
@@ -163,11 +163,10 @@ export const ingestMessageHandler: WriteHandlerDef = {
163
163
  const threadAggId = mailThreadAggregateId(tenantId, threadKey);
164
164
 
165
165
  // ---------------------------------------------------------------
166
- // 3. PII-Encrypt. to/cc werden VOR encryption JSON-stringified —
167
- // im Payload steht der Ciphertext-String, nicht das Array
168
- // (primitives only, upcaster-safe). Kein KMS konfiguriert =
169
- // plaintext-passthrough (Engine-off-Verhalten, Muster
170
- // billing-foundation process-event #724/#800).
166
+ // 3. PII encryption. Serialize to/cc as JSON BEFORE encryption so the
167
+ // payload contains a ciphertext string rather than an array
168
+ // (primitives only, upcaster-safe). If no KMS is configured, pass
169
+ // through plaintext (engine-off behavior).
171
170
  // ---------------------------------------------------------------
172
171
  const piiKms = configuredPiiSubjectKms();
173
172
  const messagePlainPii = {
@@ -243,14 +242,14 @@ export const ingestMessageHandler: WriteHandlerDef = {
243
242
  // concurrent ingests on the same thread (Watch-Push vs.
244
243
  // Poll-Reconciliation overlap, or two different messages of the
245
244
  // same thread arriving at once) converge on the true count.
246
- // acquireNamespacedAdvisoryLock below (issue #2155) serializes this whole
245
+ // acquireNamespacedAdvisoryLock below serializes this whole
247
246
  // countWhere+append section per threadAggId — transaction-scoped,
248
247
  // so it survives tryAppendEvent's inner SAVEPOINT and releases at
249
248
  // the enclosing TX's commit/rollback. Without it, a concurrent
250
249
  // commit landing between countWhere and tryAppendEvent's own fresh
251
250
  // version-read makes the append succeed with a stale count instead
252
251
  // of a VersionConflictError, so the retry loop below never sees it
253
- // as a conflict to retry (#1229's original gap). Unlike step 4, a
252
+ // as a conflict to retry (the original gap). Unlike step 4, a
254
253
  // lost version-conflict race here must NOT be treated as a no-op
255
254
  // duplicate — skipping would leave this message's contribution to
256
255
  // messageCount/lastMessageAt out of the thread forever. Exhausting
@@ -315,8 +314,8 @@ export const ingestMessageHandler: WriteHandlerDef = {
315
314
  }
316
315
 
317
316
  // ---------------------------------------------------------------
318
- // 6. Dedup-Anchor. Läuft in derselben TX wie die appends — stirbt
319
- // der Handler, rollt alles zusammen zurück.
317
+ // 6. Deduplication anchor. It runs in the same TX as the appends, so
318
+ // if the handler fails, everything is rolled back together.
320
319
  // ---------------------------------------------------------------
321
320
  await ctx.db.insertOne(seenMessageTable, {
322
321
  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 {
11
11
  configuredPiiSubjectKms,
12
12
  decryptPiiFieldValues,
@@ -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
 
11
11
  import {
12
12
  configuredPiiSubjectKms,
@@ -42,8 +42,8 @@ export const listMessagesQuery: QueryHandlerDef = {
42
42
  if (payload.scope) filter["scope"] = payload.scope;
43
43
 
44
44
  const allRows = await ctx.db.selectMany(inboundMessagesProjectionTable, filter);
45
- // Scope-Sichtbarkeit (Plan Entscheidung 2): Messages persönlicher
46
- // Postfächer nur für Owner + TenantAdmin/SystemAdmin.
45
+ // Scope visibility: messages in personal mailboxes are visible only to the
46
+ // owner or TenantAdmin/SystemAdmin.
47
47
  const rows = allRows.filter((row) => isVisibleToCaller(row, ctx.user));
48
48
  const piiKms = configuredPiiSubjectKms();
49
49
  if (!piiKms) return { rows };
@@ -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
 
6
5
  export function isVisibleToCaller(
7
6
  row: Readonly<Record<string, unknown>>,
@@ -1,9 +1,14 @@
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
5
 
6
- import type { WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
6
+ import { ROLES } from "@cosmicdrift/kumiko-framework/auth";
7
+ import {
8
+ type SessionUser,
9
+ SYSTEM_USER_ID,
10
+ type WriteHandlerDef,
11
+ } from "@cosmicdrift/kumiko-framework/engine";
7
12
  import { failNotFound, failUnprocessable } from "@cosmicdrift/kumiko-framework/errors";
8
13
  import * as z from "zod";
9
14
  import { InboundMailAccountStatuses } from "../constants.ts";
@@ -27,12 +32,19 @@ export const updateAccountSchema = z.object({
27
32
  /** Ops-Signal ("idle", "watching", "backoff:3", ...). */
28
33
  watchState: z.string().max(100).optional(),
29
34
  displayName: z.string().max(200).optional(),
30
- /** Audit-Grund für metadata.headers ("watch_supervisor",
31
- * "oauth_refresh", "tenant_admin"). */
32
- reason: z.string().min(1).max(100),
35
+ /** Audit reason for metadata.headers, honored for the system identity only
36
+ * ("watch_supervisor", "oauth_refresh"); user callers get a role-derived reason. */
37
+ reason: z.string().min(1).max(100).optional(),
33
38
  });
34
39
  type UpdateAccountPayload = z.infer<typeof updateAccountSchema>;
35
40
 
41
+ const SYSTEM_FALLBACK_REASON = "system";
42
+
43
+ function auditReasonFor(user: SessionUser, requestedReason: string | undefined): string {
44
+ if (user.id === SYSTEM_USER_ID) return requestedReason ?? SYSTEM_FALLBACK_REASON;
45
+ return user.roles.includes(ROLES.SystemAdmin) ? "system_admin" : "tenant_admin";
46
+ }
47
+
36
48
  export const updateAccountHandler: WriteHandlerDef = {
37
49
  name: "update-account",
38
50
  schema: updateAccountSchema,
@@ -48,15 +60,15 @@ export const updateAccountHandler: WriteHandlerDef = {
48
60
  return failNotFound("mail-account", payload.accountId);
49
61
  }
50
62
  if (current.status === InboundMailAccountStatuses.disconnected) {
51
- // Getrennte Accounts sind final — Re-Enable läuft über einen
52
- // frischen connect (neuer Stream, neuer Secret-Slot). Verhindert
53
- // dass ein nachzügelnder Supervisor-Tick einen disconnected
54
- // Account wieder auf active hebt (Race Disconnect vs. Poll).
63
+ // Disconnected accounts are final; re-enabling requires a fresh connect
64
+ // (new stream, new secret slot). This prevents a delayed supervisor tick
65
+ // from restoring a disconnected account to active (disconnect vs. poll
66
+ // race).
55
67
  return failUnprocessable("account_disconnected", { accountId: payload.accountId });
56
68
  }
57
69
 
58
- // Merge: address/provider/authMethod kommen 1:1 aus dem letzten
59
- // Snapshot (address bleibt Ciphertext — nie re-encrypten).
70
+ // address/provider/authMethod come unchanged from the latest snapshot
71
+ // (address remains ciphertext—never re-encrypt it).
60
72
  const eventPayload: MailAccountEventPayload = {
61
73
  ...current,
62
74
  ...(payload.status !== undefined ? { status: payload.status } : {}),
@@ -65,7 +77,7 @@ export const updateAccountHandler: WriteHandlerDef = {
65
77
  };
66
78
  const headers: MailAccountEventHeaders = {
67
79
  providerName: current.provider,
68
- reason: payload.reason,
80
+ reason: auditReasonFor(event.user, payload.reason),
69
81
  };
70
82
  await ctx.unsafeAppendEvent({
71
83
  aggregateId: payload.accountId,
@@ -38,5 +38,4 @@ export const INBOUND_MAIL_FOUNDATION_I18N: Readonly<Record<string, { readonly en
38
38
  },
39
39
  [formFieldKey("accountId")]: { en: "Mailbox" },
40
40
  [formFieldKey("displayName")]: { en: "Name" },
41
- [formFieldKey("reason")]: { en: "Reason" },
42
41
  };
@@ -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
 
13
14
  import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
14
15
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
@@ -18,14 +19,14 @@ const STATE_PURPOSE = "inbound-mail-oauth-connect";
18
19
 
19
20
  export type OAuthStatePayload = {
20
21
  readonly tenantId: string;
21
- /** null = shared-Postfach, sonst persönliches Postfach dieses Users. */
22
+ /** null = shared mailbox; otherwise this user's personal mailbox. */
22
23
  readonly ownerUserId: string | null;
23
24
  readonly providerKey: string;
24
- /** Postfach-Adresse aus dem Connect-Request — landet nach dem
25
- * Token-Exchange im MailAccount. */
25
+ /** Mailbox address from the connect request; after token exchange, it is
26
+ * stored in the MailAccount. */
26
27
  readonly mailbox: string;
27
- /** Einmal-Nonce — macht jeden state einzigartig (kein Replay über
28
- * zwei parallele Connect-Flows hinweg). */
28
+ /** One-time nonce makes each state unique, preventing replay across
29
+ * two parallel connect flows. */
29
30
  readonly nonce: string;
30
31
  };
31
32
 
@@ -72,8 +73,8 @@ export function verifyOAuthState(
72
73
  const expected = sign(hmacInput(payloadB64, expiresAtMs), secret);
73
74
  const expectedBuf = Buffer.from(expected, "base64url");
74
75
  const providedBuf = Buffer.from(providedSig, "base64url");
75
- // Length-check VOR timingSafeEqual — die würde bei Längen-Mismatch
76
- // werfen, und der Throw selbst leakt via Timing.
76
+ // Check the length before timingSafeEqual: it throws on a length mismatch,
77
+ // and the throw itself leaks information through timing.
77
78
  if (expectedBuf.length !== providedBuf.length) return { ok: false, reason: "bad_signature" };
78
79
  if (!timingSafeEqual(expectedBuf, providedBuf)) return { ok: false, reason: "bad_signature" };
79
80
 
@@ -1,21 +1,22 @@
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
 
20
21
  import {
21
22
  buildEntityTable,
@@ -32,8 +33,8 @@ import type {
32
33
  MailThreadEventPayload,
33
34
  } from "./events.ts";
34
35
 
35
- // Drizzle-table-instances aus den entity-shapes — geteilt zwischen
36
- // projection-applies und list-queries (ein column-namespace).
36
+ // Drizzle table instances derived from the entity shapes, shared between
37
+ // projection applies and list queries to provide one column namespace.
37
38
  export const mailAccountsProjectionTable = buildEntityTable("mail-account", mailAccountEntity);
38
39
  export const inboundMessagesProjectionTable = buildEntityTable(
39
40
  "inbound-message",
@@ -57,9 +58,10 @@ const mailThreadsProjectionMeta: EntityTableMeta = requireEntityTableMeta(
57
58
  );
58
59
 
59
60
  // =============================================================================
60
- // mail-account — connected/updated/disconnected teilen den payload-shape,
61
- // der event-type taggt was passiert ist. Alle drei UPSERT-full für
62
- // defensive consistency (rebuild-aus-dem-Nichts, out-of-order).
61
+ // mail-account — connected/updated/disconnected share the payload shape;
62
+ // the event type identifies what happened. All three perform a full UPSERT
63
+ // for defensive consistency during from-scratch rebuilds and out-of-order
64
+ // processing.
63
65
  // =============================================================================
64
66
 
65
67
  const applyMailAccountUpsert = defineApply<MailAccountEventPayload>(async (event, tx) => {
@@ -91,16 +93,16 @@ const applyMailAccountUpsert = defineApply<MailAccountEventPayload>(async (event
91
93
 
92
94
  /** mail-account-connected → UPSERT full. */
93
95
  export const applyMailAccountConnected = applyMailAccountUpsert;
94
- /** mail-account-updated → UPSERT full (status/watchState-Übergänge). */
96
+ /** mail-account-updated → full UPSERT for status/watchState transitions. */
95
97
  export const applyMailAccountUpdated = applyMailAccountUpsert;
96
- /** mail-account-disconnected → UPSERT full (payload.status=disconnected).
97
- * Row bleibt (Audit-Sicht in der Account-Liste), Stream bleibt. */
98
+ /** mail-account-disconnected → full UPSERT (payload.status=disconnected).
99
+ * The row and stream remain for audit visibility in the account list. */
98
100
  export const applyMailAccountDisconnected = applyMailAccountUpsert;
99
101
 
100
102
  // =============================================================================
101
- // inbound-message — genau EIN received-event pro Stream (deterministic
102
- // aggregateId). INSERT-ignore: Replays no-op'en auf der PK statt zu
103
- // knallen; es gibt keinen update-Fall.
103
+ // inbound-message — exactly one received event per stream (deterministic
104
+ // aggregateId). INSERT-ignore makes replays no-ops on the primary key;
105
+ // there is no update case.
104
106
  // =============================================================================
105
107
 
106
108
  /** inbound-message-received → INSERT ... ON CONFLICT DO NOTHING. */
@@ -127,13 +129,13 @@ export const applyInboundMessageReceived = defineApply<InboundMessageEventPayloa
127
129
  );
128
130
 
129
131
  // =============================================================================
130
- // mail-thread — Rollup pro (tenantId, threadKey). Der write-handler
131
- // berechnet messageCount/lastMessageAt und appendet den updated-event
132
- // mit dem NEUEN Stand — die apply ist ein dummer UPSERT-full (kein
133
- // increment in der apply: Replays wären sonst nicht idempotent).
132
+ // mail-thread — rollup per (tenantId, threadKey). The write handler computes
133
+ // messageCount/lastMessageAt and appends the updated event with the NEW state.
134
+ // The apply performs a full UPSERT rather than incrementing, because
135
+ // replays would otherwise not be idempotent.
134
136
  // =============================================================================
135
137
 
136
- /** mail-thread-updated → UPSERT full mit dem Payload-Snapshot. */
138
+ /** mail-thread-updated → full UPSERT with the payload snapshot. */
137
139
  export const applyMailThreadUpdated = defineApply<MailThreadEventPayload>(async (event, tx) => {
138
140
  const p = event.payload;
139
141
  const mutable = {
@@ -1,8 +1,8 @@
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
 
7
7
  import { INBOUND_MAIL_FOUNDATION_FEATURE, INBOUND_MAIL_PROVIDER_EXTENSION } from "./constants.ts";
8
8
  import {
@@ -12,8 +12,8 @@ import {
12
12
  type MailAccountRecord,
13
13
  } from "./types.ts";
14
14
 
15
- /** Lookup per Provider-Key ("imap", "m365-graph", ...) — genutzt von den
16
- * OAuth-Connect-Routen, wo noch kein Account existiert. */
15
+ /** Looks up a provider by key ("imap", "m365-graph", ...); used by OAuth
16
+ * connect routes before an account exists. */
17
17
  export function resolveInboundProviderForKey(
18
18
  ctx: InboundMailContext,
19
19
  providerKey: string,
@@ -42,8 +42,8 @@ export function resolveInboundProviderForKey(
42
42
  return usage.options;
43
43
  }
44
44
 
45
- /** Lookup für einen konkreten Account — der Standard-Pfad in Poll-Job
46
- * und Watch-Supervisor. */
45
+ /** Looks up the provider for a specific account; the standard path for poll jobs
46
+ * and the watch supervisor. */
47
47
  export function resolveInboundProviderForAccount(
48
48
  ctx: InboundMailContext,
49
49
  account: MailAccountRecord,