@cosmicdrift/kumiko-samples 0.385.0 → 0.387.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) 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 +2 -2
  5. package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
  6. package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +0 -2
  7. package/packages/bundled-features/src/audit/screens.ts +1 -1
  8. package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
  9. package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
  10. package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
  11. package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
  12. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
  13. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
  14. package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
  15. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  16. package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
  17. package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
  18. package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
  19. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +34 -37
  20. package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
  21. package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
  22. package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
  23. package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
  24. package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
  25. package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
  26. package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
  27. package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
  28. package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
  29. package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
  30. package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
  31. package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
  32. package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
  33. package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
  34. package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
  35. package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
  36. package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
  37. package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
  38. package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
  39. package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
  40. package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
  41. package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
  42. package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
  43. package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
  44. package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
  45. package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
  46. package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
  47. package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
  48. package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
  49. package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
  50. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
  51. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
  52. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  53. package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
  54. package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
  55. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  56. package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
  57. package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
  58. package/packages/bundled-features/src/auth-mfa/web/i18n.ts +3 -3
  59. package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
  60. package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
  61. package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +6 -6
  62. package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
  63. package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
  64. package/packages/bundled-features/src/billing-foundation/events.ts +22 -21
  65. package/packages/bundled-features/src/billing-foundation/feature.ts +42 -43
  66. package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
  67. package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +18 -17
  68. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
  69. package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
  70. package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +20 -20
  71. package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
  72. package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
  73. package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
  74. package/packages/bundled-features/src/billing-foundation/types.ts +64 -65
  75. package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +4 -4
  76. package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
  77. package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
  78. package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
  79. package/packages/bundled-features/src/cap-counter/enforce-cap.ts +64 -67
  80. package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
  81. package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
  82. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
  83. package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
  84. package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +1 -1
  85. package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
  86. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
  87. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
  88. package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
  89. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
  90. package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
  91. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
  92. package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
  93. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
  94. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
  95. package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
  96. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
  97. package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
  98. package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
  99. package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
  100. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
  101. package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
  102. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
  103. package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
  104. package/packages/bundled-features/src/config/resolver.ts +4 -4
  105. package/packages/bundled-features/src/config/table.ts +10 -10
  106. package/packages/bundled-features/src/config/write-helpers.ts +1 -1
  107. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +13 -12
  108. package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
  109. package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
  110. package/packages/bundled-features/src/custom-fields/events.ts +7 -8
  111. package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
  112. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
  113. package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
  114. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
  115. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
  116. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
  117. package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
  118. package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
  119. package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.ts +1 -1
  120. package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
  121. package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -12
  122. package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
  123. package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
  124. package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
  125. package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
  126. package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
  127. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
  128. package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
  129. package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
  130. package/packages/bundled-features/src/data-retention/feature.ts +11 -18
  131. package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
  132. package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
  133. package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
  134. package/packages/bundled-features/src/data-retention/presets.ts +18 -23
  135. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  136. package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
  137. package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
  138. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
  139. package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
  140. package/packages/bundled-features/src/delivery/feature.ts +3 -3
  141. package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
  142. package/packages/bundled-features/src/delivery/tables.ts +9 -8
  143. package/packages/bundled-features/src/delivery/unsubscribe.ts +4 -4
  144. package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
  145. package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
  146. package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
  147. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
  148. package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
  149. package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +4 -4
  150. package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
  151. package/packages/bundled-features/src/feature-toggles/feature.ts +1 -1
  152. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  153. package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
  154. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  155. package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
  156. package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
  157. package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
  158. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  159. package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
  160. package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
  161. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
  162. package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
  163. package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
  164. package/packages/bundled-features/src/files/feature.ts +6 -6
  165. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
  166. package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
  167. package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
  168. package/packages/bundled-features/src/folders/feature.ts +1 -1
  169. package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
  170. package/packages/bundled-features/src/folders/web/tree.ts +5 -5
  171. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
  172. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
  173. package/packages/bundled-features/src/form-draft/entity.ts +3 -3
  174. package/packages/bundled-features/src/form-draft/feature.ts +4 -5
  175. package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
  176. package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
  177. package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
  178. package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
  179. package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
  180. package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
  181. package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
  182. package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
  183. package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
  184. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
  185. package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
  186. package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
  187. package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
  188. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
  189. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
  190. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
  191. package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
  192. package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +11 -11
  193. package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
  194. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
  195. package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
  196. package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
  197. package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
  198. package/packages/bundled-features/src/inbound-mail-foundation/types.ts +66 -67
  199. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +69 -68
  200. package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
  201. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
  202. package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
  203. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
  204. package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
  205. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
  206. package/packages/bundled-features/src/jobs/events.ts +1 -1
  207. package/packages/bundled-features/src/jobs/feature.ts +6 -7
  208. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
  209. package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
  210. package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
  211. package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
  212. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  213. package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
  214. package/packages/bundled-features/src/jobs/job-run-logger.ts +14 -15
  215. package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
  216. package/packages/bundled-features/src/jobs/screens.ts +1 -1
  217. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  218. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  219. package/packages/bundled-features/src/ledger/entity.ts +5 -5
  220. package/packages/bundled-features/src/ledger/feature.ts +3 -3
  221. package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
  222. package/packages/bundled-features/src/ledger/recurring.ts +12 -12
  223. package/packages/bundled-features/src/ledger/schemas.ts +1 -1
  224. package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
  225. package/packages/bundled-features/src/ledger/web/index.ts +7 -7
  226. package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
  227. package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
  228. package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
  229. package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
  230. package/packages/bundled-features/src/mail-foundation/feature.ts +26 -27
  231. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
  232. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
  233. package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
  234. package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
  235. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
  236. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
  237. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
  238. package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
  239. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
  240. package/packages/bundled-features/src/managed-pages/table.ts +16 -15
  241. package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
  242. package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
  243. package/packages/bundled-features/src/notes-history/entity.ts +4 -4
  244. package/packages/bundled-features/src/notes-history/feature.ts +2 -2
  245. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  246. package/packages/bundled-features/src/page-render/layout.ts +9 -9
  247. package/packages/bundled-features/src/page-render/markdown.ts +11 -11
  248. package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
  249. package/packages/bundled-features/src/personal-access-tokens/feature.ts +5 -5
  250. package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
  251. package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
  252. package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
  253. package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
  254. package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
  255. package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
  256. package/packages/bundled-features/src/secrets/feature.ts +9 -9
  257. package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
  258. package/packages/bundled-features/src/seo/feature.ts +3 -3
  259. package/packages/bundled-features/src/sessions/constants.ts +1 -1
  260. package/packages/bundled-features/src/sessions/feature.ts +9 -9
  261. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
  262. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +2 -2
  263. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  264. package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
  265. package/packages/bundled-features/src/sessions/screens.ts +2 -2
  266. package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
  267. package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
  268. package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
  269. package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +1 -1
  270. package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
  271. package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
  272. package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
  273. package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
  274. package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
  275. package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
  276. package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
  277. package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
  278. package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
  279. package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
  280. package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
  281. package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
  282. package/packages/bundled-features/src/subscription-stripe/feature.ts +44 -43
  283. package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
  284. package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
  285. package/packages/bundled-features/src/subscription-stripe/runtime.ts +2 -2
  286. package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
  287. package/packages/bundled-features/src/tags/feature.ts +3 -3
  288. package/packages/bundled-features/src/tags/screens.ts +1 -1
  289. package/packages/bundled-features/src/template-resolver/api.ts +10 -10
  290. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +5 -5
  291. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
  292. package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
  293. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
  294. package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
  295. package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
  296. package/packages/bundled-features/src/template-resolver/seeding.ts +4 -4
  297. package/packages/bundled-features/src/template-resolver/table.ts +13 -14
  298. package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
  299. package/packages/bundled-features/src/tenant/feature.ts +7 -7
  300. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
  301. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  302. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  303. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  304. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
  305. package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
  306. package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
  307. package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
  308. package/packages/bundled-features/src/tenant/screens.ts +1 -1
  309. package/packages/bundled-features/src/tenant/seeding.ts +19 -18
  310. package/packages/bundled-features/src/tenant/testing.ts +5 -6
  311. package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
  312. package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
  313. package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
  314. package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
  315. package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
  316. package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
  317. package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
  318. package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
  319. package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
  320. package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
  321. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +2 -2
  322. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
  323. package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
  324. package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
  325. package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
  326. package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
  327. package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
  328. package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
  329. package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
  330. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
  331. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +8 -8
  332. package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
  333. package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
  334. package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
  335. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
  336. package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
  337. package/packages/bundled-features/src/user/schema/user.ts +45 -44
  338. package/packages/bundled-features/src/user/seeding.ts +40 -40
  339. package/packages/bundled-features/src/user/testing.ts +3 -3
  340. package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
  341. package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
  342. package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
  343. package/packages/bundled-features/src/user-data-rights/feature.ts +112 -113
  344. package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
  345. package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
  346. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
  347. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
  348. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
  349. package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
  350. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
  351. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +4 -4
  352. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
  353. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
  354. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
  355. package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
  356. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
  357. package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
  358. package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
  359. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
  360. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +166 -276
  361. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +85 -107
  362. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
  363. package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
  364. package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
  365. package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
  366. package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
  367. package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
  368. package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
  369. package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
  370. package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
  371. package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
  372. package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
  373. package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
  374. package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
  375. package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
  376. package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
  377. package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
  378. package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
  379. package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +1 -1
  380. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
  381. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
  382. package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
  383. package/packages/bundled-features/src/user-profile/index.ts +3 -3
  384. package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
  385. package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
  386. package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
  387. package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
  388. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
  389. package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
  390. package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
  391. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
  392. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
  393. package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
  394. package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
  395. package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
@@ -1,44 +1,44 @@
1
1
  // kumiko-feature-version: 1
2
2
  //
3
- // inbound-mail-foundation — Plugin-Host für eingehende E-Mail
4
- // (Inbox-Föderation). Gegenstück zu mail-foundation (outbound): getrennte
5
- // Extension-Points, getrennter State — Architektur-Vorbild ist
6
- // file-foundation (Foundation besitzt State), nicht mail-transport.
3
+ // inbound-mail-foundation — Plugin host for inbound e-mail
4
+ // (inbox federation). Counterpart to mail-foundation (outbound): separate
5
+ // extension points, separate state — architectural model is
6
+ // file-foundation (the foundation owns state), not mail-transport.
7
7
  //
8
- // **Multi-Provider von Tag 1** (wie billing-foundation): KEIN globaler
9
- // `provider`-config-key. Ein Tenant verbindet parallel IMAP- und (später)
10
- // M365-/Gmail-Postfächer; der Provider steht pro MailAccount.
8
+ // **Multi-provider from day one** (as with billing-foundation): NO global
9
+ // `provider` config key. A tenant can connect IMAP and (later) M365/Gmail
10
+ // mailboxes in parallel; the provider is specified per MailAccount.
11
11
  //
12
- // **Was diese Foundation liefert:**
13
- // 1. **Plugin-API** für Inbound-Provider via r.extendsRegistrar
12
+ // **What this foundation provides:**
13
+ // 1. **Plugin API** for inbound providers via r.extendsRegistrar
14
14
  // ("inboundMailProvider"): verify/fetch/oauth?/watch? (types.ts).
15
- // 2. **3 event-sourced Streams** — mail-account (Lifecycle),
16
- // inbound-message (genau EIN received-Event pro Mail, deterministic
17
- // aggregateId ⇒ exactly-once trotz at-least-once-Ingest),
18
- // mail-thread (Rollup). Volle Historie replay-fähig für spätere
19
- // Consumer (Business-Prozesse: Ticket, Beleg, Auto-Antwort).
20
- // 3. **Inline-Projections** auf read_mail_accounts /
15
+ // 2. **3 event-sourced streams** — mail-account (lifecycle),
16
+ // inbound-message (exactly ONE received event per message, deterministic
17
+ // aggregateId ⇒ exactly-once despite at-least-once ingest),
18
+ // mail-thread (rollup). Full replayable history for later
19
+ // consumers (business processes: ticket, receipt, auto-reply).
20
+ // 3. **Inline projections** into read_mail_accounts /
21
21
  // read_inbound_messages / read_mail_threads (read-your-own-write).
22
- // 4. **Write-/Query-Handler**: connect/update/disconnect-account,
22
+ // 4. **Write/query handlers**: connect/update/disconnect-account,
23
23
  // ingest-message (programmatic, SystemAdmin), account:list +
24
- // message:list (PII-decrypted, scope-gefiltert).
25
- // 5. **createInboundMailConnectRoutes**: OAuth-Connect + anonymer
26
- // Callback (außerhalb /api/*), state HMAC-signiert.
27
- // 6. **createInboundMailSupervisor**: app-verdrahteter Watch-(IDLE)-
28
- // Supervisor mit Backoff + Reconciliation-Poll.
24
+ // message:list (PII-decrypted, scope-filtered).
25
+ // 5. **createInboundMailConnectRoutes**: OAuth connect + anonymous
26
+ // callback (outside /api/*), with HMAC-signed state.
27
+ // 6. **createInboundMailSupervisor**: app-wired watch (IDLE)
28
+ // supervisor with backoff + reconciliation poll.
29
29
  //
30
- // **Was diese Foundation NICHT macht:**
31
- // - Keine Business-Semantik (Intent, Ticket, Zuweisung, gelesen/
32
- // erledigt) — das gehört dem App-Consumer (z.B. via Event-Job auf
33
- // inbound-message-received + eigener Projection).
34
- // - Kein Body-Blob im Event-Store: rawMime → file-foundation via
35
- // Supervisor-storeBody-Hook, Event trägt nur bodyRef.
36
- // - Kein IMAP-Flag-Write-back (V1) — Inbox-Status lebt beim Consumer.
30
+ // **What this foundation does NOT do:**
31
+ // - No business semantics (intent, ticket, assignment, read/
32
+ // completed) — those belong to the app consumer (for example, via an
33
+ // event job on inbound-message-received + its own projection).
34
+ // - No body blob in the event store: rawMime → file-foundation via
35
+ // the Supervisor-storeBody-Hook; the event carries only bodyRef.
36
+ // - No IMAP flag write-back (V1) — inbox status belongs to the consumer.
37
37
  //
38
38
  // **PII/GDPR:** address/from/to/cc/subject/snippet are `personal: "tenant"`
39
39
  // — encrypted BEFORE every event append (the only write path), event log AND
40
40
  // projections carry ciphertext; tenant-destroy shreds the subject key
41
- // (crypto-shredding, same pattern as billing-foundation #800). The destroy
41
+ // (crypto-shredding, the same pattern as billing-foundation). The destroy
42
42
  // hook additionally archives all streams + deletes the rows.
43
43
 
44
44
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
@@ -111,7 +111,7 @@ export function createInboundMailFoundationFeature() {
111
111
  category: "notifications",
112
112
  recommended: false,
113
113
  });
114
- // EXT_TENANT_DATA-Hook braucht den tenant-lifecycle-Host.
114
+ // The EXT_TENANT_DATA hook requires the tenant-lifecycle host.
115
115
  r.requires({ features: ["tenant-lifecycle"] });
116
116
 
117
117
  // 5 fine-grained domain-events (Payload-Schemas: events.ts).
@@ -135,7 +135,7 @@ export function createInboundMailFoundationFeature() {
135
135
  piiFields: "none",
136
136
  });
137
137
 
138
- // Inline projections — apply in derselben TX wie der Append.
138
+ // Inline projections — apply in the same transaction as the append.
139
139
  r.projection({
140
140
  name: "mail-account",
141
141
  source: MAIL_ACCOUNT_AGGREGATE_TYPE,
@@ -177,7 +177,7 @@ export function createInboundMailFoundationFeature() {
177
177
 
178
178
  // Sync machinery: high-frequency tick state, deliberately NOT
179
179
  // event-sourced — r.storeTable keeps the migration DDL but excludes the
180
- // tables from the projection rebuild (#494/#498 class).
180
+ // tables from the projection rebuild.
181
181
  r.storeTable(syncCursorTable, {
182
182
  reason: "read_side.mail_sync_cursors_direct_write",
183
183
  });
@@ -203,8 +203,8 @@ export function createInboundMailFoundationFeature() {
203
203
  r.screen(mailAccountEditScreen);
204
204
  r.translations({ keys: INBOUND_MAIL_FOUNDATION_I18N });
205
205
 
206
- // Entity-genaue GDPR-Destroy-Hooks — der gdpr-storage-Boot-Validator
207
- // prueft die EXT_TENANT_DATA-Registrierung pro tenant-subject-Entity.
206
+ // Entity-specific GDPR destroy hooks — the gdpr-storage boot validator
207
+ // checks the EXT_TENANT_DATA registration for each tenant-subject entity.
208
208
  r.useExtension(EXT_TENANT_DATA, "mail-account", {
209
209
  destroy: mailAccountTenantDestroyHook,
210
210
  escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
@@ -218,7 +218,7 @@ export function createInboundMailFoundationFeature() {
218
218
  escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
219
219
  });
220
220
 
221
- // Data-Retention (#957) — perTenant fan-out (one run per tenant, like
221
+ // Data-Retention — perTenant fan-out (one run per tenant, like
222
222
  // data-retention:retention-cleanup): runInboundMailRetention's raw query
223
223
  // helpers need the unfiltered runner, so the handler declares escapeHatch
224
224
  // and reaches for ctx.db.unsafeRaw(). Without this cron, read_inbound_messages
@@ -245,10 +245,10 @@ export function createInboundMailFoundationFeature() {
245
245
  const T = (await import("@cosmicdrift/kumiko-framework/time")).getTemporal();
246
246
  const retentionDb = ctx.db.unsafeRaw() as DbConnection; // @cast-boundary db-operator — jobs never run inside a DbTx
247
247
 
248
- // Body-Objekte liegen in file-foundation. Provider lazy + memoized —
249
- // heute schreibt der Ingest kein bodyRef (storeBody-Hook ungebunden),
250
- // der Provider wird also nie gebaut. Sobald storeBody wired ist, raeumt
251
- // die Retention die Bodies mit ab.
248
+ // Body objects are stored in file-foundation. The provider is lazy and memoized —
249
+ // ingest currently writes no bodyRef (the storeBody hook is not wired),
250
+ // so the provider is never built. Once storeBody is wired, retention
251
+ // also cleans up the bodies.
252
252
  let providerPromise: Promise<FileStorageProvider> | null = null;
253
253
  const deleteBodyObject = async (bodyRef: string): Promise<void> => {
254
254
  if (!providerPromise) {
@@ -1,13 +1,13 @@
1
- // Geteilter State-Loader für update-account / disconnect-account.
1
+ // Shared state loader for update-account / disconnect-account.
2
2
  //
3
- // Die mail-account-Events sind full-snapshots (Muster billing-foundation:
4
- // "Alle nutzen denselben payload-shape, der event-type taggt was
5
- // passiert ist") — ein Übergangs-Handler lädt den letzten Snapshot,
6
- // merged seine Delta-Felder rein und appendet den neuen Snapshot.
3
+ // mail-account events are full snapshots (following the billing-foundation
4
+ // pattern: "All events use the same payload shape; the event-type identifies
5
+ // what happened") — a transitional handler loads the latest snapshot, merges
6
+ // its delta fields into it, and appends the new snapshot.
7
7
  //
8
- // **PII-Disziplin:** `address` steht im geladenen Payload bereits als
9
- // Ciphertext und wird 1:1 durchkopiert — NIE re-encrypten (würde bei
10
- // fehlendem KMS decrypt erzwingen bzw. Double-Encryption produzieren).
8
+ // **PII discipline:** `address` is already ciphertext in the loaded payload
9
+ // and is copied byte-for-byte — NEVER re-encrypt it (that would require KMS
10
+ // decryption when unavailable or produce double encryption).
11
11
 
12
12
  import type { HandlerContext } from "@cosmicdrift/kumiko-framework/engine";
13
13
  import type { MailAccountEventPayload } from "../events.ts";
@@ -1,17 +1,16 @@
1
- // connect-account — Tenant-Admin verbindet ein Postfach. Legt den
2
- // mail-account-Stream an (aggregateId = random uuid = accountId =
3
- // Secret-Slot-Key für IMAP-Passwort/OAuth-Refresh-Token).
1
+ // connect-account — A tenant admin connects a mailbox. Creates the
2
+ // mail-account stream (aggregateId = random uuid = accountId =
3
+ // secret-slot key for the IMAP password/OAuth refresh token).
4
4
  //
5
- // **Was hier NICHT passiert:**
6
- // - Kein Secret-Write: IMAP-Credentials laufen über den secrets-Pfad,
7
- // OAuth-Tokens über die generischen /inbound-mail/oauth-Routen —
8
- // beides VOR bzw. NACH diesem Call, nie durch den Handler-Payload
9
- // (Plain-Passwörter gehören nicht in einen Write-Payload, der im
10
- // Dispatcher-Log landen kann).
11
- // - Kein Verbindungs-Test: der Watch-Supervisor probiert den ersten
12
- // fetch und schaltet bei Fehler via update-account auf auth_error —
13
- // der Connect bleibt schnell und offline-fähig (Test-Ergebnis kommt
14
- // asynchron als Status-Übergang).
5
+ // **What does NOT happen here:**
6
+ // - No secret write: IMAP credentials use the secrets path, and OAuth
7
+ // tokens use the generic /inbound-mail/oauth routes—both before or
8
+ // after this call, never in the handler payload (plain passwords must
9
+ // not enter a write payload that can appear in the dispatcher log).
10
+ // - No connection test: the watch supervisor attempts the first fetch
11
+ // and switches to auth_error via update-account on failure—the connect
12
+ // stays fast and offline-capable (the test result arrives asynchronously
13
+ // as a status transition).
15
14
 
16
15
  import {
17
16
  configuredPiiSubjectKms,
@@ -30,7 +29,7 @@ import {
30
29
  } from "../events.ts";
31
30
 
32
31
  export const connectAccountSchema = z.object({
33
- /** Provider-Key wie an der Extension registriert ("imap",
32
+ /** Provider key registered with the extension ("imap",
34
33
  * "m365-graph", "gmail-rest"). */
35
34
  provider: z.string().min(1).max(50),
36
35
  authMethod: z.enum([
@@ -39,16 +38,16 @@ export const connectAccountSchema = z.object({
39
38
  InboundMailAuthMethods.oauth,
40
39
  ]),
41
40
  displayName: z.string().max(200),
42
- /** Postfach-Adresse, Plaintext — wird hier encrypted. */
41
+ /** Mailbox address in plaintext; it is encrypted here. */
43
42
  address: z.string().min(1).max(320),
44
- /** "shared" = tenant-geteilt (info@) · "user" = persönliches Postfach
45
- * des Callers (ownerUserId wird aus der Session gezogen, nie aus dem
46
- * Payload — kein Fremd-Claiming). */
43
+ /** "shared" = shared across the tenant (info@) · "user" = the caller's
44
+ * personal mailbox (ownerUserId is taken from the session, never from
45
+ * the payload—preventing claims on another user's mailbox). */
47
46
  scope: z.enum(["shared", "user"]),
48
- /** NUR für den programmatic OAuth-Callback-Pfad (SystemAdmin): dort
49
- * ist der Dispatcher-User ein SystemUser, der echte Owner steht im
50
- * HMAC-verifizierten state. Tenant-Caller dürfen das Feld nicht
51
- * setzen (Fremd-Claiming-Sperre im Handler). */
47
+ /** Only for the programmatic OAuth callback path (SystemAdmin): there,
48
+ * the dispatcher user is a SystemUser and the actual owner is in the
49
+ * HMAC-verified state. Tenant callers must not set this field (the
50
+ * handler prevents claims on another user's mailbox). */
52
51
  ownerUserIdOverride: z.string().max(36).nullable().optional(),
53
52
  });
54
53
  type ConnectAccountPayload = z.infer<typeof connectAccountSchema>;
@@ -75,8 +74,8 @@ export const connectAccountHandler: WriteHandlerDef = {
75
74
  ? event.user.id
76
75
  : null;
77
76
 
78
- // PII-Encrypt der Adresse vor dem append — einziger Write-Pfad auf
79
- // den Stream, deckt Event-Log UND Projection ab (#800-Muster).
77
+ // PII-encrypt the address before the append. This is the only write path to
78
+ // the stream, so it covers both the event log and the projection.
80
79
  const piiKms = configuredPiiSubjectKms();
81
80
  const plainPii = { tenantId, address: payload.address };
82
81
  const encryptedFields = piiKms
@@ -96,8 +95,8 @@ export const connectAccountHandler: WriteHandlerDef = {
96
95
  ownerUserId,
97
96
  displayName: payload.displayName,
98
97
  address: encryptedFields.address,
99
- // active ab Connect — der Supervisor greift den Account beim
100
- // nächsten Tick auf und degradiert ihn bei Credential-Fehlern.
98
+ // The account is active upon connection; the supervisor picks it up on
99
+ // the next tick and downgrades it when credentials fail.
101
100
  status: InboundMailAccountStatuses.active,
102
101
  watchState: "idle",
103
102
  };
@@ -1,11 +1,11 @@
1
- // disconnect-account — Tenant-Admin trennt ein Postfach. Stream bleibt
2
- // (Audit-Historie), Status wird disconnected, der Watch-Supervisor
3
- // überspringt den Account ab dem nächsten Tick. Secret-Cleanup (IMAP-
4
- // Passwort/Refresh-Token im Slot accountId) macht der Aufrufer-Flow —
5
- // der Handler fasst den secrets-Pfad nicht an.
1
+ // disconnect-account — A TenantAdmin disconnects a mailbox. The stream is retained
2
+ // for audit history, the status becomes disconnected, and the watch supervisor
3
+ // skips the account starting with the next tick. Secret cleanup (IMAP password/
4
+ // refresh token in the accountId slot) is handled by the caller flow; this handler
5
+ // does not touch the secrets path.
6
6
  //
7
- // Idempotent: disconnect auf bereits disconnected Account ist ein
8
- // success-no-op (kein zweites Event) — Doppelklick-/Retry-freundlich.
7
+ // Idempotent: disconnecting an already disconnected account is a success no-op
8
+ // with no second event, making double-clicks and retries safe.
9
9
 
10
10
  import type { WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
11
11
  import { failNotFound } from "@cosmicdrift/kumiko-framework/errors";
@@ -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,7 +1,7 @@
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
6
  import type { WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
7
7
  import { failNotFound, failUnprocessable } from "@cosmicdrift/kumiko-framework/errors";
@@ -27,7 +27,7 @@ export const updateAccountSchema = z.object({
27
27
  /** Ops-Signal ("idle", "watching", "backoff:3", ...). */
28
28
  watchState: z.string().max(100).optional(),
29
29
  displayName: z.string().max(200).optional(),
30
- /** Audit-Grund für metadata.headers ("watch_supervisor",
30
+ /** Audit reason for metadata.headers ("watch_supervisor",
31
31
  * "oauth_refresh", "tenant_admin"). */
32
32
  reason: z.string().min(1).max(100),
33
33
  });
@@ -48,15 +48,15 @@ export const updateAccountHandler: WriteHandlerDef = {
48
48
  return failNotFound("mail-account", payload.accountId);
49
49
  }
50
50
  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).
51
+ // Disconnected accounts are final; re-enabling requires a fresh connect
52
+ // (new stream, new secret slot). This prevents a delayed supervisor tick
53
+ // from restoring a disconnected account to active (disconnect vs. poll
54
+ // race).
55
55
  return failUnprocessable("account_disconnected", { accountId: payload.accountId });
56
56
  }
57
57
 
58
- // Merge: address/provider/authMethod kommen 1:1 aus dem letzten
59
- // Snapshot (address bleibt Ciphertext — nie re-encrypten).
58
+ // address/provider/authMethod come unchanged from the latest snapshot
59
+ // (address remains ciphertext—never re-encrypt it).
60
60
  const eventPayload: MailAccountEventPayload = {
61
61
  ...current,
62
62
  ...(payload.status !== undefined ? { status: payload.status } : {}),