@cosmicdrift/kumiko-bundled-features 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 (470) hide show
  1. package/LICENSE +21 -57
  2. package/dist/agent-tools/tool-catalog.js +1 -1
  3. package/dist/agent-tools/tool-dispatch.js +0 -2
  4. package/dist/audit/screens.js +1 -1
  5. package/dist/auth-email-password/feature.js +1 -1
  6. package/dist/auth-email-password/handlers/change-password.write.js +3 -3
  7. package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
  8. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
  9. package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
  10. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  11. package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
  12. package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
  13. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
  14. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  15. package/dist/auth-email-password/handlers/login.write.js +1 -1
  16. package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
  17. package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
  18. package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
  19. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  20. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
  21. package/dist/auth-email-password/index.js +5 -5
  22. package/dist/auth-email-password/lockout-store.js +1 -1
  23. package/dist/auth-email-password/seeding.d.ts +42 -45
  24. package/dist/auth-email-password/seeding.js +51 -53
  25. package/dist/auth-email-password/signup-token-store.js +8 -8
  26. package/dist/auth-email-password/testing.js +3 -3
  27. package/dist/auth-email-password/web/auth-client.d.ts +2 -2
  28. package/dist/auth-email-password/web/auth-client.js +36 -37
  29. package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
  30. package/dist/auth-email-password/web/auth-gate.js +15 -16
  31. package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
  32. package/dist/auth-email-password/web/client-plugin.js +4 -5
  33. package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
  34. package/dist/auth-email-password/web/constants.js +3 -3
  35. package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
  36. package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
  37. package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
  38. package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
  39. package/dist/auth-email-password/web/index.js +5 -5
  40. package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
  41. package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
  42. package/dist/auth-email-password/web/login-screen.d.ts +1 -1
  43. package/dist/auth-email-password/web/login-screen.js +2 -3
  44. package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
  45. package/dist/auth-email-password/web/reset-password-screen.js +12 -13
  46. package/dist/auth-email-password/web/session.d.ts +10 -9
  47. package/dist/auth-email-password/web/session.js +28 -29
  48. package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
  49. package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
  50. package/dist/auth-email-password/web/signup-screen.js +13 -13
  51. package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
  52. package/dist/auth-email-password/web/tenant-switcher.js +21 -22
  53. package/dist/auth-email-password/web/use-shell-user.js +12 -13
  54. package/dist/auth-email-password/web/user-menu.d.ts +4 -4
  55. package/dist/auth-email-password/web/user-menu.js +12 -13
  56. package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
  57. package/dist/auth-email-password/web/verify-email-screen.js +9 -10
  58. package/dist/auth-foundation/boot-checks.js +4 -4
  59. package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
  60. package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
  61. package/dist/auth-foundation/types.js +2 -2
  62. package/dist/auth-mfa/handlers/disable.write.js +3 -3
  63. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
  64. package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
  65. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
  66. package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
  67. package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
  68. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  69. package/dist/auth-mfa/token-secrets.js +1 -1
  70. package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
  71. package/dist/auth-mfa/web/client-plugin.js +1 -1
  72. package/dist/auth-mfa/web/i18n.js +3 -3
  73. package/dist/auth-mfa/web/index.js +4 -4
  74. package/dist/auth-mfa/web/mfa-client.js +17 -16
  75. package/dist/auth-mfa/web/mfa-verify-screen.js +6 -6
  76. package/dist/billing-foundation/aggregate-id.d.ts +5 -5
  77. package/dist/billing-foundation/aggregate-id.js +10 -11
  78. package/dist/billing-foundation/entities.js +27 -27
  79. package/dist/billing-foundation/events.js +18 -17
  80. package/dist/billing-foundation/feature.js +42 -43
  81. package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
  82. package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
  83. package/dist/billing-foundation/handlers/create-checkout-session.write.js +18 -17
  84. package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
  85. package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
  86. package/dist/billing-foundation/handlers/process-event.write.js +20 -20
  87. package/dist/billing-foundation/projection.d.ts +15 -11
  88. package/dist/billing-foundation/projection.js +38 -37
  89. package/dist/billing-foundation/subscription-tier-sync.js +3 -3
  90. package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
  91. package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
  92. package/dist/billing-foundation/types.d.ts +40 -41
  93. package/dist/billing-foundation/types.js +20 -20
  94. package/dist/billing-foundation/web/billing-plans-panel.js +4 -4
  95. package/dist/cap-counter/aggregate-id.js +8 -9
  96. package/dist/cap-counter/constants.js +11 -12
  97. package/dist/cap-counter/enforce-cap.d.ts +59 -62
  98. package/dist/cap-counter/enforce-cap.js +47 -48
  99. package/dist/cap-counter/entity.js +29 -29
  100. package/dist/cap-counter/feature.js +34 -35
  101. package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
  102. package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
  103. package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
  104. package/dist/cap-counter/stock-cap-guard.js +1 -1
  105. package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
  106. package/dist/channel-email/smtp-transport.d.ts +18 -17
  107. package/dist/channel-email/smtp-transport.js +24 -21
  108. package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
  109. package/dist/compliance-profiles/feature.js +4 -4
  110. package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
  111. package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
  112. package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
  113. package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
  114. package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
  115. package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
  116. package/dist/compliance-profiles/schema/profile-selection.js +18 -23
  117. package/dist/compliance-profiles/seeding.js +14 -15
  118. package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
  119. package/dist/compliance-profiles-ops/index.js +2 -2
  120. package/dist/config/handlers/readiness.query.d.ts +4 -4
  121. package/dist/config/handlers/readiness.query.js +1 -1
  122. package/dist/config/handlers/reencrypt.job.js +4 -5
  123. package/dist/config/handlers/set.write.js +4 -4
  124. package/dist/config/resolver.js +4 -4
  125. package/dist/config/table.js +10 -10
  126. package/dist/config/write-helpers.js +1 -1
  127. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
  128. package/dist/crypto-shredding/handlers/forget-subject.write.js +12 -11
  129. package/dist/custom-fields/aggregate-id.d.ts +12 -13
  130. package/dist/custom-fields/aggregate-id.js +16 -17
  131. package/dist/custom-fields/entity.js +49 -47
  132. package/dist/custom-fields/events.js +7 -8
  133. package/dist/custom-fields/feature.d.ts +14 -14
  134. package/dist/custom-fields/feature.js +53 -54
  135. package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
  136. package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
  137. package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
  138. package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
  139. package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
  140. package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
  141. package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
  142. package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
  143. package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
  144. package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
  145. package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
  146. package/dist/custom-fields/lib/field-access.js +2 -2
  147. package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
  148. package/dist/custom-fields/lib/quota.js +1 -1
  149. package/dist/custom-fields/lib/value-schema.js +10 -12
  150. package/dist/custom-fields/run-retention.js +3 -3
  151. package/dist/custom-fields/schemas.js +14 -14
  152. package/dist/custom-fields/web/client-plugin.js +2 -5
  153. package/dist/custom-fields/web/constants.js +2 -2
  154. package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
  155. package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
  156. package/dist/custom-fields/wire-for-entity.js +65 -67
  157. package/dist/custom-fields/wire-user-data-rights.js +3 -3
  158. package/dist/data-retention/_internal/parse-override.js +2 -3
  159. package/dist/data-retention/feature.js +11 -18
  160. package/dist/data-retention/handlers/policy-for.query.js +6 -6
  161. package/dist/data-retention/keep-for.d.ts +7 -7
  162. package/dist/data-retention/keep-for.js +15 -15
  163. package/dist/data-retention/override-schema.d.ts +3 -4
  164. package/dist/data-retention/override-schema.js +13 -15
  165. package/dist/data-retention/presets.d.ts +4 -5
  166. package/dist/data-retention/presets.js +18 -23
  167. package/dist/data-retention/resolve-tenant-preset.js +17 -16
  168. package/dist/data-retention/resolver.d.ts +12 -12
  169. package/dist/data-retention/resolver.js +24 -23
  170. package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
  171. package/dist/data-retention/run-retention-cleanup.js +61 -51
  172. package/dist/data-retention/schema/tenant-retention-override.js +13 -11
  173. package/dist/delivery/feature.js +2 -2
  174. package/dist/delivery/handlers/log.query.js +1 -1
  175. package/dist/delivery/tables.js +9 -8
  176. package/dist/delivery/unsubscribe.js +4 -4
  177. package/dist/document-ingest-foundation/entity.js +4 -4
  178. package/dist/document-ingest-foundation/events.js +2 -2
  179. package/dist/document-ingest-foundation/feature.js +2 -2
  180. package/dist/document-ingest-foundation/pages.js +1 -1
  181. package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
  182. package/dist/feature-toggles/compose-tier-resolver.js +1 -1
  183. package/dist/feature-toggles/feature.js +1 -1
  184. package/dist/feature-toggles/global-feature-state-table.js +1 -1
  185. package/dist/feature-toggles/handlers/registered.query.js +5 -5
  186. package/dist/feature-toggles/toggle-sync-signal.js +1 -1
  187. package/dist/feature-toggles/web/constants.js +1 -1
  188. package/dist/file-derivatives/feature.d.ts +1 -1
  189. package/dist/file-derivatives/feature.js +1 -1
  190. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  191. package/dist/file-derivatives/presets.js +1 -1
  192. package/dist/file-foundation/feature.js +6 -6
  193. package/dist/file-provider-inmemory/feature.d.ts +1 -1
  194. package/dist/file-provider-inmemory/feature.js +16 -16
  195. package/dist/file-provider-s3/feature.js +16 -16
  196. package/dist/file-provider-s3/lib/s3-provider.js +6 -6
  197. package/dist/files/feature.js +6 -6
  198. package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
  199. package/dist/files-tenant-data/hooks.js +24 -26
  200. package/dist/files-tenant-data/index.js +1 -1
  201. package/dist/folders/feature.d.ts +1 -1
  202. package/dist/folders/web/folder-manager.js +2 -2
  203. package/dist/folders/web/tree.js +5 -5
  204. package/dist/form-draft/db/queries/cleanup.js +1 -1
  205. package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
  206. package/dist/form-draft/entity.js +3 -3
  207. package/dist/form-draft/feature.js +4 -5
  208. package/dist/form-draft/handlers/discard.write.js +1 -1
  209. package/dist/form-draft/release-file-refs.js +6 -6
  210. package/dist/form-draft/schemas.js +3 -3
  211. package/dist/form-draft/web/constants.js +0 -2
  212. package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
  213. package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
  214. package/dist/inbound-mail-foundation/connect-routes.js +4 -3
  215. package/dist/inbound-mail-foundation/constants.d.ts +22 -24
  216. package/dist/inbound-mail-foundation/constants.js +30 -33
  217. package/dist/inbound-mail-foundation/entities.d.ts +12 -12
  218. package/dist/inbound-mail-foundation/entities.js +47 -48
  219. package/dist/inbound-mail-foundation/events.d.ts +4 -3
  220. package/dist/inbound-mail-foundation/events.js +50 -47
  221. package/dist/inbound-mail-foundation/feature.js +39 -39
  222. package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
  223. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
  224. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
  225. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
  226. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
  227. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
  228. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
  229. package/dist/inbound-mail-foundation/handlers/update-account.write.js +11 -11
  230. package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
  231. package/dist/inbound-mail-foundation/oauth-state.js +11 -10
  232. package/dist/inbound-mail-foundation/projection.d.ts +4 -4
  233. package/dist/inbound-mail-foundation/projection.js +31 -29
  234. package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
  235. package/dist/inbound-mail-foundation/provider-factory.js +9 -9
  236. package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
  237. package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
  238. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
  239. package/dist/inbound-mail-foundation/types.d.ts +45 -46
  240. package/dist/inbound-mail-foundation/types.js +21 -21
  241. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
  242. package/dist/inbound-mail-foundation/watch-supervisor.js +57 -56
  243. package/dist/inbound-provider-imap/credential-document.js +13 -13
  244. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  245. package/dist/inbound-provider-imap/feature.js +42 -40
  246. package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
  247. package/dist/inbound-provider-imap/imap-client.js +20 -19
  248. package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
  249. package/dist/inbound-provider-inmemory/feature.js +19 -19
  250. package/dist/jobs/db/queries/retention.js +2 -2
  251. package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
  252. package/dist/jobs/events.js +1 -1
  253. package/dist/jobs/feature.js +5 -6
  254. package/dist/jobs/handlers/detail.query.js +4 -4
  255. package/dist/jobs/handlers/list.query.js +1 -1
  256. package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
  257. package/dist/jobs/handlers/reindex-entity.job.js +1 -1
  258. package/dist/jobs/handlers/retry.write.js +1 -1
  259. package/dist/jobs/job-instant.js +1 -1
  260. package/dist/jobs/job-run-logger.js +10 -11
  261. package/dist/jobs/job-run-table.js +3 -3
  262. package/dist/jobs/screens.js +1 -1
  263. package/dist/jobs/tenant-job-failure-table.js +1 -1
  264. package/dist/jobs/tenant-job-run-table.js +1 -1
  265. package/dist/ledger/entity.js +5 -5
  266. package/dist/ledger/feature.js +3 -3
  267. package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
  268. package/dist/ledger/recurring.js +12 -12
  269. package/dist/ledger/schemas.js +1 -1
  270. package/dist/ledger/web/constants.js +2 -2
  271. package/dist/ledger/web/index.js +7 -7
  272. package/dist/legal-pages/feature.d.ts +4 -4
  273. package/dist/legal-pages/feature.js +25 -26
  274. package/dist/legal-pages/markdown.js +3 -3
  275. package/dist/legal-pages/web/client-plugin.js +23 -24
  276. package/dist/legal-pages/web/index.js +0 -1
  277. package/dist/mail-foundation/feature.d.ts +2 -2
  278. package/dist/mail-foundation/feature.js +24 -25
  279. package/dist/mail-transport-inmemory/feature.d.ts +4 -4
  280. package/dist/mail-transport-inmemory/feature.js +27 -28
  281. package/dist/mail-transport-smtp/feature.js +20 -20
  282. package/dist/managed-pages/branding.js +6 -6
  283. package/dist/managed-pages/feature.d.ts +26 -26
  284. package/dist/managed-pages/feature.js +34 -34
  285. package/dist/managed-pages/handlers/by-slug.query.js +5 -6
  286. package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
  287. package/dist/managed-pages/handlers/set.write.js +5 -7
  288. package/dist/managed-pages/screens/page-screens.js +11 -11
  289. package/dist/managed-pages/seeding.js +8 -8
  290. package/dist/managed-pages/table.js +13 -12
  291. package/dist/managed-pages/web/client-plugin.d.ts +1 -1
  292. package/dist/managed-pages/web/client-plugin.js +5 -5
  293. package/dist/managed-pages/web/i18n.js +1 -1
  294. package/dist/notes-history/entity.js +4 -4
  295. package/dist/notes-history/feature.d.ts +2 -2
  296. package/dist/notes-history-user-data/hooks.js +1 -1
  297. package/dist/page-render/layout.js +9 -9
  298. package/dist/page-render/markdown.js +11 -11
  299. package/dist/page-render/security-headers.js +7 -6
  300. package/dist/personal-access-tokens/feature.js +5 -5
  301. package/dist/personal-access-tokens/roles.js +2 -2
  302. package/dist/readiness/handlers/status.query.js +3 -3
  303. package/dist/renderer-foundation/api.js +12 -13
  304. package/dist/renderer-foundation/constants.js +2 -2
  305. package/dist/renderer-foundation/feature.js +7 -7
  306. package/dist/secrets/feature.js +9 -9
  307. package/dist/secrets/web/constants.js +2 -2
  308. package/dist/seo/feature.js +3 -3
  309. package/dist/sessions/constants.d.ts +1 -1
  310. package/dist/sessions/constants.js +1 -1
  311. package/dist/sessions/feature.js +8 -8
  312. package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
  313. package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
  314. package/dist/sessions/handlers/revoke.write.js +1 -1
  315. package/dist/sessions/schema/user-session.js +4 -4
  316. package/dist/sessions/screens.js +2 -2
  317. package/dist/sessions/session-callbacks.js +2 -2
  318. package/dist/sessions/session-revoked-event.js +2 -2
  319. package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
  320. package/dist/shared/decrypt-stored-pii.js +1 -1
  321. package/dist/shared/encrypt-for-direct-write.js +1 -1
  322. package/dist/shared/map-with-concurrency.js +5 -4
  323. package/dist/shared/parent-visibility.js +2 -2
  324. package/dist/shared/password-hashing.js +1 -1
  325. package/dist/shared/signup-handover.js +1 -2
  326. package/dist/shared/single-use-token-store.js +1 -1
  327. package/dist/subscription-mollie/constants.js +15 -17
  328. package/dist/subscription-mollie/feature.d.ts +17 -18
  329. package/dist/subscription-mollie/feature.js +24 -24
  330. package/dist/subscription-mollie/index.js +3 -3
  331. package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
  332. package/dist/subscription-mollie/plugin-methods.js +15 -14
  333. package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
  334. package/dist/subscription-mollie/verify-webhook.js +27 -27
  335. package/dist/subscription-stripe/constants.js +4 -6
  336. package/dist/subscription-stripe/feature.d.ts +14 -14
  337. package/dist/subscription-stripe/feature.js +35 -34
  338. package/dist/subscription-stripe/index.js +6 -6
  339. package/dist/subscription-stripe/plugin-methods.js +18 -18
  340. package/dist/subscription-stripe/runtime.d.ts +1 -1
  341. package/dist/subscription-stripe/runtime.js +1 -1
  342. package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
  343. package/dist/subscription-stripe/verify-webhook.js +59 -61
  344. package/dist/tags/feature.d.ts +3 -3
  345. package/dist/tags/screens.js +1 -1
  346. package/dist/template-resolver/api.js +10 -10
  347. package/dist/template-resolver/handlers/find-by-id.query.js +5 -5
  348. package/dist/template-resolver/handlers/list.query.js +1 -1
  349. package/dist/template-resolver/handlers/shared.js +2 -2
  350. package/dist/template-resolver/handlers/template-write.js +3 -3
  351. package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
  352. package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
  353. package/dist/template-resolver/seeding.js +4 -4
  354. package/dist/template-resolver/table.js +10 -11
  355. package/dist/template-resolver/web/client-plugin.js +2 -2
  356. package/dist/tenant/feature.js +7 -7
  357. package/dist/tenant/handlers/member-directory.query.js +1 -1
  358. package/dist/tenant/handlers/members.query.js +1 -1
  359. package/dist/tenant/handlers/team-list.query.js +1 -1
  360. package/dist/tenant/handlers/tenant-directory.query.js +1 -1
  361. package/dist/tenant/invitation-table.js +37 -40
  362. package/dist/tenant/membership-table.js +3 -3
  363. package/dist/tenant/schema/tenant.js +7 -9
  364. package/dist/tenant/screens.js +1 -1
  365. package/dist/tenant/seeding.d.ts +6 -5
  366. package/dist/tenant/seeding.js +12 -12
  367. package/dist/tenant/testing.js +5 -6
  368. package/dist/tenant/web/constants.js +2 -2
  369. package/dist/tenant-handover/events.js +5 -7
  370. package/dist/tenant-handover/feature.js +1 -1
  371. package/dist/tenant-handover/grant.js +1 -1
  372. package/dist/tenant-handover/handlers/claim.write.js +1 -1
  373. package/dist/tenant-handover/move-entity-graph.js +8 -9
  374. package/dist/tenant-handover/signup-handover-provider.js +1 -2
  375. package/dist/tenant-handover/transfer-graph.js +4 -5
  376. package/dist/tenant-lifecycle/boot-checks.js +1 -1
  377. package/dist/tenant-lifecycle/feature.js +1 -1
  378. package/dist/tenant-settings/constants.js +1 -1
  379. package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
  380. package/dist/tenant-settings/tenant-defaults.js +9 -2
  381. package/dist/tier-engine/aggregate-id.d.ts +11 -11
  382. package/dist/tier-engine/aggregate-id.js +15 -16
  383. package/dist/tier-engine/compose-app.d.ts +14 -14
  384. package/dist/tier-engine/compose-app.js +1 -1
  385. package/dist/tier-engine/entity.js +18 -19
  386. package/dist/tier-engine/feature.d.ts +19 -17
  387. package/dist/tier-engine/feature.js +68 -69
  388. package/dist/tier-engine/handlers/active-tier.query.js +6 -7
  389. package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
  390. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +5 -5
  391. package/dist/tier-engine/handlers/set-tenant-tier.write.js +3 -3
  392. package/dist/tier-engine/tier-resolver.js +2 -2
  393. package/dist/tier-engine/trial.js +8 -8
  394. package/dist/tier-engine/web/index.js +4 -4
  395. package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
  396. package/dist/user/handlers/create.write.js +4 -4
  397. package/dist/user/schema/user.d.ts +11 -11
  398. package/dist/user/schema/user.js +45 -44
  399. package/dist/user/seeding.d.ts +15 -15
  400. package/dist/user/seeding.js +28 -28
  401. package/dist/user/testing.js +3 -3
  402. package/dist/user-data-rights/audit-download.d.ts +8 -8
  403. package/dist/user-data-rights/audit-download.js +19 -20
  404. package/dist/user-data-rights/boot-checks.js +1 -1
  405. package/dist/user-data-rights/deletion-token.js +1 -1
  406. package/dist/user-data-rights/feature.d.ts +49 -50
  407. package/dist/user-data-rights/feature.js +54 -53
  408. package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
  409. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
  410. package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
  411. package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
  412. package/dist/user-data-rights/handlers/export-status.query.js +8 -9
  413. package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
  414. package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
  415. package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
  416. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
  417. package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
  418. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
  419. package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
  420. package/dist/user-data-rights/handlers/request-export.write.js +42 -41
  421. package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
  422. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
  423. package/dist/user-data-rights/index.js +8 -10
  424. package/dist/user-data-rights/lib/default-mailers.js +3 -3
  425. package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
  426. package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
  427. package/dist/user-data-rights/run-export-jobs.js +127 -233
  428. package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
  429. package/dist/user-data-rights/run-forget-cleanup.js +63 -82
  430. package/dist/user-data-rights/run-user-export.d.ts +34 -33
  431. package/dist/user-data-rights/run-user-export.js +55 -57
  432. package/dist/user-data-rights/schema/download-attempt.js +11 -11
  433. package/dist/user-data-rights/schema/download-token.js +37 -41
  434. package/dist/user-data-rights/schema/export-job.d.ts +4 -4
  435. package/dist/user-data-rights/schema/export-job.js +65 -67
  436. package/dist/user-data-rights/token-helpers.d.ts +8 -9
  437. package/dist/user-data-rights/token-helpers.js +21 -25
  438. package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
  439. package/dist/user-data-rights/web/client-plugin.js +1 -1
  440. package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
  441. package/dist/user-data-rights/web/constants.js +1 -1
  442. package/dist/user-data-rights/web/index.js +5 -5
  443. package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
  444. package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
  445. package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
  446. package/dist/user-data-rights/zip-path.d.ts +15 -15
  447. package/dist/user-data-rights/zip-path.js +41 -40
  448. package/dist/user-data-rights-defaults/feature.js +15 -15
  449. package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
  450. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
  451. package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
  452. package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
  453. package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
  454. package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
  455. package/dist/user-profile/handlers/change-email.write.js +13 -13
  456. package/dist/user-profile/index.js +3 -3
  457. package/dist/user-profile/web/client-plugin.js +1 -1
  458. package/dist/user-profile/web/constants.js +1 -1
  459. package/dist/user-profile/web/profile-screen.js +1 -1
  460. package/dist/workflow-runner/aggregate-id.d.ts +1 -1
  461. package/dist/workflow-runner/aggregate-id.js +1 -1
  462. package/dist/workflow-runner/event-subscriber.js +4 -5
  463. package/dist/workflow-runner/event-trigger.js +4 -17
  464. package/dist/workflow-runner/feature.js +2 -2
  465. package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
  466. package/dist/workflow-runner/pending-projection.js +6 -7
  467. package/dist/workflow-runner/runner.js +6 -6
  468. package/dist/workflow-runner/tables.js +6 -6
  469. package/dist/workflow-runner/workflow-registry.js +1 -1
  470. package/package.json +10 -10
@@ -1,10 +1,10 @@
1
- // Browser-Seite von POST /api/auth/mfa/verify — completes the two-step
2
- // login LoginScreen started when the server responded mfaRequired. Same
3
- // fetch/CSRF pattern as auth-email-password's login() (pre-session, no
4
- // csrfHeader() — there's no session yet to protect). Response shape is
1
+ // Browser side of POST /api/auth/mfa/verify — completes the two-step
2
+ // login that LoginScreen started when the server responded with mfaRequired.
3
+ // Uses the same fetch/CSRF pattern as auth-email-password's login(), but runs
4
+ // before a session exists, so it does not call csrfHeader(). The response is
5
5
  // byte-identical to /auth/login's ({isSuccess, token, user} | {isSuccess:
6
- // false, error}) since auth-routes.ts mints via the same
7
- // mintSessionAndRespond() for both routes.
6
+ // false, error}) because auth-routes.ts uses mintSessionAndRespond() for both
7
+ // routes.
8
8
  // kumiko-lint-ignore cross-feature-import client-only types, the feature's server barrel has no web/ re-export
9
9
  import { toLoginResponse, } from "../../auth-email-password/web/index.js";
10
10
  export async function verifyMfaChallenge(challengeToken, code) {
@@ -40,11 +40,12 @@ export async function verifyMfaChallenge(challengeToken, code) {
40
40
  },
41
41
  };
42
42
  }
43
- // Browser-Seite von POST /api/auth/mfa/preauth-enable-start — lets a user
43
+ // Browser side of POST /api/auth/mfa/preauth-enable-start — lets a user
44
44
  // blocked at login by MFA enforcement generate a TOTP secret/QR without a
45
- // session, using the preauthSetupToken login()'s mfa-setup-required result
46
- // carries. No JWT/cookie here (see auth-routes.ts's route comment) — the
47
- // response's setupToken is consumed by confirmMfaSetupPreauth below.
45
+ // session, using the preauthSetupToken carried by login()'s
46
+ // mfa-setup-required result. No JWT/cookie is issued here (see the route
47
+ // comment in auth-routes.ts); the response's
48
+ // setupToken is consumed by confirmMfaSetupPreauth below.
48
49
  export async function startMfaSetupPreauth(preauthSetupToken, accountLabel) {
49
50
  const res = await fetch("/api/auth/mfa/preauth-enable-start", {
50
51
  method: "POST",
@@ -85,12 +86,12 @@ export async function startMfaSetupPreauth(preauthSetupToken, accountLabel) {
85
86
  },
86
87
  };
87
88
  }
88
- // Browser-Seite von POST /api/auth/mfa/preauth-confirm — completes both
89
- // the enrollment startMfaSetupPreauth began and the login mfa-setup-
90
- // required block. Response shape mirrors /auth/mfa/verify's (mints via
91
- // the same mintSessionAndRespond()), same as verifyMfaChallenge above —
92
- // kept as its own function rather than a shared helper so this file's
93
- // two already-tested request shapes stay independently editable.
89
+ // Browser side of POST /api/auth/mfa/preauth-confirm — completes both the
90
+ // enrollment started by startMfaSetupPreauth and the login
91
+ // mfa-setup-required block. Its response mirrors /auth/mfa/verify's and is
92
+ // minted via the same mintSessionAndRespond(). It remains a separate function
93
+ // so this file's two already-tested request shapes stay independently
94
+ // editable.
94
95
  export async function confirmMfaSetupPreauth(setupToken, code) {
95
96
  const res = await fetch("/api/auth/mfa/preauth-confirm", {
96
97
  method: "POST",
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // Login-Challenge-Step, gerendert wenn LoginScreen's onMfaChallenge feuert
3
- // (/auth/login antwortete mfaRequired). Stilistisch wie login-screen.tsx:
4
- // useState + direkter fetch-Call, kein Dispatcher — es existiert noch kein
5
- // JWT. Nach Erfolg ruft es session.refresh() statt eines Hard-Reloads, weil
6
- // der Aufrufer (typisch ein Wizard-State im App-Root) sofort neu rendern
7
- // will, sobald status:"authenticated" ankommt.
2
+ // Login challenge step, rendered when LoginScreen's onMfaChallenge fires
3
+ // (/auth/login returned mfaRequired). It follows login-screen.tsx:
4
+ // useState plus a direct fetch call, without a dispatcher because no JWT
5
+ // exists yet. After success, it calls session.refresh() instead of a hard
6
+ // reload so the caller (typically wizard state in the app root) can render
7
+ // immediately when status:"authenticated" arrives.
8
8
  import { usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
9
9
  import { useState } from "react";
10
10
  // kumiko-lint-ignore cross-feature-import client-only barrel, the feature's server barrel has no web/ re-export
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Deterministic aggregate-id für die subscription eines Plattform-
3
- * Tenants. EINE Subscription pro Tenant (Add-Ons sind line-items in
4
- * derselben subscription, nicht eigene). Provider-Wechsel (z.B.
5
- * Stripe→Mollie-Migration) appended einen neuen event auf denselben
6
- * Stream — selber Tenant, selber Aggregate-Stream.
2
+ * Deterministic aggregate ID for a platform tenant's subscription. Exactly
3
+ * one subscription exists per tenant; add-ons are line items in that
4
+ * subscription, not separate aggregates. A provider change, such as a
5
+ * Stripe→Mollie migration, appends a new event to the same stream because
6
+ * the tenant and aggregate stream remain the same.
7
7
  */
8
8
  export declare function subscriptionAggregateId(tenantId: string): string;
9
9
  /**
@@ -1,10 +1,9 @@
1
1
  import { v5 as uuidv5 } from "uuid";
2
- // Fixed UUID-namespace für die deterministic aggregate-id-Ableitung.
3
- // Generiert einmalig (2026-05-03), in Stein gemeißelt: ein Wechsel
4
- // würde jeden existing aggregate-Stream re-keyen → kaputter
5
- // Subscription-State, kaputte Audit-History. Drift-Pin in
6
- // __tests__/feature.test.ts pinnt die UUID.
7
- /** Pro Plattform-Tenant existiert genau EIN subscription-Aggregate. */
2
+ // Fixed UUID namespace for deterministic aggregate-id derivation.
3
+ // Generated once and immutable: changing it would re-key every existing
4
+ // aggregate stream, breaking subscription state and audit history. The drift
5
+ // pin in __tests__/feature.test.ts locks the UUID.
6
+ /** Exactly one subscription aggregate exists per platform tenant. */
8
7
  const SUBSCRIPTION_NAMESPACE = "5c3b2d1e-9a4f-4e8c-b7a3-1f8d6c2e9a4b";
9
8
  /** Exactly ONE payment-aggregate-stream exists per platform tenant (it
10
9
  * collects many payment-received events — one stream per tenant, not one
@@ -20,11 +19,11 @@ const PAYMENT_ROW_NAMESPACE = "3a1c9f4e-6b2d-4c8a-9e5f-7d4b1a2c8e6f";
20
19
  * declaration (one stream per request). Generated 2026-10-03, set in stone. */
21
20
  const TERMINATION_UNMATCHED_NAMESPACE = "7e2f4b9a-3c1d-4a68-8d05-b6c9e1f27a34";
22
21
  /**
23
- * Deterministic aggregate-id für die subscription eines Plattform-
24
- * Tenants. EINE Subscription pro Tenant (Add-Ons sind line-items in
25
- * derselben subscription, nicht eigene). Provider-Wechsel (z.B.
26
- * Stripe→Mollie-Migration) appended einen neuen event auf denselben
27
- * Stream — selber Tenant, selber Aggregate-Stream.
22
+ * Deterministic aggregate ID for a platform tenant's subscription. Exactly
23
+ * one subscription exists per tenant; add-ons are line items in that
24
+ * subscription, not separate aggregates. A provider change, such as a
25
+ * Stripe→Mollie migration, appends a new event to the same stream because
26
+ * the tenant and aggregate stream remain the same.
28
27
  */
29
28
  // @wrapper-known uuid-domain
30
29
  export function subscriptionAggregateId(tenantId) {
@@ -1,38 +1,38 @@
1
1
  import { collectPiiSubjectFields } from "@cosmicdrift/kumiko-framework/crypto";
2
2
  import { createEntity, createTextField, createTimestampField, } from "@cosmicdrift/kumiko-framework/engine";
3
- // `subscription` — current state pro Plattform-Tenant (= Read-Model)
3
+ // `subscription` — current state per platform tenant (= read model)
4
4
  // =============================================================================
5
5
  //
6
- // Inline-Projection-Target. Geschrieben vom `subscription`-projection-
7
- // apply (siehe feature.ts), NIE direkt vom handler. Source-of-truth ist
8
- // der event-store stream `subscription` mit aggregate-id =
6
+ // Inline projection target. Written by the `subscription` projection-
7
+ // apply (see feature.ts), NEVER directly by the handler. Source of truth is
8
+ // the event-store stream `subscription` with aggregate-id =
9
9
  // uuidv5(SUBSCRIPTION_NAMESPACE, tenantId).
10
10
  //
11
- // EINE Row pro Plattform-Tenant. Aggregate-ID ist deterministic, damit
12
- // Webhook-Replays (Stripe sendet bei Hängern bis zu 5x in 4h) auf
13
- // denselben Stream schreiben statt zwei Rows zu erzeugen.
11
+ // ONE row per platform tenant. The aggregate ID is deterministic so that
12
+ // webhook replays (Stripe sends up to 5 times in 4 hours when delivery is
13
+ // stalled) write to the same stream instead of creating two rows.
14
14
  //
15
- // **Felder:**
16
- // - providerName: "stripe" / "mollie" — welcher Provider die
17
- // Subscription hält. Provider-Wechsel = neuer event auf demselben
18
- // Stream, projection überschreibt.
19
- // - providerCustomerId / providerSubscriptionId: provider-eigene
20
- // IDs.
15
+ // **Fields:**
16
+ // - providerName: "stripe" / "mollie" — the provider holding the
17
+ // subscription. A provider change is a new event on the same stream;
18
+ // the projection overwrites the value.
19
+ // - providerCustomerId / providerSubscriptionId: provider-specific IDs.
21
20
  // - status: active / past_due / canceled / trialing / incomplete —
22
- // normalisiert über provider-grenzen hinweg.
23
- // - tier: "free" / "pro" / ... — vom tier-engine konsumiert. Aus
24
- // price-to-tier-Map resolved im Plugin.
25
- // - currentPeriodEnd: wann läuft die aktuelle Billing-Period aus.
21
+ // normalized across providers.
22
+ // - tier: "free" / "pro" / ... — consumed by the tier engine. Resolved
23
+ // from the price-to-tier map in the plugin.
24
+ // - currentPeriodEnd: when the current billing period ends.
26
25
  // - cancelAt: when a scheduled cancellation ends the subscription;
27
26
  // nullable because a renewing subscription has none.
28
27
  //
29
- // **Was hier NICHT ist:**
30
- // - invoice-history, payment-method, line-items, tax-info → all das
31
- // fetcht der Tenant via customer-portal-session direkt vom Provider.
28
+ // **Not included here:**
29
+ // - invoice-history, payment-method, line-items, tax-info — the tenant
30
+ // fetches all of these directly from the provider via a
31
+ // customer-portal-session.
32
32
  //
33
- // **Audit/event-history:** lebt im event-store unter dem `subscription`-
34
- // stream — KEIN eigene `subscription-event`-Tabelle mehr (= ES ist die
35
- // audit-truth, replay-fähig durch upcasters).
33
+ // **Audit/event history:** lives in the event store under the `subscription`
34
+ // stream — there is NO separate `subscription-event` table (= ES is the
35
+ // audit source of truth and can be replayed through upcasters).
36
36
  export const subscriptionEntity = createEntity({
37
37
  table: "read_subscriptions",
38
38
  fields: {
@@ -43,10 +43,10 @@ export const subscriptionEntity = createEntity({
43
43
  reason: "technical_reference",
44
44
  }),
45
45
  // `personal: "tenant"` (not `encrypted`): the field must crypto-shred when
46
- // eraseSubjectKeys erases the tenant's subject key on tenant-destroy
47
- // (#800). `encrypted: true` uses the app-wide master key instead — that
46
+ // eraseSubjectKeys erases the tenant's subject key on tenant-destroy.
47
+ // `encrypted: true` uses the app-wide master key instead — that
48
48
  // key is never erased per-tenant, so it would only add encryption-at-
49
- // rest, not the erasure guarantee #800 actually asks for.
49
+ // rest, not the erasure guarantee.
50
50
  // maxLength 1000, not 200: the stored value is PII-ciphertext
51
51
  // (`kumiko-pii:v1:<subject>:<blob>`), not the raw provider id — a
52
52
  // 200-char plaintext id becomes ~300+ chars of ciphertext. Matches
@@ -106,7 +106,7 @@ export const paymentEntity = createEntity({
106
106
  reason: "technical_reference",
107
107
  }),
108
108
  // Same `personal: "tenant"` rationale as subscriptionEntity above —
109
- // crypto-shreds on tenant-destroy (#800) via eraseSubjectKeys.
109
+ // crypto-shreds on tenant-destroy via eraseSubjectKeys.
110
110
  providerCustomerId: createTextField({
111
111
  required: true,
112
112
  maxLength: 1000,
@@ -1,22 +1,22 @@
1
- // Domain-events für subscription-foundation.
1
+ // Domain events for subscription-foundation.
2
2
  //
3
- // **Pattern:** event-sourced — jeder Provider-Webhook (nach Plugin-
4
- // verify) wird zu einem domain-event auf dem subscription-stream
5
- // (= ein stream pro Tenant via subscriptionAggregateId(tenantId)).
6
- // Read-model = inline projection in `subscriptions`-Tabelle.
3
+ // **Pattern:** event-sourced — each provider webhook (after plugin
4
+ // verification) becomes a domain event on the subscription stream
5
+ // (= one stream per tenant via subscriptionAggregateId(tenantId)).
6
+ // The read model is an inline projection in the `subscriptions` table.
7
7
  //
8
- // 5 fine-grained event-typen statt einem generic "webhook-received"-
9
- // bucket — events sind business-facts: future-consumer (billing-history,
10
- // accounting-export, churn-analytics) listenen direkt auf den event-
11
- // type ohne payload-discriminator.
8
+ // Five fine-grained event types instead of a generic "webhook-received"
9
+ // bucket — events are business facts: future consumers (billing-history,
10
+ // accounting-export, churn-analytics) listen directly for the event type
11
+ // without a payload discriminator.
12
12
  import * as z from "zod";
13
13
  import { BILLING_FOUNDATION_FEATURE, SubscriptionStatuses } from "./web/constants.js";
14
14
  import { CONSENT_LOCALES } from "./web/consumer-protection/consent-locale.js";
15
- // Aggregate-type für den event-store. Eine subscription pro Tenant ist
16
- // ein stream; der subscriptionAggregateId-helper liefert die stream-id.
15
+ // Aggregate type for the event store. One subscription per tenant is
16
+ // one stream; the subscriptionAggregateId helper provides the stream ID.
17
17
  export const SUBSCRIPTION_AGGREGATE_TYPE = "subscription";
18
- // Event-name-Konstanten — short-form (für r.defineEvent) + qualifizierte
19
- // FQN (für ctx.unsafeAppendEvent + projection-apply-keys).
18
+ // Event-name constants — short form (for r.defineEvent) and qualified
19
+ // FQN (for ctx.unsafeAppendEvent and projection-apply keys).
20
20
  export const SUBSCRIPTION_CREATED_EVENT_SHORT = "subscription-created";
21
21
  export const SUBSCRIPTION_UPDATED_EVENT_SHORT = "subscription-updated";
22
22
  export const SUBSCRIPTION_CANCELED_EVENT_SHORT = "subscription-canceled";
@@ -27,7 +27,7 @@ export const SUBSCRIPTION_UPDATED_EVENT_QN = `${BILLING_FOUNDATION_FEATURE}:even
27
27
  export const SUBSCRIPTION_CANCELED_EVENT_QN = `${BILLING_FOUNDATION_FEATURE}:event:${SUBSCRIPTION_CANCELED_EVENT_SHORT}`;
28
28
  export const INVOICE_PAID_EVENT_QN = `${BILLING_FOUNDATION_FEATURE}:event:${INVOICE_PAID_EVENT_SHORT}`;
29
29
  export const INVOICE_PAYMENT_FAILED_EVENT_QN = `${BILLING_FOUNDATION_FEATURE}:event:${INVOICE_PAYMENT_FAILED_EVENT_SHORT}`;
30
- // Status-enum für event-payloads (= subscription-state-snapshot vom Provider).
30
+ // Status enum for event payloads (= the provider's subscription-state snapshot).
31
31
  const statusEnum = z.enum([
32
32
  SubscriptionStatuses.active,
33
33
  SubscriptionStatuses.trialing,
@@ -35,10 +35,11 @@ const statusEnum = z.enum([
35
35
  SubscriptionStatuses.canceled,
36
36
  SubscriptionStatuses.incomplete,
37
37
  ]);
38
- // Common payload — alle 5 events tragen denselben subscription-state-
39
- // snapshot. Event-type tagged was passiert ist, payload den state-after.
38
+ // Common payload — all five events carry the same subscription-state
39
+ // snapshot. The event type identifies what happened; the payload contains
40
+ // the resulting state.
40
41
  // The raw provider event is deliberately not stored: it carries plaintext
41
- // PII and event headers are not crypto-shreddable.
42
+ // PII, and event headers cannot be crypto-shredded.
42
43
  export const subscriptionEventPayloadSchema = z.object({
43
44
  providerName: z.string().min(1).max(50),
44
45
  // 1000, not 200: these two are `tenantOwned: true` on the entity (see
@@ -1,54 +1,53 @@
1
1
  // kumiko-feature-version: 1
2
2
  //
3
- // subscription-foundation als Kumiko bundled feature (Plugin-Host).
3
+ // subscription-foundation as a Kumiko bundled feature (plugin host).
4
4
  //
5
- // **Multi-Provider von Tag 1** — der App-Builder kann mehrere Plugins
6
- // parallel mounten (subscription-stripe + subscription-paypal +
7
- // subscription-apple-iap + ...) und der Endkunde wählt beim Subscribe-
8
- // Klick zwischen Karte/PayPal/Apple-Pay/Klarna/SEPA (Disney+-Pattern).
9
- // KEIN globaler `provider`-config-key — alle gemounteten Plugins sind
10
- // aktiv.
5
+ // **Multi-provider from day one** — the app builder can mount multiple plugins
6
+ // in parallel (subscription-stripe + subscription-paypal +
7
+ // subscription-apple-iap + ...), and the end user chooses between
8
+ // card/PayPal/Apple Pay/Klarna/SEPA at checkout (Disney+ pattern).
9
+ // There is no global `provider` config key — all mounted plugins are active.
11
10
  //
12
- // **Was diese Foundation liefert:**
13
- // 1. **Plugin-API** für Subscription-Provider via `r.extendsRegistrar(
11
+ // **What this foundation provides:**
12
+ // 1. **Plugin API** for subscription providers via `r.extendsRegistrar(
14
13
  // "subscriptionProvider", ...)`.
15
- // 2. **5 Domain-Events** auf dem `subscription`-stream (eine
16
- // stream-id pro Tenant): created/updated/canceled/invoice-paid/
17
- // invoice-payment-failed. Audit-history kommt frei vom event-store.
18
- // 3. **Inline-Projection** auf `read_subscriptions` (= current state
19
- // pro Tenant). Apply läuft in derselben TX wie der event-append
14
+ // 2. **5 domain events** on the `subscription` stream (one stream ID per
15
+ // tenant): created/updated/canceled/invoice-paid/invoice-payment-failed.
16
+ // Audit history is provided automatically by the event store.
17
+ // 3. **Inline projection** onto `read_subscriptions` (current state per
18
+ // tenant). Apply runs in the same TX as the event append
20
19
  // → read-your-own-write semantics.
21
- // 4. **process-event-handler**: programmatic write-handler den der
22
- // webhook-handler aufruft, dispatcht zu type-passendem appendEvent.
20
+ // 4. **process-event handler**: a programmatic write handler called by the
21
+ // webhook handler that dispatches to the type-matched appendEvent.
23
22
  // 5. **createSubscriptionWebhookRoute**: factory for the `entry:"signature"`
24
23
  // extraRoute `/api/subscription/webhook/:providerName`.
25
- // 6. **payment-received event + read_payments projection**: one-off-
26
- // payments (checkout mode "payment") get their own event, own
27
- // per-tenant aggregate, and own `process-payment-event` write-handler
28
- // — not a sixth SubscriptionEventTypes value (fw#2791).
24
+ // 6. **payment-received event + read_payments projection**: one-off payments
25
+ // (checkout mode "payment") get their own event, per-tenant aggregate,
26
+ // and `process-payment-event` write handler — not a sixth
27
+ // SubscriptionEventTypes value.
29
28
  // 7. **Optional billing-plans catalog** (`createBillingFoundationFeature({
30
29
  // baseUrl, catalog })`): a `billing-foundation:query:billing-plans`
31
- // query plus `start-plan-checkout`/`switch-plan` write-handlers and a
30
+ // query plus `start-plan-checkout`/`switch-plan` write handlers and a
32
31
  // dormant `billing-plans` dashboard screen/panel, all derived from the
33
- // one `catalog` option — no separate per-app price wiring.
32
+ // single `catalog` option — no separate per-app price wiring.
34
33
  //
35
- // **Was diese Foundation NICHT macht:**
36
- // - Kein r.entity für `subscription`. Die Tabelle ist eine reine
37
- // Read-Projection — kein CRUD-Pfad. Schreibt wird ausschließlich
38
- // via projection-apply, getriggert von einem der 5 events.
39
- // - Kein Tier-Sync zum tier-engine. App-Owner liest die subscription-
40
- // row via `getSubscriptionForTenant(ctx, tenantId)` wenn er möchte.
41
- // - Keine provider-spezifischen Configs.
42
- // - Kein Marketplace-Use-Case (App-Tenant billed Endkunden via
43
- // Stripe Connect). Kommt als separate `marketplace-foundation`.
34
+ // **What this foundation does NOT do:**
35
+ // - No r.entity for `subscription`. The table is a read-only projection —
36
+ // there is no CRUD path. It is written exclusively via projection-apply,
37
+ // triggered by one of the 5 events.
38
+ // - No tier sync with tier-engine. App owners can read the subscription row
39
+ // via `getSubscriptionForTenant(ctx, tenantId)` if needed.
40
+ // - No provider-specific configs.
41
+ // - No marketplace use case (the app tenant bills end customers via Stripe
42
+ // Connect). That comes later as a separate `marketplace-foundation`.
44
43
  //
45
- // **Provider-Wechsel:** Disney+-Pattern (= Tenant cancelt Stripe-sub,
46
- // startet neue mit PayPal) wird heute als zweiter `subscription-created`-
47
- // event modelliert. UPSERT in der projection-apply überschreibt den
48
- // existing row mit dem neuen providerName. Reicht für MVP. Wenn das
49
- // business-fact "Provider-Wechsel" ein eigenes domain-event braucht
50
- // (z.B. für analytics: "wie viele Wechsel im Monat?"), kommt ein
51
- // `subscription-provider-changed`-event-type später.
44
+ // **Provider changes:** The Disney+ pattern (the tenant cancels a Stripe
45
+ // subscription and starts a new one with PayPal) is currently modeled as a
46
+ // second `subscription-created` event. UPSERT in projection-apply overwrites
47
+ // the existing row with the new providerName. This is sufficient for the MVP.
48
+ // If the business fact "provider change" needs its own domain event (for
49
+ // example, for analytics such as "how many changes per month?"), a
50
+ // `subscription-provider-changed` event type can be added later.
52
51
  import { defineFeature, EXT_TENANT_DATA, } from "@cosmicdrift/kumiko-framework/engine";
53
52
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
54
53
  import { registerConsumerProtection } from "./consumer-protection/register-consent.js";
@@ -147,18 +146,18 @@ export function createBillingFoundationFeature(options = {}) {
147
146
  [PAYMENT_RECEIVED_EVENT_QN]: applyPaymentReceived,
148
147
  },
149
148
  });
150
- // Plugin extension-point. Provider-Plugins registrieren sich hier.
149
+ // Plugin extension point. Provider plugins register here.
151
150
  r.extendsRegistrar(SUBSCRIPTION_PROVIDER_EXTENSION, {
152
151
  onRegister: () => {
153
152
  // No side-effects at register-time.
154
153
  },
155
154
  });
156
- // Custom write-handlers:
157
- // - process-event: programmatic entry-point vom webhook-handler;
158
- // dispatcht zu type-passendem appendEvent
155
+ // Custom write handlers:
156
+ // - process-event: programmatic entry point called by the webhook
157
+ // handler; dispatches to the type-matched appendEvent
159
158
  // - create-checkout-session: bare priceId-driven checkout (hardened,
160
159
  // see checkout-core)
161
- // - create-portal-session: Tenant-Admin "Manage Subscription"-flow
160
+ // - create-portal-session: Tenant Admin "Manage Subscription" flow
162
161
  r.writeHandler(createProcessEventHandler(widened.now));
163
162
  r.writeHandler(createCheckoutSessionHandler(widened));
164
163
  r.writeHandler(createPortalSessionHandler(widened));
@@ -15,7 +15,7 @@ export type SubscriptionView = {
15
15
  * apply-function started stamping it from `event.createdAt`. */
16
16
  readonly lastChangedAt: Temporal.Instant;
17
17
  };
18
- /** Liefert die einzige subscription-row für den Tenant (deterministic
19
- * aggregate-id), oder null wenn der Tenant nie subscribed hat. Status
20
- * kann active/canceled/past_due/etc sein — Caller entscheidet was tun. */
18
+ /** Returns the tenant's only subscription row (deterministic
19
+ * aggregate ID), or null if the tenant has never subscribed. The status
20
+ * may be active/canceled/past_due/etc.; the caller decides what to do. */
21
21
  export declare function getSubscriptionForTenant(ctx: HandlerContext, tenantId: string): Promise<SubscriptionView | null>;
@@ -1,13 +1,11 @@
1
1
  /// <reference types="temporal-polyfill/global" preserve="true" />
2
- // Resolver-helper: liest die current subscription-row für einen Tenant
3
- // aus der read_subscriptions-projection.
4
2
  import { configuredPiiSubjectKms, decryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
5
3
  import { subscriptionAggregateId } from "./aggregate-id.js";
6
4
  import { SUBSCRIPTION_PII_FIELDS } from "./entities.js";
7
5
  import { subscriptionsProjectionTable } from "./projection.js";
8
- /** Liefert die einzige subscription-row für den Tenant (deterministic
9
- * aggregate-id), oder null wenn der Tenant nie subscribed hat. Status
10
- * kann active/canceled/past_due/etc sein — Caller entscheidet was tun. */
6
+ /** Returns the tenant's only subscription row (deterministic
7
+ * aggregate ID), or null if the tenant has never subscribed. The status
8
+ * may be active/canceled/past_due/etc.; the caller decides what to do. */
11
9
  export async function getSubscriptionForTenant(ctx, tenantId) {
12
10
  const aggId = subscriptionAggregateId(tenantId);
13
11
  const rows = await ctx.db.selectMany(subscriptionsProjectionTable, { id: aggId }, { limit: 1 });
@@ -1,18 +1,18 @@
1
- // create-checkout-session — Tenant-Admin klickt "Upgrade to Pro" (oder
2
- // wählt zwischen Karte/PayPal/Apple-Pay). Handler findet den
3
- // providerName aus der payload, lookuppt den Plugin, ruft
4
- // `plugin.createCheckoutSession(ctx, ...)`, returnt hosted-page-URL.
5
- // Tenant-Admin wird dorthin redirected.
1
+ // create-checkout-session — Tenant admin clicks "Upgrade to Pro" (or
2
+ // chooses between card/PayPal/Apple Pay). The handler reads providerName
3
+ // from the payload, looks up the plugin, calls
4
+ // `plugin.createCheckoutSession(ctx, ...)`, and returns the hosted-page URL.
5
+ // The tenant admin is redirected there.
6
6
  //
7
- // **Multi-Provider-Pfad:** payload.providerName ist der entityName
8
- // eines registrierten Plugins ("stripe" / "paypal" / "mollie" / ...).
9
- // App-Builder zeigt eine UI-Liste der gemounteten provider, Endkunde
10
- // pickt einen, dieser handler dispatched zum richtigen Plugin.
7
+ // **Multi-provider path:** payload.providerName is the entityName
8
+ // of a registered plugin ("stripe" / "paypal" / "mollie" / ...).
9
+ // The app builder shows a UI list of mounted providers; the customer
10
+ // selects one, and this handler dispatches to the matching plugin.
11
11
  //
12
- // **Tenant-resolution:** ctx.user.tenantId wird als metadata an den
13
- // Provider mitgegeben. Beim subsequent webhook (subscription.created)
14
- // liest verifyAndParseWebhook das aus dem provider-payload zurück und
15
- // resolved den Tenant.
12
+ // **Tenant resolution:** ctx.user.tenantId is passed to the provider as
13
+ // metadata. On the subsequent webhook (subscription.created),
14
+ // verifyAndParseWebhook reads it back from the provider payload and
15
+ // resolves the tenant.
16
16
  //
17
17
  // **Hardening:** successUrl/cancelUrl must share `options.baseUrl`'s
18
18
  // origin; mode:"subscription" requires priceId to be a known price of the
@@ -31,12 +31,13 @@ const createCheckoutSessionSchema = z.object({
31
31
  providerName: z.string().min(1).max(50),
32
32
  /** Provider-eigene price/plan-ID. */
33
33
  priceId: z.string().min(1).max(200),
34
- /** Wo der Endkunde nach erfolgreichem checkout landed. */
34
+ /** Where the customer lands after a successful checkout. */
35
35
  successUrl: z.string().url(),
36
- /** Wo der Endkunde landed wenn er abbricht. */
36
+ /** Where the customer lands if they cancel. */
37
37
  cancelUrl: z.string().url(),
38
- /** Optional: existierender provider-customer wenn der Tenant schon
39
- * einen account beim Provider hat (= Plan-Wechsel statt Neuregistrierung). */
38
+ /** Optional: existing provider customer when the tenant already
39
+ * has an account with the provider (= plan change instead of a new
40
+ * registration). */
40
41
  providerCustomerId: z.string().max(200).optional(),
41
42
  /** Optional: `"payment"` for a one-off checkout (e.g. credit top-up)
42
43
  * instead of a recurring subscription. Defaults to `"subscription"`. */
@@ -1,17 +1,16 @@
1
- // create-portal-session — Tenant-Admin klickt "Manage Subscription".
2
- // Handler findet die current subscription des Tenants, lookuppt den
3
- // passenden Plugin (= subscription.providerName-Spalte), ruft
4
- // `plugin.createPortalSession(ctx, ...)`, returnt hosted-portal-URL.
1
+ // create-portal-session — Tenant admin clicks "Manage Subscription".
2
+ // The handler finds the tenant's current subscription, looks up the matching
3
+ // plugin (= the `subscription.providerName` column), calls
4
+ // `plugin.createPortalSession(ctx, ...)`, and returns the hosted portal URL.
5
5
  //
6
- // **Provider-resolution:** anders als create-checkout-session (= der
7
- // Tenant wählt einen NEUEN Provider beim Subscribe) ist hier der
8
- // Provider durch die existing subscription-row festgelegt — Tenant
9
- // kann nicht zum Portal eines OTHER Providers, weil der ihn nicht
10
- // kennt.
6
+ // **Provider resolution:** unlike create-checkout-session (where the tenant
7
+ // chooses a NEW provider when subscribing), the provider here is fixed by the
8
+ // existing subscription row. The tenant cannot access another provider's
9
+ // portal because the subscription does not belong to that provider.
11
10
  //
12
- // **returnUrl:** computed server-side via `portalReturnUrl` (catalog's
13
- // returnPath, or baseUrl itself) — the client no longer supplies one, so
14
- // there is no client-controlled redirect to harden against.
11
+ // **returnUrl:** computed server-side via `portalReturnUrl` (the catalog's
12
+ // returnPath, or baseUrl itself). The client no longer supplies one, so there
13
+ // is no client-controlled redirect to harden against.
15
14
  import { configuredPiiSubjectKms, decryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
16
15
  import { selectMany } from "@cosmicdrift/kumiko-framework/db";
17
16
  import * as z from "zod";
@@ -1,7 +1,7 @@
1
- // list-subscriptions — sysadmin-cross-tenant list-query auf der
2
- // `read_subscriptions`-projection. Tenant-Admins lesen ihre eigene
3
- // subscription via getSubscriptionForTenant-helper (= ctx.db ist
4
- // tenant-scoped, gibt automatisch nur die row des Callers zurück).
1
+ // list-subscriptions — sysadmin cross-tenant list query on the
2
+ // `read_subscriptions` projection. Tenant admins read their own
3
+ // subscription through the getSubscriptionForTenant helper (= ctx.db is
4
+ // tenant-scoped and automatically returns only the caller's row).
5
5
  import { configuredPiiSubjectKms, decryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
6
6
  import * as z from "zod";
7
7
  import { SUBSCRIPTION_PII_FIELDS } from "../entities.js";
@@ -1,16 +1,16 @@
1
- // process-event — programmatic write-handler den der webhook-handler
2
- // (createSubscriptionWebhookRoute) aufruft NACHDEM Plugin den raw-body
3
- // verifiziert + zu SubscriptionEvent normalisiert hat.
1
+ // process-event — programmatic write handler called by the webhook handler
2
+ // (createSubscriptionWebhookRoute) AFTER the plugin has verified the raw body
3
+ // and normalized it into a SubscriptionEvent.
4
4
  //
5
- // **ES-Pattern:**
6
- // 1. Idempotency-check: lädt subscription-stream + scannt nach
7
- // bereits gesehenem `metadata.providerEventId`. Provider-Replay
8
- // (Stripe-Retry-Storm) sieht denselben event-id → duplicate=true,
9
- // kein zweiter append.
10
- // 2. Type-mapping: SubscriptionEvent.type (= normalisiert vom Plugin)
11
- // → einer der 5 ES-event-typen.
12
- // 3. ctx.unsafeAppendEvent — Inline-projection materialisiert die
13
- // `read_subscriptions`-row in derselben TX.
5
+ // **ES pattern:**
6
+ // 1. Idempotency check: loads the subscription stream and scans for an
7
+ // already-seen `metadata.providerEventId`. A provider replay
8
+ // (Stripe retry storm) has the same event ID → duplicate=true,
9
+ // with no second append.
10
+ // 2. Type mapping: SubscriptionEvent.type (= normalized by the plugin)
11
+ // → one of the 5 ES event types.
12
+ // 3. ctx.unsafeAppendEvent — the inline projection materializes the
13
+ // `read_subscriptions` row in the same TX.
14
14
  import { configuredPiiSubjectKms, encryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
15
15
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
16
16
  import { propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
@@ -21,9 +21,9 @@ import { INVOICE_PAID_EVENT_QN, INVOICE_PAYMENT_FAILED_EVENT_QN, SUBSCRIPTION_AG
21
21
  import { getSubscriptionForTenant } from "../get-subscription-for-tenant.js";
22
22
  import { BILLING_SUBSCRIPTION_LOCK_NAMESPACE, isSubscriptionBlockingCheckout, isSwitchableSubscriptionStatus, SubscriptionEventTypes, SubscriptionStatuses, } from "../web/constants.js";
23
23
  // =============================================================================
24
- // Input-Schema = der normalisierte SubscriptionEvent (ohne tenantId, der
25
- // kommt aus event.user.tenantId — der webhook-handler setzt den
26
- // programmatic-user mit der vom Plugin aufgelösten tenantId).
24
+ // Input schema = the normalized SubscriptionEvent (without tenantId, which
25
+ // comes from event.user.tenantId — the webhook handler sets the
26
+ // programmatic user with the tenantId resolved by the plugin).
27
27
  // =============================================================================
28
28
  const eventTypeSchema = z.enum([
29
29
  SubscriptionEventTypes.created,
@@ -153,9 +153,9 @@ export async function appendSubscriptionEvent(ctx, tenantId, rawPayload, now = T
153
153
  // read_subscriptions row with a single call. The subject is the
154
154
  // TENANT (tenantOwned) — tenant-destroy's subject-keys stage
155
155
  // (eraseSubjectKeys) erases exactly this key, so both copies become
156
- // genuinely unreadable (#800) once that stage runs, not just
156
+ // genuinely unreadable once that stage runs, not just
157
157
  // "encrypted at rest". No adapter configured = engine off (fields
158
- // stay plaintext, pre-#724-phase-C behavior) — mirrors how the
158
+ // stay plaintext) — mirrors how the
159
159
  // event-store-executor treats an absent piiKms().
160
160
  // ---------------------------------------------------------------
161
161
  const piiKms = configuredPiiSubjectKms();
@@ -203,9 +203,9 @@ export async function appendSubscriptionEvent(ctx, tenantId, rawPayload, now = T
203
203
  // Handler
204
204
  // =============================================================================
205
205
  //
206
- // SystemAdmin-only: dieser handler wird ausschließlich vom programmatic
207
- // webhook-handler aufgerufen (mit einem internal SystemUser), nie vom
208
- // Tenant-Admin direkt.
206
+ // SystemAdmin-only: this handler is called exclusively by the programmatic
207
+ // webhook handler (with an internal SystemUser), never directly by the
208
+ // tenant admin.
209
209
  // One subscription aggregate exists per tenant, but a tenant can legitimately hold two provider
210
210
  // subscriptions over time (a stale `incomplete` one superseded by a fresh checkout). A late or
211
211
  // retried event of the old subscription must not overwrite the row of the live one, so an event of a