@cosmicdrift/kumiko-samples 0.366.0 → 0.368.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 (411) hide show
  1. package/package.json +1 -1
  2. package/packages/bundled-features/package.json +16 -2
  3. package/packages/bundled-features/src/audit/handlers/details.query.ts +1 -1
  4. package/packages/bundled-features/src/audit/handlers/list.query.ts +1 -1
  5. package/packages/bundled-features/src/audit/run-escape-hatch-retention.ts +5 -5
  6. package/packages/bundled-features/src/auth-email-password/bootstrap.ts +1 -1
  7. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +10 -3
  8. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +10 -3
  9. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  10. package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +6 -2
  11. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +1 -1
  12. package/packages/bundled-features/src/auth-email-password/seeding.ts +2 -2
  13. package/packages/bundled-features/src/auth-foundation/feature.ts +43 -34
  14. package/packages/bundled-features/src/auth-foundation/index.ts +1 -0
  15. package/packages/bundled-features/src/auth-mfa/db/queries.ts +5 -2
  16. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +1 -1
  17. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  18. package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +2 -2
  19. package/packages/bundled-features/src/auth-mfa/handlers/status.query.ts +1 -1
  20. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  21. package/packages/bundled-features/src/auth-mfa/mfa-code-verifier.ts +1 -1
  22. package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +1 -1
  23. package/packages/bundled-features/src/auth-mfa-user-data/index.ts +19 -10
  24. package/packages/bundled-features/src/billing-foundation/billing-info-query.ts +1 -1
  25. package/packages/bundled-features/src/billing-foundation/feature.ts +138 -135
  26. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +1 -1
  27. package/packages/bundled-features/src/billing-foundation/projection.ts +3 -2
  28. package/packages/bundled-features/src/cap-counter/calendar-cap-usage-reservation.ts +52 -1
  29. package/packages/bundled-features/src/cap-counter/cap-reservation.ts +203 -15
  30. package/packages/bundled-features/src/cap-counter/changes.json +13 -0
  31. package/packages/bundled-features/src/cap-counter/feature.ts +84 -73
  32. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +3 -4
  33. package/packages/bundled-features/src/cap-counter/index.ts +9 -1
  34. package/packages/bundled-features/src/cap-counter/tables.ts +10 -3
  35. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -2
  36. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +6 -2
  37. package/packages/bundled-features/src/cap-overview/handlers/tenant-options.query.ts +1 -1
  38. package/packages/bundled-features/src/channel-email/changes.json +6 -0
  39. package/packages/bundled-features/src/channel-email/email-channel.ts +12 -2
  40. package/packages/bundled-features/src/channel-email/feature.ts +1 -1
  41. package/packages/bundled-features/src/channel-in-app/handlers/inbox.query.ts +1 -1
  42. package/packages/bundled-features/src/channel-in-app/handlers/mark-all-read.write.ts +1 -1
  43. package/packages/bundled-features/src/channel-in-app/handlers/mark-read.write.ts +1 -1
  44. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +1 -1
  45. package/packages/bundled-features/src/channel-in-app/tables.ts +1 -1
  46. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +1 -1
  47. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +1 -1
  48. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +1 -2
  49. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +1 -1
  50. package/packages/bundled-features/src/compliance-profiles/seeding.ts +8 -4
  51. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +26 -17
  52. package/packages/bundled-features/src/config/db/queries/resolver.ts +1 -1
  53. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +2 -2
  54. package/packages/bundled-features/src/config/resolver.ts +1 -1
  55. package/packages/bundled-features/src/config/write-helpers.ts +1 -1
  56. package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
  57. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +9 -7
  58. package/packages/bundled-features/src/custom-fields/db/queries/field-access.ts +1 -1
  59. package/packages/bundled-features/src/custom-fields/db/queries/projection.ts +1 -1
  60. package/packages/bundled-features/src/custom-fields/db/queries/quota.ts +1 -1
  61. package/packages/bundled-features/src/custom-fields/db/queries/retention.ts +6 -2
  62. package/packages/bundled-features/src/custom-fields/db/queries/user-data-rights.ts +1 -1
  63. package/packages/bundled-features/src/custom-fields/feature.ts +11 -14
  64. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +2 -2
  65. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +2 -2
  66. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +2 -2
  67. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +2 -2
  68. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +4 -4
  69. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  70. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +16 -10
  71. package/packages/bundled-features/src/delivery/address-opt-out.ts +5 -2
  72. package/packages/bundled-features/src/delivery/attempt-log-retention.ts +1 -1
  73. package/packages/bundled-features/src/delivery/changes.json +12 -0
  74. package/packages/bundled-features/src/delivery/channel-context.ts +2 -1
  75. package/packages/bundled-features/src/delivery/db/queries/address-opt-outs.ts +1 -1
  76. package/packages/bundled-features/src/delivery/db/queries/preferences.ts +1 -1
  77. package/packages/bundled-features/src/delivery/delivery-service.ts +70 -8
  78. package/packages/bundled-features/src/delivery/feature.ts +2 -2
  79. package/packages/bundled-features/src/delivery/handlers/log.query.ts +3 -2
  80. package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +1 -1
  81. package/packages/bundled-features/src/delivery/handlers/unsubscribe-address.write.ts +10 -5
  82. package/packages/bundled-features/src/delivery/index.ts +6 -0
  83. package/packages/bundled-features/src/delivery/testing.ts +2 -0
  84. package/packages/bundled-features/src/delivery/types.ts +4 -0
  85. package/packages/bundled-features/src/delivery/unsubscribe-link.ts +73 -0
  86. package/packages/bundled-features/src/delivery/unsubscribe-page-strings.ts +17 -0
  87. package/packages/bundled-features/src/delivery/unsubscribe.ts +94 -31
  88. package/packages/bundled-features/src/delivery/upsert-preference.ts +5 -2
  89. package/packages/bundled-features/src/derivatives-sharp/feature.ts +21 -12
  90. package/packages/bundled-features/src/derivatives-sharp/index.ts +1 -1
  91. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +112 -103
  92. package/packages/bundled-features/src/document-ingest-foundation/forget-extract-with-file-ref.ts +3 -3
  93. package/packages/bundled-features/src/document-ingest-foundation/index.ts +4 -1
  94. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  95. package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -5
  96. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  97. package/packages/bundled-features/src/file-derivatives/feature.ts +134 -129
  98. package/packages/bundled-features/src/file-derivatives/handlers/public-variant-by-file-ref.query.ts +1 -1
  99. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  100. package/packages/bundled-features/src/file-foundation/feature.ts +38 -29
  101. package/packages/bundled-features/src/file-foundation/index.ts +1 -0
  102. package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +1 -1
  103. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +32 -21
  104. package/packages/bundled-features/src/file-provider-inmemory/index.ts +6 -1
  105. package/packages/bundled-features/src/file-provider-s3/changes.json +10 -1
  106. package/packages/bundled-features/src/file-provider-s3/env-feature.ts +62 -0
  107. package/packages/bundled-features/src/file-provider-s3/feature.ts +107 -73
  108. package/packages/bundled-features/src/file-provider-s3/index.ts +6 -1
  109. package/packages/bundled-features/src/file-provider-s3/lib/index.ts +3 -0
  110. package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/s3-provider.ts +19 -19
  111. package/packages/bundled-features/src/file-provider-s3-env/index.ts +7 -2
  112. package/packages/bundled-features/src/files-provider-s3/index.ts +11 -3
  113. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +1 -1
  114. package/packages/bundled-features/src/files-tenant-data/hooks.ts +1 -2
  115. package/packages/bundled-features/src/folders/feature.ts +8 -3
  116. package/packages/bundled-features/src/folders-user-data/index.ts +27 -18
  117. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
  118. package/packages/bundled-features/src/form-draft/db/queries/draft-count.ts +1 -1
  119. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +3 -2
  120. package/packages/bundled-features/src/form-draft/feature.ts +6 -1
  121. package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +2 -2
  122. package/packages/bundled-features/src/form-draft/index.ts +1 -1
  123. package/packages/bundled-features/src/form-draft/lookup.ts +1 -1
  124. package/packages/bundled-features/src/form-draft-user-data/index.ts +19 -10
  125. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +165 -154
  126. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +1 -2
  127. package/packages/bundled-features/src/inbound-mail-foundation/index.ts +1 -1
  128. package/packages/bundled-features/src/inbound-mail-foundation/oauth-access-token.ts +5 -2
  129. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +3 -2
  130. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +1 -1
  131. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +22 -13
  132. package/packages/bundled-features/src/inbound-provider-imap/index.ts +6 -1
  133. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +20 -12
  134. package/packages/bundled-features/src/inbound-provider-inmemory/index.ts +1 -0
  135. package/packages/bundled-features/src/jobs/db/queries/retention.ts +1 -1
  136. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +1 -1
  137. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +1 -1
  138. package/packages/bundled-features/src/jobs/handlers/list.query.ts +7 -2
  139. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  140. package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +1 -1
  141. package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +1 -1
  142. package/packages/bundled-features/src/jobs/job-run-logger.ts +11 -10
  143. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  144. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  145. package/packages/bundled-features/src/ledger/feature.ts +6 -3
  146. package/packages/bundled-features/src/mail-foundation/feature.ts +107 -55
  147. package/packages/bundled-features/src/mail-foundation/index.ts +4 -0
  148. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +25 -17
  149. package/packages/bundled-features/src/mail-transport-inmemory/index.ts +6 -1
  150. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +91 -79
  151. package/packages/bundled-features/src/mail-transport-smtp/index.ts +1 -0
  152. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +1 -1
  153. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +1 -2
  154. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +1 -2
  155. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -4
  156. package/packages/bundled-features/src/metrics/compute.ts +1 -1
  157. package/packages/bundled-features/src/metrics/filters.ts +1 -1
  158. package/packages/bundled-features/src/metrics/validate.ts +1 -1
  159. package/packages/bundled-features/src/notes-history/feature.ts +6 -3
  160. package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
  161. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  162. package/packages/bundled-features/src/notes-history-user-data/index.ts +27 -18
  163. package/packages/bundled-features/src/personal-access-tokens/changes.json +6 -0
  164. package/packages/bundled-features/src/personal-access-tokens/feature.ts +17 -2
  165. package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +1 -1
  166. package/packages/bundled-features/src/personal-access-tokens/handlers/list.query.ts +2 -2
  167. package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
  168. package/packages/bundled-features/src/personal-access-tokens/resolver.ts +1 -1
  169. package/packages/bundled-features/src/personal-access-tokens/revoke-for-user.ts +2 -2
  170. package/packages/bundled-features/src/personal-access-tokens/roles.ts +8 -6
  171. package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -0
  172. package/packages/bundled-features/src/readiness/feature.ts +25 -16
  173. package/packages/bundled-features/src/readiness/index.ts +1 -1
  174. package/packages/bundled-features/src/secrets/db/queries/read.ts +1 -1
  175. package/packages/bundled-features/src/secrets/feature.ts +8 -3
  176. package/packages/bundled-features/src/secrets/handlers/rotate.job.ts +2 -2
  177. package/packages/bundled-features/src/secrets/secrets-context.ts +4 -3
  178. package/packages/bundled-features/src/sessions/db/queries/cleanup.ts +1 -1
  179. package/packages/bundled-features/src/sessions/handlers/detail.query.ts +1 -1
  180. package/packages/bundled-features/src/sessions/handlers/list.query.ts +2 -2
  181. package/packages/bundled-features/src/sessions/handlers/mine.query.ts +1 -1
  182. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +1 -1
  183. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +1 -1
  184. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  185. package/packages/bundled-features/src/sessions/session-callbacks.ts +14 -7
  186. package/packages/bundled-features/src/sessions/testing.ts +1 -1
  187. package/packages/bundled-features/src/tags/feature.ts +6 -3
  188. package/packages/bundled-features/src/template-resolver/api.ts +1 -1
  189. package/packages/bundled-features/src/template-resolver/changes.json +25 -0
  190. package/packages/bundled-features/src/template-resolver/compile-document-body.ts +61 -9
  191. package/packages/bundled-features/src/template-resolver/document-sanitizer.ts +19 -0
  192. package/packages/bundled-features/src/template-resolver/document-schema.ts +33 -0
  193. package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +10 -2
  194. package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +1 -1
  195. package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +1 -2
  196. package/packages/bundled-features/src/template-resolver/handlers/collection-item.query.ts +1 -1
  197. package/packages/bundled-features/src/template-resolver/handlers/collection-list.query.ts +1 -2
  198. package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +1 -1
  199. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +9 -3
  200. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +1 -1
  201. package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +1 -1
  202. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +9 -2
  203. package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +1 -1
  204. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +7 -2
  205. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +8 -3
  206. package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +1 -1
  207. package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +1 -1
  208. package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +1 -1
  209. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +22 -2
  210. package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +1 -1
  211. package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +1 -1
  212. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +1 -1
  213. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +1 -1
  214. package/packages/bundled-features/src/template-resolver/index.ts +4 -0
  215. package/packages/bundled-features/src/template-resolver/qualified-names.ts +1 -0
  216. package/packages/bundled-features/src/template-resolver/seeding.ts +57 -10
  217. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +1 -1
  218. package/packages/bundled-features/src/template-resolver/template-preview.ts +3 -1
  219. package/packages/bundled-features/src/template-resolver/template-resources.ts +1 -1
  220. package/packages/bundled-features/src/template-resolver/template-system-only.ts +21 -0
  221. package/packages/bundled-features/src/template-resolver/template-validation.ts +48 -24
  222. package/packages/bundled-features/src/template-resolver/testing.ts +1 -1
  223. package/packages/bundled-features/src/template-resolver/web/i18n.ts +2 -0
  224. package/packages/bundled-features/src/template-resolver-user-data/index.ts +23 -14
  225. package/packages/bundled-features/src/tenant/handlers/active-tenant-ids.query.ts +1 -1
  226. package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +1 -2
  227. package/packages/bundled-features/src/tenant/handlers/cancel-invitation.write.ts +1 -1
  228. package/packages/bundled-features/src/tenant/handlers/invitations.query.ts +1 -1
  229. package/packages/bundled-features/src/tenant/handlers/me.query.ts +1 -1
  230. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
  231. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  232. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  233. package/packages/bundled-features/src/tenant/handlers/remove-member.write.ts +2 -1
  234. package/packages/bundled-features/src/tenant/handlers/resolve-user-ids.query.ts +1 -1
  235. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  236. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
  237. package/packages/bundled-features/src/tenant/handlers/update-member-roles.write.ts +1 -2
  238. package/packages/bundled-features/src/tenant/invited-membership.ts +2 -2
  239. package/packages/bundled-features/src/tenant/last-tenant-admin.ts +1 -2
  240. package/packages/bundled-features/src/tenant/seeding.ts +12 -12
  241. package/packages/bundled-features/src/tenant-lifecycle/handlers/cancel-destruction.write.ts +1 -2
  242. package/packages/bundled-features/src/tenant-lifecycle/handlers/request-destruction.write.ts +1 -2
  243. package/packages/bundled-features/src/tenant-lifecycle/lib/revoke-tenant-sessions.ts +1 -1
  244. package/packages/bundled-features/src/tenant-lifecycle/lifecycle-gate.ts +1 -1
  245. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +3 -3
  246. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +10 -5
  247. package/packages/bundled-features/src/tenant-lifecycle/testing.ts +3 -3
  248. package/packages/bundled-features/src/tenant-settings/feature.ts +34 -29
  249. package/packages/bundled-features/src/tier-engine/feature.ts +426 -428
  250. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +2 -3
  251. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +5 -2
  252. package/packages/bundled-features/src/user/changes.json +6 -0
  253. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +1 -1
  254. package/packages/bundled-features/src/user/handlers/create.write.ts +1 -2
  255. package/packages/bundled-features/src/user/handlers/find-for-auth.query.ts +1 -1
  256. package/packages/bundled-features/src/user/handlers/list.query.ts +1 -1
  257. package/packages/bundled-features/src/user/handlers/update-roles.ts +2 -1
  258. package/packages/bundled-features/src/user/index.ts +5 -1
  259. package/packages/bundled-features/src/user/invited-global-roles.ts +2 -2
  260. package/packages/bundled-features/src/user/principal-status.ts +13 -3
  261. package/packages/bundled-features/src/user/resolve-display-names.ts +1 -1
  262. package/packages/bundled-features/src/user/seeding.ts +5 -5
  263. package/packages/bundled-features/src/user-data-rights/audit-download.ts +2 -2
  264. package/packages/bundled-features/src/user-data-rights/changes.json +6 -0
  265. package/packages/bundled-features/src/user-data-rights/db/queries/export-jobs.ts +1 -1
  266. package/packages/bundled-features/src/user-data-rights/db/queries/forget-cleanup.ts +1 -1
  267. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +1 -1
  268. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +1 -1
  269. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +1 -1
  270. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +1 -1
  271. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +1 -1
  272. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +1 -2
  273. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +3 -3
  274. package/packages/bundled-features/src/user-data-rights/lib/deny-if-target-outside-admin-tenant.ts +1 -1
  275. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +7 -2
  276. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +7 -3
  277. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +11 -5
  278. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +10 -5
  279. package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +1 -2
  280. package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
  281. package/packages/bundled-features/src/waitlist/lib.ts +5 -2
  282. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +1 -1
  283. package/packages/bundled-features/src/workflow-runner/feature.ts +58 -47
  284. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +1 -1
  285. package/packages/bundled-features/src/workflow-runner/index.ts +1 -1
  286. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +1 -1
  287. package/samples/apps/admin-console/src/run-config.ts +2 -2
  288. package/samples/apps/cap-billing-demo/package.json +3 -0
  289. package/samples/apps/cap-billing-demo/src/feature.ts +2 -2
  290. package/samples/apps/cap-billing-demo/src/run-config.ts +8 -8
  291. package/samples/apps/marketing-demo/src/app/seed.ts +1 -1
  292. package/samples/apps/marketing-demo/src/db/queries/seed-counts.ts +1 -1
  293. package/samples/apps/showcase/package.json +3 -0
  294. package/samples/apps/showcase/src/app/seed-items.ts +1 -1
  295. package/samples/apps/styleguide/src/app/seed.ts +2 -2
  296. package/samples/apps/styleguide/src/features/ai-settings/seed.ts +2 -2
  297. package/samples/apps/ui-walkthrough/scripts/emit-e2e-data.ts +1 -1
  298. package/samples/apps/ui-walkthrough/src/app/auth-constants.ts +1 -1
  299. package/samples/apps/ui-walkthrough/src/app/seed-rental.ts +2 -2
  300. package/samples/apps/ui-walkthrough/src/app/seed-templates.ts +2 -0
  301. package/samples/apps/ui-walkthrough/src/app/seed-vehicles.ts +1 -1
  302. package/samples/apps/ui-walkthrough/src/app/seed.ts +1 -1
  303. package/samples/apps/ui-walkthrough/src/app/template-seed-data.ts +12 -0
  304. package/samples/apps/ui-walkthrough/src/db/queries/row-counts.ts +1 -1
  305. package/samples/apps/ui-walkthrough/src/db/queries/task-counts.ts +1 -1
  306. package/samples/apps/ui-walkthrough/src/features/billing/feature.ts +7 -0
  307. package/samples/apps/ui-walkthrough/src/features/billing/i18n.ts +2 -0
  308. package/samples/apps/use-all-bundled/feature-manifest.json +4 -4
  309. package/samples/apps/use-all-bundled/package.json +4 -0
  310. package/samples/apps/use-all-bundled/scripts/check-coverage.ts +2 -2
  311. package/samples/apps/use-all-bundled/src/app/auth-constants.ts +1 -1
  312. package/samples/apps/use-all-bundled/src/app/cap-overview-caps.ts +2 -2
  313. package/samples/apps/use-all-bundled/src/app/dev-app-options.ts +1 -1
  314. package/samples/apps/use-all-bundled/src/app/seed-documents.ts +1 -1
  315. package/samples/apps/use-all-bundled/src/app/seed.ts +11 -5
  316. package/samples/apps/use-all-bundled/src/run-config.ts +55 -56
  317. package/samples/apps/user-data-rights-demo/README.md +2 -2
  318. package/samples/apps/user-data-rights-demo/package.json +3 -0
  319. package/samples/apps/user-data-rights-demo/src/run-config.ts +7 -7
  320. package/samples/apps/workspaces/package.json +3 -0
  321. package/samples/recipes/access-control/package.json +3 -0
  322. package/samples/recipes/anonymous-access/package.json +3 -0
  323. package/samples/recipes/anonymous-access-multitenant/package.json +3 -0
  324. package/samples/recipes/apex-landing/package.json +1 -0
  325. package/samples/recipes/apex-surface-auth/package.json +3 -0
  326. package/samples/recipes/apex-surface-auth/src/feature.ts +2 -2
  327. package/samples/recipes/api-worker-split/package.json +3 -0
  328. package/samples/recipes/api-worker-split/src/feature.ts +1 -2
  329. package/samples/recipes/auth-claims/package.json +3 -0
  330. package/samples/recipes/auth-foundation-providers/src/feature.ts +1 -1
  331. package/samples/recipes/auth-mfa/package.json +3 -0
  332. package/samples/recipes/basic-entity/package.json +3 -0
  333. package/samples/recipes/chat-channels/package.json +3 -0
  334. package/samples/recipes/compliance-profiles-demo/package.json +3 -0
  335. package/samples/recipes/cross-feature-events/package.json +3 -1
  336. package/samples/recipes/cross-feature-events/src/feature.ts +1 -1
  337. package/samples/recipes/crypto-shredding-hr/package.json +3 -0
  338. package/samples/recipes/currencies-global/package.json +3 -0
  339. package/samples/recipes/currencies-per-tenant/package.json +3 -0
  340. package/samples/recipes/custom-fields-basic/package.json +3 -0
  341. package/samples/recipes/custom-handlers/package.json +3 -0
  342. package/samples/recipes/dashboard-stats/package.json +3 -0
  343. package/samples/recipes/delivery-notifications/package.json +3 -0
  344. package/samples/recipes/e2e-generator/package.json +3 -0
  345. package/samples/recipes/embedded/package.json +3 -0
  346. package/samples/recipes/embedded-entity-form/package.json +1 -0
  347. package/samples/recipes/encrypted-tenant-config/README.md +1 -1
  348. package/samples/recipes/encrypted-tenant-config/package.json +3 -0
  349. package/samples/recipes/error-contract/package.json +3 -0
  350. package/samples/recipes/event-sourcing/package.json +3 -1
  351. package/samples/recipes/event-sourcing/src/feature.ts +16 -20
  352. package/samples/recipes/event-sourcing/tsconfig.json +2 -6
  353. package/samples/recipes/feature-toggles/package.json +3 -0
  354. package/samples/recipes/field-access/package.json +3 -0
  355. package/samples/recipes/files-post-processing/package.json +1 -0
  356. package/samples/recipes/golden-path/README.md +30 -0
  357. package/samples/recipes/golden-path/package.json +11 -0
  358. package/samples/recipes/golden-path/src/feature.ts +70 -0
  359. package/samples/recipes/idempotency/package.json +3 -0
  360. package/samples/recipes/inbound-mail-triage/package.json +3 -0
  361. package/samples/recipes/lane-routing/package.json +3 -0
  362. package/samples/recipes/ledger-banking/package.json +3 -0
  363. package/samples/recipes/ledger-invoicing/package.json +3 -0
  364. package/samples/recipes/legal-pages/package.json +3 -0
  365. package/samples/recipes/lifecycle-hooks/package.json +3 -0
  366. package/samples/recipes/managed-config/package.json +3 -0
  367. package/samples/recipes/managed-pages/package.json +3 -0
  368. package/samples/recipes/notes-history-basic/package.json +3 -0
  369. package/samples/recipes/ownership/package.json +3 -0
  370. package/samples/recipes/pdf-audit-export/package.json +1 -0
  371. package/samples/recipes/pipeline-basics/package.json +3 -0
  372. package/samples/recipes/public-share-token/package.json +3 -0
  373. package/samples/recipes/public-share-token/src/feature.ts +1 -1
  374. package/samples/recipes/rate-limiting/package.json +3 -0
  375. package/samples/recipes/realtime-sse/package.json +3 -0
  376. package/samples/recipes/record-detail-layout/package.json +1 -0
  377. package/samples/recipes/reference-data/package.json +3 -0
  378. package/samples/recipes/relations/package.json +3 -0
  379. package/samples/recipes/screens-nav/package.json +3 -0
  380. package/samples/recipes/search/package.json +3 -0
  381. package/samples/recipes/secrets-demo/package.json +3 -0
  382. package/samples/recipes/security-baseline/src/feature.ts +2 -2
  383. package/samples/recipes/session-revocation/README.md +1 -1
  384. package/samples/recipes/session-revocation/package.json +3 -0
  385. package/samples/recipes/session-revocation/src/feature.ts +1 -1
  386. package/samples/recipes/state-machine/package.json +3 -1
  387. package/samples/recipes/state-machine/src/entities/invoice.ts +2 -2
  388. package/samples/recipes/state-machine/src/events.ts +19 -0
  389. package/samples/recipes/state-machine/src/feature.ts +25 -30
  390. package/samples/recipes/state-machine/src/handlers/_helpers.ts +13 -14
  391. package/samples/recipes/state-machine/src/handlers/create.ts +1 -1
  392. package/samples/recipes/state-machine/src/handlers/transitions.ts +129 -122
  393. package/samples/recipes/state-machine/src/reducer.ts +1 -1
  394. package/samples/recipes/state-machine/tsconfig.json +2 -6
  395. package/samples/recipes/tags-basic/package.json +3 -0
  396. package/samples/recipes/tenant-isolation/package.json +3 -0
  397. package/samples/recipes/tenant-settings/package.json +3 -0
  398. package/samples/recipes/tier-admin/package.json +3 -0
  399. package/samples/recipes/timezones/package.json +3 -0
  400. package/samples/recipes/tsconfig.base.json +1 -1
  401. package/samples/recipes/user-data-rights/package.json +3 -0
  402. package/samples/recipes/user-data-rights/src/feature.ts +6 -2
  403. package/samples/recipes/user-profile/package.json +3 -0
  404. package/samples/recipes/user-profile/src/feature.ts +2 -2
  405. package/samples/recipes/webhook-step/package.json +3 -0
  406. package/samples/recipes/wizard-form/package.json +1 -0
  407. package/samples/recipes/workflow-engine/package.json +3 -0
  408. package/samples/recipes/workflow-engine/src/db/queries/suspended-runs.ts +5 -2
  409. package/samples/recipes/writeform-section/package.json +1 -0
  410. package/packages/bundled-features/src/file-provider-s3-env/feature.ts +0 -58
  411. /package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/env-helper.ts +0 -0
@@ -134,150 +134,153 @@ export function createBillingFoundationFeature<TTier extends string = string>(
134
134
  }),
135
135
  };
136
136
 
137
- return defineFeature(BILLING_FOUNDATION_FEATURE, (r) => {
138
- r.describe(
139
- "Plugin host for subscription billing — manages the `read_subscriptions` projection table and exposes 5 domain events (subscription created/updated/canceled, invoice paid/failed) appended by the foundation's own `billing-foundation:write:process-event` write-handler after provider plugins verify and normalize each webhook. Also manages a separate `read_payments` projection table (one row per one-off-payment) fed by its own `payment-received` event and `billing-foundation:write:process-payment-event` write-handler. Also ships `billing-foundation:write:create-checkout-session` and `billing-foundation:write:create-portal-session` write-handlers, a `billing-foundation:query:subscription:list` query handler, and a `createSubscriptionWebhookRoute` factory for the `/api/subscription/webhook/:providerName` extraRoute. `createBillingFoundationFeature({ baseUrl, catalog })` additionally derives a `billing-foundation:query:billing-plans` query, `start-plan-checkout`/`switch-plan` write-handlers and a dormant billing-plans dashboard screen/panel from the catalog. Also ships `billing-foundation:write:sync-subscription` (pulls a provider plugin's live subscription state via `retrieveSubscription` and appends drift as a `subscription.updated` event — catches changes made on the provider's own dashboard that never reached us as a webhook) and the `sync-subscriptions` job (manual-trigger + runOnBoot, perTenant) that dispatches it. Low-level building block — use `subscription-stripe` or `subscription-mollie` unless you are writing a new payment provider.",
140
- );
141
- r.uiHints({
142
- displayLabel: "Billing · Foundation",
143
- category: "billing",
144
- recommended: false,
145
- });
146
- r.requires({ features: ["tenant-lifecycle", "compliance-profiles"] });
147
- // 5 fine-grained domain-events. All 5 share the same payload shape (a
148
- // subscription-state snapshot); the event type tags what happened.
149
- // Future consumers (billing-history, accounting) listen directly on
150
- // the event type, no payload discriminator needed.
151
- // piiFields: "none" — provider ids are tenantOwned ciphertext, not plaintext personal data.
152
- r.defineEvent(SUBSCRIPTION_CREATED_EVENT_SHORT, subscriptionEventPayloadSchema, {
153
- piiFields: "none",
154
- });
155
- r.defineEvent(SUBSCRIPTION_UPDATED_EVENT_SHORT, subscriptionEventPayloadSchema, {
156
- piiFields: "none",
157
- });
158
- r.defineEvent(SUBSCRIPTION_CANCELED_EVENT_SHORT, subscriptionEventPayloadSchema, {
159
- piiFields: "none",
160
- });
161
- r.defineEvent(INVOICE_PAID_EVENT_SHORT, subscriptionEventPayloadSchema, { piiFields: "none" });
162
- r.defineEvent(INVOICE_PAYMENT_FAILED_EVENT_SHORT, subscriptionEventPayloadSchema, {
163
- piiFields: "none",
164
- });
165
- // Own event, own aggregate-type — a one-off-payment is not a subscription
166
- // state transition. piiFields: "none" for the same reason as the 5 above:
167
- // providerCustomerId is tenantOwned ciphertext, not plaintext personal data.
168
- r.defineEvent(PAYMENT_RECEIVED_EVENT_SHORT, paymentEventPayloadSchema, { piiFields: "none" });
137
+ return defineFeature(
138
+ BILLING_FOUNDATION_FEATURE,
139
+ (r) => {
140
+ r.describe(
141
+ "Plugin host for subscription billing — manages the `read_subscriptions` projection table and exposes 5 domain events (subscription created/updated/canceled, invoice paid/failed) appended by the foundation's own `billing-foundation:write:process-event` write-handler after provider plugins verify and normalize each webhook. Also manages a separate `read_payments` projection table (one row per one-off-payment) fed by its own `payment-received` event and `billing-foundation:write:process-payment-event` write-handler. Also ships `billing-foundation:write:create-checkout-session` and `billing-foundation:write:create-portal-session` write-handlers, a `billing-foundation:query:subscription:list` query handler, and a `createSubscriptionWebhookRoute` factory for the `/api/subscription/webhook/:providerName` extraRoute. `createBillingFoundationFeature({ baseUrl, catalog })` additionally derives a `billing-foundation:query:billing-plans` query, `start-plan-checkout`/`switch-plan` write-handlers and a dormant billing-plans dashboard screen/panel from the catalog. Also ships `billing-foundation:write:sync-subscription` (pulls a provider plugin's live subscription state via `retrieveSubscription` and appends drift as a `subscription.updated` event — catches changes made on the provider's own dashboard that never reached us as a webhook) and the `sync-subscriptions` job (manual-trigger + runOnBoot, perTenant) that dispatches it. Low-level building block — use `subscription-stripe` or `subscription-mollie` unless you are writing a new payment provider.",
142
+ );
143
+ r.uiHints({
144
+ displayLabel: "Billing · Foundation",
145
+ category: "billing",
146
+ recommended: false,
147
+ });
148
+ r.requires({ features: ["tenant-lifecycle", "compliance-profiles"] });
149
+ // 5 fine-grained domain-events. All 5 share the same payload shape (a
150
+ // subscription-state snapshot); the event type tags what happened.
151
+ // Future consumers (billing-history, accounting) listen directly on
152
+ // the event type, no payload discriminator needed.
153
+ // piiFields: "none" — provider ids are tenantOwned ciphertext, not plaintext personal data.
154
+ r.defineEvent(SUBSCRIPTION_CREATED_EVENT_SHORT, subscriptionEventPayloadSchema, {
155
+ piiFields: "none",
156
+ });
157
+ r.defineEvent(SUBSCRIPTION_UPDATED_EVENT_SHORT, subscriptionEventPayloadSchema, {
158
+ piiFields: "none",
159
+ });
160
+ r.defineEvent(SUBSCRIPTION_CANCELED_EVENT_SHORT, subscriptionEventPayloadSchema, {
161
+ piiFields: "none",
162
+ });
163
+ r.defineEvent(INVOICE_PAID_EVENT_SHORT, subscriptionEventPayloadSchema, {
164
+ piiFields: "none",
165
+ });
166
+ r.defineEvent(INVOICE_PAYMENT_FAILED_EVENT_SHORT, subscriptionEventPayloadSchema, {
167
+ piiFields: "none",
168
+ });
169
+ // Own event, own aggregate-type — a one-off-payment is not a subscription
170
+ // state transition. piiFields: "none" for the same reason as the 5 above:
171
+ // providerCustomerId is tenantOwned ciphertext, not plaintext personal data.
172
+ r.defineEvent(PAYMENT_RECEIVED_EVENT_SHORT, paymentEventPayloadSchema, { piiFields: "none" });
169
173
 
170
- // Inline projection: materialized current state in `read_subscriptions`.
171
- // Apply runs in the same TX as ctx.unsafeAppendEvent — read-your-own-
172
- // write without a dispatcher tick.
173
- r.projection({
174
- name: "subscription",
175
- source: SUBSCRIPTION_AGGREGATE_TYPE,
176
- table: subscriptionsProjectionTable,
177
- entity: subscriptionEntity,
178
- apply: {
179
- [SUBSCRIPTION_CREATED_EVENT_QN]: applySubscriptionCreated,
180
- [SUBSCRIPTION_UPDATED_EVENT_QN]: applySubscriptionUpdated,
181
- [SUBSCRIPTION_CANCELED_EVENT_QN]: applySubscriptionCanceled,
182
- [INVOICE_PAID_EVENT_QN]: applyInvoicePaid,
183
- [INVOICE_PAYMENT_FAILED_EVENT_QN]: applyInvoicePaymentFailed,
184
- },
185
- });
174
+ // Inline projection: materialized current state in `read_subscriptions`.
175
+ // Apply runs in the same TX as ctx.unsafeAppendEvent — read-your-own-
176
+ // write without a dispatcher tick.
177
+ r.projection({
178
+ name: "subscription",
179
+ source: SUBSCRIPTION_AGGREGATE_TYPE,
180
+ table: subscriptionsProjectionTable,
181
+ entity: subscriptionEntity,
182
+ apply: {
183
+ [SUBSCRIPTION_CREATED_EVENT_QN]: applySubscriptionCreated,
184
+ [SUBSCRIPTION_UPDATED_EVENT_QN]: applySubscriptionUpdated,
185
+ [SUBSCRIPTION_CANCELED_EVENT_QN]: applySubscriptionCanceled,
186
+ [INVOICE_PAID_EVENT_QN]: applyInvoicePaid,
187
+ [INVOICE_PAYMENT_FAILED_EVENT_QN]: applyInvoicePaymentFailed,
188
+ },
189
+ });
186
190
 
187
- // Second inline projection: `read_payments`, one row per one-off-payment.
188
- r.projection({
189
- name: "payment",
190
- source: PAYMENT_AGGREGATE_TYPE,
191
- table: paymentsProjectionTable,
192
- entity: paymentEntity,
193
- apply: {
194
- [PAYMENT_RECEIVED_EVENT_QN]: applyPaymentReceived,
195
- },
196
- });
191
+ // Second inline projection: `read_payments`, one row per one-off-payment.
192
+ r.projection({
193
+ name: "payment",
194
+ source: PAYMENT_AGGREGATE_TYPE,
195
+ table: paymentsProjectionTable,
196
+ entity: paymentEntity,
197
+ apply: {
198
+ [PAYMENT_RECEIVED_EVENT_QN]: applyPaymentReceived,
199
+ },
200
+ });
197
201
 
198
- // Plugin extension-point. Provider-Plugins registrieren sich hier.
199
- r.extendsRegistrar(SUBSCRIPTION_PROVIDER_EXTENSION, {
200
- onRegister: () => {
201
- // No side-effects at register-time.
202
- },
203
- });
202
+ // Plugin extension-point. Provider-Plugins registrieren sich hier.
203
+ r.extendsRegistrar(SUBSCRIPTION_PROVIDER_EXTENSION, {
204
+ onRegister: () => {
205
+ // No side-effects at register-time.
206
+ },
207
+ });
204
208
 
205
- // Custom write-handlers:
206
- // - process-event: programmatic entry-point vom webhook-handler;
207
- // dispatcht zu type-passendem appendEvent
208
- // - create-checkout-session: bare priceId-driven checkout (hardened,
209
- // see checkout-core)
210
- // - create-portal-session: Tenant-Admin "Manage Subscription"-flow
211
- r.writeHandler(createProcessEventHandler(widened.now));
212
- r.writeHandler(createCheckoutSessionHandler(widened));
213
- r.writeHandler(createPortalSessionHandler(widened));
214
- // - process-payment-event: programmatic entry-point from the webhook-
215
- // handler for one-off-payments; appends onto the payment-aggregate
216
- r.writeHandler(processPaymentEventHandler);
217
- // - sync-subscription: backfill entry-point for the sync-subscriptions
218
- // job below; pulls the live provider state and appends drift as a
219
- // subscription.updated event. Registered unconditionally (not
220
- // catalog-gated) — it operates on whatever subscription already
221
- // exists for the tenant, independent of the billing-plans catalog.
222
- r.writeHandler(syncSubscriptionHandler);
209
+ // Custom write-handlers:
210
+ // - process-event: programmatic entry-point vom webhook-handler;
211
+ // dispatcht zu type-passendem appendEvent
212
+ // - create-checkout-session: bare priceId-driven checkout (hardened,
213
+ // see checkout-core)
214
+ // - create-portal-session: Tenant-Admin "Manage Subscription"-flow
215
+ r.writeHandler(createProcessEventHandler(widened.now));
216
+ r.writeHandler(createCheckoutSessionHandler(widened));
217
+ r.writeHandler(createPortalSessionHandler(widened));
218
+ // - process-payment-event: programmatic entry-point from the webhook-
219
+ // handler for one-off-payments; appends onto the payment-aggregate
220
+ r.writeHandler(processPaymentEventHandler);
221
+ // - sync-subscription: backfill entry-point for the sync-subscriptions
222
+ // job below; pulls the live provider state and appends drift as a
223
+ // subscription.updated event. Registered unconditionally (not
224
+ // catalog-gated) — it operates on whatever subscription already
225
+ // exists for the tenant, independent of the billing-plans catalog.
226
+ r.writeHandler(syncSubscriptionHandler);
223
227
 
224
- // Custom list-query on the subscription-projection (raw drizzle
225
- // table; no r.entity since writes go through projection-apply).
226
- r.queryHandler(listSubscriptionsQuery);
228
+ // Custom list-query on the subscription-projection (raw drizzle
229
+ // table; no r.entity since writes go through projection-apply).
230
+ r.queryHandler(listSubscriptionsQuery);
227
231
 
228
- // Error-keys from checkout-core (redirect-origin, unknown-price, ...)
229
- // fire from create-checkout-session even without a catalog — register
230
- // unconditionally rather than splitting the i18n surface by option.
231
- r.translations({ keys: BILLING_FOUNDATION_I18N });
232
- if (widened.consumerProtection) {
233
- registerConsumerProtection(r, widened, widened.consumerProtection);
234
- }
232
+ // Error-keys from checkout-core (redirect-origin, unknown-price, ...)
233
+ // fire from create-checkout-session even without a catalog — register
234
+ // unconditionally rather than splitting the i18n surface by option.
235
+ r.translations({ keys: BILLING_FOUNDATION_I18N });
236
+ if (widened.consumerProtection) {
237
+ registerConsumerProtection(r, widened, widened.consumerProtection);
238
+ }
235
239
 
236
- if (widened.catalog) {
237
- const { catalog } = widened;
238
- r.queryHandler(createBillingPlansQuery(widened, catalog));
239
- r.writeHandler(createStartPlanCheckoutHandler(widened, catalog));
240
- r.writeHandler(createSwitchPlanHandler(widened, catalog));
241
- r.screen(createBillingPlansScreen(catalog.viewRoles));
242
- }
240
+ if (widened.catalog) {
241
+ const { catalog } = widened;
242
+ r.queryHandler(createBillingPlansQuery(widened, catalog));
243
+ r.writeHandler(createStartPlanCheckoutHandler(widened, catalog));
244
+ r.writeHandler(createSwitchPlanHandler(widened, catalog));
245
+ r.screen(createBillingPlansScreen(catalog.viewRoles));
246
+ }
243
247
 
244
- // Backfill job: catches provider-side drift (e.g. a cancel_at set on
245
- // the provider's own dashboard) that never reached us as a webhook.
246
- // manual-trigger + runOnBoot (not cron) — this is an on-demand/boot
247
- // reconciliation pass, not a recurring sweep; an app that wants a
248
- // recurring sync can dispatch billing-foundation:job:sync-subscriptions
249
- // from its own cron job. perTenant + runOnBoot are compatible (only
250
- // bootGate is not). Registered unconditionally, same reasoning as the
251
- // sync-subscription write-handler above.
252
- r.job({
253
- name: "sync-subscriptions",
254
- trigger: { manual: true },
255
- perTenant: true,
256
- runOnBoot: true,
257
- handler: async (_payload, ctx) => {
258
- const result = await ctx.write(SubscriptionFoundationHandlers.syncSubscription, {});
259
- if (!result.isSuccess) {
260
- throw new Error(
261
- `billing-foundation:sync-subscriptions: sync-subscription write failed: ${JSON.stringify(result.error)}`,
262
- );
263
- }
264
- ctx.log.info(`[billing-foundation:sync-subscriptions] ${JSON.stringify(result.data)}`);
265
- },
266
- });
248
+ // Backfill job: catches provider-side drift (e.g. a cancel_at set on
249
+ // the provider's own dashboard) that never reached us as a webhook.
250
+ // manual-trigger + runOnBoot (not cron) — this is an on-demand/boot
251
+ // reconciliation pass, not a recurring sweep; an app that wants a
252
+ // recurring sync can dispatch billing-foundation:job:sync-subscriptions
253
+ // from its own cron job. perTenant + runOnBoot are compatible (only
254
+ // bootGate is not). Registered unconditionally, same reasoning as the
255
+ // sync-subscription write-handler above.
256
+ r.job({
257
+ name: "sync-subscriptions",
258
+ trigger: { manual: true },
259
+ perTenant: true,
260
+ runOnBoot: true,
261
+ handler: async (_payload, ctx) => {
262
+ const result = await ctx.write(SubscriptionFoundationHandlers.syncSubscription, {});
263
+ if (!result.isSuccess) {
264
+ throw new Error(
265
+ `billing-foundation:sync-subscriptions: sync-subscription write failed: ${JSON.stringify(result.error)}`,
266
+ );
267
+ }
268
+ ctx.log.info(`[billing-foundation:sync-subscriptions] ${JSON.stringify(result.data)}`);
269
+ },
270
+ });
267
271
 
268
- r.useExtension(EXT_TENANT_DATA, "subscription", {
269
- destroy: subscriptionTenantDestroyHook,
270
- escapeHatch: { reason: SUBSCRIPTION_TENANT_DESTROY_ARCHIVE_REASON },
271
- });
272
- r.useExtension(EXT_TENANT_DATA, "payment", {
273
- destroy: paymentTenantDestroyHook,
274
- escapeHatch: { reason: PAYMENT_TENANT_DESTROY_ARCHIVE_REASON },
275
- });
276
- });
272
+ r.useExtension(EXT_TENANT_DATA, "subscription", {
273
+ destroy: subscriptionTenantDestroyHook,
274
+ escapeHatch: { reason: SUBSCRIPTION_TENANT_DESTROY_ARCHIVE_REASON },
275
+ });
276
+ r.useExtension(EXT_TENANT_DATA, "payment", {
277
+ destroy: paymentTenantDestroyHook,
278
+ escapeHatch: { reason: PAYMENT_TENANT_DESTROY_ARCHIVE_REASON },
279
+ });
280
+ },
281
+ Object.keys(options).length === 0 ? { dedupeOptions: {} } : undefined,
282
+ );
277
283
  }
278
284
 
279
- // Back-compat: existing consumers importing the plain const keep working
280
- // unchanged (no baseUrl/catalog — create-checkout-session's redirect-origin
281
- // check then rejects every call as UnconfiguredError, matching the
282
- // changes.json migration note).
285
+ /** @deprecated Use createBillingFoundationFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
283
286
  export const billingFoundationFeature = createBillingFoundationFeature();
@@ -13,11 +13,11 @@
13
13
  // returnPath, or baseUrl itself) — the client no longer supplies one, so
14
14
  // there is no client-controlled redirect to harden against.
15
15
 
16
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
17
16
  import {
18
17
  configuredPiiSubjectKms,
19
18
  decryptPiiFieldValues,
20
19
  } from "@cosmicdrift/kumiko-framework/crypto";
20
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
21
21
  import type { WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
22
22
  import * as z from "zod";
23
23
  import { subscriptionAggregateId } from "../aggregate-id.js";
@@ -15,11 +15,12 @@
15
15
  // import). setupTestStack pusht sie automatisch via r.projection.table.
16
16
 
17
17
  import {
18
+ buildEntityTable,
19
+ type EntityTableMeta,
18
20
  insertOnConflictDoNothing,
19
21
  requireEntityTableMeta,
20
22
  upsertOnConflict,
21
- } from "@cosmicdrift/kumiko-framework/bun-db";
22
- import { buildEntityTable, type EntityTableMeta } from "@cosmicdrift/kumiko-framework/db";
23
+ } from "@cosmicdrift/kumiko-framework/db";
23
24
  import { defineApply } from "@cosmicdrift/kumiko-framework/engine";
24
25
  import { paymentRowId } from "./aggregate-id.js";
25
26
  import { paymentEntity, subscriptionEntity } from "./entities.js";
@@ -1,6 +1,8 @@
1
1
  import type { CapCounterContext } from "./book-cap-usage.js";
2
2
  import {
3
3
  type CalendarCapReservation,
4
+ consumeCalendarCapReservation,
5
+ releaseCapReservation,
4
6
  releaseExpiredCapReservations,
5
7
  reserveCalendarCap,
6
8
  settleCalendarCapReservation,
@@ -20,10 +22,12 @@ export type CalendarCapUsageReservationSpec = Omit<CalendarCapDef, "amount" | "n
20
22
  };
21
23
 
22
24
  export type CalendarCapUsageReservation = {
25
+ readonly reservationId: string;
23
26
  readonly amount: number;
24
27
  // Counter value right after this reservation was booked.
25
28
  readonly counterValue: number;
26
29
  // Replaces the reserved amount with the actual one; rejects a second settle and one after release.
30
+ // actualAmount is the total used, including units consumed through a handle.
27
31
  settle(actualAmount: number): Promise<void>;
28
32
  // Gives the reserved amount back; a no-op once settled.
29
33
  release(): Promise<void>;
@@ -72,6 +76,7 @@ export async function reserveCalendarCapUsage(
72
76
  let state: ReservationState = "open";
73
77
 
74
78
  return {
79
+ reservationId: reservation.reservationId,
75
80
  amount: spec.amount,
76
81
  counterValue: reservation.counterValue,
77
82
  async settle(actualAmount) {
@@ -83,7 +88,11 @@ export async function reserveCalendarCapUsage(
83
88
  await settleCalendarCapReservation(
84
89
  ctx,
85
90
  reservation.reservationId,
86
- { capName: spec.capName, periodStartIso: spec.periodStartIso, actualAmount },
91
+ {
92
+ capName: spec.capName,
93
+ periodStartIso: spec.periodStartIso,
94
+ actualAmount,
95
+ },
87
96
  outsideTransaction,
88
97
  );
89
98
  } catch (error) {
@@ -99,3 +108,45 @@ export async function reserveCalendarCapUsage(
99
108
  },
100
109
  };
101
110
  }
111
+
112
+ export type CalendarCapReservationHandleSpec = Pick<
113
+ CalendarCapUsageReservationSpec,
114
+ "capName" | "periodStartIso" | "outsideTransaction"
115
+ >;
116
+
117
+ export type CalendarCapReservationHandle = {
118
+ // Moves units from reserved to booked, counter unchanged; rejects more than the still-reserved rest.
119
+ consume(units: number): Promise<void>;
120
+ // Gives back the unconsumed rest; a no-op once settled or already released.
121
+ release(): Promise<void>;
122
+ };
123
+
124
+ // Addresses a reservation by id so a job can consume it per unit; capName and period are needed
125
+ // because the row may already be swept, in which case consume books the units directly.
126
+ export function calendarCapReservationHandle(
127
+ ctx: CapCounterContext,
128
+ reservationId: string,
129
+ spec: CalendarCapReservationHandleSpec,
130
+ ): CalendarCapReservationHandle {
131
+ const outsideTransaction = spec.outsideTransaction ?? true;
132
+ let released = false;
133
+ return {
134
+ async consume(units) {
135
+ if (released) {
136
+ throw new Error(`cap-counter: reservation for "${spec.capName}" is already released`);
137
+ }
138
+ await consumeCalendarCapReservation(
139
+ ctx,
140
+ reservationId,
141
+ { capName: spec.capName, periodStartIso: spec.periodStartIso, units },
142
+ outsideTransaction,
143
+ );
144
+ },
145
+ async release() {
146
+ // skip: release is idempotent, a second call has nothing left to give back
147
+ if (released) return;
148
+ await releaseCapReservation(ctx, reservationId, outsideTransaction);
149
+ released = true;
150
+ },
151
+ };
152
+ }