@cosmicdrift/kumiko-samples 0.385.0 → 0.387.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) hide show
  1. package/LICENSE +21 -57
  2. package/README.md +1 -1
  3. package/package.json +2 -2
  4. package/packages/bundled-features/package.json +2 -2
  5. package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
  6. package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +0 -2
  7. package/packages/bundled-features/src/audit/screens.ts +1 -1
  8. package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
  9. package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
  10. package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
  11. package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
  12. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
  13. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
  14. package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
  15. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  16. package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
  17. package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
  18. package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
  19. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +34 -37
  20. package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
  21. package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
  22. package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
  23. package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
  24. package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
  25. package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
  26. package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
  27. package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
  28. package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
  29. package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
  30. package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
  31. package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
  32. package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
  33. package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
  34. package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
  35. package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
  36. package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
  37. package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
  38. package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
  39. package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
  40. package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
  41. package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
  42. package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
  43. package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
  44. package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
  45. package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
  46. package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
  47. package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
  48. package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
  49. package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
  50. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
  51. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
  52. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  53. package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
  54. package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
  55. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  56. package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
  57. package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
  58. package/packages/bundled-features/src/auth-mfa/web/i18n.ts +3 -3
  59. package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
  60. package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
  61. package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +6 -6
  62. package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
  63. package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
  64. package/packages/bundled-features/src/billing-foundation/events.ts +22 -21
  65. package/packages/bundled-features/src/billing-foundation/feature.ts +42 -43
  66. package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
  67. package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +18 -17
  68. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
  69. package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
  70. package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +20 -20
  71. package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
  72. package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
  73. package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
  74. package/packages/bundled-features/src/billing-foundation/types.ts +64 -65
  75. package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +4 -4
  76. package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
  77. package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
  78. package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
  79. package/packages/bundled-features/src/cap-counter/enforce-cap.ts +64 -67
  80. package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
  81. package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
  82. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
  83. package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
  84. package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +1 -1
  85. package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
  86. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
  87. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
  88. package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
  89. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
  90. package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
  91. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
  92. package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
  93. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
  94. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
  95. package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
  96. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
  97. package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
  98. package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
  99. package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
  100. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
  101. package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
  102. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
  103. package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
  104. package/packages/bundled-features/src/config/resolver.ts +4 -4
  105. package/packages/bundled-features/src/config/table.ts +10 -10
  106. package/packages/bundled-features/src/config/write-helpers.ts +1 -1
  107. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +13 -12
  108. package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
  109. package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
  110. package/packages/bundled-features/src/custom-fields/events.ts +7 -8
  111. package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
  112. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
  113. package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
  114. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
  115. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
  116. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
  117. package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
  118. package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
  119. package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.ts +1 -1
  120. package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
  121. package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -12
  122. package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
  123. package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
  124. package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
  125. package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
  126. package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
  127. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
  128. package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
  129. package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
  130. package/packages/bundled-features/src/data-retention/feature.ts +11 -18
  131. package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
  132. package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
  133. package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
  134. package/packages/bundled-features/src/data-retention/presets.ts +18 -23
  135. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  136. package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
  137. package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
  138. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
  139. package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
  140. package/packages/bundled-features/src/delivery/feature.ts +3 -3
  141. package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
  142. package/packages/bundled-features/src/delivery/tables.ts +9 -8
  143. package/packages/bundled-features/src/delivery/unsubscribe.ts +4 -4
  144. package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
  145. package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
  146. package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
  147. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
  148. package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
  149. package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +4 -4
  150. package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
  151. package/packages/bundled-features/src/feature-toggles/feature.ts +1 -1
  152. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  153. package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
  154. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  155. package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
  156. package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
  157. package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
  158. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  159. package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
  160. package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
  161. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
  162. package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
  163. package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
  164. package/packages/bundled-features/src/files/feature.ts +6 -6
  165. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
  166. package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
  167. package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
  168. package/packages/bundled-features/src/folders/feature.ts +1 -1
  169. package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
  170. package/packages/bundled-features/src/folders/web/tree.ts +5 -5
  171. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
  172. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
  173. package/packages/bundled-features/src/form-draft/entity.ts +3 -3
  174. package/packages/bundled-features/src/form-draft/feature.ts +4 -5
  175. package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
  176. package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
  177. package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
  178. package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
  179. package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
  180. package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
  181. package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
  182. package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
  183. package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
  184. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
  185. package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
  186. package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
  187. package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
  188. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
  189. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
  190. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
  191. package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
  192. package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +11 -11
  193. package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
  194. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
  195. package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
  196. package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
  197. package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
  198. package/packages/bundled-features/src/inbound-mail-foundation/types.ts +66 -67
  199. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +69 -68
  200. package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
  201. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
  202. package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
  203. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
  204. package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
  205. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
  206. package/packages/bundled-features/src/jobs/events.ts +1 -1
  207. package/packages/bundled-features/src/jobs/feature.ts +6 -7
  208. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
  209. package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
  210. package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
  211. package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
  212. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  213. package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
  214. package/packages/bundled-features/src/jobs/job-run-logger.ts +14 -15
  215. package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
  216. package/packages/bundled-features/src/jobs/screens.ts +1 -1
  217. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  218. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  219. package/packages/bundled-features/src/ledger/entity.ts +5 -5
  220. package/packages/bundled-features/src/ledger/feature.ts +3 -3
  221. package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
  222. package/packages/bundled-features/src/ledger/recurring.ts +12 -12
  223. package/packages/bundled-features/src/ledger/schemas.ts +1 -1
  224. package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
  225. package/packages/bundled-features/src/ledger/web/index.ts +7 -7
  226. package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
  227. package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
  228. package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
  229. package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
  230. package/packages/bundled-features/src/mail-foundation/feature.ts +26 -27
  231. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
  232. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
  233. package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
  234. package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
  235. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
  236. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
  237. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
  238. package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
  239. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
  240. package/packages/bundled-features/src/managed-pages/table.ts +16 -15
  241. package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
  242. package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
  243. package/packages/bundled-features/src/notes-history/entity.ts +4 -4
  244. package/packages/bundled-features/src/notes-history/feature.ts +2 -2
  245. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  246. package/packages/bundled-features/src/page-render/layout.ts +9 -9
  247. package/packages/bundled-features/src/page-render/markdown.ts +11 -11
  248. package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
  249. package/packages/bundled-features/src/personal-access-tokens/feature.ts +5 -5
  250. package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
  251. package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
  252. package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
  253. package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
  254. package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
  255. package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
  256. package/packages/bundled-features/src/secrets/feature.ts +9 -9
  257. package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
  258. package/packages/bundled-features/src/seo/feature.ts +3 -3
  259. package/packages/bundled-features/src/sessions/constants.ts +1 -1
  260. package/packages/bundled-features/src/sessions/feature.ts +9 -9
  261. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
  262. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +2 -2
  263. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  264. package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
  265. package/packages/bundled-features/src/sessions/screens.ts +2 -2
  266. package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
  267. package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
  268. package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
  269. package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +1 -1
  270. package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
  271. package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
  272. package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
  273. package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
  274. package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
  275. package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
  276. package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
  277. package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
  278. package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
  279. package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
  280. package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
  281. package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
  282. package/packages/bundled-features/src/subscription-stripe/feature.ts +44 -43
  283. package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
  284. package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
  285. package/packages/bundled-features/src/subscription-stripe/runtime.ts +2 -2
  286. package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
  287. package/packages/bundled-features/src/tags/feature.ts +3 -3
  288. package/packages/bundled-features/src/tags/screens.ts +1 -1
  289. package/packages/bundled-features/src/template-resolver/api.ts +10 -10
  290. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +5 -5
  291. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
  292. package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
  293. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
  294. package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
  295. package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
  296. package/packages/bundled-features/src/template-resolver/seeding.ts +4 -4
  297. package/packages/bundled-features/src/template-resolver/table.ts +13 -14
  298. package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
  299. package/packages/bundled-features/src/tenant/feature.ts +7 -7
  300. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
  301. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  302. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  303. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  304. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
  305. package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
  306. package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
  307. package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
  308. package/packages/bundled-features/src/tenant/screens.ts +1 -1
  309. package/packages/bundled-features/src/tenant/seeding.ts +19 -18
  310. package/packages/bundled-features/src/tenant/testing.ts +5 -6
  311. package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
  312. package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
  313. package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
  314. package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
  315. package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
  316. package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
  317. package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
  318. package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
  319. package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
  320. package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
  321. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +2 -2
  322. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
  323. package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
  324. package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
  325. package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
  326. package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
  327. package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
  328. package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
  329. package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
  330. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
  331. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +8 -8
  332. package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
  333. package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
  334. package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
  335. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
  336. package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
  337. package/packages/bundled-features/src/user/schema/user.ts +45 -44
  338. package/packages/bundled-features/src/user/seeding.ts +40 -40
  339. package/packages/bundled-features/src/user/testing.ts +3 -3
  340. package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
  341. package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
  342. package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
  343. package/packages/bundled-features/src/user-data-rights/feature.ts +112 -113
  344. package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
  345. package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
  346. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
  347. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
  348. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
  349. package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
  350. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
  351. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +4 -4
  352. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
  353. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
  354. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
  355. package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
  356. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
  357. package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
  358. package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
  359. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
  360. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +166 -276
  361. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +85 -107
  362. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
  363. package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
  364. package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
  365. package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
  366. package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
  367. package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
  368. package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
  369. package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
  370. package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
  371. package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
  372. package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
  373. package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
  374. package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
  375. package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
  376. package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
  377. package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
  378. package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
  379. package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +1 -1
  380. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
  381. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
  382. package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
  383. package/packages/bundled-features/src/user-profile/index.ts +3 -3
  384. package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
  385. package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
  386. package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
  387. package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
  388. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
  389. package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
  390. package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
  391. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
  392. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
  393. package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
  394. package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
  395. package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
@@ -3,19 +3,19 @@ import { createEntity, createTextField } from "@cosmicdrift/kumiko-framework/eng
3
3
 
4
4
  // Config values are event-sourced. Each (key, scope) is its own aggregate
5
5
  // stream — lifecycle events `configValue.created / .updated / .deleted`
6
- // flow through createEventStoreExecutor, which writes the stream + this
7
- // projection in one TX. Reads stay O(1) against the projection.
6
+ // flow through createEventStoreExecutor, which writes the stream and this
7
+ // projection in one TX. Reads remain O(1) against the projection.
8
8
  //
9
9
  // System-scope rows use SYSTEM_TENANT_ID (not null) — buildBaseColumns
10
- // (via buildEntityTable) forces tenant_id NOT NULL, so die pre-ES "NULL
11
- // means system" convention is replaced with a fixed sentinel. Der unique
12
- // index über (key, tenant_id, user_id) prevent duplicate writes at the DB
13
- // level — deklariert via entity.indexes.
10
+ // (via buildEntityTable) forces tenant_id NOT NULL, so the pre-ES "NULL
11
+ // means system" convention is replaced with a fixed sentinel. The unique
12
+ // index on (key, tenant_id, user_id) prevents duplicate writes at the DB
13
+ // level — declared via entity.indexes.
14
14
  //
15
- // Single-Source-of-Truth: `configValueEntity`. Die DB-Tabelle wird über
16
- // buildEntityTable aus der EntityDefinition abgeleitet, der unique-Index
17
- // ist via entity.indexes deklariert. Plural-Re-Export `configValuesTable`
18
- // dient handlers (`reset.write.ts` etc.) als typisierte Drizzle-Table-Ref.
15
+ // Single source of truth: `configValueEntity`. The DB table is derived from
16
+ // the EntityDefinition through buildEntityTable, and the unique index is
17
+ // declared via entity.indexes. The plural re-export `configValuesTable`
18
+ // provides handlers (`reset.write.ts` etc.) with a typed Drizzle table ref.
19
19
  export const configValueEntity = createEntity({
20
20
  table: "read_config_values",
21
21
  fields: {
@@ -226,7 +226,7 @@ export function resolveScopeIds(
226
226
  }
227
227
 
228
228
  // The subject a piiEncrypted config value is encrypted under, for the scope
229
- // actually written to (kumiko-platform#231/#459). Pure — no I/O — so a bug
229
+ // actually written to. Pure — no I/O — so a bug
230
230
  // here (e.g. picking the writer's identity instead of the row's target,
231
231
  // see entity fields' explicit userOwned.ownerField for why that
232
232
  // distinction matters) is caught by a fast unit test, not only the DB-
@@ -112,7 +112,7 @@ function subjectAggregateId(raw: SubjectIdInput): string {
112
112
  }
113
113
 
114
114
  // The record subject names its own entity — resolve it against the registry
115
- // instead of trusting the payload straight into resolveTableName/SQL (#2786).
115
+ // instead of trusting the payload straight into resolveTableName/SQL.
116
116
  function findRegisteredEntity(
117
117
  features: ReadonlyMap<string, FeatureDefinition>,
118
118
  entityName: string,
@@ -124,7 +124,7 @@ function findRegisteredEntity(
124
124
  return undefined;
125
125
  }
126
126
 
127
- // Tenant-scope guard (mh#349): DataProtectionOfficer is a tenant-scoped role,
127
+ // Tenant-scope guard: DataProtectionOfficer is a tenant-scoped role,
128
128
  // but the handler otherwise erases ANY subject cross-tenant on a raw
129
129
  // (un-scoped) client — a Tenant-A DPO who learns a Tenant-B subject id
130
130
  // (export, support ticket, log line) could destroy it. SystemAdmin
@@ -182,7 +182,7 @@ async function resolveTenantScopeDenial(
182
182
  return ownedInTenant ? undefined : memberDenied;
183
183
  }
184
184
 
185
- // fw#2789/#2805: blockDelete (legally mandated physical retention, e.g.
185
+ // blockDelete (legally mandated physical retention, e.g.
186
186
  // ledger/invoice text) means this command must refuse, not silently
187
187
  // anonymize or proceed. Refused when the host entity itself declares
188
188
  // blockDelete OR the owning tenant's effective data-retention policy
@@ -213,7 +213,7 @@ async function resolveRetentionDenial(
213
213
  const effective = await resolveRetentionPolicyForTenant({
214
214
  db: runner,
215
215
  registry: ctx.registry,
216
- tenantId: owningTenantId as TenantId,
216
+ tenantId: owningTenantId,
217
217
  entityName: raw.entity,
218
218
  });
219
219
  return effective.policy?.strategy === "blockDelete" ? deny() : undefined;
@@ -241,8 +241,8 @@ function denialReasonOf(failure: WriteFailure): string {
241
241
  return failure.error.code;
242
242
  }
243
243
 
244
- // Denied cross-tenant probes must still leave an audit trail (fw#2348).
245
- // Appended outside the handler tx (fw#2592): the caller's
244
+ // Denied cross-tenant probes must still leave an audit trail.
245
+ // Appended outside the handler tx: the caller's
246
246
  // `return tenantScopeDenial` rolls that tx back.
247
247
  async function appendDenialAuditEvent(
248
248
  ctx: HandlerContext,
@@ -285,7 +285,7 @@ async function appendDenialAuditEvent(
285
285
  registry: ctx.registry,
286
286
  db: denialAuditRunner,
287
287
  // MUST be event.user.tenantId, never SYSTEM_TENANT_ID — unsafeRaw
288
- // bypasses TenantDb's scoping, so this is the only guard against a cross-tenant denial event (fw#2452).
288
+ // bypasses TenantDb's scoping, so this is the only guard against a cross-tenant denial event.
289
289
  tenantId: event.user.tenantId,
290
290
  userId: String(event.user.id),
291
291
  callSiteLabel: "forget-subject denial audit",
@@ -339,11 +339,11 @@ async function sweepDerivedSubjectData(
339
339
  };
340
340
 
341
341
  await runStep(async (crossTenantSubjectRunner) => {
342
- // Blind-index sweep (#818): nulls bidx columns now so the deterministic
342
+ // Blind-index sweep: nulls bidx columns now so the deterministic
343
343
  // HMAC doesn't stay equality-matchable; raw because the ciphertext prefix addresses the subject across tenants.
344
344
  await nullBlindIndexesForSubject(crossTenantSubjectRunner, ctx.registry.features, subjectKey);
345
345
 
346
- // Derived search index still holds plaintext (#1610) — purge next to the
346
+ // Derived search index still holds plaintext — purge next to the
347
347
  // blind-index sweep. No adapter → no-op (apps without search).
348
348
  if (ctx.searchAdapter) {
349
349
  await purgeSearchDocumentsForSubject(
@@ -442,7 +442,8 @@ async function appendSubjectForgotten(
442
442
  {
443
443
  registry: ctx.registry,
444
444
  db: outsideRunner,
445
- // MUST be event.user.tenantId, never SYSTEM_TENANT_ID — unsafeRaw bypasses TenantDb's scoping (fw#2452).
445
+ // MUST be event.user.tenantId, never SYSTEM_TENANT_ID — unsafeRaw bypasses TenantDb's
446
+ // scoping.
446
447
  tenantId: event.user.tenantId,
447
448
  userId: String(event.user.id),
448
449
  callSiteLabel: "forget-subject audit",
@@ -466,7 +467,7 @@ async function appendSubjectForgotten(
466
467
  // The automated Art.-17 path (user-data-rights forget-cleanup) calls
467
468
  // kms.eraseKey directly inside its per-user sub-tx; this command is the
468
469
  // standalone trigger for cases outside that pipeline (authority requests,
469
- // tenant-destroy in Sprint 5, operator recovery).
470
+ // tenant-destroy, operator recovery).
470
471
  export const forgetSubjectWrite = defineWriteHandler({
471
472
  name: "forget-subject",
472
473
  schema: forgetSubjectSchema,
@@ -558,7 +559,7 @@ export const forgetSubjectWrite = defineWriteHandler({
558
559
  // callable. Mirror of the automated Art.-17 path (userDeleteHook:
559
560
  // status=Deleted; apiTokenDeleteHook: revoke):
560
561
  // - user.updated as lifecycle event (updateUserLifecycle), so a
561
- // read_users rebuild doesn't wipe the flip (#494)
562
+ // read_users rebuild doesn't wipe the flip
562
563
  // - sessions don't need active revocation — session-callbacks
563
564
  // re-validate user.status on every request (isPrincipalBlocked
564
565
  // blocks Deleted).
@@ -1,28 +1,27 @@
1
1
  import { v5 as uuidv5 } from "uuid";
2
2
 
3
- // Fixed UUID-namespace für custom-field-definition aggregate-id-Ableitung.
4
- // Generiert einmalig (2026-05-22), in Stein gemeißelt: ein Wechsel würde
5
- // jeden existing fieldDefinition-Stream re-keyen → kaputter event-replay,
6
- // kaputte definition-history. Drift-Pin in __tests__/drift.test.ts.
3
+ // Fixed UUID namespace for deriving custom-field definition aggregate IDs.
4
+ // Generated once; changing it would re-key every existing fieldDefinition stream,
5
+ // breaking event replay and definition history. Drift is pinned in
6
+ // __tests__/drift.test.ts.
7
7
  const FIELD_DEFINITION_NAMESPACE = "f1d3b2c7-4e5a-4b9c-8d1f-2a3b4c5d6e7f";
8
8
 
9
9
  /**
10
- * Deterministic aggregate-id für ein fieldDefinition-Aggregate aus dem
11
- * Tripel (tenantId, entityName, fieldKey). Pro (Tenant|System, Entity,
12
- * FieldKey) existiert genau ein Aggregate.
10
+ * Deterministic aggregate ID for a fieldDefinition aggregate from the tuple
11
+ * (tenantId, entityName, fieldKey). Exactly one aggregate exists per
12
+ * (Tenant|System, Entity, FieldKey).
13
13
  *
14
- * **Scope-Semantik:**
15
- * - System-Scope: `tenantId = SYSTEM_TENANT_ID` → die fieldDefinition
16
- * gilt für alle Tenants (vendor-defined).
17
- * - Tenant-Scope: `tenantId = <tenant-uuid>` → pro Tenant eigene
14
+ * **Scope semantics:**
15
+ * - System scope: `tenantId = SYSTEM_TENANT_ID` → the fieldDefinition applies
16
+ * to all tenants (vendor-defined).
17
+ * - Tenant scope: `tenantId = <tenant-uuid>` → each tenant has its own
18
18
  * fieldDefinition.
19
19
  *
20
- * **Conflict-Rule** (durchgesetzt im write-handler, NICHT via DB-constraint):
21
- * Pro (entityName, fieldKey) darf nur EINE Definition existieren — entweder
22
- * system oder tenant, nicht beide. Wenn system `customer.internalNumber`
23
- * definiert, kann Tenant kein eigenes `customer.internalNumber` mehr
24
- * definieren (422 `fieldKey_conflict`). Verhindert Resolution-Ambiguität
25
- * beim Read.
20
+ * **Conflict rule** (enforced in the write handler, NOT via a DB constraint):
21
+ * Only ONE definition may exist per (entityName, fieldKey)—system or tenant,
22
+ * but not both. If system defines `customer.internalNumber`, a tenant cannot
23
+ * define its own `customer.internalNumber` (422 `fieldKey_conflict`). This
24
+ * prevents ambiguity when resolving the field during reads.
26
25
  */
27
26
  // @wrapper-known uuid-domain
28
27
  export function fieldDefinitionAggregateId(
@@ -5,35 +5,36 @@ import {
5
5
  createTextField,
6
6
  } from "@cosmicdrift/kumiko-framework/engine";
7
7
 
8
- // fieldDefinition — Tenant- oder System-scoped Custom-Field-Definition.
8
+ // fieldDefinition — Tenant- or system-scoped custom-field definition.
9
9
  //
10
- // **Tenant-Scope:** `tenantId`-Base-Column wird vom Framework automatisch
11
- // gesetzt. Bei system-scope-Definitionen ist `tenantId = SYSTEM_TENANT_ID`;
12
- // bei tenant-scope der current-tenant. Beide leben in derselben Tabelle,
13
- // Scope ergibt sich aus dem tenantId-Wert (no separate `scope`-column).
10
+ // **Tenant scope:** The `tenantId` base column is set automatically by the
11
+ // framework. For system-scope definitions, `tenantId = SYSTEM_TENANT_ID`;
12
+ // for tenant-scope definitions, it is the current tenant. Both use the same
13
+ // table; the scope is determined by the tenantId value (no separate `scope`
14
+ // column).
14
15
  //
15
- // **Conflict-Rule:** pro (entityName, fieldKey) darf nur eine Definition
16
- // existieren — entweder system oder tenant, nicht beide. Resolution beim
17
- // Read = `WHERE tenantId IN (SYSTEM_TENANT_ID, <current-tenant>)`.
18
- // Conflict-Check ist write-handler-side, NICHT DB-constraint (DB hat
19
- // natürliche UNIQUE auf (tenantId, entityName, fieldKey) durch Aggregate-
20
- // ID-Konstruktion).
16
+ // **Conflict rule:** only one definition may exist per (entityName, fieldKey)
17
+ // — either system or tenant, not both. Resolution on read = `WHERE tenantId IN
18
+ // (SYSTEM_TENANT_ID, <current-tenant>)`. The conflict check is performed by
19
+ // the write handler, NOT enforced by a DB constraint (the DB has a natural
20
+ // UNIQUE constraint on (tenantId, entityName, fieldKey) through aggregate-ID
21
+ // construction).
21
22
  //
22
- // **Spec-Drift**: Spec Z.40-54 hat eine separate `custom_field_value`-
23
- // Tabelle. Plan-Doc v2 hat das durch jsonb-on-host-entity ersetzt
24
- // (D2-pur-Storage). Hier definieren wir NUR die definition-Entity; values
25
- // landen in `read_<entity>.customFields` jsonb via MSP (B2).
23
+ // **Spec drift**: Spec Z.40-54 defines a separate `custom_field_value` table.
24
+ // Plan-Doc v2 replaced it with jsonb on the host entity (pure jsonb storage).
25
+ // This defines ONLY the definition entity; values land in
26
+ // `read_<entity>.customFields` jsonb via MSP.
26
27
  //
27
- // **Was hier NICHT als Stammfeld-Spalte landet**:
28
- // - `defaultValue`, `options`, `fieldAccess`, `label` — alles in
29
- // `serializedField` jsonb gepackt (Builder-Reuse: dehydrierter
30
- // r.field.X()-Output). Spec Z.18-38 listet sie als separate Spalten,
31
- // aber Builder-Reuse macht das redundant — der serialized Builder
32
- // enthält alle diese Aspekte type-safe.
33
- // - `version` (optimistic-lock) — ES-redundant, wir nutzen aggregate-
34
- // stream-version (Sprint E-Pattern).
35
- // - `createdAt/updatedAt/createdBy/updatedBy` — automatic via base-
36
- // columns + events.
28
+ // **What is NOT stored as a base-field column here**:
29
+ // - `defaultValue`, `options`, `fieldAccess`, `label` — all packed into
30
+ // `serializedField` jsonb (builder reuse: dehydrated
31
+ // r.field.X()-output). Spec Z.18-38 lists them as separate columns, but
32
+ // builder reuse makes that redundant — the serialized builder contains all
33
+ // these aspects in a type-safe form.
34
+ // - `version` (optimistic lock) — redundant with event sourcing; we use the
35
+ // aggregate stream version.
36
+ // - `createdAt/updatedAt/createdBy/updatedBy` — automatic through base
37
+ // columns and events.
37
38
  export const fieldDefinitionEntity = createEntity({
38
39
  table: "read_custom_field_definitions",
39
40
  description:
@@ -47,20 +48,21 @@ export const fieldDefinitionEntity = createEntity({
47
48
  // NB: `retention.strategy` below is the data-retention purge policy, a
48
49
  // SEPARATE knob from this executor flag — it does not drive executor.delete.
49
50
  softDelete: true,
50
- // B1.5 retention-policy — fieldDefinitions sind tenant-Schema-Metadaten,
51
- // keine PII-Daten. Lange Retention für Audit (Compliance kann "wann hat
52
- // Tenant das Feld definiert / geändert / gelöscht" fragen).
51
+ // Retention policy — field definitions are tenant-schema metadata, not PII.
52
+ // Long retention supports audits (compliance can ask when a tenant defined,
53
+ // changed, or deleted the field).
53
54
  //
54
- // 10-Jahre keepFor ist konservativer Default; per-Tenant kann via
55
- // tenantRetentionOverride für eigene Edge-Cases gesetzt werden
56
- // (z.B. shorter für test-tenants).
55
+ // The 10-year keepFor is a conservative default; tenants can override it
56
+ // through tenantRetentionOverride for their own edge cases
57
+ // (e.g. shorter retention for test tenants).
57
58
  retention: {
58
59
  keepFor: "10y",
59
60
  strategy: "softDelete",
60
61
  },
61
62
  fields: {
62
- // Ziel-Entity-Name, für die dieses Field definiert wird (z.B. "property",
63
- // "customer"). Max 64 char passt zu Kumiko's entity-name-Convention.
63
+ // The entity name for which this field is defined (e.g. "property",
64
+ // "customer"). The 64-character maximum follows Kumiko's entity-name
65
+ // convention.
64
66
  entityName: createTextField({
65
67
  required: true,
66
68
  maxLength: 64,
@@ -68,8 +70,8 @@ export const fieldDefinitionEntity = createEntity({
68
70
  reason: "technical_reference",
69
71
  }),
70
72
 
71
- // Field-Key (z.B. "internalNumber", "vipFlag") — kebab-case oder camelCase
72
- // erlaubt; UI-rendering nutzt label statt fieldKey.
73
+ // Field key (e.g. "internalNumber", "vipFlag") — kebab-case and camelCase
74
+ // are allowed; UI rendering uses label instead of fieldKey.
73
75
  fieldKey: createTextField({
74
76
  required: true,
75
77
  maxLength: 64,
@@ -77,8 +79,8 @@ export const fieldDefinitionEntity = createEntity({
77
79
  reason: "technical_reference",
78
80
  }),
79
81
 
80
- // Field-Type aus dem SUPPORTED_FIELD_TYPES-Set. Validiert via Zod im
81
- // write-handler.
82
+ // Field type from the SUPPORTED_FIELD_TYPES set. Validated with Zod in the
83
+ // write handler.
82
84
  type: createTextField({
83
85
  required: true,
84
86
  maxLength: 16,
@@ -86,22 +88,22 @@ export const fieldDefinitionEntity = createEntity({
86
88
  reason: "technical_reference",
87
89
  }),
88
90
 
89
- // Required-Flag — wird beim Entity-Write gegen den value gecheckt
90
- // (Stammfeld-identische Semantik, Spec-Promise Z.4).
91
+ // Required flag — checked against the value during entity writes
92
+ // (the same semantics as a base field).
91
93
  required: createBooleanField({ required: true }),
92
94
 
93
- // Searchable-Flag — wenn true, contribuiert das Field zum Search-Doc
94
- // via F3 search-payload-extension.
95
+ // Searchable flag — when true, the field contributes to the search document
96
+ // through the search-payload extension.
95
97
  searchable: createBooleanField({ required: true }),
96
98
 
97
- // UI-Display-Order. Tenant kann seine Felder via UI sortieren.
99
+ // UI display order, allowing tenants to sort their fields in the UI.
98
100
  displayOrder: createNumberField({ required: true, integer: true }),
99
101
 
100
- // Builder-Reuse: serialisierter r.field.X(opts)-Output als jsonb.
101
- // Beinhaltet type-options (enum-values, money-currency, embedded-schema),
102
- // defaultValue, fieldAccess, i18n-labels. Beim Write-Validation
103
- // dehydriert der handler dies zurück zu einer r.field.X()-Instanz und
104
- // nutzt deren .schema für value-Validation.
102
+ // Builder reuse: serialized r.field.X(opts) output stored as jsonb.
103
+ // It includes type options (enum values, money currency, embedded schema),
104
+ // defaultValue, fieldAccess, and i18n labels. During write validation, the
105
+ // handler dehydrates this back into an r.field.X() instance and uses its
106
+ // .schema for value validation.
105
107
  serializedField: createTextField({
106
108
  required: true,
107
109
  maxLength: 65536,
@@ -1,17 +1,16 @@
1
1
  import * as z from "zod";
2
2
 
3
- // Domain-Events für custom-field-VALUES. customField.set + .cleared leben
4
- // auf der host-aggregate stream (Plan-Doc v2 ES-Option-B: customField-Events
5
- // auf demselben Stream wie die host-entity's eigene Events).
3
+ // Domain events for custom-field values. customField.set and .cleared live
4
+ // on the host aggregate stream, alongside the host entity's own events.
6
5
  //
7
- // Aggregate-Type im Event ist der host-entity-name (z.B. "property"),
8
- // aggregate-id ist die host-entity-row-id (z.B. property-uuid). So konsumieren
9
- // die customFields-MSPs nur die Events ihrer wired-entities (filtered via
10
- // aggregate-type-match an der jeweiligen consumer-side-MSP-Registration).
6
+ // The event's aggregate type is the host entity name (for example, "property"),
7
+ // and its aggregate ID is the host entity row ID (for example, property-uuid).
8
+ // This ensures customFields-MSPs consume only events for their wired entities,
9
+ // filtered by aggregate-type match in each consumer-side-MSP registration.
11
10
 
12
11
  export const customFieldSetSchema = z.object({
13
12
  fieldKey: z.string().min(1).max(64),
14
- // Every set carries its value (custom fields hold no PII, #972) — replay
13
+ // Every set carries its value (custom fields hold no PII) — replay
15
14
  // reproduces the projection fully. Stays optional at the type layer only
16
15
  // because z.unknown() is inherently optional; the apply side treats
17
16
  // `value === undefined` as an anomaly and warns.
@@ -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 {