@cosmicdrift/kumiko-samples 0.386.0 → 0.388.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (530) hide show
  1. package/LICENSE +21 -57
  2. package/README.md +1 -1
  3. package/package.json +2 -2
  4. package/packages/bundled-features/package.json +9 -2
  5. package/packages/bundled-features/src/agent-tools/changes.json +6 -0
  6. package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
  7. package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +9 -9
  8. package/packages/bundled-features/src/audit/changes.json +12 -0
  9. package/packages/bundled-features/src/audit/handlers/audit-events.ts +1 -1
  10. package/packages/bundled-features/src/audit/screens.ts +1 -1
  11. package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
  12. package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
  13. package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
  14. package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
  15. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
  16. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
  17. package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
  18. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  19. package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
  20. package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
  21. package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
  22. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +34 -37
  23. package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
  24. package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
  25. package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
  26. package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
  27. package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
  28. package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
  29. package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
  30. package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
  31. package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
  32. package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
  33. package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
  34. package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
  35. package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
  36. package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
  37. package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
  38. package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
  39. package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
  40. package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
  41. package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
  42. package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
  43. package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
  44. package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
  45. package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
  46. package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
  47. package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
  48. package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
  49. package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
  50. package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
  51. package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
  52. package/packages/bundled-features/src/auth-mfa/changes.json +6 -0
  53. package/packages/bundled-features/src/auth-mfa/feature-exports.ts +2 -2
  54. package/packages/bundled-features/src/auth-mfa/feature.ts +6 -0
  55. package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
  56. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
  57. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
  58. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  59. package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
  60. package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
  61. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  62. package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
  63. package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
  64. package/packages/bundled-features/src/auth-mfa/web/i18n.ts +9 -4
  65. package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
  66. package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
  67. package/packages/bundled-features/src/auth-mfa/web/mfa-code-or-recovery-field.tsx +68 -0
  68. package/packages/bundled-features/src/auth-mfa/web/mfa-disable-dialog.tsx +23 -13
  69. package/packages/bundled-features/src/auth-mfa/web/mfa-regenerate-recovery-dialog.tsx +23 -13
  70. package/packages/bundled-features/src/auth-mfa/web/mfa-setup-preauth-screen.tsx +15 -6
  71. package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +71 -24
  72. package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
  73. package/packages/bundled-features/src/billing-foundation/changes.json +55 -0
  74. package/packages/bundled-features/src/billing-foundation/checkout-core.ts +32 -42
  75. package/packages/bundled-features/src/billing-foundation/consumer-protection/confirmation-mail.ts +8 -2
  76. package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-gate.ts +2 -0
  77. package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +14 -3
  78. package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +3 -4
  79. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-receipt-limit.ts +12 -6
  80. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +35 -19
  81. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +12 -8
  82. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-revoke.ts +14 -8
  83. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +5 -0
  84. package/packages/bundled-features/src/billing-foundation/consumer-protection/withdrawal-period.ts +8 -10
  85. package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
  86. package/packages/bundled-features/src/billing-foundation/events.ts +23 -21
  87. package/packages/bundled-features/src/billing-foundation/feature.ts +45 -44
  88. package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
  89. package/packages/bundled-features/src/billing-foundation/handlers/billing-plans.query.ts +71 -6
  90. package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +19 -17
  91. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
  92. package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
  93. package/packages/bundled-features/src/billing-foundation/handlers/plan-switch-preview.query.ts +65 -0
  94. package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +29 -22
  95. package/packages/bundled-features/src/billing-foundation/handlers/start-plan-checkout.write.ts +44 -8
  96. package/packages/bundled-features/src/billing-foundation/handlers/switch-plan.write.ts +72 -82
  97. package/packages/bundled-features/src/billing-foundation/handlers/sync-subscription.write.ts +14 -1
  98. package/packages/bundled-features/src/billing-foundation/i18n.ts +22 -0
  99. package/packages/bundled-features/src/billing-foundation/index.ts +2 -0
  100. package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +62 -27
  101. package/packages/bundled-features/src/billing-foundation/plan-switch.ts +84 -0
  102. package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
  103. package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
  104. package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
  105. package/packages/bundled-features/src/billing-foundation/types.ts +144 -66
  106. package/packages/bundled-features/src/billing-foundation/validate-options.ts +19 -0
  107. package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +123 -51
  108. package/packages/bundled-features/src/billing-foundation/web/checkout-consent-dialog.tsx +89 -42
  109. package/packages/bundled-features/src/billing-foundation/web/constants.ts +4 -0
  110. package/packages/bundled-features/src/billing-foundation/web/plan-price.ts +55 -0
  111. package/packages/bundled-features/src/billing-foundation/web/plan-switch-confirm-dialog.tsx +224 -0
  112. package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
  113. package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
  114. package/packages/bundled-features/src/cap-counter/cap-reservation.ts +5 -1
  115. package/packages/bundled-features/src/cap-counter/changes.json +18 -0
  116. package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
  117. package/packages/bundled-features/src/cap-counter/enforce-cap.ts +66 -68
  118. package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
  119. package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
  120. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
  121. package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
  122. package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +9 -2
  123. package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
  124. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
  125. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
  126. package/packages/bundled-features/src/channel-email/changes.json +6 -0
  127. package/packages/bundled-features/src/channel-email/feature.ts +1 -1
  128. package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
  129. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
  130. package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
  131. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
  132. package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
  133. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
  134. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
  135. package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
  136. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
  137. package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
  138. package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
  139. package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
  140. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
  141. package/packages/bundled-features/src/config/changes.json +12 -0
  142. package/packages/bundled-features/src/config/handlers/cascade.query.ts +4 -2
  143. package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
  144. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
  145. package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
  146. package/packages/bundled-features/src/config/handlers/values.query.ts +4 -2
  147. package/packages/bundled-features/src/config/resolver.ts +4 -4
  148. package/packages/bundled-features/src/config/table.ts +10 -10
  149. package/packages/bundled-features/src/config/write-helpers.ts +28 -9
  150. package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
  151. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +23 -21
  152. package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
  153. package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
  154. package/packages/bundled-features/src/custom-fields/events.ts +7 -8
  155. package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
  156. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
  157. package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
  158. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
  159. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
  160. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
  161. package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
  162. package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
  163. package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.ts +1 -1
  164. package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
  165. package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -12
  166. package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
  167. package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
  168. package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
  169. package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
  170. package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
  171. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
  172. package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
  173. package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
  174. package/packages/bundled-features/src/data-retention/feature.ts +11 -18
  175. package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
  176. package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
  177. package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
  178. package/packages/bundled-features/src/data-retention/presets.ts +18 -23
  179. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  180. package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
  181. package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
  182. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
  183. package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
  184. package/packages/bundled-features/src/delivery/changes.json +30 -0
  185. package/packages/bundled-features/src/delivery/channel-context.ts +9 -3
  186. package/packages/bundled-features/src/delivery/db/queries/preferences.ts +2 -2
  187. package/packages/bundled-features/src/delivery/delivery-service.ts +35 -5
  188. package/packages/bundled-features/src/delivery/feature.ts +3 -3
  189. package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
  190. package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +20 -1
  191. package/packages/bundled-features/src/delivery/handlers/unsubscribe-page-chrome.query.ts +1 -1
  192. package/packages/bundled-features/src/delivery/tables.ts +9 -8
  193. package/packages/bundled-features/src/delivery/unsubscribe-link.ts +3 -1
  194. package/packages/bundled-features/src/delivery/unsubscribe-page-strings.ts +1 -0
  195. package/packages/bundled-features/src/delivery/unsubscribe-page.ts +6 -0
  196. package/packages/bundled-features/src/delivery/unsubscribe.ts +40 -19
  197. package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
  198. package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
  199. package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
  200. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
  201. package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
  202. package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +4 -4
  203. package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
  204. package/packages/bundled-features/src/feature-toggles/feature.ts +1 -1
  205. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  206. package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
  207. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  208. package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
  209. package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
  210. package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
  211. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  212. package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
  213. package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
  214. package/packages/bundled-features/src/file-foundation/index.ts +1 -0
  215. package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +7 -1
  216. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
  217. package/packages/bundled-features/src/file-provider-s3/env-named-feature.ts +0 -2
  218. package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
  219. package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
  220. package/packages/bundled-features/src/files/README.md +1 -1
  221. package/packages/bundled-features/src/files/feature.ts +6 -6
  222. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
  223. package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
  224. package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
  225. package/packages/bundled-features/src/folders/feature.ts +1 -1
  226. package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
  227. package/packages/bundled-features/src/folders/web/tree.ts +5 -5
  228. package/packages/bundled-features/src/form-draft/changes.json +6 -0
  229. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +3 -3
  230. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
  231. package/packages/bundled-features/src/form-draft/decrypt-draft.ts +4 -1
  232. package/packages/bundled-features/src/form-draft/entity.ts +3 -3
  233. package/packages/bundled-features/src/form-draft/feature.ts +4 -5
  234. package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
  235. package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
  236. package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
  237. package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
  238. package/packages/bundled-features/src/host-routing/README.md +1 -1
  239. package/packages/bundled-features/src/host-routing/changes.json +6 -0
  240. package/packages/bundled-features/src/host-routing/dispatch.ts +16 -17
  241. package/packages/bundled-features/src/host-routing/options.ts +2 -1
  242. package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
  243. package/packages/bundled-features/src/inbound-mail-foundation/changes.json +18 -0
  244. package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
  245. package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
  246. package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
  247. package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
  248. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
  249. package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
  250. package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
  251. package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
  252. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
  253. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
  254. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
  255. package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
  256. package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +27 -15
  257. package/packages/bundled-features/src/inbound-mail-foundation/i18n.ts +0 -1
  258. package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
  259. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
  260. package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
  261. package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
  262. package/packages/bundled-features/src/inbound-mail-foundation/screens.ts +0 -3
  263. package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
  264. package/packages/bundled-features/src/inbound-mail-foundation/types.ts +70 -70
  265. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +101 -84
  266. package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
  267. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
  268. package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
  269. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
  270. package/packages/bundled-features/src/jobs/changes.json +13 -0
  271. package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
  272. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
  273. package/packages/bundled-features/src/jobs/events.ts +1 -1
  274. package/packages/bundled-features/src/jobs/feature.ts +20 -11
  275. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
  276. package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
  277. package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
  278. package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
  279. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  280. package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +45 -40
  281. package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +63 -59
  282. package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
  283. package/packages/bundled-features/src/jobs/job-run-logger.ts +19 -19
  284. package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
  285. package/packages/bundled-features/src/jobs/screens.ts +1 -1
  286. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  287. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  288. package/packages/bundled-features/src/ledger/entity.ts +5 -5
  289. package/packages/bundled-features/src/ledger/feature.ts +3 -3
  290. package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
  291. package/packages/bundled-features/src/ledger/recurring.ts +12 -12
  292. package/packages/bundled-features/src/ledger/schemas.ts +1 -1
  293. package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
  294. package/packages/bundled-features/src/ledger/web/index.ts +7 -7
  295. package/packages/bundled-features/src/legal-pages/README.md +1 -1
  296. package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
  297. package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
  298. package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
  299. package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
  300. package/packages/bundled-features/src/mail-foundation/changes.json +6 -0
  301. package/packages/bundled-features/src/mail-foundation/feature.ts +31 -30
  302. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
  303. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
  304. package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
  305. package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
  306. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
  307. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
  308. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
  309. package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
  310. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
  311. package/packages/bundled-features/src/managed-pages/table.ts +16 -15
  312. package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
  313. package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
  314. package/packages/bundled-features/src/notes-history/entity.ts +4 -4
  315. package/packages/bundled-features/src/notes-history/feature.ts +2 -2
  316. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  317. package/packages/bundled-features/src/page-render/layout.ts +9 -9
  318. package/packages/bundled-features/src/page-render/markdown.ts +11 -11
  319. package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
  320. package/packages/bundled-features/src/personal-access-tokens/feature.ts +9 -6
  321. package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
  322. package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
  323. package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
  324. package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
  325. package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
  326. package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
  327. package/packages/bundled-features/src/renderer-pdf/changes.json +6 -0
  328. package/packages/bundled-features/src/renderer-pdf/render-table-pdf.ts +27 -10
  329. package/packages/bundled-features/src/secrets/feature.ts +9 -9
  330. package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
  331. package/packages/bundled-features/src/seo/feature.ts +3 -3
  332. package/packages/bundled-features/src/sessions/constants.ts +1 -1
  333. package/packages/bundled-features/src/sessions/feature.ts +16 -11
  334. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
  335. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +2 -2
  336. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  337. package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
  338. package/packages/bundled-features/src/sessions/screens.ts +2 -2
  339. package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
  340. package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
  341. package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
  342. package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +11 -1
  343. package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
  344. package/packages/bundled-features/src/shared/index.ts +1 -1
  345. package/packages/bundled-features/src/shared/mail-template-body.ts +10 -3
  346. package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
  347. package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
  348. package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
  349. package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
  350. package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
  351. package/packages/bundled-features/src/step-dispatcher/changes.json +6 -0
  352. package/packages/bundled-features/src/step-dispatcher/feature.ts +1 -0
  353. package/packages/bundled-features/src/subscription-dodo/changes.json +14 -0
  354. package/packages/bundled-features/src/subscription-dodo/client.ts +45 -0
  355. package/packages/bundled-features/src/subscription-dodo/constants.ts +24 -0
  356. package/packages/bundled-features/src/subscription-dodo/feature.ts +207 -0
  357. package/packages/bundled-features/src/subscription-dodo/index.ts +16 -0
  358. package/packages/bundled-features/src/subscription-dodo/plugin-methods.ts +345 -0
  359. package/packages/bundled-features/src/subscription-dodo/runtime.ts +126 -0
  360. package/packages/bundled-features/src/subscription-dodo/verify-webhook.ts +262 -0
  361. package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
  362. package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
  363. package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
  364. package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
  365. package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
  366. package/packages/bundled-features/src/subscription-stripe/changes.json +12 -0
  367. package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
  368. package/packages/bundled-features/src/subscription-stripe/feature.ts +45 -43
  369. package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
  370. package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
  371. package/packages/bundled-features/src/subscription-stripe/runtime.ts +9 -8
  372. package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
  373. package/packages/bundled-features/src/tags/feature.ts +3 -3
  374. package/packages/bundled-features/src/tags/screens.ts +1 -1
  375. package/packages/bundled-features/src/template-resolver/api.ts +41 -14
  376. package/packages/bundled-features/src/template-resolver/changes.json +48 -0
  377. package/packages/bundled-features/src/template-resolver/compile-document-body.ts +1 -0
  378. package/packages/bundled-features/src/template-resolver/feature.ts +2 -2
  379. package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +3 -2
  380. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +27 -5
  381. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +3 -2
  382. package/packages/bundled-features/src/template-resolver/handlers/document-base.ts +3 -2
  383. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +8 -7
  384. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +19 -20
  385. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +15 -5
  386. package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
  387. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
  388. package/packages/bundled-features/src/template-resolver/handlers/tenant-override-counts.query.ts +9 -5
  389. package/packages/bundled-features/src/template-resolver/handlers/tenant-override-selection.ts +8 -6
  390. package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +44 -5
  391. package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
  392. package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
  393. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +37 -26
  394. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +7 -2
  395. package/packages/bundled-features/src/template-resolver/seeding.ts +36 -18
  396. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +22 -4
  397. package/packages/bundled-features/src/template-resolver/table.ts +13 -14
  398. package/packages/bundled-features/src/template-resolver/template-delivery-policy.ts +0 -11
  399. package/packages/bundled-features/src/template-resolver/template-meta.ts +12 -4
  400. package/packages/bundled-features/src/template-resolver/template-preview.ts +11 -3
  401. package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
  402. package/packages/bundled-features/src/template-resolver/web/constants.ts +7 -5
  403. package/packages/bundled-features/src/template-resolver/web/index.ts +7 -0
  404. package/packages/bundled-features/src/template-resolver/web/mail-layout-constants.ts +8 -0
  405. package/packages/bundled-features/src/tenant/changes.json +6 -0
  406. package/packages/bundled-features/src/tenant/feature.ts +7 -7
  407. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +10 -4
  408. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  409. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  410. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  411. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +8 -5
  412. package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
  413. package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
  414. package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
  415. package/packages/bundled-features/src/tenant/screens.ts +1 -1
  416. package/packages/bundled-features/src/tenant/seeding.ts +19 -18
  417. package/packages/bundled-features/src/tenant/testing.ts +5 -6
  418. package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
  419. package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
  420. package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
  421. package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
  422. package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
  423. package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
  424. package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
  425. package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
  426. package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
  427. package/packages/bundled-features/src/tenant-lifecycle/changes.json +6 -0
  428. package/packages/bundled-features/src/tenant-lifecycle/constants.ts +5 -0
  429. package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
  430. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +7 -3
  431. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
  432. package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
  433. package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
  434. package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
  435. package/packages/bundled-features/src/tier-engine/changes.json +6 -0
  436. package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
  437. package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
  438. package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
  439. package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
  440. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
  441. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +12 -9
  442. package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
  443. package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
  444. package/packages/bundled-features/src/tier-engine/web/constants.ts +3 -3
  445. package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
  446. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
  447. package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
  448. package/packages/bundled-features/src/user/schema/user.ts +45 -44
  449. package/packages/bundled-features/src/user/seeding.ts +40 -40
  450. package/packages/bundled-features/src/user/testing.ts +3 -3
  451. package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
  452. package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
  453. package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
  454. package/packages/bundled-features/src/user-data-rights/feature.ts +112 -113
  455. package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
  456. package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
  457. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
  458. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
  459. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
  460. package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
  461. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
  462. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +4 -4
  463. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
  464. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
  465. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
  466. package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
  467. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
  468. package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
  469. package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
  470. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
  471. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +169 -280
  472. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +87 -108
  473. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
  474. package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
  475. package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
  476. package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
  477. package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
  478. package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
  479. package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
  480. package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
  481. package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
  482. package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
  483. package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
  484. package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
  485. package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
  486. package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
  487. package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
  488. package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
  489. package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
  490. package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +1 -1
  491. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
  492. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
  493. package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
  494. package/packages/bundled-features/src/user-profile/index.ts +3 -3
  495. package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
  496. package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
  497. package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
  498. package/packages/bundled-features/src/waitlist/changes.json +18 -0
  499. package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +2 -1
  500. package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +5 -5
  501. package/packages/bundled-features/src/waitlist/import.ts +5 -0
  502. package/packages/bundled-features/src/waitlist/legacy-migrate.ts +22 -3
  503. package/packages/bundled-features/src/waitlist/link-on-signup.ts +20 -10
  504. package/packages/bundled-features/src/waitlist/options.ts +3 -0
  505. package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
  506. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
  507. package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
  508. package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
  509. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
  510. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
  511. package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
  512. package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
  513. package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
  514. package/samples/apps/styleguide/src/features/widgets/i18n.ts +11 -0
  515. package/samples/apps/styleguide/src/features/widgets/web/Widgets.tsx +24 -0
  516. package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-constants.ts +5 -0
  517. package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-features.ts +90 -15
  518. package/samples/apps/use-all-bundled/e2e-billing-gallery/server.ts +16 -6
  519. package/samples/apps/use-all-bundled/feature-manifest.json +120 -3
  520. package/samples/apps/use-all-bundled/src/run-config.ts +9 -3
  521. package/samples/recipes/auth-mfa/README.md +5 -0
  522. package/samples/recipes/auth-mfa/package.json +5 -2
  523. package/samples/recipes/auth-mfa/src/web/confirmation-code-step.tsx +49 -0
  524. package/samples/recipes/auth-mfa/tsconfig.json +8 -0
  525. package/samples/recipes/env-composition/README.md +3 -1
  526. package/samples/recipes/env-composition/src/env.ts +2 -0
  527. package/samples/recipes/legal-pages/README.md +1 -1
  528. package/samples/recipes/rate-limiting/README.md +18 -0
  529. package/samples/recipes/rate-limiting/src/feature.ts +12 -0
  530. package/packages/bundled-features/src/billing-foundation/consumer-protection/stored-user-email.ts +0 -12
@@ -1,50 +1,49 @@
1
- // custom-fields — Tenant- + System-scoped Custom-Field-Definitions +
2
- // generische Custom-Field-VALUE write-handler (host-stream-events).
1
+ // custom-fields — tenant- and system-scoped custom-field definitions plus
2
+ // generic custom-field value write-handlers (host-stream events).
3
3
  //
4
- // **Scope: supplemental business data, NO PII (#972).** Custom fields sind
5
- // für tenant-spezifische Zusatzinfos (Referenznummern, Flags, Kategorien) —
6
- // nicht für personenbezogene Daten. Das frühere `sensitive`-Flag wurde
7
- // entfernt; das Schema rejected es und `parseSerializedField` wirft auf
8
- // Alt-Definitionen. Werte stehen vollständig im Event-Log (rebuild-safe).
4
+ // **Scope: supplemental business data, NO PII.** Custom fields are for
5
+ // tenant-specific additional data (reference numbers, flags, categories),
6
+ // not personally identifiable information. The former `sensitive` flag was
7
+ // removed; the schema rejects it and `parseSerializedField` throws for legacy
8
+ // definitions. Values are stored entirely in the event log (rebuild-safe).
9
9
  // PII belongs in schema-entity fields with a `personal` annotation
10
10
  // (crypto-shredding, event ciphertext, forget pipeline).
11
11
  //
12
- // **Was diese Feature liefert (B1 + B2, 2026-05-23):**
13
- // 1. r.entity({ name: "field-definition" }) — Definition-Storage (event-sourced).
14
- // 2. define-tenant-field / define-system-field — RBAC write-handlers für
15
- // Definition-CRUD.
12
+ // **This feature provides:**
13
+ // 1. r.entity({ name: "field-definition" }) — event-sourced definition storage.
14
+ // 2. define-tenant-field / define-system-field — RBAC write-handlers for
15
+ // definition CRUD.
16
16
  // 3. delete-tenant-field / delete-system-field — RBAC write-handlers.
17
- // 3b. update-tenant-field — Vollersatz-Edit (Bug-Bash D2); type immutable.
18
- // 4. set-custom-field / clear-custom-field — write-handlers für VALUES.
19
- // Emittieren customField.set/.cleared-Events auf host-aggregate-stream.
20
- // 5. r.defineEvent für customField.set/.cleared + fieldDefinition.deleted.
21
- // 6. r.extendsRegistrar("customFields") — registriert die extension-name
22
- // damit consumer via r.useExtension("customFields", "<entity>") opt-in.
23
- // 7. defineEntityListHandler — read fieldDefinitions (B1-limit: nur tenant-
24
- // scope; B2-todo: system+tenant UNION als custom query).
17
+ // 3b. update-tenant-field — full-replacement edit; type is immutable.
18
+ // 4. set-custom-field / clear-custom-field — write-handlers for VALUES.
19
+ // They emit customField.set/.cleared events on the host aggregate stream.
20
+ // 5. r.defineEvent for customField.set/.cleared + fieldDefinition.deleted.
21
+ // 6. r.extendsRegistrar("customFields") — registers the extension name so
22
+ // consumers can opt in via r.useExtension("customFields", "<entity>").
23
+ // 7. defineEntityListHandler — reads fieldDefinitions (currently tenant-
24
+ // scoped; a system+tenant UNION requires a custom query).
25
25
  //
26
- // **Consumer-side-Wiring** (siehe wire-for-entity.ts):
27
- // Consumer ruft `wireCustomFieldsFor(r, entityName, entityTable)` auf —
28
- // das registriert pro host-entity: useExtension + MSP (jsonb-projection)
29
- // + postQuery-hook (flatten) + search-payload-extension.
26
+ // **Consumer-side wiring** (see wire-for-entity.ts):
27
+ // The consumer calls `wireCustomFieldsFor(r, entityName, entityTable)`,
28
+ // which registers per host entity: useExtension + MSP (JSONB projection)
29
+ // + postQuery hook (flattening) + search-payload extension.
30
30
  //
31
- // **Host-Entity-Requirement**:
32
- // Consumer MUSS in der entity-definition eine `customFields`-Spalte als
33
- // `customFieldsField()` (jsonb) deklarieren.
31
+ // **Host-entity requirement**:
32
+ // The consumer MUST declare a `customFields` column as
33
+ // `customFieldsField()` (JSONB) in the entity definition.
34
34
  //
35
- // **Exports-Pattern (2026-05-23 refactor)**:
35
+ // **Exports pattern**:
36
36
  // `createCustomFieldsFeature().exports.{setEvent,clearedEvent,fieldDefinitionDeletedEvent}`
37
- // liefern typed EventDef-handles. Handler + wire-for-entity nutzen
38
- // `<event>.name` als compile-time-literal-typed qualified-string — keine
39
- // hand-gebauten Template-Literals mehr (T1 hat den toKebab-collapse-drift
40
- // aufgedeckt, siehe Memory feedback_event_def_exports_pattern).
37
+ // provides typed EventDef handles. Handlers and wire-for-entity use
38
+ // `<event>.name` as a compile-time literal-typed qualified string instead of
39
+ // hand-built template literals, which drifted from the real names once
40
+ // toKebab collapsed them.
41
41
  //
42
- // **Noch offen (future iterations)**:
43
- // - Cross-scope-conflict-Detection (Tenant überschreibt system fieldKey)
44
- // - Cross-Scope-Read-UNION (system + tenant fieldDefinitions in einem List)
45
- // (cap-counter-quota → T1.5e, user-data-rights-anonymization → T1.5c,
46
- // Value-Validation gegen serializedField → set-custom-field via fieldToZod —
47
- // alle erledigt.)
42
+ // **Still open:**
43
+ // - Cross-scope conflict detection (a tenant overriding a system fieldKey)
44
+ // - Cross-scope read UNION (system + tenant fieldDefinitions in one list)
45
+ // (cap-counter quota, user-data-rights anonymization, and value validation
46
+ // against serializedField via fieldToZod in set-custom-field are complete.)
48
47
 
49
48
  import {
50
49
  defineEntityListHandler,
@@ -97,10 +96,9 @@ const fieldDefinitionDeletedSchema = z.object({
97
96
  tenantId: z.string().optional(),
98
97
  });
99
98
 
100
- // Handler-/Access-Varianten die zwischen Singleton und Options-Variante
101
- // differieren können. Alles andere registriert registerCustomFields für
102
- // beide identisch, damit ein neues Event/Handler nie still die
103
- // Options-Variante verfehlt.
99
+ // Handler and access variants can differ between the singleton and options
100
+ // variant. Everything else registers identically through registerCustomFields
101
+ // so a new event or handler cannot silently be omitted from the options variant.
104
102
  type RegisterVariant = {
105
103
  readonly defineTenantHandler: WriteHandlerDef;
106
104
  readonly updateTenantHandler: WriteHandlerDef;
@@ -125,9 +123,9 @@ function registerCustomFields(
125
123
  });
126
124
  r.entity({ name: "field-definition", ...fieldDefinitionEntity });
127
125
 
128
- // Event-types — qualified als "custom-fields:event:<short-name>".
129
- // Returned EventDefs liefern .name als compile-time literal-typed string,
130
- // den Handler + MSP-keys konsumieren statt Template-Literal-Konstruktion.
126
+ // Event types — qualified as "custom-fields:event:<short-name>".
127
+ // Returned EventDefs expose .name as a compile-time literal-typed string,
128
+ // which handlers and MSP keys consume instead of constructing template literals.
131
129
  // `value: z.unknown()` has no field-level schema to catalog under piiFields
132
130
  // (event PII covers string fields only), so "no PII" is a convention here,
133
131
  // not an enforced guarantee.
@@ -143,31 +141,31 @@ function registerCustomFields(
143
141
  { piiFields: "none" },
144
142
  );
145
143
 
146
- // Extension-Registrar — registriert dass diese Extension existiert.
147
- // Consumer-side: r.useExtension("customFields", "<entity>") MARKIERT
148
- // opt-in, aber wired NICHTS automatisch. Consumer MUSS zusätzlich
149
- // `wireCustomFieldsFor(r, entity, table)` aufrufen damit MSP +
150
- // postQuery-hook + search-extension tatsächlich registriert werden.
151
- // Empty-options-Pattern (`{}`) ist absichtlich — boot-time-onRegister-
152
- // wiring würde Closure über Drizzle-Table benötigen, die der Consumer
153
- // bei extendsRegistrar-Registration nicht kennt. Daher consumer-side
154
- // explicit-wiring statt magic-auto-wiring.
144
+ // Registers that this extension exists.
145
+ // Consumer-side: r.useExtension("customFields", "<entity>") marks opt-in,
146
+ // but does not wire anything automatically. The consumer MUST also call
147
+ // `wireCustomFieldsFor(r, entity, table)` to register the MSP, postQuery hook,
148
+ // and search extension.
149
+ // The empty-options pattern (`{}`) is intentional: boot-time onRegister
150
+ // wiring would require a closure over the Drizzle table, which the consumer
151
+ // does not provide during extendsRegistrar registration. Explicit consumer-
152
+ // side wiring therefore avoids implicit magic.
155
153
  r.extendsRegistrar(CUSTOM_FIELDS_EXTENSION, {});
156
154
 
157
- // Definition-CRUD handlers (B1; update kam mit Bug-Bash D2 2026-06-08).
155
+ // Definition CRUD handlers.
158
156
  r.writeHandler(variant.defineTenantHandler);
159
157
  r.writeHandler(defineSystemFieldHandler);
160
158
  r.writeHandler(variant.updateTenantHandler);
161
159
  r.writeHandler(variant.deleteTenantHandler);
162
160
  r.writeHandler(deleteSystemFieldHandler);
163
161
 
164
- // Value-write handlers (B2). Emittieren events auf host-aggregate-stream.
162
+ // Value write handlers. They emit events on the host aggregate stream.
165
163
  r.writeHandler(variant.setHandler);
166
164
  r.writeHandler(variant.clearHandler);
167
165
 
168
- // List-Query — tenant-scoped (B1-limit). Die CustomFieldsFormSection
169
- // dispatcht diesen QN hart — Apps mit eigenem Rollen-Vokabular
170
- // überschreiben die Rollen via fieldDefinitionListRoles.
166
+ // The list query is tenant-scoped. CustomFieldsFormSection dispatches this
167
+ // query name directly, so apps with their own role vocabulary must override
168
+ // the roles through fieldDefinitionListRoles.
171
169
  r.queryHandler(
172
170
  defineEntityListHandler("field-definition", fieldDefinitionEntity, {
173
171
  access: { roles: variant.fieldDefinitionListRoles },
@@ -193,24 +191,24 @@ const defaultCustomFieldsFeature = defineFeature(CUSTOM_FIELDS_FEATURE_NAME, (r)
193
191
  );
194
192
 
195
193
  export type CustomFieldsFeatureOptions = {
196
- /** T1.5e: Quota für define-tenant-field. */
194
+ /** Quota for define-tenant-field. */
197
195
  readonly fieldDefinitionLimitPerTenant?: number;
198
- /** Rollen für set-/clear-custom-field — die Save-Pfade der
199
- * CustomFieldsFormSection. Default ["TenantAdmin","TenantMember"];
200
- * Apps mit eigenem Rollen-Vokabular (z.B. ["Admin","Editor"]) MÜSSEN
201
- * das setzen, sonst ist der Value-Save für jeden App-User
202
- * access_denied (Role-Naming-Drift). */
196
+ /** Roles for set-/clear-custom-field, used by the save paths in
197
+ * CustomFieldsFormSection. Default ["TenantAdmin","TenantMember"];
198
+ * apps with their own role vocabulary (for example ["Admin","Editor"])
199
+ * MUST set this, otherwise value saving is access_denied for every app user
200
+ * (role-naming drift). */
203
201
  readonly valueWriteRoles?: readonly string[];
204
- /** Rollen für custom-fields:query:field-definition:list — der Lade-Pfad
205
- * der CustomFieldsFormSection. Default ["TenantAdmin"]. Wird valueWriteRoles
206
- * gesetzt, dies aber NICHT, erben die Value-Rollen hier hinein (Union mit
207
- * dem Default, damit Admins den List-Zugriff behalten) — sonst lädt die
208
- * FormSection für Value-Writer nie (access_denied), während der Save-Pfad
209
- * offen wäre (asymmetrischer Bruch). */
202
+ /** Roles for custom-fields:query:field-definition:list, used by the loading
203
+ * path in CustomFieldsFormSection. Default ["TenantAdmin"]. If
204
+ * valueWriteRoles is set but this is not, the value roles are inherited here
205
+ * (unioned with the default so admins retain list access); otherwise the
206
+ * FormSection cannot load for value writers (access_denied) while the save
207
+ * path remains open (an asymmetric break). */
210
208
  readonly fieldDefinitionListRoles?: readonly string[];
211
209
  /** Access roles for the definition-CRUD triad (`define-tenant-field`,
212
- * `update-tenant-field`, `delete-tenant-field`) — hard-wired to ["TenantAdmin"]
213
- * before #2296. Apps with their own role vocabulary (e.g. ["Admin","Editor"])
210
+ * `update-tenant-field`, `delete-tenant-field`) — hard-wired to ["TenantAdmin"].
211
+ * Apps with their own role vocabulary (e.g. ["Admin","Editor"])
214
212
  * MUST set this, else field-definition management is access_denied for every
215
213
  * app-user without a "TenantAdmin" role. Only covers the tenant-scope triad —
216
214
  * define-/delete-system-field stay hard-wired to ["SystemAdmin"], since
@@ -19,13 +19,13 @@ export type ClearCustomFieldPayload = z.infer<typeof clearCustomFieldPayloadSche
19
19
  const CLEAR_CUSTOM_FIELD_REASON =
20
20
  "reads custom field definitions with an explicit tenant_id = caller tenant via raw SQL with read retry";
21
21
 
22
- // clear-custom-field — entfernt einen Custom-Field-Wert von einer host-
23
- // entity. Emittiert customField.cleared-Event; MSP entfernt key aus
24
- // jsonb-column (key-removal, nicht null-set).
22
+ // clear-custom-field — removes a custom-field value from a host entity.
23
+ // Emits the customField.cleared event; MSP removes the key from the
24
+ // jsonb column (key removal, not setting it to null).
25
25
  //
26
- // T1.5b: per-field fieldAccess.write gate — caller muss eine der definierten
27
- // Rollen halten falls fieldDefinition.serializedField.fieldAccess.write
28
- // gesetzt ist. Handler-level RBAC (TenantAdmin/Member) bleibt zusätzlich.
26
+ // Per-field fieldAccess.write gate: the caller must hold one of the defined
27
+ // roles when fieldDefinition.serializedField.fieldAccess.write is set.
28
+ // Handler-level RBAC (TenantAdmin/Member) still applies as well.
29
29
  export const clearCustomFieldHandler: WriteHandlerDef = {
30
30
  name: "clear-custom-field",
31
31
  schema: clearCustomFieldPayloadSchema,
@@ -73,8 +73,9 @@ export const clearCustomFieldHandler: WriteHandlerDef = {
73
73
  },
74
74
  };
75
75
 
76
- /** Pendant zu createSetCustomFieldHandler — gleiche Rollen für set + clear,
77
- * ein Wert ohne Clear-Recht wäre nur halb beherrschbar. */
76
+ /** Companion to createSetCustomFieldHandler: set and clear use the same roles;
77
+ * allowing a value to be set without allowing it to be cleared would leave
78
+ * access control incomplete. */
78
79
  export function createClearCustomFieldHandler(
79
80
  roles: readonly string[] = DEFAULT_VALUE_WRITE_ROLES,
80
81
  ): WriteHandlerDef {
@@ -7,38 +7,40 @@ import { countTenantFieldDefinitions } from "../lib/quota.ts";
7
7
  import { type DefineFieldPayload, defineFieldPayloadSchema } from "../schemas.ts";
8
8
  import { DEFAULT_FIELD_DEFINITION_WRITE_ROLES } from "../web/constants.ts";
9
9
 
10
- // define-tenant-field — TenantAdmin definiert eine Custom-Field-Definition
11
- // für seinen eigenen Tenant. tenantId wird automatisch aus event.user.tenantId
12
- // abgeleitet (NICHT vom Caller setzbar — verhindert Cross-Tenant-Mutation).
10
+ // define-tenant-field — TenantAdmin defines a custom-field definition
11
+ // for its own tenant. tenantId is derived automatically from
12
+ // event.user.tenantId (NOT settable by the caller — prevents cross-tenant
13
+ // mutation).
13
14
  //
14
- // **Same-scope-conflict** wird natürlich durch aggregate-version-conflict
15
- // enforced: deterministische aggregate-id aus uuidv5(tenant, entity, fieldKey)
16
- // macht einen zweiten Create auf dieselbe Definition ein version_conflict.
17
- // Dispatcher returnt 409. Saubere Idempotency-Garantie ohne extra DB-roundtrip.
15
+ // **Same-scope-conflict** is naturally enforced by the
16
+ // aggregate-version-conflict: the deterministic aggregate-id from
17
+ // uuidv5(tenant, entity, fieldKey) makes a second Create for the same
18
+ // definition a version_conflict. The dispatcher returns 409, providing a
19
+ // clean idempotency guarantee without an extra DB round trip.
18
20
  //
19
- // **Cross-scope-conflict** (tenant versucht fieldKey zu definieren der bereits
20
- // system-scope existiert) wird in B1 NICHT enforced — aggregate-ids
21
- // unterscheiden sich (verschiedene tenantIds in uuidv5), beide writes gehen
22
- // durch. Resolution beim Read (B2) zeigt dann den system-scope-Wert. v2
23
- // kann r.systemScope-Sub-Handler einführen um cross-scope-conflict am Write
24
- // abzulehnen.
21
+ // **Cross-scope-conflict** (a tenant attempts to define a fieldKey that
22
+ // already exists in the system scope) is NOT enforced here — the aggregate
23
+ // IDs differ (different tenantIds in uuidv5), so both writes proceed.
24
+ // Resolution at read time shows the system-scope value. A future version
25
+ // could introduce an r.systemScope sub-handler to reject cross-scope-conflict
26
+ // at write time.
25
27
  //
26
- // **Quota (T1.5e)**: optional `fieldDefinitionLimitPerTenant` gate. When the
27
- // tenant already has ≥ limit definitions, the handler rejects with
28
- // `unprocessable` + reason `cap_exceeded` BEFORE attempting the insert.
29
- // The factory below closes over the limit; the legacy const-export keeps
30
- // behavior unchanged for callers who didn't opt into a limit.
28
+ // **Quota**: optional `fieldDefinitionLimitPerTenant` gate. When the tenant
29
+ // already has ≥ limit definitions, the handler rejects with `unprocessable`
30
+ // and reason `cap_exceeded` BEFORE attempting the insert. The factory below
31
+ // closes over the limit; the legacy const-export preserves behavior for
32
+ // callers that did not opt into a limit.
31
33
  //
32
- // Soft cap, not a hard guarantee: the count-then-insert is not serialized, so
34
+ // Soft cap, not a hard guarantee: count-then-insert is not serialized, so
33
35
  // N concurrent defines with distinct fieldKeys can each read `current < limit`
34
- // and overshoot by up to N. Acceptable here — defining fields is an admin-only,
35
- // low-frequency action and the limit is not wired to billing/tier enforcement.
36
- // If an exact cap is ever needed, serialize via advisory lock or a count
37
- // constraint at the insert.
36
+ // and overshoot by up to N. This is acceptable because defining fields is an
37
+ // admin-only, low-frequency action and the limit is not wired to
38
+ // billing/tier enforcement. If an exact cap is ever needed, serialize via
39
+ // advisory lock or add a count constraint at the insert.
38
40
  export interface DefineTenantFieldOptions {
39
41
  /** Soft cap — `>= limit` definitions per tenant rejects further defines (see header: concurrent defines may overshoot). */
40
42
  readonly fieldDefinitionLimitPerTenant?: number;
41
- /** Access roles for this handler. Default ["TenantAdmin"] (#2296) — apps with
43
+ /** Access roles for this handler. Default ["TenantAdmin"] — apps with
42
44
  * their own role vocabulary pass this via createCustomFieldsFeature({
43
45
  * fieldDefinitionWriteRoles }), which threads the same roles into
44
46
  * update-/delete-tenant-field too (the definition-CRUD triad shares one gate). */
@@ -66,7 +68,7 @@ export function createDefineTenantFieldHandler(
66
68
  const payload = event.payload as DefineFieldPayload; // @cast-boundary engine-payload
67
69
  const tenantId = event.user.tenantId;
68
70
 
69
- // TenantAdmin darf NICHT system-scope schreiben — strict-guard.
71
+ // TenantAdmin MUST NOT write to the system scope — strict guard.
70
72
  if (isSystemTenant(tenantId)) {
71
73
  throw new Error(
72
74
  "define-tenant-field: tenantId is SYSTEM_TENANT_ID — use define-system-field for system-scope definitions",
@@ -101,5 +103,5 @@ export function createDefineTenantFieldHandler(
101
103
  }
102
104
 
103
105
  // Backwards-compat: existing imports of `defineTenantFieldHandler` keep
104
- // working — the handler has no quota, identical to pre-T1.5e behavior.
106
+ // working — the handler has no quota, identical to behavior before the quota.
105
107
  export const defineTenantFieldHandler: WriteHandlerDef = createDefineTenantFieldHandler();
@@ -6,11 +6,10 @@ import { createCustomFieldsFeature } from "../feature.ts";
6
6
  import { type DeleteFieldPayload, deleteFieldPayloadSchema } from "../schemas.ts";
7
7
  import { FIELD_DEFINITION_AGGREGATE_TYPE } from "../web/constants.ts";
8
8
 
9
- // delete-system-field — SystemAdmin entfernt eine system-weite Field-
10
- // Definition. Konsequenz: KEIN Tenant kann mehr neue Werte dafür setzen,
11
- // existing Werte in read_<entity>.customFields jsonb bleiben aber bestehen
12
- // (B2's MSP wird sie via customFieldDefinition.deleted-Event aufräumen).
13
- // Events bleiben für Audit.
9
+ // delete-system-field — SystemAdmin deletes a system-wide field definition.
10
+ // Tenants can no longer set new values for it, but existing values remain in
11
+ // read_<entity>.customFields jsonb until host-entity MSPs remove them in
12
+ // response to the customFieldDefinition.deleted event. Events remain for audit.
14
13
  export const deleteSystemFieldHandler: WriteHandlerDef = {
15
14
  name: "delete-system-field",
16
15
  schema: deleteFieldPayloadSchema,
@@ -32,8 +31,8 @@ export const deleteSystemFieldHandler: WriteHandlerDef = {
32
31
  streamTenantId,
33
32
  });
34
33
 
35
- // Cascade-cleanup-Event — host-entity-MSPs entfernen orphan values aus
36
- // ihrer customFields jsonb. Im selben TX = atomic.
34
+ // Cascade-cleanup event — host-entity MSPs remove orphaned values from their
35
+ // customFields jsonb in the same transaction for atomicity.
37
36
  if (result.isSuccess) {
38
37
  await ctx.unsafeAppendEvent({
39
38
  aggregateId,
@@ -8,18 +8,17 @@ import {
8
8
  FIELD_DEFINITION_AGGREGATE_TYPE,
9
9
  } from "../web/constants.ts";
10
10
 
11
- // delete-tenant-field — TenantAdmin löscht eigene Field-Definition.
12
- // Spec-Promise (Plan-Doc v2 "wie Entity-Delete"): Events bleiben im event-
13
- // store für Audit-Trail. Read-Projection-Row wird entfernt. B2 wird die
14
- // Cleanup-Pipeline (`customFieldDefinition.deleted`-Event → MSP entfernt
15
- // values aus read_<entity>.customFields jsonb) wirklich wiren — in B1
16
- // kümmern wir uns nur um die Definition selbst.
11
+ // delete-tenant-field — TenantAdmin deletes their own field definition.
12
+ // Events remain in the event store for the audit trail, while the read-projection
13
+ // row is removed. The cleanup pipeline (`customFieldDefinition.deleted`-Event → MSP
14
+ // removes values from read_<entity>.customFields jsonb) is wired separately; this
15
+ // handler only manages the definition itself.
17
16
  //
18
- // **Idempotency:** Delete auf nicht-existente Definition → version_conflict
19
- // (executor.delete returns failure, dispatcher 404/422). Caller sieht "not
20
- // found" — kein Crash.
17
+ // **Idempotency:** Deleting a non-existent definition results in version_conflict
18
+ // (executor.delete returns failure, dispatcher 404/422). The caller sees "not
19
+ // found" rather than an exception.
21
20
  export interface DeleteTenantFieldOptions {
22
- /** Access roles for this handler. Default ["TenantAdmin"] (#2296) — see
21
+ /** Access roles for this handler. Default ["TenantAdmin"] — see
23
22
  * DefineTenantFieldOptions.roles, the definition-CRUD triad shares one gate. */
24
23
  readonly roles?: readonly string[];
25
24
  }
@@ -52,9 +51,9 @@ export function createDeleteTenantFieldHandler(
52
51
 
53
52
  const result = await fieldDefinitionExecutor.delete({ id: aggregateId }, event.user, ctx.db);
54
53
 
55
- // Emit cascade-cleanup-Event NACH erfolgreichem Delete. host-entity-MSPs
56
- // (registriert via wireCustomFieldsFor) konsumieren das + entfernen orphan
57
- // values aus ihrer customFields jsonb. Im selben TX = atomic cleanup.
54
+ // Emit the cascade-cleanup event after a successful delete. Host-entity MSPs
55
+ // registered via wireCustomFieldsFor consume it and remove orphaned values
56
+ // from their customFields jsonb. The same transaction makes cleanup atomic.
58
57
  if (result.isSuccess) {
59
58
  await ctx.unsafeAppendEvent({
60
59
  aggregateId,
@@ -25,30 +25,27 @@ export type SetCustomFieldPayload = z.infer<typeof setCustomFieldPayloadSchema>;
25
25
  const SET_CUSTOM_FIELD_REASON =
26
26
  "reads custom field definitions with an explicit tenant_id = caller tenant via raw SQL with read retry";
27
27
 
28
- // set-custom-field — schreibt einen Custom-Field-Wert auf eine host-entity.
28
+ // set-custom-field — writes a custom-field value to a host entity.
29
29
  //
30
- // **ES-Option-B**: emittiert customField.set-Event auf dem host-aggregate
30
+ // Emits a customField.set event on the host-aggregate
31
31
  // stream (aggregateType = host-entity-name, aggregateId = host-entity-id).
32
- // Last-Wins-Semantik: customField.set wird OHNE expectedVersion appended,
33
- // concurrent writes auf gleiches Field gehen beide durch (Plan-Doc v2
34
- // Concurrency-Tabelle).
32
+ // Last-wins semantics: customField.set is appended WITHOUT expectedVersion,
33
+ // so concurrent writes to the same field both succeed.
35
34
  //
36
- // **Write-Pfad (Single-Fetch)** — eine fieldDefinition-Ladung, drei Gates:
37
- // 1. Definition fehlt → 404.
38
- // 2. field-access (T1.5b): fieldAccess.write-Rollen müssen intersecten, sonst
39
- // 403/422. Handler-level RBAC (TenantAdmin/Member) bleibt zusätzlich.
40
- // 3. Value-Validation (Builder-Reuse): der Wert wird gegen das aus
41
- // serializedField rehydrierte fieldToZod-Schema geparst. Type-Mismatch →
42
- // 422, KEIN Event entsteht (Projection bleibt typed — Plan-Doc
43
- // Stammfeld-Identität). `value: null` ODER `value: undefined` auf einem
44
- // typisierten Feld sind Type-Mismatches → 422; zum Entfernen eines Werts
45
- // dient clear-custom-field.
35
+ // **Write path (single fetch)** — one fieldDefinition load, three gates:
36
+ // 1. Definition missing → 404.
37
+ // 2. field-access: fieldAccess.write roles must intersect, otherwise
38
+ // 403/422. Handler-level RBAC (TenantAdmin/Member) also applies.
39
+ // 3. Value validation (builder reuse): the value is parsed against the
40
+ // fieldToZod schema rehydrated from serializedField. Type mismatch →
41
+ // 422, NO event is created (the projection remains typed). `value: null`
42
+ // OR `value: undefined` on a typed field are type mismatches → 422; use
43
+ // clear-custom-field to remove a value.
46
44
  //
47
- // Scope: ECHTE type-only Validation. value-schema.ts strippt `required`,
48
- // `maxLength`, `format` und `default` aus dem serializedField bevor fieldToZod
49
- // daraus ein Schema baut — wir prüfen nur die Type-Shape. Required-on-set,
50
- // Default-Application und Length-/Format-Enforcement bleiben out-of-scope
51
- // (Plan-Doc "Stammfeld-Identität" listet sie als eigene Zeilen).
45
+ // Scope: TRUE type-only validation. value-schema.ts strips `required`,
46
+ // `maxLength`, `format`, and `default` from serializedField before building
47
+ // a schema from fieldToZod — we check only the type shape. Required-on-set,
48
+ // default application, and length/format enforcement remain out of scope.
52
49
  export const setCustomFieldHandler: WriteHandlerDef = {
53
50
  name: "set-custom-field",
54
51
  schema: setCustomFieldPayloadSchema,
@@ -95,11 +92,11 @@ export const setCustomFieldHandler: WriteHandlerDef = {
95
92
  }
96
93
  }
97
94
 
98
- // Emit customField.set on host-aggregate stream. unsafeAppendEvent
99
- // (statt strict appendEvent) weil event-type-map keine cross-feature-
100
- // augmentation für diesen event-typ hat — wir nutzen den qualified
101
- // string-namen direkt. Der Wert steht IMMER im Event (custom fields
102
- // tragen keine PII, #972) — Replay reproduziert die Projection voll.
95
+ // Emit customField.set on the host-aggregate stream. unsafeAppendEvent
96
+ // is used instead of strict appendEvent because event-type-map has no
97
+ // cross-feature augmentation for this event type; the qualified string
98
+ // name is used directly. The value is ALWAYS included in the event
99
+ // (custom fields carry no PII), so replay fully reproduces the projection.
103
100
  await ctx.unsafeAppendEvent({
104
101
  aggregateId: payload.entityId,
105
102
  aggregateType: payload.entityName,
@@ -114,9 +111,9 @@ export const setCustomFieldHandler: WriteHandlerDef = {
114
111
  },
115
112
  };
116
113
 
117
- /** Value-Write mit App-Rollen statt der Bundle-Defaults — Apps mit eigenem
118
- * Rollen-Vokabular (z.B. "Admin"/"Editor") reichen ihre Rollen über
119
- * createCustomFieldsFeature({ valueWriteRoles }) hierher durch. */
114
+ /** Value writes use app roles instead of the bundle defaults — apps with a
115
+ * custom role vocabulary (e.g. "Admin"/"Editor") pass their roles here via
116
+ * createCustomFieldsFeature({ valueWriteRoles }). */
120
117
  export function createSetCustomFieldHandler(
121
118
  roles: readonly string[] = DEFAULT_VALUE_WRITE_ROLES,
122
119
  ): WriteHandlerDef {
@@ -15,10 +15,10 @@ import { DEFAULT_FIELD_DEFINITION_WRITE_ROLES } from "../web/constants.ts";
15
15
  //
16
16
  // **type is immutable**; an omitted type keeps the stored one. A type change
17
17
  // would orphan existing values in the host entities' customFields jsonb (a
18
- // text value under a number field), so delete + re-define is the honest path
19
- // (Bug-Bash D2: deliberately no delete+redefine inside update, since that
20
- // destroys event history and field ids, which is exactly the break a type
21
- // change needs to make visible).
18
+ // text value under a number field), so delete + re-define is the honest path.
19
+ // There is deliberately no delete+redefine inside update, since that destroys
20
+ // event history and field ids, which is exactly the break a type change needs
21
+ // to make visible.
22
22
  //
23
23
  // **Known MVP limit (deliberate):** the edit does NOT reconcile existing host
24
24
  // values against the new definition. Narrowed constraints (enum value removed,
@@ -32,7 +32,7 @@ import { DEFAULT_FIELD_DEFINITION_WRITE_ROLES } from "../web/constants.ts";
32
32
  // (same trade-off as the quota soft cap in define), so last write wins instead
33
33
  // of a version round trip through the edit screen.
34
34
  export interface UpdateTenantFieldOptions {
35
- /** Access roles for this handler. Default ["TenantAdmin"] (#2296) — see
35
+ /** Access roles for this handler. Default ["TenantAdmin"] — see
36
36
  * DefineTenantFieldOptions.roles, the definition-CRUD triad shares one gate. */
37
37
  readonly roles?: readonly string[];
38
38
  }
@@ -87,7 +87,7 @@ export function createUpdateTenantFieldHandler(
87
87
  });
88
88
  }
89
89
 
90
- // entityName/fieldKey sind die Identität — nicht Teil der changes.
90
+ // entityName/fieldKey define the identity and must not be included in changes.
91
91
  const {
92
92
  entityName: _entityName,
93
93
  fieldKey: _fieldKey,
@@ -1,4 +1,4 @@
1
- // T1.5b — per-field write access-check for the set/clear handlers.
1
+ // Per-field write access-check for the set/clear handlers.
2
2
  // Plus single-fetch loader so set-custom-field can run access-check AND
3
3
  // value-validation off one DB read (no double fetch).
4
4
 
@@ -31,7 +31,7 @@ export async function loadFieldDefinition(
31
31
  ): Promise<LoadedFieldDefinition> {
32
32
  const serialized = await selectSerializedFieldDefinition(runner, tenantId, entityName, fieldKey);
33
33
  if (serialized === null) return { found: false };
34
- // parseSerializedField throws on a #972 legacy `sensitive` definition —
34
+ // parseSerializedField throws on a legacy `sensitive` definition —
35
35
  // that's a corrupt/unprocessable row from this write-gate's perspective,
36
36
  // same fail-closed treatment as a shape that fails isShape().
37
37
  try {
@@ -42,7 +42,7 @@ export function parseSerializedField(raw: unknown): SerializedFieldShape | null
42
42
  const parsed = typeof raw === "string" ? parseJsonSafe<unknown>(raw, null) : raw;
43
43
  if (!isShape(parsed)) return null;
44
44
  // Fail loud instead of silently dropping the key: a stored definition with
45
- // `sensitive` predates #972 and its PII expectations (event-log exclusion,
45
+ // `sensitive` predates and its PII expectations (event-log exclusion,
46
46
  // forget-strip) no longer hold — the field must be recreated.
47
47
  if ("sensitive" in parsed) {
48
48
  throw new Error(
@@ -1,4 +1,4 @@
1
- // T1.5e — per-tenant fieldDefinition quota.
1
+ // Per-tenant fieldDefinition quota.
2
2
  //
3
3
  // Re-exports from db/queries/quota.ts for backward-compatible import paths.
4
4
 
@@ -8,23 +8,21 @@ import type * as z from "zod";
8
8
  import { SUPPORTED_FIELD_TYPES } from "../web/constants.ts";
9
9
 
10
10
  // Builds a Zod schema that validates a custom-field VALUE against its
11
- // fieldDefinition. Reuses the framework's `fieldToZod` (Builder-Reuse /
12
- // Stammfeld-Identität, Plan-Doc) — one field-type-schema source, no drift
13
- // between Stammfeld- and Custom-Field-validation.
11
+ // fieldDefinition. Reuses the framework's `fieldToZod` so built-in and
12
+ // custom-field validation share one field-type schema source.
14
13
  //
15
- // Scope: type-shape only. fieldToZod also folds `required`, `maxLength`,
16
- // `format`, and `default` into Zod refinements; we strip those before the
17
- // call so set-custom-field rejects type-mismatches and only type-mismatches.
18
- // Required-on-set, default-application, and length/format-enforcement remain
19
- // out-of-scope per the Plan-Doc ("Stammfeld-Identität" lists them as
20
- // separate concerns).
14
+ // Scope: type-shape only. `fieldToZod` also folds `required`, `maxLength`,
15
+ // `format`, and `default` into Zod refinements; stripping them before the
16
+ // call ensures that setting a custom field rejects only type mismatches.
17
+ // Required-on-set, default application, and length/format enforcement remain
18
+ // separate concerns.
21
19
  //
22
- // Vocabulary bridge: custom-fields expose `enum` (Plan + `r.field.enum([...])`)
23
- // where the framework's FieldDefinition calls the equivalent type `select`
20
+ // Vocabulary bridge: custom fields expose `enum` through `r.field.enum([...])`,
21
+ // while the framework's FieldDefinition calls the equivalent type `select`
24
22
  // with an `options` array.
25
23
  //
26
24
  // Returns `null` when the serialized field is unparseable or names a type
27
- // outside the custom-fields-supported set — callers then skip value-validation.
25
+ // outside the custom-fields-supported set, allowing callers to skip validation.
28
26
 
29
27
  const SUPPORTED_TYPES_SET: ReadonlySet<string> = new Set(SUPPORTED_FIELD_TYPES);
30
28
  const SUPPORTED_EMBEDDED_SUB_TYPES: ReadonlySet<string> = new Set([
@@ -1,4 +1,4 @@
1
- // T1.5d — per-field retention sweep for the customFields jsonb.
1
+ // Per-field retention sweep for the customFields jsonb.
2
2
  //
3
3
  // Iterates one host entity's rows, looks up every fieldDefinition with a
4
4
  // `retention` policy, and strips/nulls customField values whose host-row
@@ -158,7 +158,7 @@ async function loadRetentionPolicies(
158
158
  for (const raw of rows) {
159
159
  // skip: see asHostRow rationale.
160
160
  if (!isFieldDefinitionRow(raw)) continue;
161
- // parseSerializedField throws on a #972 legacy `sensitive` definition —
161
+ // parseSerializedField throws on a legacy `sensitive` definition —
162
162
  // one unmigrated field must not abort the whole tenant's retention sweep
163
163
  // for every other field; skip it (no retention policy to apply anyway).
164
164
  let parsed: ReturnType<typeof parseSerializedField>;
@@ -178,7 +178,7 @@ interface InstantLike {
178
178
  readonly epochMilliseconds: number;
179
179
  }
180
180
 
181
- // guard:dup-ok — false positive: gleiche TypeGuard-Struktur wie isFieldDefinitionRow, völlig andere Semantik
181
+ // guard:dup-ok — false positive: same type-guard structure as isFieldDefinitionRow, but completely different semantics
182
182
  function isInstantLike(value: unknown): value is InstantLike {
183
183
  if (!value || typeof value !== "object") return false;
184
184
  if (!("epochMilliseconds" in value)) return false;