@cosmicdrift/kumiko-samples 0.385.0 → 0.387.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) hide show
  1. package/LICENSE +21 -57
  2. package/README.md +1 -1
  3. package/package.json +2 -2
  4. package/packages/bundled-features/package.json +2 -2
  5. package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
  6. package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +0 -2
  7. package/packages/bundled-features/src/audit/screens.ts +1 -1
  8. package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
  9. package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
  10. package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
  11. package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
  12. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
  13. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
  14. package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
  15. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  16. package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
  17. package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
  18. package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
  19. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +34 -37
  20. package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
  21. package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
  22. package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
  23. package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
  24. package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
  25. package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
  26. package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
  27. package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
  28. package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
  29. package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
  30. package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
  31. package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
  32. package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
  33. package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
  34. package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
  35. package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
  36. package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
  37. package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
  38. package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
  39. package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
  40. package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
  41. package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
  42. package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
  43. package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
  44. package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
  45. package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
  46. package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
  47. package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
  48. package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
  49. package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
  50. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
  51. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
  52. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  53. package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
  54. package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
  55. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  56. package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
  57. package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
  58. package/packages/bundled-features/src/auth-mfa/web/i18n.ts +3 -3
  59. package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
  60. package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
  61. package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +6 -6
  62. package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
  63. package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
  64. package/packages/bundled-features/src/billing-foundation/events.ts +22 -21
  65. package/packages/bundled-features/src/billing-foundation/feature.ts +42 -43
  66. package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
  67. package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +18 -17
  68. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
  69. package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
  70. package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +20 -20
  71. package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
  72. package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
  73. package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
  74. package/packages/bundled-features/src/billing-foundation/types.ts +64 -65
  75. package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +4 -4
  76. package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
  77. package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
  78. package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
  79. package/packages/bundled-features/src/cap-counter/enforce-cap.ts +64 -67
  80. package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
  81. package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
  82. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
  83. package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
  84. package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +1 -1
  85. package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
  86. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
  87. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
  88. package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
  89. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
  90. package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
  91. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
  92. package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
  93. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
  94. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
  95. package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
  96. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
  97. package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
  98. package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
  99. package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
  100. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
  101. package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
  102. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
  103. package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
  104. package/packages/bundled-features/src/config/resolver.ts +4 -4
  105. package/packages/bundled-features/src/config/table.ts +10 -10
  106. package/packages/bundled-features/src/config/write-helpers.ts +1 -1
  107. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +13 -12
  108. package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
  109. package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
  110. package/packages/bundled-features/src/custom-fields/events.ts +7 -8
  111. package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
  112. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
  113. package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
  114. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
  115. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
  116. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
  117. package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
  118. package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
  119. package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.ts +1 -1
  120. package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
  121. package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -12
  122. package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
  123. package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
  124. package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
  125. package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
  126. package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
  127. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
  128. package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
  129. package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
  130. package/packages/bundled-features/src/data-retention/feature.ts +11 -18
  131. package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
  132. package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
  133. package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
  134. package/packages/bundled-features/src/data-retention/presets.ts +18 -23
  135. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  136. package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
  137. package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
  138. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
  139. package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
  140. package/packages/bundled-features/src/delivery/feature.ts +3 -3
  141. package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
  142. package/packages/bundled-features/src/delivery/tables.ts +9 -8
  143. package/packages/bundled-features/src/delivery/unsubscribe.ts +4 -4
  144. package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
  145. package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
  146. package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
  147. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
  148. package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
  149. package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +4 -4
  150. package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
  151. package/packages/bundled-features/src/feature-toggles/feature.ts +1 -1
  152. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  153. package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
  154. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  155. package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
  156. package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
  157. package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
  158. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  159. package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
  160. package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
  161. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
  162. package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
  163. package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
  164. package/packages/bundled-features/src/files/feature.ts +6 -6
  165. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
  166. package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
  167. package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
  168. package/packages/bundled-features/src/folders/feature.ts +1 -1
  169. package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
  170. package/packages/bundled-features/src/folders/web/tree.ts +5 -5
  171. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
  172. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
  173. package/packages/bundled-features/src/form-draft/entity.ts +3 -3
  174. package/packages/bundled-features/src/form-draft/feature.ts +4 -5
  175. package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
  176. package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
  177. package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
  178. package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
  179. package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
  180. package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
  181. package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
  182. package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
  183. package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
  184. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
  185. package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
  186. package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
  187. package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
  188. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
  189. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
  190. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
  191. package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
  192. package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +11 -11
  193. package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
  194. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
  195. package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
  196. package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
  197. package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
  198. package/packages/bundled-features/src/inbound-mail-foundation/types.ts +66 -67
  199. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +69 -68
  200. package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
  201. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
  202. package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
  203. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
  204. package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
  205. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
  206. package/packages/bundled-features/src/jobs/events.ts +1 -1
  207. package/packages/bundled-features/src/jobs/feature.ts +6 -7
  208. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
  209. package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
  210. package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
  211. package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
  212. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  213. package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
  214. package/packages/bundled-features/src/jobs/job-run-logger.ts +14 -15
  215. package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
  216. package/packages/bundled-features/src/jobs/screens.ts +1 -1
  217. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  218. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  219. package/packages/bundled-features/src/ledger/entity.ts +5 -5
  220. package/packages/bundled-features/src/ledger/feature.ts +3 -3
  221. package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
  222. package/packages/bundled-features/src/ledger/recurring.ts +12 -12
  223. package/packages/bundled-features/src/ledger/schemas.ts +1 -1
  224. package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
  225. package/packages/bundled-features/src/ledger/web/index.ts +7 -7
  226. package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
  227. package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
  228. package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
  229. package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
  230. package/packages/bundled-features/src/mail-foundation/feature.ts +26 -27
  231. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
  232. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
  233. package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
  234. package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
  235. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
  236. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
  237. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
  238. package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
  239. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
  240. package/packages/bundled-features/src/managed-pages/table.ts +16 -15
  241. package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
  242. package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
  243. package/packages/bundled-features/src/notes-history/entity.ts +4 -4
  244. package/packages/bundled-features/src/notes-history/feature.ts +2 -2
  245. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  246. package/packages/bundled-features/src/page-render/layout.ts +9 -9
  247. package/packages/bundled-features/src/page-render/markdown.ts +11 -11
  248. package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
  249. package/packages/bundled-features/src/personal-access-tokens/feature.ts +5 -5
  250. package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
  251. package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
  252. package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
  253. package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
  254. package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
  255. package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
  256. package/packages/bundled-features/src/secrets/feature.ts +9 -9
  257. package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
  258. package/packages/bundled-features/src/seo/feature.ts +3 -3
  259. package/packages/bundled-features/src/sessions/constants.ts +1 -1
  260. package/packages/bundled-features/src/sessions/feature.ts +9 -9
  261. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
  262. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +2 -2
  263. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  264. package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
  265. package/packages/bundled-features/src/sessions/screens.ts +2 -2
  266. package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
  267. package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
  268. package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
  269. package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +1 -1
  270. package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
  271. package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
  272. package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
  273. package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
  274. package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
  275. package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
  276. package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
  277. package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
  278. package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
  279. package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
  280. package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
  281. package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
  282. package/packages/bundled-features/src/subscription-stripe/feature.ts +44 -43
  283. package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
  284. package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
  285. package/packages/bundled-features/src/subscription-stripe/runtime.ts +2 -2
  286. package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
  287. package/packages/bundled-features/src/tags/feature.ts +3 -3
  288. package/packages/bundled-features/src/tags/screens.ts +1 -1
  289. package/packages/bundled-features/src/template-resolver/api.ts +10 -10
  290. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +5 -5
  291. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
  292. package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
  293. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
  294. package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
  295. package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
  296. package/packages/bundled-features/src/template-resolver/seeding.ts +4 -4
  297. package/packages/bundled-features/src/template-resolver/table.ts +13 -14
  298. package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
  299. package/packages/bundled-features/src/tenant/feature.ts +7 -7
  300. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
  301. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  302. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  303. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  304. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
  305. package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
  306. package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
  307. package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
  308. package/packages/bundled-features/src/tenant/screens.ts +1 -1
  309. package/packages/bundled-features/src/tenant/seeding.ts +19 -18
  310. package/packages/bundled-features/src/tenant/testing.ts +5 -6
  311. package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
  312. package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
  313. package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
  314. package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
  315. package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
  316. package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
  317. package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
  318. package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
  319. package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
  320. package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
  321. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +2 -2
  322. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
  323. package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
  324. package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
  325. package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
  326. package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
  327. package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
  328. package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
  329. package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
  330. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
  331. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +8 -8
  332. package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
  333. package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
  334. package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
  335. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
  336. package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
  337. package/packages/bundled-features/src/user/schema/user.ts +45 -44
  338. package/packages/bundled-features/src/user/seeding.ts +40 -40
  339. package/packages/bundled-features/src/user/testing.ts +3 -3
  340. package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
  341. package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
  342. package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
  343. package/packages/bundled-features/src/user-data-rights/feature.ts +112 -113
  344. package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
  345. package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
  346. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
  347. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
  348. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
  349. package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
  350. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
  351. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +4 -4
  352. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
  353. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
  354. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
  355. package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
  356. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
  357. package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
  358. package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
  359. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
  360. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +166 -276
  361. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +85 -107
  362. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
  363. package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
  364. package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
  365. package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
  366. package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
  367. package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
  368. package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
  369. package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
  370. package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
  371. package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
  372. package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
  373. package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
  374. package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
  375. package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
  376. package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
  377. package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
  378. package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
  379. package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +1 -1
  380. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
  381. package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
  382. package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
  383. package/packages/bundled-features/src/user-profile/index.ts +3 -3
  384. package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
  385. package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
  386. package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
  387. package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
  388. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
  389. package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
  390. package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
  391. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
  392. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
  393. package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
  394. package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
  395. package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
@@ -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
@@ -51,12 +51,13 @@ const createCheckoutSessionSchema = z.object({
51
51
  providerName: z.string().min(1).max(50),
52
52
  /** Provider-eigene price/plan-ID. */
53
53
  priceId: z.string().min(1).max(200),
54
- /** Wo der Endkunde nach erfolgreichem checkout landed. */
54
+ /** Where the customer lands after a successful checkout. */
55
55
  successUrl: z.string().url(),
56
- /** Wo der Endkunde landed wenn er abbricht. */
56
+ /** Where the customer lands if they cancel. */
57
57
  cancelUrl: z.string().url(),
58
- /** Optional: existierender provider-customer wenn der Tenant schon
59
- * einen account beim Provider hat (= Plan-Wechsel statt Neuregistrierung). */
58
+ /** Optional: existing provider customer when the tenant already
59
+ * has an account with the provider (= plan change instead of a new
60
+ * registration). */
60
61
  providerCustomerId: z.string().max(200).optional(),
61
62
  /** Optional: `"payment"` for a one-off checkout (e.g. credit top-up)
62
63
  * 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
 
16
15
  import {
17
16
  configuredPiiSubjectKms,
@@ -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 {
6
6
  configuredPiiSubjectKms,
7
7
  decryptPiiFieldValues,
@@ -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
 
15
15
  import {
16
16
  configuredPiiSubjectKms,
@@ -42,9 +42,9 @@ import {
42
42
  } from "../web/constants.ts";
43
43
 
44
44
  // =============================================================================
45
- // Input-Schema = der normalisierte SubscriptionEvent (ohne tenantId, der
46
- // kommt aus event.user.tenantId — der webhook-handler setzt den
47
- // programmatic-user mit der vom Plugin aufgelösten tenantId).
45
+ // Input schema = the normalized SubscriptionEvent (without tenantId, which
46
+ // comes from event.user.tenantId — the webhook handler sets the
47
+ // programmatic user with the tenantId resolved by the plugin).
48
48
  // =============================================================================
49
49
 
50
50
  const eventTypeSchema = z.enum([
@@ -208,9 +208,9 @@ export async function appendSubscriptionEvent(
208
208
  // read_subscriptions row with a single call. The subject is the
209
209
  // TENANT (tenantOwned) — tenant-destroy's subject-keys stage
210
210
  // (eraseSubjectKeys) erases exactly this key, so both copies become
211
- // genuinely unreadable (#800) once that stage runs, not just
211
+ // genuinely unreadable once that stage runs, not just
212
212
  // "encrypted at rest". No adapter configured = engine off (fields
213
- // stay plaintext, pre-#724-phase-C behavior) — mirrors how the
213
+ // stay plaintext) — mirrors how the
214
214
  // event-store-executor treats an absent piiKms().
215
215
  // ---------------------------------------------------------------
216
216
  const piiKms = configuredPiiSubjectKms();
@@ -268,9 +268,9 @@ export async function appendSubscriptionEvent(
268
268
  // Handler
269
269
  // =============================================================================
270
270
  //
271
- // SystemAdmin-only: dieser handler wird ausschließlich vom programmatic
272
- // webhook-handler aufgerufen (mit einem internal SystemUser), nie vom
273
- // Tenant-Admin direkt.
271
+ // SystemAdmin-only: this handler is called exclusively by the programmatic
272
+ // webhook handler (with an internal SystemUser), never directly by the
273
+ // tenant admin.
274
274
  // One subscription aggregate exists per tenant, but a tenant can legitimately hold two provider
275
275
  // subscriptions over time (a stale `incomplete` one superseded by a fresh checkout). A late or
276
276
  // retried event of the old subscription must not overwrite the row of the live one, so an event of a
@@ -1,18 +1,18 @@
1
- // Inline-projection für `read_subscriptions`. Materialisiert die 5
2
- // subscription-events in eine row pro Tenant.
1
+ // Inline projection for `read_subscriptions`. Materializes the 5
2
+ // subscription events into one row per tenant.
3
3
  //
4
- // Apply läuft in derselben TX wie ctx.unsafeAppendEvent — Caller sieht
5
- // seinen Schreib-State sofort (kein dispatcher-tick nötig). PK = event.
6
- // aggregateId (= deterministic uuidv5 pro Tenant) → replays kollidieren
7
- // auf der PK statt doppelte rows zu erzeugen.
4
+ // Apply runs in the same transaction as ctx.unsafeAppendEvent, so the caller
5
+ // sees its write state immediately (no dispatcher tick required). The PK is
6
+ // event.aggregateId (= deterministic uuidv5 per tenant), so replays collide
7
+ // on the PK instead of creating duplicate rows.
8
8
  //
9
- // **Production-deployment caveat:** der Generator in
10
- // `samples/apps/platform/drizzle/generate.ts` scant `feature.entities` —
11
- // `subscriptionsProjectionTable` ist als raw drizzle-pgTable in der
12
- // projection registriert, NICHT als r.entity. Apps die subscription-
13
- // foundation production mounten müssen die Tabelle in ihre eigene
14
- // `drizzle/generate.ts` ergänzen (= via subscriptionsProjectionTable-
15
- // import). setupTestStack pusht sie automatisch via r.projection.table.
9
+ // **Production-deployment caveat:** the generator in
10
+ // `samples/apps/platform/drizzle/generate.ts` scans `feature.entities` —
11
+ // `subscriptionsProjectionTable` is registered in the projection as a raw
12
+ // drizzle-pgTable, NOT as r.entity. Apps mounting subscription-foundation in
13
+ // production must add the table to their own `drizzle/generate.ts` (via an
14
+ // import of subscriptionsProjectionTable). setupTestStack pushes it
15
+ // automatically via r.projection.table.
16
16
 
17
17
  import {
18
18
  buildEntityTable,
@@ -26,9 +26,9 @@ import { paymentRowId } from "./aggregate-id.ts";
26
26
  import { paymentEntity, subscriptionEntity } from "./entities.ts";
27
27
  import type { PaymentEventPayload, SubscriptionEventPayload } from "./events.ts";
28
28
 
29
- // Drizzle-table-instance aus dem entity-shape. Wird sowohl von der
30
- // projection-apply als auch von list-query / get-helper genutzt damit
31
- // alle drei Stellen denselben column-namespace teilen.
29
+ // This Drizzle table instance is derived from the entity shape and is shared
30
+ // by the projection apply, list query, and get helper so all three use the
31
+ // same column namespace.
32
32
  export const subscriptionsProjectionTable = buildEntityTable("subscription", subscriptionEntity);
33
33
 
34
34
  // Same production-deployment caveat as subscriptionsProjectionTable above:
@@ -38,11 +38,11 @@ export const paymentsProjectionTable = buildEntityTable("payment", paymentEntity
38
38
 
39
39
  // Unbranded metas: the apply functions below ARE the executor of these
40
40
  // projections, so they may write through the typed helpers.
41
- const subscriptionsProjectionMeta: EntityTableMeta = requireEntityTableMeta(
41
+ export const subscriptionsProjectionMeta: EntityTableMeta = requireEntityTableMeta(
42
42
  subscriptionsProjectionTable,
43
43
  "subscription",
44
44
  );
45
- const paymentsProjectionMeta: EntityTableMeta = requireEntityTableMeta(
45
+ export const paymentsProjectionMeta: EntityTableMeta = requireEntityTableMeta(
46
46
  paymentsProjectionTable,
47
47
  "payment",
48
48
  );
@@ -99,10 +99,10 @@ async function upsert(
99
99
  }>,
100
100
  fullPayload: SubscriptionEventPayload,
101
101
  ): Promise<void> {
102
- // INSERT-fallback braucht ALL fields (NOT NULL constraints). Wenn
103
- // jemand nur teil-felder updated (z.B. invoice-payment-failed nur
104
- // status+tier), nutzen wir trotzdem den vollen payload für den
105
- // INSERT-Pfad und nur den teil-`set` für ON CONFLICT.
102
+ // The INSERT fallback requires ALL fields because of NOT NULL constraints.
103
+ // If an update changes only some fields (for example, invoice-payment-failed
104
+ // changes only status+tier), the full payload is still used for the INSERT
105
+ // path, while only the partial `set` is used for ON CONFLICT.
106
106
  const insertCols = {
107
107
  id: event.aggregateId,
108
108
  tenantId: event.tenantId,
@@ -123,23 +123,23 @@ async function upsert(
123
123
  }
124
124
 
125
125
  // =============================================================================
126
- // Apply-functions — eine pro event-typ
126
+ // Apply functions — one per event type
127
127
  //
128
- // Alle UPSERT für defensive consistency: ein out-of-order event
129
- // (z.B. rebuild-from-events) kann in jeder Reihenfolge ankommen
130
- // und die row korrekt materialisieren.
128
+ // All use UPSERT for defensive consistency: an out-of-order event (for
129
+ // example, during a rebuild-from-events) can arrive in any order and still
130
+ // materialize the row correctly.
131
131
  // =============================================================================
132
132
 
133
- /** subscription-created → UPSERT mit allen Feldern. PK = aggregateId =
134
- * subscriptionAggregateId(tenantId), one row pro Tenant. UPSERT damit
135
- * Disney+-Wechsel-Pattern (= zweiter Provider sendet create für selben
136
- * Tenant) den existing row überschreibt statt PK-conflict. */
133
+ /** subscription-created → UPSERT with all fields. PK = aggregateId =
134
+ * subscriptionAggregateId(tenantId), with one row per tenant. UPSERT allows
135
+ * the Disney+-change pattern (a second provider sends create for the same
136
+ * tenant) to overwrite the existing row instead of causing a PK conflict. */
137
137
  export const applySubscriptionCreated = defineApply<SubscriptionEventPayload>(async (event, tx) => {
138
138
  const full = fullSetFromPayload(event.payload);
139
139
  await upsert(tx, event, { ...full, ...cancelAtSetFromPayload(event.payload) }, event.payload);
140
140
  });
141
141
 
142
- /** subscription-updated → UPSERT mit allen Feldern. */
142
+ /** subscription-updated → UPSERT with all fields. */
143
143
  export const applySubscriptionUpdated = defineApply<SubscriptionEventPayload>(async (event, tx) => {
144
144
  const full = fullSetFromPayload(event.payload);
145
145
  await upsert(tx, event, { ...full, ...cancelAtSetFromPayload(event.payload) }, event.payload);
@@ -163,8 +163,9 @@ export const applySubscriptionCanceled = defineApply<SubscriptionEventPayload>(
163
163
  },
164
164
  );
165
165
 
166
- /** invoice-paid → state-update (status, tier, currentPeriodEnd).
167
- * Invoice-history selbst lebt im event-store (= Replay-fähig). */
166
+ /** invoice-paid → state update (status, tier, currentPeriodEnd).
167
+ * The invoice history itself lives in the event store, so it remains
168
+ * replayable. */
168
169
  export const applyInvoicePaid = defineApply<SubscriptionEventPayload>(async (event, tx) => {
169
170
  const p = event.payload;
170
171
  await upsert(
@@ -180,10 +181,10 @@ export const applyInvoicePaid = defineApply<SubscriptionEventPayload>(async (eve
180
181
  );
181
182
  });
182
183
 
183
- /** invoice-payment-failed → status (typisch past_due) + tier. tier-
184
- * engine liest die row + entscheidet ob downgrade. currentPeriodEnd
185
- * bewusst nicht — die Period ist noch nicht "vorbei", payment hat
186
- * nur nicht geklappt. */
184
+ /** invoice-payment-failed → status (typically past_due) + tier. The tier
185
+ * engine reads the row and decides whether to downgrade. currentPeriodEnd is
186
+ * intentionally unchanged: the period has not "ended"; payment simply
187
+ * failed. */
187
188
  export const applyInvoicePaymentFailed = defineApply<SubscriptionEventPayload>(
188
189
  async (event, tx) => {
189
190
  const p = event.payload;
@@ -1,7 +1,7 @@
1
1
  // Generic Stripe/PayPal-webhook → tier-engine sync route. Extracted from the
2
- // near-identical webhook-route.ts app copies in show-pony and publicstatus
3
- // (infra#446) — the only per-app variables were the TierName union/default,
4
- // so it is now a factory parameter.
2
+ // near-identical webhook-route.ts app copies in show-pony and publicstatus — the
3
+ // only per-app variables were the TierName union/default, so it is now a factory
4
+ // parameter.
5
5
 
6
6
  import {
7
7
  isTierAssignmentSource,
@@ -1,10 +1,9 @@
1
- import type { EntityTableMeta } from "@cosmicdrift/kumiko-framework/db";
2
1
  import { declareEscapeHatch, type TenantDataHookCtx } from "@cosmicdrift/kumiko-framework/engine";
3
2
  import { archiveStream } from "@cosmicdrift/kumiko-framework/event-store";
4
3
  import { resolveProfileForTenant } from "../compliance-profiles/index.ts";
5
4
  import { paymentAggregateId, subscriptionAggregateId } from "./aggregate-id.ts";
6
5
  import { PAYMENT_AGGREGATE_TYPE, SUBSCRIPTION_AGGREGATE_TYPE } from "./events.ts";
7
- import { paymentsProjectionTable, subscriptionsProjectionTable } from "./projection.ts";
6
+ import { paymentsProjectionMeta, subscriptionsProjectionMeta } from "./projection.ts";
8
7
 
9
8
  // providerCustomerId/providerSubscriptionId are `personal: "tenant"` on the
10
9
  // entity (envelope-encrypted with the tenant subject key, see entities.ts) —
@@ -19,7 +18,7 @@ export const SUBSCRIPTION_TENANT_DESTROY_ARCHIVE_REASON =
19
18
  export const PAYMENT_TENANT_DESTROY_ARCHIVE_REASON =
20
19
  "tenant-destroy looks up the compliance profile and archives the payment event-stream before the projection rows are redacted/deleted";
21
20
 
22
- /** Tenant-destroy hook for billing PII (#800). HGB retains the accounting
21
+ /** Tenant-destroy hook for billing PII. HGB retains the accounting
23
22
  * row but redacts the two provider-subject PII fields; other profiles
24
23
  * hard-delete the row. Either way the subscription stream is archived so a
25
24
  * future projection rebuild can't resurrect what was erased. */
@@ -32,12 +31,12 @@ export async function subscriptionTenantDestroyHook(ctx: TenantDataHookCtx): Pro
32
31
  const aggregateId = subscriptionAggregateId(ctx.tenantId);
33
32
  if (profile.key === "de-hr-dsgvo-hgb") {
34
33
  await ctx.db.updateMany(
35
- subscriptionsProjectionTable as EntityTableMeta,
34
+ subscriptionsProjectionMeta,
36
35
  { providerCustomerId: REDACTED_PII_VALUE, providerSubscriptionId: REDACTED_PII_VALUE },
37
36
  { id: aggregateId },
38
37
  );
39
38
  } else {
40
- await ctx.db.deleteMany(subscriptionsProjectionTable as EntityTableMeta, { id: aggregateId });
39
+ await ctx.db.deleteMany(subscriptionsProjectionMeta, { id: aggregateId });
41
40
  }
42
41
  await archiveStream(ctx.db.unsafeRaw(), {
43
42
  tenantId: ctx.tenantId,
@@ -48,7 +47,7 @@ export async function subscriptionTenantDestroyHook(ctx: TenantDataHookCtx): Pro
48
47
  });
49
48
  }
50
49
 
51
- /** Tenant-destroy hook for payment PII (#800). Unlike subscriptionTenantDestroyHook
50
+ /** Tenant-destroy hook for payment PII. Unlike subscriptionTenantDestroyHook
52
51
  * (one row per tenant, targeted by `id`), a tenant can have many payment
53
52
  * rows — the predicate here is `tenantId`, not `id`. The payment-stream
54
53
  * itself is still one stream per tenant (paymentAggregateId), so
@@ -62,12 +61,12 @@ export async function paymentTenantDestroyHook(ctx: TenantDataHookCtx): Promise<
62
61
  const aggregateId = paymentAggregateId(ctx.tenantId);
63
62
  if (profile.key === "de-hr-dsgvo-hgb") {
64
63
  await ctx.db.updateMany(
65
- paymentsProjectionTable as EntityTableMeta,
64
+ paymentsProjectionMeta,
66
65
  { providerCustomerId: REDACTED_PII_VALUE },
67
66
  { tenantId: ctx.tenantId },
68
67
  );
69
68
  } else {
70
- await ctx.db.deleteMany(paymentsProjectionTable as EntityTableMeta, {
69
+ await ctx.db.deleteMany(paymentsProjectionMeta, {
71
70
  tenantId: ctx.tenantId,
72
71
  });
73
72
  }
@@ -1,29 +1,29 @@
1
1
  /// <reference types="temporal-polyfill/global" preserve="true" />
2
- // Plugin-Contract + Domain-Types der subscription-foundation. Provider-
3
- // Plugins (subscription-stripe, subscription-mollie, ...) implementieren
4
- // `SubscriptionProviderPlugin` und registrieren via
2
+ // Plugin contract and domain types for subscription-foundation. Provider
3
+ // plugins (subscription-stripe, subscription-mollie, ...) implement
4
+ // `SubscriptionProviderPlugin` and register via
5
5
  // `r.useExtension("subscriptionProvider", "<name>", { build })`.
6
6
  //
7
7
  // **Two-phase plugin contract:**
8
- // 1. **Pre-tenant-resolution:** `verifyAndParseWebhook` läuft BEVOR
9
- // ein Tenant aus dem Event aufgelöst ist — kein HandlerContext
10
- // verfügbar. Das **Webhook-secret ist app-wide** (App-Owner's
11
- // Stripe-/PayPal-Account, nicht Tenant-Sache). Damit ein Plugin den
12
- // secret ZUR LAUFFZEIT aus dem secrets-Feature lesen kann (statt aus
13
- // einem mount-time-Closure), reicht der webhook-handler einen
14
- // optionalen system-scoped `SecretsContext` als 3. Arg durch — der
15
- // Plugin liest seine app-wide-Secrets daraus un-audited unter
16
- // SYSTEM_TENANT_ID. Plugins, die ihre Keys weiter aus einem Closure
17
- // halten (z.B. mollie), ignorieren den Param → backward-compatible.
8
+ // 1. **Pre-tenant-resolution:** `verifyAndParseWebhook` runs BEFORE
9
+ // a tenant is resolved from the event, so no HandlerContext is
10
+ // available. The **webhook secret is app-wide** (the App Owner's
11
+ // Stripe-/PayPal-account, not tenant-specific). To let a plugin read
12
+ // the secret from the secrets feature AT RUNTIME (instead of a
13
+ // mount-time closure), the webhook handler passes an optional
14
+ // system-scoped `SecretsContext` as the third argument. The plugin
15
+ // reads its app-wide secrets from it without auditing under
16
+ // SYSTEM_TENANT_ID. Plugins that keep their keys in a closure
17
+ // (e.g. mollie) ignore the parameter → backward-compatible.
18
18
  // 2. **Post-tenant-resolution:** `createPortalSession` +
19
- // `cancelSubscription` werden aus regulären write-handlern
20
- // gerufen mit voll-aufgelöstem HandlerContext. Plugin kann
21
- // hier ctx.config + ctx.secrets nutzen für tenant-spezifische
22
- // Konfiguration (z.B. tenant-eigene customer-id-mapping).
19
+ // `cancelSubscription` are called from regular write handlers with
20
+ // a fully resolved HandlerContext. The plugin can use ctx.config +
21
+ // ctx.secrets for tenant-specific configuration (e.g. tenant-owned
22
+ // customer-id mappings).
23
23
  //
24
- // Foundation nutzt nur den common-subset der Provider-Funktionalität —
25
- // proration, multi-currency, coupons etc. bleiben provider-spezifisch
26
- // und sind über den Customer-Portal-Link erreichbar.
24
+ // Foundation uses only the common subset of provider functionality;
25
+ // proration, multi-currency, coupons, etc. remain provider-specific and
26
+ // are available through the Customer Portal link.
27
27
 
28
28
  import type { TenantDb } from "@cosmicdrift/kumiko-framework/db";
29
29
  import type { HandlerContext, TenantId } from "@cosmicdrift/kumiko-framework/engine";
@@ -41,12 +41,12 @@ import {
41
41
  import type { ConsentLocale } from "./web/consumer-protection/consent-locale.ts";
42
42
 
43
43
  // =============================================================================
44
- // Normalisierter Webhook-Event
44
+ // Normalized Webhook Event
45
45
  // =============================================================================
46
46
  //
47
- // Der Plugin parsed den raw provider-payload und liefert diese Form
48
- // zurück. Foundation kennt KEINE Stripe-/Mollie-types direkt — der
49
- // Plugin abstrahiert.
47
+ // The plugin parses the raw provider payload and returns this shape.
48
+ // Foundation has no direct knowledge of Stripe-/Mollie-types; the plugin
49
+ // provides the abstraction.
50
50
 
51
51
  export type SubscriptionEvent = {
52
52
  /** Discriminator against PaymentEvent. Optional (instead of required) so
@@ -55,32 +55,31 @@ export type SubscriptionEvent = {
55
55
  * `parsed.kind === BillingEventKinds.payment` correctly, because only
56
56
  * PaymentEvent["kind"] can take that value. */
57
57
  readonly kind?: typeof BillingEventKinds.subscription;
58
- /** Provider-eigene Event-ID — UNIQUE-key für Idempotency.
59
- * Stripe: "evt_..."; Mollie: payment-id oder subscription-id. */
58
+ /** Provider-owned event ID — UNIQUE key for idempotency.
59
+ * Stripe: "evt_..."; Mollie: payment-id or subscription-id. */
60
60
  readonly providerEventId: string;
61
61
  /** Discriminator — welcher Plugin diesen Event geliefert hat. */
62
62
  readonly providerName: string;
63
63
  /** Normalisierter Event-Type. Plugin filtert provider-spezifische
64
64
  * Sub-Types raus (Stripe hat ~80 Event-types, wir kennen 5). */
65
65
  readonly type: SubscriptionEventType;
66
- /** Plattform-Tenant-ID (provider-customer-metadata oder lookup
67
- * via providerCustomerId). Plugin macht die resolution. */
66
+ /** Platform tenant ID (provider-customer metadata or lookup via
67
+ * providerCustomerId). The plugin performs the resolution. */
68
68
  readonly tenantId: string;
69
69
  /** Consent id echoed back from checkout metadata; omitted when absent or
70
70
  * malformed. */
71
71
  readonly consentId?: string;
72
- /** Provider-eigene customer-id für späteren Lookup bei events
73
- * ohne metadata. */
72
+ /** Provider-owned customer ID for later lookup when events lack
73
+ * metadata. */
74
74
  readonly providerCustomerId: string;
75
75
  /** Provider-eigene subscription-id. */
76
76
  readonly providerSubscriptionId: string;
77
77
  /** Normalisierter status. */
78
78
  readonly status: SubscriptionStatus;
79
- /** Resolved tier — Plugin liest die price-id aus dem event und
80
- * mapped via plugin-eigenem `<plugin>:config:price-to-tier` auf
81
- * einen tier-name. Wenn der price-id im Mapping fehlt, returnt
82
- * der Plugin null aus verifyAndParseWebhook (= "unknown event,
83
- * ignore"). */
79
+ /** Resolved tier — the plugin reads the price ID from the event and
80
+ * maps it through the plugin's `<plugin>:config:price-to-tier` to a
81
+ * tier name. If the price ID is absent from the mapping, the plugin
82
+ * returns null from verifyAndParseWebhook (= "unknown event, ignore"). */
84
83
  readonly tier: string;
85
84
  /** ISO-timestamp wann die aktuelle Billing-Period endet. */
86
85
  readonly currentPeriodEnd: string;
@@ -172,32 +171,32 @@ export type SubscriptionProviderPlugin = {
172
171
  ) => Promise<SubscriptionEvent | PaymentEvent | null>;
173
172
 
174
173
  /**
175
- * **Post-tenant-resolution** — wird aus dem
176
- * `create-checkout-session`-write-handler gerufen. Plugin baut
177
- * eine provider-eigene checkout-session und returnt die hosted-
178
- * page-URL — Tenant-Admin wird dorthin redirected, schließt den
179
- * Bezahl-Flow ab, Provider sendet `subscription.created`-webhook
180
- * mit `metadata.tenantId` zurück.
174
+ * **Post-tenant-resolution** — called from the
175
+ * `create-checkout-session` write handler. The plugin builds a
176
+ * provider-specific checkout session and returns its hosted-page URL;
177
+ * the tenant admin is redirected there to complete payment, and the
178
+ * provider sends a `subscription.created` webhook with
179
+ * `metadata.tenantId`.
181
180
  *
182
- * Optional: Apple-IAP hat keinen Web-Checkout (alles in der App).
183
- * Apps die ausschließlich Apple-IAP nutzen lassen das weg.
181
+ * Optional: Apple-IAP has no web checkout (everything happens in the app).
182
+ * Apps that use only Apple-IAP omit this field.
184
183
  */
185
184
  readonly createCheckoutSession?: (
186
185
  ctx: HandlerContext,
187
186
  options: {
188
- /** Provider-eigene price/plan-ID die der Endkunde abonniert. */
187
+ /** Provider-owned price/plan ID that the customer subscribes to. */
189
188
  readonly priceId: string;
190
- /** Plattform-Tenant-ID — landet als metadata im checkout-session
191
- * damit der subsequent webhook den tenant resolved (siehe
192
- * `verifyAndParseWebhook`'s metadata.tenantId-lookup). */
189
+ /** Platform tenant ID — stored as metadata in the checkout session
190
+ * so the subsequent webhook can resolve the tenant (see the
191
+ * `verifyAndParseWebhook` metadata.tenantId lookup). */
193
192
  readonly tenantId: string;
194
- /** Wo der Endkunde nach erfolgreichem checkout landed. */
193
+ /** Where the customer lands after a successful checkout. */
195
194
  readonly successUrl: string;
196
- /** Wo der Endkunde landed wenn er abbricht. */
195
+ /** Where the customer lands if they cancel. */
197
196
  readonly cancelUrl: string;
198
- /** Optional: existierende provider-customer-id wenn der Tenant
199
- * schon einen Account beim Provider hat. Sonst legt der Provider
200
- * beim checkout einen neuen customer an. */
197
+ /** Optional: existing provider customer ID when the tenant already
198
+ * has an account with the provider. Otherwise, the provider
199
+ * creates a new customer during checkout. */
201
200
  readonly providerCustomerId?: string;
202
201
  /** Checkout mode. `"subscription"` (default) starts a recurring
203
202
  * billing flow; `"payment"` a one-off checkout (e.g. pay-per-use
@@ -215,17 +214,17 @@ export type SubscriptionProviderPlugin = {
215
214
  ) => Promise<{ readonly url: string }>;
216
215
 
217
216
  /**
218
- * **Post-tenant-resolution** — wird aus einem write-handler gerufen
219
- * mit voll-aufgelöstem ctx. Erstellt einen self-service Portal-Link.
217
+ * **Post-tenant-resolution** — called from a write handler with a
218
+ * fully resolved ctx. Creates a self-service Portal link.
220
219
  * Stripe: customer-portal-session, Mollie: hosted-management-page.
221
- * Tenant-Admin klickt darauf um Subscription selbst zu verwalten
222
- * (cancel, payment-method, ...).
220
+ * The tenant admin uses it to manage the subscription themselves
221
+ * (cancel, payment method, ...).
223
222
  *
224
- * Optional weil nicht jeder Provider einen Portal-Pattern hat
225
- * (Apple-IAP managed Subs in der Apple-App, kein Web-Portal).
226
- * Plugin der das nicht supported kann das Field weglassen — foundation
227
- * returnt dann "portal_not_supported"-error wenn ein Tenant-Admin
228
- * den Portal-Link anfordert.
223
+ * Optional because not every provider has a Portal pattern
224
+ * (Apple-IAP subscriptions are managed in the Apple app, with no web
225
+ * Portal). A plugin that does not support this can omit the field;
226
+ * the foundation then returns a "portal_not_supported" error when a
227
+ * tenant admin requests the Portal link.
229
228
  */
230
229
  readonly createPortalSession?: (
231
230
  ctx: HandlerContext,
@@ -236,10 +235,10 @@ export type SubscriptionProviderPlugin = {
236
235
  ) => Promise<{ readonly url: string }>;
237
236
 
238
237
  /**
239
- * Optional: Cancel-aus-der-App-API. Wenn nicht implementiert, kann
240
- * der Tenant nur über den Customer-Portal-Link cancellen (oder gar
241
- * nicht, wenn auch createPortalSession fehlt — dann ist
242
- * Cancel-Flow Provider-Dashboard-only).
238
+ * Optional: in-app cancellation API. If not implemented, the tenant
239
+ * can cancel only through the Customer Portal link (or not at all if
240
+ * createPortalSession is also missing — the cancellation flow is then
241
+ * provider-dashboard-only).
243
242
  */
244
243
  readonly cancelSubscription?: (
245
244
  ctx: HandlerContext,
@@ -78,10 +78,10 @@ function manageOrReactivateAction(
78
78
  };
79
79
  }
80
80
 
81
- /** `!canPurchase` hides every CTA outright (spec: "keine CTAs, Hinweis
82
- * purchaseNotAllowed") — distinct from the `unavailable` action's disabled
83
- * CTA, which still shows a button (e.g. for a plan whose price failed to
84
- * load) so this check runs before the general unavailable-fallback. */
81
+ /** `!canPurchase` hides every CTA outright (see `purchaseNotAllowed`) — distinct
82
+ * from the `unavailable` action's disabled CTA, which still shows a button
83
+ * (for example, when a plan's price failed to load), so this check runs
84
+ * before the general unavailable fallback. */
85
85
 
86
86
  function planCta(
87
87
  plan: BillingPlanView,
@@ -95,7 +95,7 @@ export function createSubscriptionWebhookRoute(options: SubscriptionWebhookRoute
95
95
  return c.json({ ignored: true }, 200);
96
96
  }
97
97
  const parsed = verified.event;
98
- const tenantId = parsed.tenantId as import("@cosmicdrift/kumiko-framework/engine").TenantId;
98
+ const tenantId = parsed.tenantId;
99
99
  if (parsed.kind === BillingEventKinds.payment) {
100
100
  const dispatched = await deps.dispatchSystemWrite({
101
101
  handlerQn: SubscriptionFoundationHandlers.processPaymentEvent,