@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.387.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (469) hide show
  1. package/LICENSE +21 -57
  2. package/dist/agent-tools/tool-catalog.js +1 -1
  3. package/dist/audit/screens.js +1 -1
  4. package/dist/auth-email-password/feature.js +1 -1
  5. package/dist/auth-email-password/handlers/change-password.write.js +3 -3
  6. package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
  7. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
  8. package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
  9. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  10. package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
  11. package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
  12. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
  13. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  14. package/dist/auth-email-password/handlers/login.write.js +1 -1
  15. package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
  16. package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
  17. package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
  18. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  19. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
  20. package/dist/auth-email-password/index.js +5 -5
  21. package/dist/auth-email-password/lockout-store.js +1 -1
  22. package/dist/auth-email-password/seeding.d.ts +42 -45
  23. package/dist/auth-email-password/seeding.js +51 -53
  24. package/dist/auth-email-password/signup-token-store.js +8 -8
  25. package/dist/auth-email-password/testing.js +3 -3
  26. package/dist/auth-email-password/web/auth-client.d.ts +2 -2
  27. package/dist/auth-email-password/web/auth-client.js +36 -37
  28. package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
  29. package/dist/auth-email-password/web/auth-gate.js +15 -16
  30. package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
  31. package/dist/auth-email-password/web/client-plugin.js +4 -5
  32. package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
  33. package/dist/auth-email-password/web/constants.js +3 -3
  34. package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
  35. package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
  36. package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
  37. package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
  38. package/dist/auth-email-password/web/index.js +5 -5
  39. package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
  40. package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
  41. package/dist/auth-email-password/web/login-screen.d.ts +1 -1
  42. package/dist/auth-email-password/web/login-screen.js +2 -3
  43. package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
  44. package/dist/auth-email-password/web/reset-password-screen.js +12 -13
  45. package/dist/auth-email-password/web/session.d.ts +10 -9
  46. package/dist/auth-email-password/web/session.js +28 -29
  47. package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
  48. package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
  49. package/dist/auth-email-password/web/signup-screen.js +13 -13
  50. package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
  51. package/dist/auth-email-password/web/tenant-switcher.js +21 -22
  52. package/dist/auth-email-password/web/use-shell-user.js +12 -13
  53. package/dist/auth-email-password/web/user-menu.d.ts +4 -4
  54. package/dist/auth-email-password/web/user-menu.js +12 -13
  55. package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
  56. package/dist/auth-email-password/web/verify-email-screen.js +9 -10
  57. package/dist/auth-foundation/boot-checks.js +4 -4
  58. package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
  59. package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
  60. package/dist/auth-foundation/types.js +2 -2
  61. package/dist/auth-mfa/handlers/disable.write.js +3 -3
  62. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
  63. package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
  64. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
  65. package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
  66. package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
  67. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  68. package/dist/auth-mfa/token-secrets.js +1 -1
  69. package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
  70. package/dist/auth-mfa/web/client-plugin.js +1 -1
  71. package/dist/auth-mfa/web/i18n.js +3 -3
  72. package/dist/auth-mfa/web/index.js +4 -4
  73. package/dist/auth-mfa/web/mfa-client.js +17 -16
  74. package/dist/auth-mfa/web/mfa-verify-screen.js +6 -6
  75. package/dist/billing-foundation/aggregate-id.d.ts +5 -5
  76. package/dist/billing-foundation/aggregate-id.js +10 -11
  77. package/dist/billing-foundation/entities.js +27 -27
  78. package/dist/billing-foundation/events.js +18 -17
  79. package/dist/billing-foundation/feature.js +42 -43
  80. package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
  81. package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
  82. package/dist/billing-foundation/handlers/create-checkout-session.write.js +18 -17
  83. package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
  84. package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
  85. package/dist/billing-foundation/handlers/process-event.write.js +20 -20
  86. package/dist/billing-foundation/projection.d.ts +15 -11
  87. package/dist/billing-foundation/projection.js +38 -37
  88. package/dist/billing-foundation/subscription-tier-sync.js +3 -3
  89. package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
  90. package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
  91. package/dist/billing-foundation/types.d.ts +40 -41
  92. package/dist/billing-foundation/types.js +20 -20
  93. package/dist/billing-foundation/web/billing-plans-panel.js +4 -4
  94. package/dist/cap-counter/aggregate-id.js +8 -9
  95. package/dist/cap-counter/constants.js +11 -12
  96. package/dist/cap-counter/enforce-cap.d.ts +59 -62
  97. package/dist/cap-counter/enforce-cap.js +47 -48
  98. package/dist/cap-counter/entity.js +29 -29
  99. package/dist/cap-counter/feature.js +34 -35
  100. package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
  101. package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
  102. package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
  103. package/dist/cap-counter/stock-cap-guard.js +1 -1
  104. package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
  105. package/dist/channel-email/smtp-transport.d.ts +18 -17
  106. package/dist/channel-email/smtp-transport.js +24 -21
  107. package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
  108. package/dist/compliance-profiles/feature.js +4 -4
  109. package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
  110. package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
  111. package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
  112. package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
  113. package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
  114. package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
  115. package/dist/compliance-profiles/schema/profile-selection.js +18 -23
  116. package/dist/compliance-profiles/seeding.js +14 -15
  117. package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
  118. package/dist/compliance-profiles-ops/index.js +2 -2
  119. package/dist/config/handlers/readiness.query.d.ts +4 -4
  120. package/dist/config/handlers/readiness.query.js +1 -1
  121. package/dist/config/handlers/reencrypt.job.js +4 -5
  122. package/dist/config/handlers/set.write.js +4 -4
  123. package/dist/config/resolver.js +4 -4
  124. package/dist/config/table.js +10 -10
  125. package/dist/config/write-helpers.js +1 -1
  126. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
  127. package/dist/crypto-shredding/handlers/forget-subject.write.js +12 -11
  128. package/dist/custom-fields/aggregate-id.d.ts +12 -13
  129. package/dist/custom-fields/aggregate-id.js +16 -17
  130. package/dist/custom-fields/entity.js +49 -47
  131. package/dist/custom-fields/events.js +7 -8
  132. package/dist/custom-fields/feature.d.ts +14 -14
  133. package/dist/custom-fields/feature.js +53 -54
  134. package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
  135. package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
  136. package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
  137. package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
  138. package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
  139. package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
  140. package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
  141. package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
  142. package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
  143. package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
  144. package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
  145. package/dist/custom-fields/lib/field-access.js +2 -2
  146. package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
  147. package/dist/custom-fields/lib/quota.js +1 -1
  148. package/dist/custom-fields/lib/value-schema.js +10 -12
  149. package/dist/custom-fields/run-retention.js +3 -3
  150. package/dist/custom-fields/schemas.js +14 -14
  151. package/dist/custom-fields/web/client-plugin.js +2 -5
  152. package/dist/custom-fields/web/constants.js +2 -2
  153. package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
  154. package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
  155. package/dist/custom-fields/wire-for-entity.js +65 -67
  156. package/dist/custom-fields/wire-user-data-rights.js +3 -3
  157. package/dist/data-retention/_internal/parse-override.js +2 -3
  158. package/dist/data-retention/feature.js +11 -18
  159. package/dist/data-retention/handlers/policy-for.query.js +6 -6
  160. package/dist/data-retention/keep-for.d.ts +7 -7
  161. package/dist/data-retention/keep-for.js +15 -15
  162. package/dist/data-retention/override-schema.d.ts +3 -4
  163. package/dist/data-retention/override-schema.js +13 -15
  164. package/dist/data-retention/presets.d.ts +4 -5
  165. package/dist/data-retention/presets.js +18 -23
  166. package/dist/data-retention/resolve-tenant-preset.js +17 -16
  167. package/dist/data-retention/resolver.d.ts +12 -12
  168. package/dist/data-retention/resolver.js +24 -23
  169. package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
  170. package/dist/data-retention/run-retention-cleanup.js +61 -51
  171. package/dist/data-retention/schema/tenant-retention-override.js +13 -11
  172. package/dist/delivery/feature.js +2 -2
  173. package/dist/delivery/handlers/log.query.js +1 -1
  174. package/dist/delivery/tables.js +9 -8
  175. package/dist/delivery/unsubscribe.js +4 -4
  176. package/dist/document-ingest-foundation/entity.js +4 -4
  177. package/dist/document-ingest-foundation/events.js +2 -2
  178. package/dist/document-ingest-foundation/feature.js +2 -2
  179. package/dist/document-ingest-foundation/pages.js +1 -1
  180. package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
  181. package/dist/feature-toggles/compose-tier-resolver.js +1 -1
  182. package/dist/feature-toggles/feature.js +1 -1
  183. package/dist/feature-toggles/global-feature-state-table.js +1 -1
  184. package/dist/feature-toggles/handlers/registered.query.js +5 -5
  185. package/dist/feature-toggles/toggle-sync-signal.js +1 -1
  186. package/dist/feature-toggles/web/constants.js +1 -1
  187. package/dist/file-derivatives/feature.d.ts +1 -1
  188. package/dist/file-derivatives/feature.js +1 -1
  189. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  190. package/dist/file-derivatives/presets.js +1 -1
  191. package/dist/file-foundation/feature.js +6 -6
  192. package/dist/file-provider-inmemory/feature.d.ts +1 -1
  193. package/dist/file-provider-inmemory/feature.js +16 -16
  194. package/dist/file-provider-s3/feature.js +16 -16
  195. package/dist/file-provider-s3/lib/s3-provider.js +6 -6
  196. package/dist/files/feature.js +6 -6
  197. package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
  198. package/dist/files-tenant-data/hooks.js +24 -26
  199. package/dist/files-tenant-data/index.js +1 -1
  200. package/dist/folders/feature.d.ts +1 -1
  201. package/dist/folders/web/folder-manager.js +2 -2
  202. package/dist/folders/web/tree.js +5 -5
  203. package/dist/form-draft/db/queries/cleanup.js +1 -1
  204. package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
  205. package/dist/form-draft/entity.js +3 -3
  206. package/dist/form-draft/feature.js +4 -5
  207. package/dist/form-draft/handlers/discard.write.js +1 -1
  208. package/dist/form-draft/release-file-refs.js +6 -6
  209. package/dist/form-draft/schemas.js +3 -3
  210. package/dist/form-draft/web/constants.js +0 -2
  211. package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
  212. package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
  213. package/dist/inbound-mail-foundation/connect-routes.js +4 -3
  214. package/dist/inbound-mail-foundation/constants.d.ts +22 -24
  215. package/dist/inbound-mail-foundation/constants.js +30 -33
  216. package/dist/inbound-mail-foundation/entities.d.ts +12 -12
  217. package/dist/inbound-mail-foundation/entities.js +47 -48
  218. package/dist/inbound-mail-foundation/events.d.ts +4 -3
  219. package/dist/inbound-mail-foundation/events.js +50 -47
  220. package/dist/inbound-mail-foundation/feature.js +39 -39
  221. package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
  222. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
  223. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
  224. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
  225. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
  226. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
  227. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
  228. package/dist/inbound-mail-foundation/handlers/update-account.write.js +11 -11
  229. package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
  230. package/dist/inbound-mail-foundation/oauth-state.js +11 -10
  231. package/dist/inbound-mail-foundation/projection.d.ts +4 -4
  232. package/dist/inbound-mail-foundation/projection.js +31 -29
  233. package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
  234. package/dist/inbound-mail-foundation/provider-factory.js +9 -9
  235. package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
  236. package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
  237. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
  238. package/dist/inbound-mail-foundation/types.d.ts +45 -46
  239. package/dist/inbound-mail-foundation/types.js +21 -21
  240. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
  241. package/dist/inbound-mail-foundation/watch-supervisor.js +57 -56
  242. package/dist/inbound-provider-imap/credential-document.js +13 -13
  243. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  244. package/dist/inbound-provider-imap/feature.js +42 -40
  245. package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
  246. package/dist/inbound-provider-imap/imap-client.js +20 -19
  247. package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
  248. package/dist/inbound-provider-inmemory/feature.js +19 -19
  249. package/dist/jobs/db/queries/retention.js +2 -2
  250. package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
  251. package/dist/jobs/events.js +1 -1
  252. package/dist/jobs/feature.js +5 -6
  253. package/dist/jobs/handlers/detail.query.js +4 -4
  254. package/dist/jobs/handlers/list.query.js +1 -1
  255. package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
  256. package/dist/jobs/handlers/reindex-entity.job.js +1 -1
  257. package/dist/jobs/handlers/retry.write.js +1 -1
  258. package/dist/jobs/job-instant.js +1 -1
  259. package/dist/jobs/job-run-logger.js +10 -11
  260. package/dist/jobs/job-run-table.js +3 -3
  261. package/dist/jobs/screens.js +1 -1
  262. package/dist/jobs/tenant-job-failure-table.js +1 -1
  263. package/dist/jobs/tenant-job-run-table.js +1 -1
  264. package/dist/ledger/entity.js +5 -5
  265. package/dist/ledger/feature.js +3 -3
  266. package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
  267. package/dist/ledger/recurring.js +12 -12
  268. package/dist/ledger/schemas.js +1 -1
  269. package/dist/ledger/web/constants.js +2 -2
  270. package/dist/ledger/web/index.js +7 -7
  271. package/dist/legal-pages/feature.d.ts +4 -4
  272. package/dist/legal-pages/feature.js +25 -26
  273. package/dist/legal-pages/markdown.js +3 -3
  274. package/dist/legal-pages/web/client-plugin.js +23 -24
  275. package/dist/legal-pages/web/index.js +0 -1
  276. package/dist/mail-foundation/feature.d.ts +2 -2
  277. package/dist/mail-foundation/feature.js +24 -25
  278. package/dist/mail-transport-inmemory/feature.d.ts +4 -4
  279. package/dist/mail-transport-inmemory/feature.js +27 -28
  280. package/dist/mail-transport-smtp/feature.js +20 -20
  281. package/dist/managed-pages/branding.js +6 -6
  282. package/dist/managed-pages/feature.d.ts +26 -26
  283. package/dist/managed-pages/feature.js +34 -34
  284. package/dist/managed-pages/handlers/by-slug.query.js +5 -6
  285. package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
  286. package/dist/managed-pages/handlers/set.write.js +5 -7
  287. package/dist/managed-pages/screens/page-screens.js +11 -11
  288. package/dist/managed-pages/seeding.js +8 -8
  289. package/dist/managed-pages/table.js +13 -12
  290. package/dist/managed-pages/web/client-plugin.d.ts +1 -1
  291. package/dist/managed-pages/web/client-plugin.js +5 -5
  292. package/dist/managed-pages/web/i18n.js +1 -1
  293. package/dist/notes-history/entity.js +4 -4
  294. package/dist/notes-history/feature.d.ts +2 -2
  295. package/dist/notes-history-user-data/hooks.js +1 -1
  296. package/dist/page-render/layout.js +9 -9
  297. package/dist/page-render/markdown.js +11 -11
  298. package/dist/page-render/security-headers.js +7 -6
  299. package/dist/personal-access-tokens/feature.js +5 -5
  300. package/dist/personal-access-tokens/roles.js +2 -2
  301. package/dist/readiness/handlers/status.query.js +3 -3
  302. package/dist/renderer-foundation/api.js +12 -13
  303. package/dist/renderer-foundation/constants.js +2 -2
  304. package/dist/renderer-foundation/feature.js +7 -7
  305. package/dist/secrets/feature.js +9 -9
  306. package/dist/secrets/web/constants.js +2 -2
  307. package/dist/seo/feature.js +3 -3
  308. package/dist/sessions/constants.d.ts +1 -1
  309. package/dist/sessions/constants.js +1 -1
  310. package/dist/sessions/feature.js +8 -8
  311. package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
  312. package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
  313. package/dist/sessions/handlers/revoke.write.js +1 -1
  314. package/dist/sessions/schema/user-session.js +4 -4
  315. package/dist/sessions/screens.js +2 -2
  316. package/dist/sessions/session-callbacks.js +2 -2
  317. package/dist/sessions/session-revoked-event.js +2 -2
  318. package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
  319. package/dist/shared/decrypt-stored-pii.js +1 -1
  320. package/dist/shared/encrypt-for-direct-write.js +1 -1
  321. package/dist/shared/map-with-concurrency.js +5 -4
  322. package/dist/shared/parent-visibility.js +2 -2
  323. package/dist/shared/password-hashing.js +1 -1
  324. package/dist/shared/signup-handover.js +1 -2
  325. package/dist/shared/single-use-token-store.js +1 -1
  326. package/dist/subscription-mollie/constants.js +15 -17
  327. package/dist/subscription-mollie/feature.d.ts +17 -18
  328. package/dist/subscription-mollie/feature.js +24 -24
  329. package/dist/subscription-mollie/index.js +3 -3
  330. package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
  331. package/dist/subscription-mollie/plugin-methods.js +15 -14
  332. package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
  333. package/dist/subscription-mollie/verify-webhook.js +27 -27
  334. package/dist/subscription-stripe/constants.js +4 -6
  335. package/dist/subscription-stripe/feature.d.ts +14 -14
  336. package/dist/subscription-stripe/feature.js +35 -34
  337. package/dist/subscription-stripe/index.js +6 -6
  338. package/dist/subscription-stripe/plugin-methods.js +18 -18
  339. package/dist/subscription-stripe/runtime.d.ts +1 -1
  340. package/dist/subscription-stripe/runtime.js +1 -1
  341. package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
  342. package/dist/subscription-stripe/verify-webhook.js +59 -61
  343. package/dist/tags/feature.d.ts +3 -3
  344. package/dist/tags/screens.js +1 -1
  345. package/dist/template-resolver/api.js +10 -10
  346. package/dist/template-resolver/handlers/find-by-id.query.js +5 -5
  347. package/dist/template-resolver/handlers/list.query.js +1 -1
  348. package/dist/template-resolver/handlers/shared.js +2 -2
  349. package/dist/template-resolver/handlers/template-write.js +3 -3
  350. package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
  351. package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
  352. package/dist/template-resolver/seeding.js +4 -4
  353. package/dist/template-resolver/table.js +10 -11
  354. package/dist/template-resolver/web/client-plugin.js +2 -2
  355. package/dist/tenant/feature.js +7 -7
  356. package/dist/tenant/handlers/member-directory.query.js +1 -1
  357. package/dist/tenant/handlers/members.query.js +1 -1
  358. package/dist/tenant/handlers/team-list.query.js +1 -1
  359. package/dist/tenant/handlers/tenant-directory.query.js +1 -1
  360. package/dist/tenant/invitation-table.js +37 -40
  361. package/dist/tenant/membership-table.js +3 -3
  362. package/dist/tenant/schema/tenant.js +7 -9
  363. package/dist/tenant/screens.js +1 -1
  364. package/dist/tenant/seeding.d.ts +6 -5
  365. package/dist/tenant/seeding.js +12 -12
  366. package/dist/tenant/testing.js +5 -6
  367. package/dist/tenant/web/constants.js +2 -2
  368. package/dist/tenant-handover/events.js +5 -7
  369. package/dist/tenant-handover/feature.js +1 -1
  370. package/dist/tenant-handover/grant.js +1 -1
  371. package/dist/tenant-handover/handlers/claim.write.js +1 -1
  372. package/dist/tenant-handover/move-entity-graph.js +8 -9
  373. package/dist/tenant-handover/signup-handover-provider.js +1 -2
  374. package/dist/tenant-handover/transfer-graph.js +4 -5
  375. package/dist/tenant-lifecycle/boot-checks.js +1 -1
  376. package/dist/tenant-lifecycle/feature.js +1 -1
  377. package/dist/tenant-settings/constants.js +1 -1
  378. package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
  379. package/dist/tenant-settings/tenant-defaults.js +9 -2
  380. package/dist/tier-engine/aggregate-id.d.ts +11 -11
  381. package/dist/tier-engine/aggregate-id.js +15 -16
  382. package/dist/tier-engine/compose-app.d.ts +14 -14
  383. package/dist/tier-engine/compose-app.js +1 -1
  384. package/dist/tier-engine/entity.js +18 -19
  385. package/dist/tier-engine/feature.d.ts +19 -17
  386. package/dist/tier-engine/feature.js +68 -69
  387. package/dist/tier-engine/handlers/active-tier.query.js +6 -7
  388. package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
  389. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +5 -5
  390. package/dist/tier-engine/handlers/set-tenant-tier.write.js +3 -3
  391. package/dist/tier-engine/tier-resolver.js +2 -2
  392. package/dist/tier-engine/trial.js +8 -8
  393. package/dist/tier-engine/web/index.js +4 -4
  394. package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
  395. package/dist/user/handlers/create.write.js +4 -4
  396. package/dist/user/schema/user.d.ts +11 -11
  397. package/dist/user/schema/user.js +45 -44
  398. package/dist/user/seeding.d.ts +15 -15
  399. package/dist/user/seeding.js +28 -28
  400. package/dist/user/testing.js +3 -3
  401. package/dist/user-data-rights/audit-download.d.ts +8 -8
  402. package/dist/user-data-rights/audit-download.js +19 -20
  403. package/dist/user-data-rights/boot-checks.js +1 -1
  404. package/dist/user-data-rights/deletion-token.js +1 -1
  405. package/dist/user-data-rights/feature.d.ts +49 -50
  406. package/dist/user-data-rights/feature.js +54 -53
  407. package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
  408. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
  409. package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
  410. package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
  411. package/dist/user-data-rights/handlers/export-status.query.js +8 -9
  412. package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
  413. package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
  414. package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
  415. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
  416. package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
  417. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
  418. package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
  419. package/dist/user-data-rights/handlers/request-export.write.js +42 -41
  420. package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
  421. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
  422. package/dist/user-data-rights/index.js +8 -10
  423. package/dist/user-data-rights/lib/default-mailers.js +3 -3
  424. package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
  425. package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
  426. package/dist/user-data-rights/run-export-jobs.js +127 -233
  427. package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
  428. package/dist/user-data-rights/run-forget-cleanup.js +63 -82
  429. package/dist/user-data-rights/run-user-export.d.ts +34 -33
  430. package/dist/user-data-rights/run-user-export.js +55 -57
  431. package/dist/user-data-rights/schema/download-attempt.js +11 -11
  432. package/dist/user-data-rights/schema/download-token.js +37 -41
  433. package/dist/user-data-rights/schema/export-job.d.ts +4 -4
  434. package/dist/user-data-rights/schema/export-job.js +65 -67
  435. package/dist/user-data-rights/token-helpers.d.ts +8 -9
  436. package/dist/user-data-rights/token-helpers.js +21 -25
  437. package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
  438. package/dist/user-data-rights/web/client-plugin.js +1 -1
  439. package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
  440. package/dist/user-data-rights/web/constants.js +1 -1
  441. package/dist/user-data-rights/web/index.js +5 -5
  442. package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
  443. package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
  444. package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
  445. package/dist/user-data-rights/zip-path.d.ts +15 -15
  446. package/dist/user-data-rights/zip-path.js +41 -40
  447. package/dist/user-data-rights-defaults/feature.js +15 -15
  448. package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
  449. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
  450. package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
  451. package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
  452. package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
  453. package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
  454. package/dist/user-profile/handlers/change-email.write.js +13 -13
  455. package/dist/user-profile/index.js +3 -3
  456. package/dist/user-profile/web/client-plugin.js +1 -1
  457. package/dist/user-profile/web/constants.js +1 -1
  458. package/dist/user-profile/web/profile-screen.js +1 -1
  459. package/dist/workflow-runner/aggregate-id.d.ts +1 -1
  460. package/dist/workflow-runner/aggregate-id.js +1 -1
  461. package/dist/workflow-runner/event-subscriber.js +4 -5
  462. package/dist/workflow-runner/event-trigger.js +4 -17
  463. package/dist/workflow-runner/feature.js +2 -2
  464. package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
  465. package/dist/workflow-runner/pending-projection.js +6 -7
  466. package/dist/workflow-runner/runner.js +6 -6
  467. package/dist/workflow-runner/tables.js +6 -6
  468. package/dist/workflow-runner/workflow-registry.js +1 -1
  469. package/package.json +10 -10
@@ -2,23 +2,21 @@ import { KumikoError } from "@cosmicdrift/kumiko-framework/errors";
2
2
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
3
3
  import { type CapCounterContext } from "./book-cap-usage.ts";
4
4
  /**
5
- * Cap-Toleranz-Profile — pro Cap-Typ asymmetrisch. Quelle: Memory
6
- * `project_pricing_byok_caps` §3 + `docs/plans/marketing/produkt/
7
- * pricing.md` Cap-Verhalten-Block.
5
+ * Cap-tolerance profiles, asymmetric by cap type.
8
6
  *
9
- * **Soft** = Notification-Schwelle (Multiplier × Limit). Bei
10
- * Erreichen wird einmalig gewarnt (lastSoftWarnedAt setzt das Flag).
11
- * Caller-Code emittiert die echte Notification.
7
+ * **Soft** = notification threshold (multiplier × limit). Once reached,
8
+ * a warning is issued (`lastSoftWarnedAt` sets the flag); caller code emits
9
+ * the actual notification.
12
10
  *
13
- * **Hard** = Schreibe-Block (Multiplier × Limit). enforceCap throwt
14
- * mit `cap_exceeded`-Error → Dispatcher mapped 429 + Upgrade-Hint.
11
+ * **Hard** = write-block threshold (multiplier × limit). `enforceCap` throws
12
+ * a `cap_exceeded` error, which the dispatcher maps to 429 with an upgrade hint.
15
13
  */
16
14
  export type CapToleranceProfile = {
17
15
  readonly soft: number;
18
16
  readonly hard: number;
19
17
  };
20
18
  export declare const CAP_TOLERANCES: {
21
- /** Mails / Tokens — billig, BYOK ab Pro. Burst-Buffer großzügig. */
19
+ /** Mails / tokens — inexpensive, with BYOK available from Pro. Generous burst buffer. */
22
20
  readonly burstable: {
23
21
  readonly soft: 1.1;
24
22
  readonly hard: 1.2;
@@ -28,12 +26,12 @@ export declare const CAP_TOLERANCES: {
28
26
  readonly soft: 1;
29
27
  readonly hard: 1.05;
30
28
  };
31
- /** Apps-Count, Plattform-Slots — gebuchte Kapazität, kein Buffer. */
29
+ /** App count and platform slots — purchased capacity, with no buffer. */
32
30
  readonly hardSlot: {
33
31
  readonly soft: 1;
34
32
  readonly hard: 1;
35
33
  };
36
- /** Egress — Bursty-Traffic legitim, nur extreme Spikes blockieren. */
34
+ /** Egress — bursty traffic is legitimate; only extreme spikes are blocked. */
37
35
  readonly egress: {
38
36
  readonly soft: 1.1;
39
37
  readonly hard: 1.3;
@@ -92,28 +90,26 @@ export declare function enforceCap(ctx: CapCounterContext, options: {
92
90
  readonly i18nKey?: string;
93
91
  }): Promise<EnforceCapResult>;
94
92
  /**
95
- * Synchronous read-and-check of the calling tenant's Rolling-Window-
96
- * Counter for `capName`. Reads the increment-events of the last
97
- * `windowDays` from the event-store and sums their `amount`. Returns:
93
+ * Synchronous read-and-check of the calling tenant's rolling-window
94
+ * counter for `capName`. Reads increment events from the last
95
+ * `windowDays` in the event store and sums their `amount`. Returns:
98
96
  * - "ok" when sum < soft-threshold
99
97
  * - "soft-hit" when soft ≤ sum < hard.
100
98
  *
101
99
  * **Throws** `CapExceededError` when sum ≥ hard-threshold.
102
100
  *
103
- * **`crossed`-flag fehlt absichtlich:** Anders als der Calendar-
104
- * Counter hat das Rolling-Aggregate keine projection-row mit
105
- * `lastSoftWarnedAt`-Flag. Dedup gegen Notification-Storm passiert
106
- * im Caller (eigener key in einer Cache-Tabelle, oder einfache
107
- * memoization für die Lebensdauer des Request). Der Result-Shape
108
- * matcht trotzdem `EnforceCapResult` damit der gleiche Caller-Code
109
- * gegen beide Funktionen funktioniert; `crossed` ist hier immer
110
- * `false` (= "wir tracken's nicht").
101
+ * **The `crossed` flag is intentionally absent:** Unlike the calendar
102
+ * counter, the rolling aggregate has no projection row with a
103
+ * `lastSoftWarnedAt` flag. The caller must deduplicate notification storms
104
+ * using its own mechanism, such as a cache-table key or request-lifetime
105
+ * memoization. The result shape still matches `EnforceCapResult` so the same
106
+ * caller code works with both functions; `crossed` is always `false` here
107
+ * (= "not tracked").
111
108
  *
112
- * **Performance-Note:** der Read summiert ALLE Events im Window für
113
- * (tenant, capName). Bei 10k+ Events/Tenant in der Window könnte
114
- * das langsam werden — dann Migration auf eine Multi-Stream-
115
- * Projection mit pre-aggregierten daily-buckets. Heute nicht
116
- * vorgezogen.
109
+ * **Performance note:** The read sums ALL events in the window for
110
+ * (tenant, capName). With 10k+ events per tenant in the window, this could
111
+ * become slow; migrate to a multi-stream projection with pre-aggregated
112
+ * daily buckets if needed.
117
113
  */
118
114
  export declare function enforceRollingCap(ctx: CapCounterContext, options: {
119
115
  readonly capName: string;
@@ -153,13 +149,13 @@ export declare class CapExceededError extends KumikoError {
153
149
  export declare function currentCalendarMonthStartIso(now?: Temporal.Instant): string;
154
150
  export declare function calendarMonthPeriodEndIso(periodStartIso: string): string;
155
151
  /**
156
- * Soft-hit-notifier callback. Caller liefert die Funktion die ein
157
- * delivery-event emittet (z.B. `delivery.send({to, template, payload})`).
158
- * Wird genau einmal pro Period beim Calendar-Counter aufgerufen
159
- * (`crossed === true` deduplicated via `markSoftWarnedHandler`).
152
+ * Soft-hit notifier callback. The caller supplies the function that emits
153
+ * a delivery event (for example, `delivery.send({to, template, payload})`).
154
+ * It is called exactly once per period for the calendar counter
155
+ * (`crossed === true`, deduplicated via `markSoftWarnedHandler`).
160
156
  *
161
- * Beim Rolling-Counter ist `crossed` immer `false` — der Caller muss
162
- * dort selbst dedup'en (oder bewusst pro request feuern lassen).
157
+ * For the rolling counter, `crossed` is always `false`; the caller must
158
+ * deduplicate notifications itself or intentionally send one per request.
163
159
  */
164
160
  export type SoftHitNotifier = (info: {
165
161
  readonly capName: string;
@@ -168,14 +164,14 @@ export type SoftHitNotifier = (info: {
168
164
  readonly tenantId: string;
169
165
  }) => Promise<void> | void;
170
166
  /**
171
- * Calendar-Period-enforcement + automatische soft-hit-Notification.
172
- * Ruft `enforceCap`, bei `crossed: true` den Notifier UND
173
- * `mark-soft-warned`-Handler (flippt `lastSoftWarnedAt` damit der
174
- * nächste Aufruf in derselben Period nicht erneut feuert).
167
+ * Calendar-period enforcement with automatic soft-hit notification.
168
+ * Calls `enforceCap`; when `crossed: true`, it calls the notifier and the
169
+ * `mark-soft-warned` handler, which flips `lastSoftWarnedAt` so that the
170
+ * same period does not trigger another notification.
175
171
  *
176
- * Returnt das `EnforceCapResult` weiter — Caller kann die Logik
177
- * verzweigen (z.B. UI-Toast bei soft-hit zusätzlich zur
178
- * Email-Notification).
172
+ * Returns the `EnforceCapResult` unchanged, allowing the caller to branch
173
+ * on the result, such as showing a UI toast in addition to the email
174
+ * notification.
179
175
  */
180
176
  export declare function enforceCapAndMaybeNotify(ctx: CapCounterContext, options: {
181
177
  readonly capName: string;
@@ -189,14 +185,14 @@ export declare function enforceCapAndMaybeNotify(ctx: CapCounterContext, options
189
185
  readonly markSoftWarnedOutsideTransaction?: boolean;
190
186
  }): Promise<EnforceCapResult>;
191
187
  /**
192
- * Rolling-Window-enforcement + immer-feuert-Notification beim soft-hit.
188
+ * Rolling-window enforcement that always sends a notification on a soft hit.
193
189
  *
194
- * **Achtung Storm-Risk:** Rolling-Counter trackt `lastSoftWarnedAt`
195
- * NICHT (kein projection-row). Bei jedem Aufruf während der Counter
196
- * im soft-Bereich ist, feuert der notifier. Der Caller muss
197
- * dedup'en — z.B. via Cache-Eintrag `lastNotified[capName]` mit TTL,
198
- * oder er ruft `enforceRollingCapAndMaybeNotify` nur einmal pro
199
- * Tag/Stunde auf (Hourly-Cron statt pro Request).
190
+ * **Storm risk:** The rolling counter does NOT track `lastSoftWarnedAt`
191
+ * (there is no projection row). On every call while the counter is in the
192
+ * soft range, the notifier fires. The caller must deduplicate, for example
193
+ * with a cache entry `lastNotified[capName]` and a TTL, or call
194
+ * `enforceRollingCapAndMaybeNotify` only once per day or hour
195
+ * (an hourly cron instead of per request).
200
196
  */
201
197
  export declare function enforceRollingCapAndMaybeNotify(ctx: CapCounterContext, options: {
202
198
  readonly capName: string;
@@ -215,24 +211,25 @@ export type StockCapResult = {
215
211
  readonly limit: number;
216
212
  };
217
213
  /**
218
- * Stock-Cap: prüft eine vom Caller LIVE gezählte Kardinalität (z.B. Anzahl
219
- * existierender Components eines Tenants) gegen ein Tier-Limit.
214
+ * Stock cap: checks a cardinality counted LIVE by the caller (for example,
215
+ * the number of existing components for a tenant) against a tier limit.
220
216
  *
221
- * Anders als {@link enforceCap}/{@link enforceRollingCap} gibt es KEINEN
222
- * gespeicherten Counter: der Caller zählt die Projektion selbst
223
- * (`count(*) WHERE tenant_id = …`) und übergibt `current`. Das ist drift-frei
224
- * (ein Delete gibt den Slot sofort frei), braucht keine Counter-Tabelle und
225
- * kein Increment/Decrement-Bookkeeping. Misst einen Bestand, keinen Fluss.
217
+ * Unlike {@link enforceCap}/{@link enforceRollingCap}, there is NO stored
218
+ * counter: the caller counts the projection itself
219
+ * (`count(*) WHERE tenant_id = …`) and passes `current`. This avoids drift
220
+ * (a delete immediately frees the slot), requires no counter table or
221
+ * increment/decrement bookkeeping, and measures a stock rather than a flow.
226
222
  *
227
- * **TOCTOU-Caveat:** Zählen und Schreiben sind nicht atomar — zwei parallele
228
- * Creates können beide `ok` sehen und das Limit um eins überschreiten (gleiche
229
- * Race wie bei {@link enforceCap}). Exakt harte Slots brauchen zusätzliche
230
- * Serialisierung im Create-Pfad (z.B. Unique-Index auf tenantId+slot).
223
+ * **TOCTOU caveat:** Counting and writing are not atomic—two concurrent
224
+ * creates can both see `ok` and exceed the limit by one (the same race as
225
+ * with {@link enforceCap}). Strictly hard slots need additional
226
+ * serialization in the create path, such as a unique index on
227
+ * tenantId+slot.
231
228
  *
232
- * Reine Funktion — wirft NICHT und mappt KEINEN HTTP-Status. Ein erreichtes
233
- * Stock-Limit heißt „Upgrade nötig", nicht „retry later" (429): der Caller
234
- * entscheidet die Reaktion, typisch ein app-eigener 422/`upgrade_required`
235
- * mit i18n. Mit `hardSlot` (soft=hard=1.0) ist die Grenze exakt `limit`.
229
+ * Pure function—it does NOT throw or map an HTTP status. Reaching a stock
230
+ * limit means "upgrade required", not "retry later" (429); the caller
231
+ * chooses the response, typically an app-specific 422/`upgrade_required`
232
+ * with i18n. With `hardSlot` (soft=hard=1.0), the boundary is exactly `limit`.
236
233
  */
237
234
  export declare function enforceStockCap(options: {
238
235
  readonly current: number;
@@ -5,13 +5,13 @@ import { markCapSoftWarned, readRollingCapUsage, resolveCapCounterScope, } from
5
5
  import { capCounterEntity } from "./entity.js";
6
6
  const { table } = createEntityExecutor("cap-counter", capCounterEntity);
7
7
  export const CAP_TOLERANCES = {
8
- /** Mails / Tokens — billig, BYOK ab Pro. Burst-Buffer großzügig. */
8
+ /** Mails / tokens — inexpensive, with BYOK available from Pro. Generous burst buffer. */
9
9
  burstable: { soft: 1.1, hard: 1.2 },
10
10
  /** DB-Storage / File-Storage — teuer + persistent. Strikter Cut. */
11
11
  storage: { soft: 1.0, hard: 1.05 },
12
- /** Apps-Count, Plattform-Slots — gebuchte Kapazität, kein Buffer. */
12
+ /** App count and platform slots — purchased capacity, with no buffer. */
13
13
  hardSlot: { soft: 1.0, hard: 1.0 },
14
- /** Egress — Bursty-Traffic legitim, nur extreme Spikes blockieren. */
14
+ /** Egress — bursty traffic is legitimate; only extreme spikes are blocked. */
15
15
  egress: { soft: 1.1, hard: 1.3 },
16
16
  };
17
17
  export function assertBelowHardCap(valueSeenByLastUnit, cap) {
@@ -84,28 +84,26 @@ export async function enforceCap(ctx, options) {
84
84
  // Enforce-Rolling-Cap helper
85
85
  // =============================================================================
86
86
  /**
87
- * Synchronous read-and-check of the calling tenant's Rolling-Window-
88
- * Counter for `capName`. Reads the increment-events of the last
89
- * `windowDays` from the event-store and sums their `amount`. Returns:
87
+ * Synchronous read-and-check of the calling tenant's rolling-window
88
+ * counter for `capName`. Reads increment events from the last
89
+ * `windowDays` in the event store and sums their `amount`. Returns:
90
90
  * - "ok" when sum < soft-threshold
91
91
  * - "soft-hit" when soft ≤ sum < hard.
92
92
  *
93
93
  * **Throws** `CapExceededError` when sum ≥ hard-threshold.
94
94
  *
95
- * **`crossed`-flag fehlt absichtlich:** Anders als der Calendar-
96
- * Counter hat das Rolling-Aggregate keine projection-row mit
97
- * `lastSoftWarnedAt`-Flag. Dedup gegen Notification-Storm passiert
98
- * im Caller (eigener key in einer Cache-Tabelle, oder einfache
99
- * memoization für die Lebensdauer des Request). Der Result-Shape
100
- * matcht trotzdem `EnforceCapResult` damit der gleiche Caller-Code
101
- * gegen beide Funktionen funktioniert; `crossed` ist hier immer
102
- * `false` (= "wir tracken's nicht").
95
+ * **The `crossed` flag is intentionally absent:** Unlike the calendar
96
+ * counter, the rolling aggregate has no projection row with a
97
+ * `lastSoftWarnedAt` flag. The caller must deduplicate notification storms
98
+ * using its own mechanism, such as a cache-table key or request-lifetime
99
+ * memoization. The result shape still matches `EnforceCapResult` so the same
100
+ * caller code works with both functions; `crossed` is always `false` here
101
+ * (= "not tracked").
103
102
  *
104
- * **Performance-Note:** der Read summiert ALLE Events im Window für
105
- * (tenant, capName). Bei 10k+ Events/Tenant in der Window könnte
106
- * das langsam werden — dann Migration auf eine Multi-Stream-
107
- * Projection mit pre-aggregierten daily-buckets. Heute nicht
108
- * vorgezogen.
103
+ * **Performance note:** The read sums ALL events in the window for
104
+ * (tenant, capName). With 10k+ events per tenant in the window, this could
105
+ * become slow; migrate to a multi-stream projection with pre-aggregated
106
+ * daily buckets if needed.
109
107
  */
110
108
  export async function enforceRollingCap(ctx, options) {
111
109
  const { user, readDb } = resolveCapCounterScope(ctx, false);
@@ -200,14 +198,14 @@ export function calendarMonthPeriodEndIso(periodStartIso) {
200
198
  .toString();
201
199
  }
202
200
  /**
203
- * Calendar-Period-enforcement + automatische soft-hit-Notification.
204
- * Ruft `enforceCap`, bei `crossed: true` den Notifier UND
205
- * `mark-soft-warned`-Handler (flippt `lastSoftWarnedAt` damit der
206
- * nächste Aufruf in derselben Period nicht erneut feuert).
201
+ * Calendar-period enforcement with automatic soft-hit notification.
202
+ * Calls `enforceCap`; when `crossed: true`, it calls the notifier and the
203
+ * `mark-soft-warned` handler, which flips `lastSoftWarnedAt` so that the
204
+ * same period does not trigger another notification.
207
205
  *
208
- * Returnt das `EnforceCapResult` weiter — Caller kann die Logik
209
- * verzweigen (z.B. UI-Toast bei soft-hit zusätzlich zur
210
- * Email-Notification).
206
+ * Returns the `EnforceCapResult` unchanged, allowing the caller to branch
207
+ * on the result, such as showing a UI toast in addition to the email
208
+ * notification.
211
209
  */
212
210
  export async function enforceCapAndMaybeNotify(ctx, options) {
213
211
  const result = await enforceCap(ctx, {
@@ -238,14 +236,14 @@ export async function enforceCapAndMaybeNotify(ctx, options) {
238
236
  return result;
239
237
  }
240
238
  /**
241
- * Rolling-Window-enforcement + immer-feuert-Notification beim soft-hit.
239
+ * Rolling-window enforcement that always sends a notification on a soft hit.
242
240
  *
243
- * **Achtung Storm-Risk:** Rolling-Counter trackt `lastSoftWarnedAt`
244
- * NICHT (kein projection-row). Bei jedem Aufruf während der Counter
245
- * im soft-Bereich ist, feuert der notifier. Der Caller muss
246
- * dedup'en — z.B. via Cache-Eintrag `lastNotified[capName]` mit TTL,
247
- * oder er ruft `enforceRollingCapAndMaybeNotify` nur einmal pro
248
- * Tag/Stunde auf (Hourly-Cron statt pro Request).
241
+ * **Storm risk:** The rolling counter does NOT track `lastSoftWarnedAt`
242
+ * (there is no projection row). On every call while the counter is in the
243
+ * soft range, the notifier fires. The caller must deduplicate, for example
244
+ * with a cache entry `lastNotified[capName]` and a TTL, or call
245
+ * `enforceRollingCapAndMaybeNotify` only once per day or hour
246
+ * (an hourly cron instead of per request).
249
247
  */
250
248
  export async function enforceRollingCapAndMaybeNotify(ctx, options) {
251
249
  const result = await enforceRollingCap(ctx, {
@@ -265,24 +263,25 @@ export async function enforceRollingCapAndMaybeNotify(ctx, options) {
265
263
  return result;
266
264
  }
267
265
  /**
268
- * Stock-Cap: prüft eine vom Caller LIVE gezählte Kardinalität (z.B. Anzahl
269
- * existierender Components eines Tenants) gegen ein Tier-Limit.
266
+ * Stock cap: checks a cardinality counted LIVE by the caller (for example,
267
+ * the number of existing components for a tenant) against a tier limit.
270
268
  *
271
- * Anders als {@link enforceCap}/{@link enforceRollingCap} gibt es KEINEN
272
- * gespeicherten Counter: der Caller zählt die Projektion selbst
273
- * (`count(*) WHERE tenant_id = …`) und übergibt `current`. Das ist drift-frei
274
- * (ein Delete gibt den Slot sofort frei), braucht keine Counter-Tabelle und
275
- * kein Increment/Decrement-Bookkeeping. Misst einen Bestand, keinen Fluss.
269
+ * Unlike {@link enforceCap}/{@link enforceRollingCap}, there is NO stored
270
+ * counter: the caller counts the projection itself
271
+ * (`count(*) WHERE tenant_id = …`) and passes `current`. This avoids drift
272
+ * (a delete immediately frees the slot), requires no counter table or
273
+ * increment/decrement bookkeeping, and measures a stock rather than a flow.
276
274
  *
277
- * **TOCTOU-Caveat:** Zählen und Schreiben sind nicht atomar — zwei parallele
278
- * Creates können beide `ok` sehen und das Limit um eins überschreiten (gleiche
279
- * Race wie bei {@link enforceCap}). Exakt harte Slots brauchen zusätzliche
280
- * Serialisierung im Create-Pfad (z.B. Unique-Index auf tenantId+slot).
275
+ * **TOCTOU caveat:** Counting and writing are not atomic—two concurrent
276
+ * creates can both see `ok` and exceed the limit by one (the same race as
277
+ * with {@link enforceCap}). Strictly hard slots need additional
278
+ * serialization in the create path, such as a unique index on
279
+ * tenantId+slot.
281
280
  *
282
- * Reine Funktion — wirft NICHT und mappt KEINEN HTTP-Status. Ein erreichtes
283
- * Stock-Limit heißt „Upgrade nötig", nicht „retry later" (429): der Caller
284
- * entscheidet die Reaktion, typisch ein app-eigener 422/`upgrade_required`
285
- * mit i18n. Mit `hardSlot` (soft=hard=1.0) ist die Grenze exakt `limit`.
281
+ * Pure function—it does NOT throw or map an HTTP status. Reaching a stock
282
+ * limit means "upgrade required", not "retry later" (429); the caller
283
+ * chooses the response, typically an app-specific 422/`upgrade_required`
284
+ * with i18n. With `hardSlot` (soft=hard=1.0), the boundary is exactly `limit`.
286
285
  */
287
286
  export function enforceStockCap(options) {
288
287
  const hardThreshold = options.limit * CAP_TOLERANCES[options.profile].hard;
@@ -1,36 +1,36 @@
1
1
  import { createBigIntField, createEntity, createTextField, createTimestampField, } from "@cosmicdrift/kumiko-framework/engine";
2
- // cap-counter — eine Row pro (tenantId, capName, periodStart). tenantId
3
- // kommt automatisch als Base-Column (Kumiko Multi-Tenant-Default).
2
+ // cap-counter — one row per (tenantId, capName, periodStart). tenantId
3
+ // is added automatically as a base column (Kumiko multi-tenant default).
4
4
  //
5
- // **Identity-Modell:**
6
- // - aggregate-id: UUID (Kumiko-ES-Pflicht)
7
- // - public natural-key: (tenantId, capName, periodStart) — die Counter-
8
- // Engine nutzt deterministic uuidv5 daraus, damit Increments gegen
9
- // denselben Stream gehen statt zwei Rows pro Tenant+Cap zu erzeugen
5
+ // **Identity model:**
6
+ // - aggregate-id: UUID (required by Kumiko ES)
7
+ // - public natural key: (tenantId, capName, periodStart) — the counter
8
+ // engine derives a deterministic uuidv5 from it so increments use the
9
+ // same stream instead of creating two rows per tenant and cap
10
10
  //
11
- // **Felder:**
12
- // - capName: das Domain-Konzept ("platform-mails", "ai-tokens-7day",
13
- // "db-storage-bytes"). Frei-form String — die App definiert ihre
14
- // Cap-Names, die Engine kennt sie nicht enumerated.
15
- // - value: aktueller Counter-Wert. Tokens, MB, Anzahl etc — Einheit
16
- // ist app-Sache, die Engine zählt nur Zahlen.
17
- // - periodStart: Timestamp wann das aktuelle Counter-Period begann.
18
- // Calendar-Month-Reset setzt einen neuen periodStart (= neue Aggregate-
19
- // Identität). Rolling-Window (z.B. KI-Tokens 7-day) setzt periodStart
20
- // einfach nicht zurück und filtert beim Read mit `WHERE timestamp >
21
- // now() - 7d` über den Event-Store-Stream — das ist Caller-Sache.
22
- // - lastSoftWarnedAt: Anti-Notification-Storm. Wenn Soft-Cap @ 110%
23
- // einmal erreicht ist, soll nicht jeder Folge-Increment eine Mail an
24
- // den Admin schicken. Pro Period maximal eine Soft-Warning, daher
25
- // diese Spalte; nullable, wird beim Reset auf null zurückgesetzt.
11
+ // **Fields:**
12
+ // - capName: the domain concept ("platform-mails", "ai-tokens-7day",
13
+ // "db-storage-bytes"). Free-form string — the app defines its cap
14
+ // names; the engine does not enumerate them.
15
+ // - value: the current counter value. Tokens, MB, count, etc. — the unit
16
+ // belongs to the app; the engine only counts numbers.
17
+ // - periodStart: timestamp when the current counter period began.
18
+ // A calendar-month reset sets a new periodStart (= new aggregate
19
+ // identity). A rolling window (e.g. AI tokens over 7 days) does not
20
+ // reset periodStart and filters on read with `WHERE timestamp >
21
+ // now() - 7d` over the event-store stream — this is the caller's
22
+ // responsibility.
23
+ // - lastSoftWarnedAt: prevents notification storms. Once the soft cap at
24
+ // 110% is reached, subsequent increments must not each send an email to
25
+ // the admin. There is at most one soft warning per period, so this
26
+ // nullable column is reset to null when the period resets.
26
27
  //
27
- // **Was bewusst NICHT in der Entity steht:**
28
- // - softLimit / hardLimit / cap-toleranz-multipliers — die kommen aus
29
- // der App-TierMap zur enforceCap-Aufruf-Zeit. Counter weiß nichts
30
- // vom Tier, nur von "wie viele zähle ich".
31
- // - userId / aggregate-Reference — Counter sind Plattform-Tenant-
32
- // scoped, nicht User-scoped (auch wenn ein User den Increment
33
- // auslöst).
28
+ // **What is intentionally not in the entity:**
29
+ // - softLimit / hardLimit / cap-tolerance multipliers — these come from
30
+ // the app's tier map when enforceCap is called. The counter knows
31
+ // nothing about the tier, only how much is being counted.
32
+ // - userId / aggregate reference — counters are scoped to the platform
33
+ // tenant, not to a user (even when a user triggers the increment).
34
34
  export const capCounterEntity = createEntity({
35
35
  table: "read_cap_counters",
36
36
  description: "One usage counter per tenant, cap name and calendar period, holding the accumulated value and the timestamp of the last soft-limit warning.",
@@ -1,49 +1,48 @@
1
- // cap-counter — Counter-Storage + Increment-API + Soft-Warn-State.
1
+ // cap-counter — Counter Storage + Increment API + Soft-Warn State.
2
2
  //
3
- // **Was diese Feature liefert:**
4
- // 1. r.entity({ name: "cap-counter" }) — Counter-Rows pro (tenant, capName,
5
- // period) für Calendar-Period-Caps (Mails/Monat, Egress/Monat).
6
- // 2. increment-Handler — atomic counter increment via deterministic
7
- // aggregate-id (try-create / executor-update). Race-frei via
8
- // event-store optimistic-lock.
9
- // 3. increment-rolling-Handler (Sprint 4) — append-only Custom-Event-
10
- // Stream für Rolling-Window-Caps (KI-Tokens-7d, Egress-24h). Kein
11
- // projection — der Wert kommt im Read aus dem Event-Stream.
12
- // 4. mark-soft-warned-Handler — flippt das Anti-Notification-Storm-
13
- // Flag (nur Calendar-Period-Counter).
14
- // 5. get-counter-Query — sync read der aktuellen Counter-Value
15
- // (Calendar).
16
- // 6. enforceCap + enforceRollingCap-Helper (siehe enforce-cap.ts) —
17
- // Pre-Save-Wrapper mit asymmetrischen Soft/Hard-Toleranzen pro
18
- // Cap-Profile.
3
+ // **What this feature provides:**
4
+ // 1. r.entity({ name: "cap-counter" }) — counter rows per (tenant, capName,
5
+ // period) for calendar-period caps (mail/month, egress/month).
6
+ // 2. increment handler — atomic counter increment via deterministic
7
+ // aggregate-id (try-create / executor-update), made race-free by the
8
+ // event-store optimistic lock.
9
+ // 3. increment-rolling handler — append-only custom-event stream for
10
+ // rolling-window caps (AI-tokens-7d, egress-24h). No projection; the
11
+ // value is read from the event stream.
12
+ // 4. mark-soft-warned handler — flips the anti-notification-storm flag
13
+ // (calendar-period counters only).
14
+ // 5. get-counter query — synchronous read of the current counter value
15
+ // (calendar period).
16
+ // 6. enforceCap + enforceRollingCap helpers (see enforce-cap.ts) —
17
+ // pre-save wrappers with asymmetric soft and hard tolerances per
18
+ // cap profile.
19
19
  //
20
- // **Calendar vs. Rolling — when to use which:**
20
+ // **Calendar vs. rolling — when to use which:**
21
21
  // - **Calendar period** (bookCapUsage + enforceCap): the cap resets at
22
- // period start (1st of the month etc.). The counter is one row in the
23
- // projection. Fast read.
22
+ // period start (the first of the month, etc.). The counter is one row in
23
+ // the projection, enabling fast reads.
24
24
  // - **Rolling window** (CapCounterHandlers.incrementRolling + enforceRollingCap):
25
- // the cap rolls continuously (e.g. "last 7 days"). Values expire
26
- // event by event without a reset. No projection; the read sums the
27
- // events of the last N days.
25
+ // the cap rolls continuously (e.g. "last 7 days"). Values expire event
26
+ // by event without a reset. There is no projection; reads sum the events
27
+ // from the last N days.
28
28
  //
29
29
  // **What this feature does NOT do:**
30
30
  // - **No foundation wiring.** mail-foundation / file-foundation /
31
- // ai-foundation are BYOK by default today and have no platform pool
31
+ // ai-foundation are BYOK by default and currently have no platform pool
32
32
  // to count. cap-counter is generic: an app owner who wants to use the
33
33
  // counter calls `bookCapUsage(...)` /
34
34
  // `ctx.write(CapCounterHandlers.incrementRolling, ...)` from their own handler.
35
- // - **No reset cron for the calendar period.** Works without one: the
36
- // periodStartIso part of the aggregate id rolls over to a fresh
37
- // counter at the period tick. Old rows stay for audit.
38
- // - **Kein Notification-Pfad als Hard-Wiring.** Cap-counter
39
- // entkoppelt — `enforceCapAndMaybeNotify` (siehe enforce-cap.ts)
40
- // ist ein Convenience-Helper, der einen Caller-supplied
41
- // emit-Callback ausführt; cap-counter kennt delivery-feature
42
- // nicht direkt.
35
+ // - **No reset cron for the calendar period.** It works without one: the
36
+ // periodStartIso part of the aggregate id rolls over to a fresh counter
37
+ // at the period boundary. Old rows remain for auditing.
38
+ // - **No notification path is hard-wired.** cap-counter is decoupled —
39
+ // `enforceCapAndMaybeNotify` (see enforce-cap.ts) is a convenience helper
40
+ // that invokes a caller-supplied emit callback; cap-counter does not know
41
+ // the delivery feature directly.
43
42
  //
44
- // **Boot-Dependencies:** keine. cap-counter ist Plain-Vanilla — kein
45
- // config, kein secrets, kein tenant-feature nötig. Tenant-Scoping kommt
46
- // vom Framework-Default (Base-Column tenantId).
43
+ // **Boot dependencies:** none. cap-counter is plain vanilla — it needs no
44
+ // config, secrets, or tenant feature. Tenant scoping comes from the framework
45
+ // default (Base-Column tenantId).
47
46
  import { access, defineEntityListHandler, defineFeature, } from "@cosmicdrift/kumiko-framework/engine";
48
47
  import { CAP_COUNTER_FEATURE, CAP_COUNTER_LIST_SCREEN_ID, ROLLING_INCREMENTED_EVENT_SHORT, ROLLING_RELEASED_EVENT_SHORT, } from "./constants.js";
49
48
  import { capCounterEntity } from "./entity.js";
@@ -1,7 +1,7 @@
1
1
  import type { WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import * as z from "zod";
3
- /** Schema des emittierten Custom-Events. Identisch zum Input-Schema:
4
- * der Caller zahlt amount, wir hängen es 1:1 an den Stream. */
3
+ /** Schema of the emitted custom event. Identical to the input schema:
4
+ * the caller supplies amount, which we append unchanged to the stream. */
5
5
  export declare const rollingIncrementedSchema: z.ZodObject<{
6
6
  capName: z.ZodString;
7
7
  amount: z.ZodDefault<z.ZodNumber>;