@cosmicdrift/kumiko-samples 0.386.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 (394) 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/audit/screens.ts +1 -1
  7. package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
  8. package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
  9. package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
  10. package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
  11. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
  12. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
  13. package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
  14. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  15. package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
  16. package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
  17. package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
  18. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +34 -37
  19. package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
  20. package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
  21. package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
  22. package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
  23. package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
  24. package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
  25. package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
  26. package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
  27. package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
  28. package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
  29. package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
  30. package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
  31. package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
  32. package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
  33. package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
  34. package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
  35. package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
  36. package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
  37. package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
  38. package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
  39. package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
  40. package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
  41. package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
  42. package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
  43. package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
  44. package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
  45. package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
  46. package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
  47. package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
  48. package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
  49. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
  50. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
  51. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  52. package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
  53. package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
  54. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  55. package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
  56. package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
  57. package/packages/bundled-features/src/auth-mfa/web/i18n.ts +3 -3
  58. package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
  59. package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
  60. package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +6 -6
  61. package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
  62. package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
  63. package/packages/bundled-features/src/billing-foundation/events.ts +22 -21
  64. package/packages/bundled-features/src/billing-foundation/feature.ts +42 -43
  65. package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
  66. package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +18 -17
  67. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
  68. package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
  69. package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +20 -20
  70. package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
  71. package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
  72. package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
  73. package/packages/bundled-features/src/billing-foundation/types.ts +64 -65
  74. package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +4 -4
  75. package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
  76. package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
  77. package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
  78. package/packages/bundled-features/src/cap-counter/enforce-cap.ts +64 -67
  79. package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
  80. package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
  81. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
  82. package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
  83. package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +1 -1
  84. package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
  85. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
  86. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
  87. package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
  88. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
  89. package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
  90. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
  91. package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
  92. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
  93. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
  94. package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
  95. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
  96. package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
  97. package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
  98. package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
  99. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
  100. package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
  101. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
  102. package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
  103. package/packages/bundled-features/src/config/resolver.ts +4 -4
  104. package/packages/bundled-features/src/config/table.ts +10 -10
  105. package/packages/bundled-features/src/config/write-helpers.ts +1 -1
  106. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +13 -12
  107. package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
  108. package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
  109. package/packages/bundled-features/src/custom-fields/events.ts +7 -8
  110. package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
  111. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
  112. package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
  113. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
  114. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
  115. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
  116. package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
  117. package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
  118. package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.ts +1 -1
  119. package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
  120. package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -12
  121. package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
  122. package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
  123. package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
  124. package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
  125. package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
  126. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
  127. package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
  128. package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
  129. package/packages/bundled-features/src/data-retention/feature.ts +11 -18
  130. package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
  131. package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
  132. package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
  133. package/packages/bundled-features/src/data-retention/presets.ts +18 -23
  134. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  135. package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
  136. package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
  137. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
  138. package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
  139. package/packages/bundled-features/src/delivery/feature.ts +3 -3
  140. package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
  141. package/packages/bundled-features/src/delivery/tables.ts +9 -8
  142. package/packages/bundled-features/src/delivery/unsubscribe.ts +4 -4
  143. package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
  144. package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
  145. package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
  146. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
  147. package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
  148. package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +4 -4
  149. package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
  150. package/packages/bundled-features/src/feature-toggles/feature.ts +1 -1
  151. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  152. package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
  153. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  154. package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
  155. package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
  156. package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
  157. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  158. package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
  159. package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
  160. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
  161. package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
  162. package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
  163. package/packages/bundled-features/src/files/feature.ts +6 -6
  164. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
  165. package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
  166. package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
  167. package/packages/bundled-features/src/folders/feature.ts +1 -1
  168. package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
  169. package/packages/bundled-features/src/folders/web/tree.ts +5 -5
  170. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
  171. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
  172. package/packages/bundled-features/src/form-draft/entity.ts +3 -3
  173. package/packages/bundled-features/src/form-draft/feature.ts +4 -5
  174. package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
  175. package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
  176. package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
  177. package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
  178. package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
  179. package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
  180. package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
  181. package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
  182. package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
  183. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
  184. package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
  185. package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
  186. package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
  187. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
  188. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
  189. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
  190. package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
  191. package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +11 -11
  192. package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
  193. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
  194. package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
  195. package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
  196. package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
  197. package/packages/bundled-features/src/inbound-mail-foundation/types.ts +66 -67
  198. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +69 -68
  199. package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
  200. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
  201. package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
  202. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
  203. package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
  204. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
  205. package/packages/bundled-features/src/jobs/events.ts +1 -1
  206. package/packages/bundled-features/src/jobs/feature.ts +6 -7
  207. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
  208. package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
  209. package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
  210. package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
  211. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  212. package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
  213. package/packages/bundled-features/src/jobs/job-run-logger.ts +14 -15
  214. package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
  215. package/packages/bundled-features/src/jobs/screens.ts +1 -1
  216. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  217. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  218. package/packages/bundled-features/src/ledger/entity.ts +5 -5
  219. package/packages/bundled-features/src/ledger/feature.ts +3 -3
  220. package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
  221. package/packages/bundled-features/src/ledger/recurring.ts +12 -12
  222. package/packages/bundled-features/src/ledger/schemas.ts +1 -1
  223. package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
  224. package/packages/bundled-features/src/ledger/web/index.ts +7 -7
  225. package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
  226. package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
  227. package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
  228. package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
  229. package/packages/bundled-features/src/mail-foundation/feature.ts +26 -27
  230. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
  231. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
  232. package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
  233. package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
  234. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
  235. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
  236. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
  237. package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
  238. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
  239. package/packages/bundled-features/src/managed-pages/table.ts +16 -15
  240. package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
  241. package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
  242. package/packages/bundled-features/src/notes-history/entity.ts +4 -4
  243. package/packages/bundled-features/src/notes-history/feature.ts +2 -2
  244. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  245. package/packages/bundled-features/src/page-render/layout.ts +9 -9
  246. package/packages/bundled-features/src/page-render/markdown.ts +11 -11
  247. package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
  248. package/packages/bundled-features/src/personal-access-tokens/feature.ts +5 -5
  249. package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
  250. package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
  251. package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
  252. package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
  253. package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
  254. package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
  255. package/packages/bundled-features/src/secrets/feature.ts +9 -9
  256. package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
  257. package/packages/bundled-features/src/seo/feature.ts +3 -3
  258. package/packages/bundled-features/src/sessions/constants.ts +1 -1
  259. package/packages/bundled-features/src/sessions/feature.ts +9 -9
  260. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
  261. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +2 -2
  262. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  263. package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
  264. package/packages/bundled-features/src/sessions/screens.ts +2 -2
  265. package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
  266. package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
  267. package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
  268. package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +1 -1
  269. package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
  270. package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
  271. package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
  272. package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
  273. package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
  274. package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
  275. package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
  276. package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
  277. package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
  278. package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
  279. package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
  280. package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
  281. package/packages/bundled-features/src/subscription-stripe/feature.ts +44 -43
  282. package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
  283. package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
  284. package/packages/bundled-features/src/subscription-stripe/runtime.ts +2 -2
  285. package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
  286. package/packages/bundled-features/src/tags/feature.ts +3 -3
  287. package/packages/bundled-features/src/tags/screens.ts +1 -1
  288. package/packages/bundled-features/src/template-resolver/api.ts +10 -10
  289. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +5 -5
  290. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
  291. package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
  292. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
  293. package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
  294. package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
  295. package/packages/bundled-features/src/template-resolver/seeding.ts +4 -4
  296. package/packages/bundled-features/src/template-resolver/table.ts +13 -14
  297. package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
  298. package/packages/bundled-features/src/tenant/feature.ts +7 -7
  299. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
  300. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  301. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  302. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  303. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
  304. package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
  305. package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
  306. package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
  307. package/packages/bundled-features/src/tenant/screens.ts +1 -1
  308. package/packages/bundled-features/src/tenant/seeding.ts +19 -18
  309. package/packages/bundled-features/src/tenant/testing.ts +5 -6
  310. package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
  311. package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
  312. package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
  313. package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
  314. package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
  315. package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
  316. package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
  317. package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
  318. package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
  319. package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
  320. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +2 -2
  321. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
  322. package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
  323. package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
  324. package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
  325. package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
  326. package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
  327. package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
  328. package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
  329. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
  330. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +8 -8
  331. package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
  332. package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
  333. package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
  334. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
  335. package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
  336. package/packages/bundled-features/src/user/schema/user.ts +45 -44
  337. package/packages/bundled-features/src/user/seeding.ts +40 -40
  338. package/packages/bundled-features/src/user/testing.ts +3 -3
  339. package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
  340. package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
  341. package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
  342. package/packages/bundled-features/src/user-data-rights/feature.ts +112 -113
  343. package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
  344. package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
  345. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
  346. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
  347. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
  348. package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
  349. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
  350. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +4 -4
  351. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
  352. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
  353. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
  354. package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
  355. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
  356. package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
  357. package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
  358. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
  359. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +166 -276
  360. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +85 -107
  361. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
  362. package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
  363. package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
  364. package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
  365. package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
  366. package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
  367. package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
  368. package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
  369. package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
  370. package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
  371. package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
  372. package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
  373. package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
  374. package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
  375. package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
  376. package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
  377. package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
  378. package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +1 -1
  379. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
  380. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
  381. package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
  382. package/packages/bundled-features/src/user-profile/index.ts +3 -3
  383. package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
  384. package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
  385. package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
  386. package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
  387. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
  388. package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
  389. package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
  390. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
  391. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
  392. package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
  393. package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
  394. package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
@@ -1,37 +1,39 @@
1
- // SMTP-Transport für EmailTransport-Interface. nodemailer-basiert
2
- // (battle-tested, TLS-AUTH-Pool-Reconnect handled). Universaler default
3
- // für apps die keinen Vendor-spezifischen Sender wollen — funktioniert
4
- // gegen jeden SMTP-Server (Gmail, eigener Postfix, Brevo-SMTP-relay,
5
- // Office 365, Mailhog für lokales testing).
1
+ // SMTP transport for the EmailTransport interface, based on nodemailer
2
+ // (battle-tested, handles TLS, auth and pool reconnects). It is the universal
3
+ // default for apps that do not need a vendor-specific sender and works with
4
+ // any SMTP server (Gmail, a private
5
+ // Postfix server, a Brevo SMTP relay, Office 365, or Mailhog for local
6
+ // testing).
6
7
  //
7
- // Why SMTP statt Vendor-API als default:
8
- // 1. EU-Story: kein Daten an US-Vendor, App-Owner wählt Server.
9
- // 2. Self-Hosting: Customer kann eigenen Mailserver nutzen, kein
8
+ // Why SMTP instead of a vendor API as the default:
9
+ // 1. EU data control: the app owner chooses the server instead of sending
10
+ // data to a US vendor.
11
+ // 2. Self-hosting: customers can use their own mail server without an
10
12
  // external account.
11
- // 3. Universalität: jeder Vendor (Brevo, Resend, Mailgun, Postmark)
12
- // bietet auch SMTP — wer Brevo will, setzt Brevos SMTP-Credentials.
13
+ // 3. Universality: every vendor (Brevo, Resend, Mailgun, Postmark) also
14
+ // offers SMTP, so Brevo users can provide Brevo SMTP credentials.
13
15
  //
14
- // Transport-Pool: nodemailer.createTransport({pool: true}) hält bis zu
15
- // 5 Verbindungen offen + reused. Bei kleinen Apps reicht das; für High-
16
- // Volume-Apps muss der Caller eine eigene Implementation mit
17
- // dedizierter Queue (BullMQ + retry) drüberlegen.
16
+ // The transport pool (createTransport({ pool: true })) keeps up to 5
17
+ // connections open and reuses them. That is enough for small apps; for
18
+ // high-volume apps the caller must layer its own implementation with a
19
+ // dedicated queue (BullMQ + retry) on top.
18
20
 
19
21
  import { createTransport, type Transporter } from "nodemailer";
20
22
  import addressparser from "nodemailer/lib/addressparser";
21
23
  import type { EmailAttachment, EmailMessage, EmailTransport } from "./types.ts";
22
24
 
23
25
  export type SmtpTransportOptions = {
24
- /** SMTP-Server-Host (z.B. "smtp.gmail.com", "in-v3.mailjet.com",
25
- * "localhost" für Mailhog/MailCatcher in dev). */
26
+ /** SMTP server host (for example, "smtp.gmail.com", "in-v3.mailjet.com",
27
+ * or "localhost" for Mailhog/MailCatcher in development). */
26
28
  readonly host: string;
27
- /** Default 587 (STARTTLS). 465 für implicit-TLS, 25 für unencrypted
28
- * (nur lokal/intern, nie public). */
29
+ /** Default 587 (STARTTLS). 465 uses implicit TLS; 25 is unencrypted
30
+ * (for local/internal use only, never public). */
29
31
  readonly port?: number;
30
- /** TLS-Mode: true = implicit TLS auf port 465, false = STARTTLS auf
31
- * 587 (oder plain auf 25). Default false (STARTTLS standard). */
32
+ /** TLS mode: true = implicit TLS on port 465, false = STARTTLS on
33
+ * 587 (or plain on 25). The default is false (STARTTLS). */
32
34
  readonly secure?: boolean;
33
- /** Optional auth — manche internal-relays nehmen IP-whitelisting statt
34
- * Login. Wenn gesetzt, beide felder pflicht. */
35
+ /** Optional authentication — some internal relays use IP allowlisting
36
+ * instead of login. When set, both fields are required. */
35
37
  readonly auth?: {
36
38
  readonly user: string;
37
39
  readonly pass: string;
@@ -120,8 +122,8 @@ export function createSmtpTransport(options: SmtpTransportOptions): EmailTranspo
120
122
  };
121
123
  }
122
124
 
123
- /** Env-Felder die `createSmtpTransportFromEnv` liest. Apps die SMTP
124
- * nutzen extenden ihr env-Schema um genau diese Keys. */
125
+ /** Environment fields read by `createSmtpTransportFromEnv`. Apps that use
126
+ * SMTP should extend their environment schema with exactly these keys. */
125
127
  export type SmtpEnv = {
126
128
  readonly SMTP_HOST?: string;
127
129
  readonly SMTP_PORT?: string;
@@ -132,14 +134,15 @@ export type SmtpEnv = {
132
134
  };
133
135
 
134
136
  /**
135
- * Boot-Time-Transport aus env. Ohne `SMTP_HOST` → `null` (Caller behandelt
136
- * das als "kein Mail-Versand", statt zu crashen). Port wird zu Number
137
- * gecoerced (default 587), `secure` ist `SMTP_SECURE === "true"`, auth nur
138
- * wenn user UND pass gesetzt sind.
137
+ * Creates a transport at boot time from the environment. Without
138
+ * `SMTP_HOST`, returns `null` so the caller can treat this as no mail
139
+ * delivery instead of crashing. The port is coerced to a number (default
140
+ * 587); `secure` is `SMTP_SECURE === "true"`; authentication is included
141
+ * only when both the user and password are set.
139
142
  *
140
- * Ersetzt den identischen `env.SMTP_HOST ? createSmtpTransport({...}) : null`
141
- * Block den jede App in bin/main.ts + bin/server.ts hand-rollte — nur die
142
- * From-Default (`fallbackFrom`) variiert pro App.
143
+ * Replaces the repeated `env.SMTP_HOST ? createSmtpTransport({...}) : null`
144
+ * block that each app previously implemented in bin/main.ts and
145
+ * bin/server.ts. Only the From default (`fallbackFrom`) varies by app.
143
146
  */
144
147
  export function createSmtpTransportFromEnv(
145
148
  env: SmtpEnv,
@@ -16,10 +16,9 @@ export const unreadCountQuery = defineQueryHandler({
16
16
  description:
17
17
  "Counts the calling user's unread in-app notification messages; use it for an inbox badge or to check whether a user has pending notifications.",
18
18
  handler: async (query, ctx) => {
19
- // The query helpers in db/query.ts have no aggregate helper — selectMany alle matching rows,
20
- // count() in JS. Pragma: unread-counts sind low-cardinality (user-
21
- // scoped, max ~hunderte rows). Wenn das wachsen sollte: raw .unsafe()
22
- // mit COUNT(*).
19
+ // The query helpers in db/query.ts have no aggregate helper, so selectMany returns all matching
20
+ // rows and count() runs in JS. This is acceptable because unread counts are low-cardinality and
21
+ // user-scoped, with at most a few hundred rows; use raw .unsafe() with COUNT(*) if that grows.
23
22
  const rows = await selectMany(ctx.db, inAppMessagesTable, {
24
23
  userId: query.user.id,
25
24
  isRead: false,
@@ -22,24 +22,23 @@ export {
22
22
  tenantComplianceProfileTable,
23
23
  } from "./schema/profile-selection.ts";
24
24
 
25
- // compliance-profiles — Tenant-weite DSGVO/Compliance-Profile-Wahl.
25
+ // compliance-profiles — Tenant-wide GDPR/compliance profile selection.
26
26
  //
27
- // Pflicht beim Tenant-Onboarding (Sprint 1.5 Banner-API). Profile
28
- // buendelt User-Rights-Grace, Notification-Sprache, Breach-Disclosure,
29
- // Audit-Retention und Sub-Processor-Anforderungen.
27
+ // Required during tenant onboarding. Each profile bundles user-rights grace
28
+ // periods, notification language, breach-disclosure rules, audit retention,
29
+ // and sub-processor requirements.
30
30
  //
31
- // Cross-Feature-API: r.exposesApi("compliance.forTenant") — andere
32
- // Features (user-data-rights in Sprint 2, tenant-lifecycle in Sprint 5)
33
- // rufen den Profile-Resolver via QN-Pattern (siehe legal-pages →
34
- // text-content fuer Pattern-Beispiel).
31
+ // Cross-feature API: r.exposesApi("compliance.forTenant") — other features
32
+ // resolve the profile through the QN pattern (see legal-pages → text-content
33
+ // for an example).
35
34
  //
36
- // Architektur-Note: Profile-Selection lebt als separate Entity
37
- // (tenantComplianceProfile), nicht als config-key im tenant-Feature.
38
- // Begruendung in schema/profile-selection.ts.
35
+ // Architectural note: Profile selection is stored as a separate entity
36
+ // (tenantComplianceProfile), not as a config key in the tenant feature.
37
+ // The reason is documented in schema/profile-selection.ts.
39
38
  export type ComplianceProfilesFeatureOptions = {
40
39
  // Access gate for the profile-picker screen and the `set-profile` write it
41
40
  // submits to — both move together so the nav entry a role sees always
42
- // matches a callable handler (#2033). Default access.admin includes
41
+ // matches a callable handler. Default access.admin includes
43
42
  // TenantAdmin, who in a line-of-business app is the operator, not the
44
43
  // platform — pass access.systemAdmin to keep this platform-only and out
45
44
  // of their nav.
@@ -59,10 +58,10 @@ export function createComplianceProfilesFeature(
59
58
  category: "compliance",
60
59
  recommended: false,
61
60
  });
62
- // Standalone — kein r.requires noetig: tenantId kommt aus dem User-
63
- // Context, Profile-Selection ist eigene Entity, sub-processor-Liste
64
- // sind Constants. Wenn S1.4+ Cross-Feature-Reads dazukommen, kommt
65
- // r.requires hier rein.
61
+ // Standalone — r.requires is not needed: tenantId comes from the user
62
+ // context, profile selection is a separate entity, and the sub-processor
63
+ // list consists of constants. Add r.requires if cross-feature reads are
64
+ // introduced.
66
65
  r.entity({ name: "tenant-compliance-profile", ...tenantComplianceProfileEntity });
67
66
 
68
67
  r.exposesApi("compliance.forTenant");
@@ -9,13 +9,10 @@ import * as z from "zod";
9
9
  import { parseComplianceProfileOverride } from "../_internal/parse-override.ts";
10
10
  import { tenantComplianceProfileTable } from "../schema/profile-selection.ts";
11
11
 
12
- // Liefert das effektive Compliance-Profile fuer den aktuellen Tenant.
13
- // Macht den exposesApi-Marker aus feature.ts mit echtem Inhalt.
12
+ // Returns the effective compliance profile for the current tenant.
14
13
  //
15
- // Default-Verhalten (Edge-Case-Decision aus S1.1): kein Profile-
16
- // Eintrag → minimal-no-region + warning="no-profile-selected".
17
- // Caller (z.B. user-data-rights in Sprint 2) sieht das warning und
18
- // kann Onboarding-Banner triggern.
14
+ // If no profile is selected, returns minimal-no-region with
15
+ // warning="no-profile-selected" so callers can trigger an onboarding banner.
19
16
  export const forTenantQuery = defineQueryHandler({
20
17
  name: "for-tenant",
21
18
  schema: z.object({}),
@@ -7,12 +7,12 @@ import {
7
7
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
8
8
  import * as z from "zod";
9
9
 
10
- // Liefert alle waehlbaren Compliance-Profile fuer das Tenant-Onboarding.
11
- // Pure In-Memory-Read der Constants — keine DB-Abfrage. Kein Caching
12
- // noetig (modulo Pre-Boot bereits aufgeloest).
10
+ // Returns all selectable compliance profiles for tenant onboarding.
11
+ // Pure in-memory read of the constants—no database query or caching is needed
12
+ // because they are already resolved before boot.
13
13
  //
14
- // Filtert minimal-no-region raus — das ist Default-Fallback, nicht
15
- // auswählbar (Production soll explizite Wahl treffen).
14
+ // Excludes minimal-no-region because it is the default fallback, not selectable;
15
+ // production must make an explicit choice.
16
16
  export const listProfilesQuery = defineQueryHandler({
17
17
  name: "list-profiles",
18
18
  schema: z.object({}),
@@ -7,7 +7,7 @@ import { tenantComplianceProfileTable } from "../schema/profile-selection.ts";
7
7
 
8
8
  // Onboarding banner trigger for tenant admin.
9
9
  //
10
- // Sprint 1.5 — minimal API endpoint, the UI banner comes in a later UI
10
+ // Minimal API endpoint, the UI banner comes in a later UI
11
11
  // sprint. Pure read query: does an entry exist in tenantComplianceProfile
12
12
  // for the current tenant?
13
13
  //
@@ -20,7 +20,7 @@ import { tenantComplianceProfileTable } from "../schema/profile-selection.ts";
20
20
  // option of createComplianceProfilesFeature) — passing the option through
21
21
  // would widen call access by default to all three access.admin roles
22
22
  // (including SystemAdmin). Instead the handler takes `pickerReachableRoles`
23
- // and deliberately resolves the #2063 special case: if the *caller's*
23
+ // and deliberately resolves the special case: if the *caller's*
24
24
  // roles no longer intersect the picker's `access` option, the query stops
25
25
  // reporting needsSelection — otherwise a tenant admin would be told to
26
26
  // open a screen they can't reach.
@@ -37,8 +37,8 @@ export function createNeedsProfileQuery(pickerReachableRoles: readonly string[])
37
37
  })) as { profileKey: ComplianceProfileKey } | null; // @cast-boundary db-runner
38
38
 
39
39
  if (row) {
40
- // S1.7 X1: minimal-no-region is no longer settable via set-profile
41
- // (Zod). If Sprint 2 ships a seedComplianceProfile helper that
40
+ // Minimal-no-region is no longer settable via set-profile
41
+ // (Zod). If a seedComplianceProfile helper ships that
42
42
  // reintroduces the migration edge case, a defensive path belongs
43
43
  // here again — until then, every existing entry is a deliberately
44
44
  // chosen production profile.
@@ -20,10 +20,10 @@ const crud = createEventStoreExecutor(tenantComplianceProfileTable, tenantCompli
20
20
  entityName: "tenant-compliance-profile",
21
21
  });
22
22
 
23
- // Schema engt sich auf die 3 oeffentlich waehlbaren Profile (Sprint 1.7
24
- // X1) — minimal-no-region ist Default-Fallback fuer "noch keine Wahl",
25
- // nicht eine waehlbare Production-Option. Symmetrisch zu
26
- // SELECTABLE_PROFILE_KEYS aus der framework/compliance-Liste.
23
+ // The schema is limited to the three publicly selectable profiles.
24
+ // `minimal-no-region` is the default fallback while no choice has been
25
+ // made yet, not a selectable production option. This mirrors
26
+ // SELECTABLE_PROFILE_KEYS from the framework/compliance list.
27
27
  const profileKeySchema = z.enum(SELECTABLE_PROFILE_KEYS);
28
28
 
29
29
  // Upsert: the first call inserts, later calls update, so repeating the same values
@@ -43,8 +43,8 @@ export const setProfileWrite = defineWriteHandler({
43
43
  override: z.string().nullable().optional(),
44
44
  tenantIdOverride: z.string().min(1).optional(),
45
45
  }),
46
- // SystemAdmin kann Profile fuer Customer-Setup setzen (Plattform-
47
- // Operator-Pfad). TenantAdmin nur fuer eigenen Tenant.
46
+ // SystemAdmin can set profiles for customer setup through the platform-
47
+ // operator path; TenantAdmin can set them only for their own tenant.
48
48
  access: { roles: access.admin },
49
49
  description:
50
50
  "Sets or replaces a tenant's compliance profile key plus an optional JSON override, for onboarding or a later region change; a system admin may target a different tenant through tenantIdOverride.",
@@ -52,15 +52,14 @@ export const setProfileWrite = defineWriteHandler({
52
52
  const tenantId = (event.payload.tenantIdOverride ?? event.user.tenantId) as TenantId; // @cast-boundary engine-payload
53
53
  const { db, streamTenantId } = requireForTenant(ctx, tenantId);
54
54
 
55
- // Override-Validation: muss parseables JSON-Object sein UND dem
56
- // ComplianceProfileOverride-Schema entsprechen (S1.9 Z3 — strict-Zod
57
- // mit Top-Level + Sub-Level-Whitelist via .strict()). Tippfehler
58
- // wie `{ userRights: { weeks: 3 } }` werden hier rejected statt vom
59
- // deepMerge silent ins Profile gespliced.
55
+ // The override must be parseable JSON representing an object and must
56
+ // conform to the ComplianceProfileOverride schema. The strict Zod
57
+ // top-level and nested allowlists reject typos such as
58
+ // `{ userRights: { weeks: 3 } }` instead of silently letting
59
+ // deepMerge splice them into the profile.
60
60
  //
61
- // Errors via writeFailure + Kumiko-Error-Klassen (S1.10 M3) statt
62
- // throw — landen so mit Path-Detail im response-body statt als
63
- // generic internal_error.
61
+ // writeFailure and Kumiko error classes preserve path details in the
62
+ // response body instead of producing a generic internal_error.
64
63
  if (event.payload.override) {
65
64
  let parsed: unknown;
66
65
  try {
@@ -8,19 +8,17 @@ import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
8
8
  import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
9
9
  import * as z from "zod";
10
10
 
11
- // Public Sub-Processor-Liste — anonymous accessible (Memory:
12
- // project_anonymous_access). Matched die DSGVO Art. 28(2) Pflicht
13
- // dass die Liste der Auftragsverarbeiter oeffentlich einsehbar ist
14
- // (typisch verlinkt aus Datenschutzerklaerung + AVV).
11
+ // Public sub-processor list, accessible anonymously. This satisfies the GDPR Art. 28(2) requirement
12
+ // that the list of processors be publicly accessible, typically linked from
13
+ // the privacy policy and data-processing agreement.
15
14
  //
16
- // Format: JSON mit getrennten active/planned-Sektionen. Tenant-Admins
17
- // kriegen Notification ueber Aenderungen via Cron-Job (Sprint 1.5+
18
- // oder S9 compliance-as-product). RSS-Feed kommt in S9.
15
+ // Format: JSON with separate active/planned sections. Tenant admins receive
16
+ // change notifications via a cron job.
19
17
  //
20
- // Zwei Auflistungen statt einer flachen Liste:
21
- // - `active`: aktuell eingesetzte Sub-Processors
22
- // - `planned`: bekannte zukünftige Sub-Processors (Tenant-Admin-
23
- // Lead-Time bevor sie aktiv werden — typisch bei AI/Stripe)
18
+ // Two lists are used instead of one flat list:
19
+ // - `active`: sub-processors currently in use
20
+ // - `planned`: known future sub-processors, giving tenant admins lead time
21
+ // before activation, as is typical for AI and Stripe providers.
24
22
  export const subProcessorsQuery = defineQueryHandler({
25
23
  name: "sub-processors",
26
24
  schema: z.object({}),
@@ -1,12 +1,12 @@
1
- // Direkter Resolver-Helper fuer Bulk-Iteration ohne dispatcher-Roundtrip.
1
+ // Direct resolver helper for bulk iteration without a dispatcher round trip.
2
2
  //
3
- // `for-tenant`-Query (handlers/for-tenant.query.ts) ist die Cross-Feature-
4
- // API fuer Handler-Pfade. Worker (S2.U3 Atom 3b) lebt im JobContext
5
- // ohne `queryAs` — braucht direkten DB-Lookup + resolveComplianceProfile.
3
+ // The `for-tenant` query (handlers/for-tenant.query.ts) is the cross-feature
4
+ // API for handler paths. Workers run in JobContext (without `queryAs`), so
5
+ // they need a direct database lookup followed by `resolveComplianceProfile`.
6
6
  //
7
- // Pattern matched data-retention's `resolveRetentionPolicyForTenant`.
8
- // Beide Pfade nutzen `resolveComplianceProfile` aus framework/compliance,
9
- // also kein Drift zwischen Query-API und Worker-Pfad.
7
+ // This follows data-retention's `resolveRetentionPolicyForTenant` pattern.
8
+ // Both paths use `resolveComplianceProfile` from framework/compliance, keeping
9
+ // the query API and worker path consistent.
10
10
 
11
11
  import {
12
12
  type ComplianceProfileKey,
@@ -5,24 +5,19 @@ import {
5
5
  createSelectField,
6
6
  } from "@cosmicdrift/kumiko-framework/engine";
7
7
 
8
- // Tenant-1-zu-1: Pro Tenant genau eine Profile-Wahl.
8
+ // One-to-one relationship: each tenant has exactly one profile selection.
9
9
  //
10
- // Architektur-Entscheidung (2026-05-06): Profile-Selection lebt als
11
- // separate Entity im compliance-profiles-Feature, NICHT als config-key
12
- // im tenant-Feature. Begruendung:
13
- // (a) override ist strukturiertes JSON, config-key-Pattern (timezone/
14
- // locale) ist key-value-flach
15
- // (b) Profile-Wechsel ist audit-relevant — Event-Store gibt das
16
- // automatisch fuer Entity-Writes
17
- // (c) Plan-Files in docs/plans/datenschutz/compliance-profiles.md
18
- // nennen sie explizit als tenantComplianceProfile-Entity
10
+ // Profile selection is a separate entity in the compliance-profiles feature,
11
+ // not a config key in the tenant feature, because:
12
+ // (a) override is structured JSON, while the config-key pattern
13
+ // (timezone/locale) is flat key-value data
14
+ // (b) profile changes are audit-relevant, which the event store handles
15
+ // automatically for entity writes
19
16
  //
20
- // Wer in 6 Monaten zweifelt warum nicht config-key: siehe oben.
21
- //
22
- // override als JSON-String in longText: kein dedizierter jsonField-Typ
23
- // im Framework; embedded hat festes Schema, das hier dynamisch ist.
24
- // Zod-Validation beim set-profile-Handler stellt Schema-Konformitaet
25
- // sicher.
17
+ // override is stored as a JSON string in longText because the framework has
18
+ // no dedicated jsonField type; embedded has a fixed schema, while this schema
19
+ // is dynamic. Zod validation in the set-profile handler ensures schema
20
+ // conformity.
26
21
  export const tenantComplianceProfileEntity = createEntity({
27
22
  table: "read_tenant_compliance_profiles",
28
23
  fields: {
@@ -30,19 +25,19 @@ export const tenantComplianceProfileEntity = createEntity({
30
25
  required: true,
31
26
  options: ["eu-dsgvo", "swiss-dsg", "de-hr-dsgvo-hgb", "minimal-no-region"] as const,
32
27
  }),
33
- // override: JSON-String mit Partial-ComplianceProfile. NULL/leer
34
- // bedeutet "Default-Profile, keine Override". Validiert beim
35
- // set-profile-Handler via Zod.
28
+ // override: JSON string containing a partial ComplianceProfile. NULL/empty
29
+ // means "default profile, no override". Validated by the
30
+ // set-profile handler via Zod.
36
31
  override: createLongTextField({
37
32
  personal: false,
38
33
  reason: "is_business_data",
39
34
  }),
40
35
  },
41
36
  indexes: [
42
- // Pro Tenant nur EIN Profile-Datensatz. Boot-Validator-Comment in
43
- // EntityIndexDef warnt vor single-column-tenantId-Index als redundant
44
- // — UNIQUE-Constraint ist hier aber semantisch noetig (1:1-Relation)
45
- // und nicht nur Performance-Hint, daher explizit deklariert.
37
+ // Only one profile record is allowed per tenant. Although the boot validator
38
+ // warns that a single-column tenantId index is redundant, the UNIQUE
39
+ // constraint is semantically required here for the one-to-one relationship,
40
+ // not merely a performance hint, so it is declared explicitly.
46
41
  { unique: true, columns: ["tenantId"] },
47
42
  ],
48
43
  });
@@ -1,14 +1,14 @@
1
- // Test-Helper für compliance-profiles. Legt einen Profile-Eintrag direkt
2
- // über den Event-Store-Executor an — gleicher Pfad wie der echte
3
- // set-profile-Handler, aber ohne Zod-Schema-Engung (akzeptiert
4
- // minimal-no-region für Migration-Edge-Case-Tests) und ohne Access-
5
- // Check. Default ifExists="skip": nur fehlende Profile anlegen.
1
+ // Test helper for compliance-profiles. Creates a profile entry directly
2
+ // through the Event Store executor—the same path as the real
3
+ // set-profile handler, but without Zod schema restrictions (accepts
4
+ // minimal-no-region for migration edge-case tests) and without an access
5
+ // check. Default ifExists="skip": creates only missing profiles.
6
6
  //
7
- // Sprint 2 user-data-rights nutzt das fuer Test-Setup ("user kann
8
- // Daten exportieren mit profile X" — pro Test ein frischer Tenant +
9
- // Profile-Wahl in einem Helper-Call).
7
+ // user-data-rights uses this for test setup ("user can export data with
8
+ // profile X": a fresh tenant and profile selection per test in one helper
9
+ // call).
10
10
  //
11
- // Pattern matched seedTextBlock aus text-content.
11
+ // The pattern matches seedTextBlock in template-resolver/seeding.ts.
12
12
 
13
13
  import type {
14
14
  ComplianceProfileKey,
@@ -50,9 +50,8 @@ export async function seedComplianceProfile(
50
50
  db: DbConnection,
51
51
  opts: SeedComplianceProfileOptions,
52
52
  ): Promise<{ id: string }> {
53
- // user.tenantId muss === opts.tenantId sein damit Event-Store-Stream
54
- // + Projection im selben Tenant-Bucket landen (Memory:
55
- // feedback_event_store_tenant_consistency).
53
+ // user.tenantId must equal opts.tenantId so the Event Store stream
54
+ // and projection remain in the same tenant bucket.
56
55
  const by = opts.by ?? { ...TestUsers.systemAdmin, tenantId: opts.tenantId };
57
56
  const tdb = createTenantDb({ db, tenantId: opts.tenantId, mode: "system" });
58
57
  const overrideJson = opts.override !== undefined ? JSON.stringify(opts.override) : null;
@@ -77,9 +76,9 @@ export async function seedComplianceProfile(
77
76
  if (!result.isSuccess) {
78
77
  throw new Error(`seedComplianceProfile create failed: ${JSON.stringify(result)}`);
79
78
  }
80
- // @cast-boundary db-row: executor.create result.data ist die
81
- // inserted Projection-Row (Record<string, unknown>); id ist nach
82
- // INSERT garantiert (Runtime-Check direkt darunter).
79
+ // @cast-boundary db-row: executor.create result.data is the
80
+ // inserted projection row (Record<string, unknown>); id is guaranteed
81
+ // after INSERT (runtime check directly below).
83
82
  const data = result.data as { id?: string };
84
83
  if (data.id === undefined) {
85
84
  throw new Error("seedComplianceProfile: executor.create did not return an id");
@@ -5,12 +5,12 @@ import * as z from "zod";
5
5
  import { tenantComplianceProfileTable } from "../../compliance-profiles/index.ts";
6
6
  import { decryptTenantNames, tenantTable } from "../../tenant/index.ts";
7
7
 
8
- // SystemAdmin platform-wide counterpart to needs-profile (#2089).
8
+ // SystemAdmin platform-wide counterpart to needs-profile.
9
9
  //
10
- // #2084 stopped needs-profile from nagging a TenantAdmin who can no longer
10
+ // The change stopped needs-profile from nagging a TenantAdmin who can no longer
11
11
  // reach a picker narrowed to access.systemAdmin — correct, but it left no
12
12
  // one else able to notice: needs-profile stays TenantAdmin-only on purpose
13
- // (widening its call-access was explicitly rejected in #2084), so a
13
+ // (widening its call-access was explicitly rejected), so a
14
14
  // SystemAdmin who owns the platform-only picker has no way to see which
15
15
  // tenants still run on minimal-no-region. This query fills that gap
16
16
  // instead of touching needs-profile: every enabled tenant that has no row
@@ -1,8 +1,8 @@
1
1
  // compliance-profiles-ops — platform-wide SystemAdmin visibility into
2
- // tenants missing a compliance-profile selection (#2089).
2
+ // tenants missing a compliance-profile selection.
3
3
  //
4
4
  // needs-profile (compliance-profiles) tells a TenantAdmin they must pick a
5
- // profile, but stays TenantAdmin-only by design (#2084) — a SystemAdmin who
5
+ // profile, but stays TenantAdmin-only by design — a SystemAdmin who
6
6
  // owns a picker narrowed to access.systemAdmin has no query at all. Kept as
7
7
  // a separate feature (mirrors folders-user-data/notes-history-user-data)
8
8
  // rather than folded into compliance-profiles: this is the one genuinely
@@ -74,17 +74,17 @@ export async function collectMissingRequiredConfig(
74
74
  db: TenantDb,
75
75
  gate?: RequiredKeyGate,
76
76
  options?: {
77
- /** Verdict-Pfade (Rollup, selbst role-gated) MÜSSEN ungefiltert zählen:
78
- * der Per-Key-read-Filter ist Info-Disclosure-Schutz für den
79
- * openToAll-Handler — im Verdict droppte er SystemAdmin-gated
80
- * required-Keys still und meldete ready:true trotz Lücke. */
77
+ /** Verdict paths (rollup, themselves role-gated) MUST count without filtering:
78
+ * the per-key read filter protects the openToAll handler from information
79
+ * disclosure, but in the verdict it dropped SystemAdmin-gated required keys
80
+ * and incorrectly reported ready:true despite the gap. */
81
81
  readonly skipAccessFilter?: boolean;
82
82
  },
83
83
  ): Promise<ReadinessMissingKey[]> {
84
84
  const resolver = requireConfigResolver(ctx, callerQn);
85
85
  const effectiveGate = gate ?? (await buildProviderSelectionGate(ctx, callerQn, user, db));
86
- // Kandidaten erst sammeln, dann EIN Batch-Resolve — die sequentielle
87
- // resolver.get-Schleife war ein N+1 über alle required Keys (272/1).
86
+ // Collect candidates first, then perform ONE batch resolve — the sequential
87
+ // resolver.get loop was an N+1 operation across all required keys (272/1).
88
88
  type KeyDef =
89
89
  ReturnType<typeof ctx.registry.getAllConfigKeys> extends ReadonlyMap<string, infer D>
90
90
  ? D
@@ -153,7 +153,7 @@ export const readinessQuery = defineQueryHandler({
153
153
  db,
154
154
  );
155
155
  // Additive, display-ready fields for the admin-shell dashboard stat
156
- // panel (fw#2312) — `missing` itself stays untouched for existing
156
+ // panel — `missing` itself stays untouched for existing
157
157
  // consumers that read the array directly.
158
158
  return {
159
159
  missing,
@@ -16,8 +16,8 @@
16
16
  // the NEW envelope: after a full run even a from-scratch rebuild only
17
17
  // ever sees the current-KEK envelope.
18
18
  //
19
- // systemScope() fail-closed pattern (framework#2056): the initial scan is
20
- // intentionally cross-tenant (system-wide key rotation), acknowledged via
19
+ // systemScope() fail-closed pattern: the initial scan is intentionally
20
+ // cross-tenant (system-wide key rotation), acknowledged via
21
21
  // UncheckedSystemDb.acknowledgeCrossTenant(). Rows are bucketed by tenant,
22
22
  // and assertRowsTenant() re-verifies each row against its bucket's tenant
23
23
  // right before the write — both checks are built locally from the exported
@@ -226,9 +226,8 @@ export const reencryptJob: JobHandlerFn = async (rawPayload, ctx): Promise<void>
226
226
  }
227
227
 
228
228
  // Re-verify the row's own tenantId against the bucket it was scanned
229
- // into, right before the write (framework#2072) — a mismatch here
230
- // fails this row only (via onRowError below), it does not abort the
231
- // whole job.
229
+ // into, right before the write — a mismatch here fails this row only
230
+ // (via onRowError below), it does not abort the whole job.
232
231
  sdbFor(tenantId).assertRowsTenant([row], "tenantId");
233
232
 
234
233
  const plaintext = await cipher.decrypt(row.value, { tenantId });
@@ -74,7 +74,8 @@ export const setWrite = defineWriteHandler({
74
74
  // rejected), but an admin override write can still target scope=
75
75
  // "system" for a tenant/user-scoped key (validateScope allows any
76
76
  // requestedScope <= definedScope) — system-row has no subject.
77
- if (keyDef.piiEncrypted && scope === ConfigScopes.system) {
77
+ const piiScope = keyDef.piiEncrypted && scope !== ConfigScopes.system ? scope : undefined;
78
+ if (keyDef.piiEncrypted && piiScope === undefined) {
78
79
  return writeFailure(
79
80
  new UnprocessableError("invalid_scope", {
80
81
  i18nKey: "config.errors.invalidScope",
@@ -153,7 +154,7 @@ export const setWrite = defineWriteHandler({
153
154
  if (keyDef.encrypted) {
154
155
  const cipher = requireConfigEncryption(ctx, "config:write:set");
155
156
  serialized = await cipher.encrypt(serialized, { tenantId });
156
- } else if (keyDef.piiEncrypted) {
157
+ } else if (piiScope !== undefined) {
157
158
  const kms = configuredPiiSubjectKms();
158
159
  if (!kms) {
159
160
  throw new InternalError({
@@ -163,8 +164,7 @@ export const setWrite = defineWriteHandler({
163
164
  `configurePiiSubjectKms(adapter) at boot.`,
164
165
  });
165
166
  }
166
- // scope="system" was already rejected above — narrow accordingly.
167
- const subject = resolvePiiSubject(scope as Exclude<typeof scope, "system">, tenantId, userId);
167
+ const subject = resolvePiiSubject(piiScope, tenantId, userId);
168
168
  const kmsCtx: KmsContext = {
169
169
  requestId: requestContext.get()?.requestId ?? "config:write:set",
170
170
  tenantId,
@@ -583,10 +583,10 @@ export function validateAppOverrides(
583
583
  );
584
584
  }
585
585
 
586
- // Per keyDef.type narrow value inline — TS narrowt nicht durch
587
- // `typeof value !== typeForKey(...)` (typeForKey returnt string,
588
- // kein discriminator). Das vermeidet `value as string|number` casts
589
- // unten, weil value innerhalb des Branches schon typed ist.
586
+ // Narrow by keyDef.type inline because TypeScript cannot narrow through
587
+ // `typeof value !== typeForKey(...)`, whose return type is string rather
588
+ // than a discriminator. This avoids `value as string|number` casts below;
589
+ // value is correctly typed within each branch.
590
590
  if (keyDef.type === "number") {
591
591
  if (typeof value !== "number") {
592
592
  throw new Error(`App-Boot-Override for "${key}": expected number, got ${typeof value}`);