@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.387.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -57
- package/dist/agent-tools/tool-catalog.js +1 -1
- package/dist/audit/screens.js +1 -1
- package/dist/auth-email-password/feature.js +1 -1
- package/dist/auth-email-password/handlers/change-password.write.js +3 -3
- package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
- package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
- package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
- package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
- package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
- package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
- package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
- package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/login.write.js +1 -1
- package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
- package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
- package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
- package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
- package/dist/auth-email-password/index.js +5 -5
- package/dist/auth-email-password/lockout-store.js +1 -1
- package/dist/auth-email-password/seeding.d.ts +42 -45
- package/dist/auth-email-password/seeding.js +51 -53
- package/dist/auth-email-password/signup-token-store.js +8 -8
- package/dist/auth-email-password/testing.js +3 -3
- package/dist/auth-email-password/web/auth-client.d.ts +2 -2
- package/dist/auth-email-password/web/auth-client.js +36 -37
- package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
- package/dist/auth-email-password/web/auth-gate.js +15 -16
- package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
- package/dist/auth-email-password/web/client-plugin.js +4 -5
- package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
- package/dist/auth-email-password/web/constants.js +3 -3
- package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
- package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
- package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
- package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
- package/dist/auth-email-password/web/index.js +5 -5
- package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
- package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
- package/dist/auth-email-password/web/login-screen.d.ts +1 -1
- package/dist/auth-email-password/web/login-screen.js +2 -3
- package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
- package/dist/auth-email-password/web/reset-password-screen.js +12 -13
- package/dist/auth-email-password/web/session.d.ts +10 -9
- package/dist/auth-email-password/web/session.js +28 -29
- package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
- package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
- package/dist/auth-email-password/web/signup-screen.js +13 -13
- package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
- package/dist/auth-email-password/web/tenant-switcher.js +21 -22
- package/dist/auth-email-password/web/use-shell-user.js +12 -13
- package/dist/auth-email-password/web/user-menu.d.ts +4 -4
- package/dist/auth-email-password/web/user-menu.js +12 -13
- package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
- package/dist/auth-email-password/web/verify-email-screen.js +9 -10
- package/dist/auth-foundation/boot-checks.js +4 -4
- package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
- package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
- package/dist/auth-foundation/types.js +2 -2
- package/dist/auth-mfa/handlers/disable.write.js +3 -3
- package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
- package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
- package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
- package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
- package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
- package/dist/auth-mfa/handlers/verify.write.js +1 -1
- package/dist/auth-mfa/token-secrets.js +1 -1
- package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
- package/dist/auth-mfa/web/client-plugin.js +1 -1
- package/dist/auth-mfa/web/i18n.js +3 -3
- package/dist/auth-mfa/web/index.js +4 -4
- package/dist/auth-mfa/web/mfa-client.js +17 -16
- package/dist/auth-mfa/web/mfa-verify-screen.js +6 -6
- package/dist/billing-foundation/aggregate-id.d.ts +5 -5
- package/dist/billing-foundation/aggregate-id.js +10 -11
- package/dist/billing-foundation/entities.js +27 -27
- package/dist/billing-foundation/events.js +18 -17
- package/dist/billing-foundation/feature.js +42 -43
- package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
- package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
- package/dist/billing-foundation/handlers/create-checkout-session.write.js +18 -17
- package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
- package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
- package/dist/billing-foundation/handlers/process-event.write.js +20 -20
- package/dist/billing-foundation/projection.d.ts +15 -11
- package/dist/billing-foundation/projection.js +38 -37
- package/dist/billing-foundation/subscription-tier-sync.js +3 -3
- package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
- package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
- package/dist/billing-foundation/types.d.ts +40 -41
- package/dist/billing-foundation/types.js +20 -20
- package/dist/billing-foundation/web/billing-plans-panel.js +4 -4
- package/dist/cap-counter/aggregate-id.js +8 -9
- package/dist/cap-counter/constants.js +11 -12
- package/dist/cap-counter/enforce-cap.d.ts +59 -62
- package/dist/cap-counter/enforce-cap.js +47 -48
- package/dist/cap-counter/entity.js +29 -29
- package/dist/cap-counter/feature.js +34 -35
- package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
- package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
- package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
- package/dist/cap-counter/stock-cap-guard.js +1 -1
- package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
- package/dist/channel-email/smtp-transport.d.ts +18 -17
- package/dist/channel-email/smtp-transport.js +24 -21
- package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
- package/dist/compliance-profiles/feature.js +4 -4
- package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
- package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
- package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
- package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
- package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
- package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
- package/dist/compliance-profiles/schema/profile-selection.js +18 -23
- package/dist/compliance-profiles/seeding.js +14 -15
- package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
- package/dist/compliance-profiles-ops/index.js +2 -2
- package/dist/config/handlers/readiness.query.d.ts +4 -4
- package/dist/config/handlers/readiness.query.js +1 -1
- package/dist/config/handlers/reencrypt.job.js +4 -5
- package/dist/config/handlers/set.write.js +4 -4
- package/dist/config/resolver.js +4 -4
- package/dist/config/table.js +10 -10
- package/dist/config/write-helpers.js +1 -1
- package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
- package/dist/crypto-shredding/handlers/forget-subject.write.js +12 -11
- package/dist/custom-fields/aggregate-id.d.ts +12 -13
- package/dist/custom-fields/aggregate-id.js +16 -17
- package/dist/custom-fields/entity.js +49 -47
- package/dist/custom-fields/events.js +7 -8
- package/dist/custom-fields/feature.d.ts +14 -14
- package/dist/custom-fields/feature.js +53 -54
- package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
- package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
- package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
- package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
- package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
- package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
- package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
- package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
- package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
- package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
- package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
- package/dist/custom-fields/lib/field-access.js +2 -2
- package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
- package/dist/custom-fields/lib/quota.js +1 -1
- package/dist/custom-fields/lib/value-schema.js +10 -12
- package/dist/custom-fields/run-retention.js +3 -3
- package/dist/custom-fields/schemas.js +14 -14
- package/dist/custom-fields/web/client-plugin.js +2 -5
- package/dist/custom-fields/web/constants.js +2 -2
- package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
- package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
- package/dist/custom-fields/wire-for-entity.js +65 -67
- package/dist/custom-fields/wire-user-data-rights.js +3 -3
- package/dist/data-retention/_internal/parse-override.js +2 -3
- package/dist/data-retention/feature.js +11 -18
- package/dist/data-retention/handlers/policy-for.query.js +6 -6
- package/dist/data-retention/keep-for.d.ts +7 -7
- package/dist/data-retention/keep-for.js +15 -15
- package/dist/data-retention/override-schema.d.ts +3 -4
- package/dist/data-retention/override-schema.js +13 -15
- package/dist/data-retention/presets.d.ts +4 -5
- package/dist/data-retention/presets.js +18 -23
- package/dist/data-retention/resolve-tenant-preset.js +17 -16
- package/dist/data-retention/resolver.d.ts +12 -12
- package/dist/data-retention/resolver.js +24 -23
- package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
- package/dist/data-retention/run-retention-cleanup.js +61 -51
- package/dist/data-retention/schema/tenant-retention-override.js +13 -11
- package/dist/delivery/feature.js +2 -2
- package/dist/delivery/handlers/log.query.js +1 -1
- package/dist/delivery/tables.js +9 -8
- package/dist/delivery/unsubscribe.js +4 -4
- package/dist/document-ingest-foundation/entity.js +4 -4
- package/dist/document-ingest-foundation/events.js +2 -2
- package/dist/document-ingest-foundation/feature.js +2 -2
- package/dist/document-ingest-foundation/pages.js +1 -1
- package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
- package/dist/feature-toggles/compose-tier-resolver.js +1 -1
- package/dist/feature-toggles/feature.js +1 -1
- package/dist/feature-toggles/global-feature-state-table.js +1 -1
- package/dist/feature-toggles/handlers/registered.query.js +5 -5
- package/dist/feature-toggles/toggle-sync-signal.js +1 -1
- package/dist/feature-toggles/web/constants.js +1 -1
- package/dist/file-derivatives/feature.d.ts +1 -1
- package/dist/file-derivatives/feature.js +1 -1
- package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
- package/dist/file-derivatives/presets.js +1 -1
- package/dist/file-foundation/feature.js +6 -6
- package/dist/file-provider-inmemory/feature.d.ts +1 -1
- package/dist/file-provider-inmemory/feature.js +16 -16
- package/dist/file-provider-s3/feature.js +16 -16
- package/dist/file-provider-s3/lib/s3-provider.js +6 -6
- package/dist/files/feature.js +6 -6
- package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
- package/dist/files-tenant-data/hooks.js +24 -26
- package/dist/files-tenant-data/index.js +1 -1
- package/dist/folders/feature.d.ts +1 -1
- package/dist/folders/web/folder-manager.js +2 -2
- package/dist/folders/web/tree.js +5 -5
- package/dist/form-draft/db/queries/cleanup.js +1 -1
- package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
- package/dist/form-draft/entity.js +3 -3
- package/dist/form-draft/feature.js +4 -5
- package/dist/form-draft/handlers/discard.write.js +1 -1
- package/dist/form-draft/release-file-refs.js +6 -6
- package/dist/form-draft/schemas.js +3 -3
- package/dist/form-draft/web/constants.js +0 -2
- package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
- package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
- package/dist/inbound-mail-foundation/connect-routes.js +4 -3
- package/dist/inbound-mail-foundation/constants.d.ts +22 -24
- package/dist/inbound-mail-foundation/constants.js +30 -33
- package/dist/inbound-mail-foundation/entities.d.ts +12 -12
- package/dist/inbound-mail-foundation/entities.js +47 -48
- package/dist/inbound-mail-foundation/events.d.ts +4 -3
- package/dist/inbound-mail-foundation/events.js +50 -47
- package/dist/inbound-mail-foundation/feature.js +39 -39
- package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
- package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
- package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
- package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
- package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
- package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
- package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
- package/dist/inbound-mail-foundation/handlers/update-account.write.js +11 -11
- package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
- package/dist/inbound-mail-foundation/oauth-state.js +11 -10
- package/dist/inbound-mail-foundation/projection.d.ts +4 -4
- package/dist/inbound-mail-foundation/projection.js +31 -29
- package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
- package/dist/inbound-mail-foundation/provider-factory.js +9 -9
- package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
- package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
- package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
- package/dist/inbound-mail-foundation/types.d.ts +45 -46
- package/dist/inbound-mail-foundation/types.js +21 -21
- package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
- package/dist/inbound-mail-foundation/watch-supervisor.js +57 -56
- package/dist/inbound-provider-imap/credential-document.js +13 -13
- package/dist/inbound-provider-imap/feature.d.ts +2 -2
- package/dist/inbound-provider-imap/feature.js +42 -40
- package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
- package/dist/inbound-provider-imap/imap-client.js +20 -19
- package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
- package/dist/inbound-provider-inmemory/feature.js +19 -19
- package/dist/jobs/db/queries/retention.js +2 -2
- package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
- package/dist/jobs/events.js +1 -1
- package/dist/jobs/feature.js +5 -6
- package/dist/jobs/handlers/detail.query.js +4 -4
- package/dist/jobs/handlers/list.query.js +1 -1
- package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
- package/dist/jobs/handlers/reindex-entity.job.js +1 -1
- package/dist/jobs/handlers/retry.write.js +1 -1
- package/dist/jobs/job-instant.js +1 -1
- package/dist/jobs/job-run-logger.js +10 -11
- package/dist/jobs/job-run-table.js +3 -3
- package/dist/jobs/screens.js +1 -1
- package/dist/jobs/tenant-job-failure-table.js +1 -1
- package/dist/jobs/tenant-job-run-table.js +1 -1
- package/dist/ledger/entity.js +5 -5
- package/dist/ledger/feature.js +3 -3
- package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
- package/dist/ledger/recurring.js +12 -12
- package/dist/ledger/schemas.js +1 -1
- package/dist/ledger/web/constants.js +2 -2
- package/dist/ledger/web/index.js +7 -7
- package/dist/legal-pages/feature.d.ts +4 -4
- package/dist/legal-pages/feature.js +25 -26
- package/dist/legal-pages/markdown.js +3 -3
- package/dist/legal-pages/web/client-plugin.js +23 -24
- package/dist/legal-pages/web/index.js +0 -1
- package/dist/mail-foundation/feature.d.ts +2 -2
- package/dist/mail-foundation/feature.js +24 -25
- package/dist/mail-transport-inmemory/feature.d.ts +4 -4
- package/dist/mail-transport-inmemory/feature.js +27 -28
- package/dist/mail-transport-smtp/feature.js +20 -20
- package/dist/managed-pages/branding.js +6 -6
- package/dist/managed-pages/feature.d.ts +26 -26
- package/dist/managed-pages/feature.js +34 -34
- package/dist/managed-pages/handlers/by-slug.query.js +5 -6
- package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
- package/dist/managed-pages/handlers/set.write.js +5 -7
- package/dist/managed-pages/screens/page-screens.js +11 -11
- package/dist/managed-pages/seeding.js +8 -8
- package/dist/managed-pages/table.js +13 -12
- package/dist/managed-pages/web/client-plugin.d.ts +1 -1
- package/dist/managed-pages/web/client-plugin.js +5 -5
- package/dist/managed-pages/web/i18n.js +1 -1
- package/dist/notes-history/entity.js +4 -4
- package/dist/notes-history/feature.d.ts +2 -2
- package/dist/notes-history-user-data/hooks.js +1 -1
- package/dist/page-render/layout.js +9 -9
- package/dist/page-render/markdown.js +11 -11
- package/dist/page-render/security-headers.js +7 -6
- package/dist/personal-access-tokens/feature.js +5 -5
- package/dist/personal-access-tokens/roles.js +2 -2
- package/dist/readiness/handlers/status.query.js +3 -3
- package/dist/renderer-foundation/api.js +12 -13
- package/dist/renderer-foundation/constants.js +2 -2
- package/dist/renderer-foundation/feature.js +7 -7
- package/dist/secrets/feature.js +9 -9
- package/dist/secrets/web/constants.js +2 -2
- package/dist/seo/feature.js +3 -3
- package/dist/sessions/constants.d.ts +1 -1
- package/dist/sessions/constants.js +1 -1
- package/dist/sessions/feature.js +8 -8
- package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
- package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
- package/dist/sessions/handlers/revoke.write.js +1 -1
- package/dist/sessions/schema/user-session.js +4 -4
- package/dist/sessions/screens.js +2 -2
- package/dist/sessions/session-callbacks.js +2 -2
- package/dist/sessions/session-revoked-event.js +2 -2
- package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
- package/dist/shared/decrypt-stored-pii.js +1 -1
- package/dist/shared/encrypt-for-direct-write.js +1 -1
- package/dist/shared/map-with-concurrency.js +5 -4
- package/dist/shared/parent-visibility.js +2 -2
- package/dist/shared/password-hashing.js +1 -1
- package/dist/shared/signup-handover.js +1 -2
- package/dist/shared/single-use-token-store.js +1 -1
- package/dist/subscription-mollie/constants.js +15 -17
- package/dist/subscription-mollie/feature.d.ts +17 -18
- package/dist/subscription-mollie/feature.js +24 -24
- package/dist/subscription-mollie/index.js +3 -3
- package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
- package/dist/subscription-mollie/plugin-methods.js +15 -14
- package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
- package/dist/subscription-mollie/verify-webhook.js +27 -27
- package/dist/subscription-stripe/constants.js +4 -6
- package/dist/subscription-stripe/feature.d.ts +14 -14
- package/dist/subscription-stripe/feature.js +35 -34
- package/dist/subscription-stripe/index.js +6 -6
- package/dist/subscription-stripe/plugin-methods.js +18 -18
- package/dist/subscription-stripe/runtime.d.ts +1 -1
- package/dist/subscription-stripe/runtime.js +1 -1
- package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
- package/dist/subscription-stripe/verify-webhook.js +59 -61
- package/dist/tags/feature.d.ts +3 -3
- package/dist/tags/screens.js +1 -1
- package/dist/template-resolver/api.js +10 -10
- package/dist/template-resolver/handlers/find-by-id.query.js +5 -5
- package/dist/template-resolver/handlers/list.query.js +1 -1
- package/dist/template-resolver/handlers/shared.js +2 -2
- package/dist/template-resolver/handlers/template-write.js +3 -3
- package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
- package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
- package/dist/template-resolver/seeding.js +4 -4
- package/dist/template-resolver/table.js +10 -11
- package/dist/template-resolver/web/client-plugin.js +2 -2
- package/dist/tenant/feature.js +7 -7
- package/dist/tenant/handlers/member-directory.query.js +1 -1
- package/dist/tenant/handlers/members.query.js +1 -1
- package/dist/tenant/handlers/team-list.query.js +1 -1
- package/dist/tenant/handlers/tenant-directory.query.js +1 -1
- package/dist/tenant/invitation-table.js +37 -40
- package/dist/tenant/membership-table.js +3 -3
- package/dist/tenant/schema/tenant.js +7 -9
- package/dist/tenant/screens.js +1 -1
- package/dist/tenant/seeding.d.ts +6 -5
- package/dist/tenant/seeding.js +12 -12
- package/dist/tenant/testing.js +5 -6
- package/dist/tenant/web/constants.js +2 -2
- package/dist/tenant-handover/events.js +5 -7
- package/dist/tenant-handover/feature.js +1 -1
- package/dist/tenant-handover/grant.js +1 -1
- package/dist/tenant-handover/handlers/claim.write.js +1 -1
- package/dist/tenant-handover/move-entity-graph.js +8 -9
- package/dist/tenant-handover/signup-handover-provider.js +1 -2
- package/dist/tenant-handover/transfer-graph.js +4 -5
- package/dist/tenant-lifecycle/boot-checks.js +1 -1
- package/dist/tenant-lifecycle/feature.js +1 -1
- package/dist/tenant-settings/constants.js +1 -1
- package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
- package/dist/tenant-settings/tenant-defaults.js +9 -2
- package/dist/tier-engine/aggregate-id.d.ts +11 -11
- package/dist/tier-engine/aggregate-id.js +15 -16
- package/dist/tier-engine/compose-app.d.ts +14 -14
- package/dist/tier-engine/compose-app.js +1 -1
- package/dist/tier-engine/entity.js +18 -19
- package/dist/tier-engine/feature.d.ts +19 -17
- package/dist/tier-engine/feature.js +68 -69
- package/dist/tier-engine/handlers/active-tier.query.js +6 -7
- package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
- package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +5 -5
- package/dist/tier-engine/handlers/set-tenant-tier.write.js +3 -3
- package/dist/tier-engine/tier-resolver.js +2 -2
- package/dist/tier-engine/trial.js +8 -8
- package/dist/tier-engine/web/index.js +4 -4
- package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
- package/dist/user/handlers/create.write.js +4 -4
- package/dist/user/schema/user.d.ts +11 -11
- package/dist/user/schema/user.js +45 -44
- package/dist/user/seeding.d.ts +15 -15
- package/dist/user/seeding.js +28 -28
- package/dist/user/testing.js +3 -3
- package/dist/user-data-rights/audit-download.d.ts +8 -8
- package/dist/user-data-rights/audit-download.js +19 -20
- package/dist/user-data-rights/boot-checks.js +1 -1
- package/dist/user-data-rights/deletion-token.js +1 -1
- package/dist/user-data-rights/feature.d.ts +49 -50
- package/dist/user-data-rights/feature.js +54 -53
- package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
- package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
- package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
- package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
- package/dist/user-data-rights/handlers/export-status.query.js +8 -9
- package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
- package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
- package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
- package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
- package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
- package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
- package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
- package/dist/user-data-rights/handlers/request-export.write.js +42 -41
- package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
- package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
- package/dist/user-data-rights/index.js +8 -10
- package/dist/user-data-rights/lib/default-mailers.js +3 -3
- package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
- package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
- package/dist/user-data-rights/run-export-jobs.js +127 -233
- package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
- package/dist/user-data-rights/run-forget-cleanup.js +63 -82
- package/dist/user-data-rights/run-user-export.d.ts +34 -33
- package/dist/user-data-rights/run-user-export.js +55 -57
- package/dist/user-data-rights/schema/download-attempt.js +11 -11
- package/dist/user-data-rights/schema/download-token.js +37 -41
- package/dist/user-data-rights/schema/export-job.d.ts +4 -4
- package/dist/user-data-rights/schema/export-job.js +65 -67
- package/dist/user-data-rights/token-helpers.d.ts +8 -9
- package/dist/user-data-rights/token-helpers.js +21 -25
- package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
- package/dist/user-data-rights/web/client-plugin.js +1 -1
- package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
- package/dist/user-data-rights/web/constants.js +1 -1
- package/dist/user-data-rights/web/index.js +5 -5
- package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
- package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
- package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
- package/dist/user-data-rights/zip-path.d.ts +15 -15
- package/dist/user-data-rights/zip-path.js +41 -40
- package/dist/user-data-rights-defaults/feature.js +15 -15
- package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
- package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
- package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
- package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
- package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
- package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
- package/dist/user-profile/handlers/change-email.write.js +13 -13
- package/dist/user-profile/index.js +3 -3
- package/dist/user-profile/web/client-plugin.js +1 -1
- package/dist/user-profile/web/constants.js +1 -1
- package/dist/user-profile/web/profile-screen.js +1 -1
- package/dist/workflow-runner/aggregate-id.d.ts +1 -1
- package/dist/workflow-runner/aggregate-id.js +1 -1
- package/dist/workflow-runner/event-subscriber.js +4 -5
- package/dist/workflow-runner/event-trigger.js +4 -17
- package/dist/workflow-runner/feature.js +2 -2
- package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
- package/dist/workflow-runner/pending-projection.js +6 -7
- package/dist/workflow-runner/runner.js +6 -6
- package/dist/workflow-runner/tables.js +6 -6
- package/dist/workflow-runner/workflow-registry.js +1 -1
- package/package.json +10 -10
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
// Inline
|
|
2
|
-
// subscription
|
|
1
|
+
// Inline projection for `read_subscriptions`. Materializes the 5
|
|
2
|
+
// subscription events into one row per tenant.
|
|
3
3
|
//
|
|
4
|
-
// Apply
|
|
5
|
-
//
|
|
6
|
-
// aggregateId (= deterministic uuidv5
|
|
7
|
-
//
|
|
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:**
|
|
10
|
-
// `samples/apps/platform/drizzle/generate.ts`
|
|
11
|
-
// `subscriptionsProjectionTable`
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
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
|
import { buildEntityTable, insertOnConflictDoNothing, requireEntityTableMeta, upsertOnConflict, } from "@cosmicdrift/kumiko-framework/db";
|
|
17
17
|
import { defineApply } from "@cosmicdrift/kumiko-framework/engine";
|
|
18
18
|
import { paymentRowId } from "./aggregate-id.js";
|
|
19
19
|
import { paymentEntity, subscriptionEntity } from "./entities.js";
|
|
20
|
-
// Drizzle
|
|
21
|
-
//
|
|
22
|
-
//
|
|
20
|
+
// This Drizzle table instance is derived from the entity shape and is shared
|
|
21
|
+
// by the projection apply, list query, and get helper so all three use the
|
|
22
|
+
// same column namespace.
|
|
23
23
|
export const subscriptionsProjectionTable = buildEntityTable("subscription", subscriptionEntity);
|
|
24
24
|
// Same production-deployment caveat as subscriptionsProjectionTable above:
|
|
25
25
|
// raw drizzle-pgTable, not an r.entity — apps mounting billing-foundation in
|
|
@@ -27,8 +27,8 @@ export const subscriptionsProjectionTable = buildEntityTable("subscription", sub
|
|
|
27
27
|
export const paymentsProjectionTable = buildEntityTable("payment", paymentEntity);
|
|
28
28
|
// Unbranded metas: the apply functions below ARE the executor of these
|
|
29
29
|
// projections, so they may write through the typed helpers.
|
|
30
|
-
const subscriptionsProjectionMeta = requireEntityTableMeta(subscriptionsProjectionTable, "subscription");
|
|
31
|
-
const paymentsProjectionMeta = requireEntityTableMeta(paymentsProjectionTable, "payment");
|
|
30
|
+
export const subscriptionsProjectionMeta = requireEntityTableMeta(subscriptionsProjectionTable, "subscription");
|
|
31
|
+
export const paymentsProjectionMeta = requireEntityTableMeta(paymentsProjectionTable, "payment");
|
|
32
32
|
// =============================================================================
|
|
33
33
|
// Shared helpers
|
|
34
34
|
// =============================================================================
|
|
@@ -63,10 +63,10 @@ function cancelAtSetFromPayload(p) {
|
|
|
63
63
|
* `getSubscriptionForTenant`'s `lastChangedAt` (staleness check for
|
|
64
64
|
* incomplete subscriptions) depends on that determinism. */
|
|
65
65
|
async function upsert(tx, event, set, fullPayload) {
|
|
66
|
-
// INSERT
|
|
67
|
-
//
|
|
68
|
-
// status+tier),
|
|
69
|
-
//
|
|
66
|
+
// The INSERT fallback requires ALL fields because of NOT NULL constraints.
|
|
67
|
+
// If an update changes only some fields (for example, invoice-payment-failed
|
|
68
|
+
// changes only status+tier), the full payload is still used for the INSERT
|
|
69
|
+
// path, while only the partial `set` is used for ON CONFLICT.
|
|
70
70
|
const insertCols = {
|
|
71
71
|
id: event.aggregateId,
|
|
72
72
|
tenantId: event.tenantId,
|
|
@@ -86,21 +86,21 @@ async function upsert(tx, event, set, fullPayload) {
|
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
// =============================================================================
|
|
89
|
-
// Apply
|
|
89
|
+
// Apply functions — one per event type
|
|
90
90
|
//
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
91
|
+
// All use UPSERT for defensive consistency: an out-of-order event (for
|
|
92
|
+
// example, during a rebuild-from-events) can arrive in any order and still
|
|
93
|
+
// materialize the row correctly.
|
|
94
94
|
// =============================================================================
|
|
95
|
-
/** subscription-created → UPSERT
|
|
96
|
-
* subscriptionAggregateId(tenantId), one row
|
|
97
|
-
* Disney+-
|
|
98
|
-
*
|
|
95
|
+
/** subscription-created → UPSERT with all fields. PK = aggregateId =
|
|
96
|
+
* subscriptionAggregateId(tenantId), with one row per tenant. UPSERT allows
|
|
97
|
+
* the Disney+-change pattern (a second provider sends create for the same
|
|
98
|
+
* tenant) to overwrite the existing row instead of causing a PK conflict. */
|
|
99
99
|
export const applySubscriptionCreated = defineApply(async (event, tx) => {
|
|
100
100
|
const full = fullSetFromPayload(event.payload);
|
|
101
101
|
await upsert(tx, event, { ...full, ...cancelAtSetFromPayload(event.payload) }, event.payload);
|
|
102
102
|
});
|
|
103
|
-
/** subscription-updated → UPSERT
|
|
103
|
+
/** subscription-updated → UPSERT with all fields. */
|
|
104
104
|
export const applySubscriptionUpdated = defineApply(async (event, tx) => {
|
|
105
105
|
const full = fullSetFromPayload(event.payload);
|
|
106
106
|
await upsert(tx, event, { ...full, ...cancelAtSetFromPayload(event.payload) }, event.payload);
|
|
@@ -115,8 +115,9 @@ export const applySubscriptionCanceled = defineApply(async (event, tx) => {
|
|
|
115
115
|
...cancelAtSetFromPayload(p),
|
|
116
116
|
}, p);
|
|
117
117
|
});
|
|
118
|
-
/** invoice-paid → state
|
|
119
|
-
*
|
|
118
|
+
/** invoice-paid → state update (status, tier, currentPeriodEnd).
|
|
119
|
+
* The invoice history itself lives in the event store, so it remains
|
|
120
|
+
* replayable. */
|
|
120
121
|
export const applyInvoicePaid = defineApply(async (event, tx) => {
|
|
121
122
|
const p = event.payload;
|
|
122
123
|
await upsert(tx, event, {
|
|
@@ -126,10 +127,10 @@ export const applyInvoicePaid = defineApply(async (event, tx) => {
|
|
|
126
127
|
...cancelAtSetFromPayload(p),
|
|
127
128
|
}, p);
|
|
128
129
|
});
|
|
129
|
-
/** invoice-payment-failed → status (
|
|
130
|
-
* engine
|
|
131
|
-
*
|
|
132
|
-
*
|
|
130
|
+
/** invoice-payment-failed → status (typically past_due) + tier. The tier
|
|
131
|
+
* engine reads the row and decides whether to downgrade. currentPeriodEnd is
|
|
132
|
+
* intentionally unchanged: the period has not "ended"; payment simply
|
|
133
|
+
* failed. */
|
|
133
134
|
export const applyInvoicePaymentFailed = defineApply(async (event, tx) => {
|
|
134
135
|
const p = event.payload;
|
|
135
136
|
await upsert(tx, event, { status: p.status, tier: p.tier, ...cancelAtSetFromPayload(p) }, p);
|
|
@@ -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
|
-
//
|
|
4
|
-
//
|
|
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
|
import { isTierAssignmentSource, TierAssignmentSources, TierEngineHandlers, TierEngineQueries, tierAssignmentAggregateId, } from "@cosmicdrift/kumiko-bundled-features/tier-engine";
|
|
6
6
|
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
7
7
|
import { subscriptionAggregateId } from "./aggregate-id.js";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { type TenantDataHookCtx } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
export declare const SUBSCRIPTION_TENANT_DESTROY_ARCHIVE_REASON = "tenant-destroy looks up the compliance profile and archives the subscription event-stream before the projection row is redacted/deleted";
|
|
3
3
|
export declare const PAYMENT_TENANT_DESTROY_ARCHIVE_REASON = "tenant-destroy looks up the compliance profile and archives the payment event-stream before the projection rows are redacted/deleted";
|
|
4
|
-
/** Tenant-destroy hook for billing PII
|
|
4
|
+
/** Tenant-destroy hook for billing PII. HGB retains the accounting
|
|
5
5
|
* row but redacts the two provider-subject PII fields; other profiles
|
|
6
6
|
* hard-delete the row. Either way the subscription stream is archived so a
|
|
7
7
|
* future projection rebuild can't resurrect what was erased. */
|
|
8
8
|
export declare function subscriptionTenantDestroyHook(ctx: TenantDataHookCtx): Promise<void>;
|
|
9
|
-
/** Tenant-destroy hook for payment PII
|
|
9
|
+
/** Tenant-destroy hook for payment PII. Unlike subscriptionTenantDestroyHook
|
|
10
10
|
* (one row per tenant, targeted by `id`), a tenant can have many payment
|
|
11
11
|
* rows — the predicate here is `tenantId`, not `id`. The payment-stream
|
|
12
12
|
* itself is still one stream per tenant (paymentAggregateId), so
|
|
@@ -3,7 +3,7 @@ import { archiveStream } from "@cosmicdrift/kumiko-framework/event-store";
|
|
|
3
3
|
import { resolveProfileForTenant } from "../compliance-profiles/index.js";
|
|
4
4
|
import { paymentAggregateId, subscriptionAggregateId } from "./aggregate-id.js";
|
|
5
5
|
import { PAYMENT_AGGREGATE_TYPE, SUBSCRIPTION_AGGREGATE_TYPE } from "./events.js";
|
|
6
|
-
import {
|
|
6
|
+
import { paymentsProjectionMeta, subscriptionsProjectionMeta } from "./projection.js";
|
|
7
7
|
// providerCustomerId/providerSubscriptionId are `personal: "tenant"` on the
|
|
8
8
|
// entity (envelope-encrypted with the tenant subject key, see entities.ts) —
|
|
9
9
|
// eraseSubjectKeys crypto-shreds them for tenants that hard-delete. HGB
|
|
@@ -13,7 +13,7 @@ const REDACTED_PII_VALUE = "[erased]";
|
|
|
13
13
|
// Compliance-profile lookup and event-stream archive both sit outside TenantDb's own methods — need the escape hatch.
|
|
14
14
|
export const SUBSCRIPTION_TENANT_DESTROY_ARCHIVE_REASON = "tenant-destroy looks up the compliance profile and archives the subscription event-stream before the projection row is redacted/deleted";
|
|
15
15
|
export const PAYMENT_TENANT_DESTROY_ARCHIVE_REASON = "tenant-destroy looks up the compliance profile and archives the payment event-stream before the projection rows are redacted/deleted";
|
|
16
|
-
/** Tenant-destroy hook for billing PII
|
|
16
|
+
/** Tenant-destroy hook for billing PII. HGB retains the accounting
|
|
17
17
|
* row but redacts the two provider-subject PII fields; other profiles
|
|
18
18
|
* hard-delete the row. Either way the subscription stream is archived so a
|
|
19
19
|
* future projection rebuild can't resurrect what was erased. */
|
|
@@ -25,10 +25,10 @@ export async function subscriptionTenantDestroyHook(ctx) {
|
|
|
25
25
|
});
|
|
26
26
|
const aggregateId = subscriptionAggregateId(ctx.tenantId);
|
|
27
27
|
if (profile.key === "de-hr-dsgvo-hgb") {
|
|
28
|
-
await ctx.db.updateMany(
|
|
28
|
+
await ctx.db.updateMany(subscriptionsProjectionMeta, { providerCustomerId: REDACTED_PII_VALUE, providerSubscriptionId: REDACTED_PII_VALUE }, { id: aggregateId });
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
31
|
-
await ctx.db.deleteMany(
|
|
31
|
+
await ctx.db.deleteMany(subscriptionsProjectionMeta, { id: aggregateId });
|
|
32
32
|
}
|
|
33
33
|
await archiveStream(ctx.db.unsafeRaw(), {
|
|
34
34
|
tenantId: ctx.tenantId,
|
|
@@ -38,7 +38,7 @@ export async function subscriptionTenantDestroyHook(ctx) {
|
|
|
38
38
|
reason: "tenant_destroy",
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
-
/** Tenant-destroy hook for payment PII
|
|
41
|
+
/** Tenant-destroy hook for payment PII. Unlike subscriptionTenantDestroyHook
|
|
42
42
|
* (one row per tenant, targeted by `id`), a tenant can have many payment
|
|
43
43
|
* rows — the predicate here is `tenantId`, not `id`. The payment-stream
|
|
44
44
|
* itself is still one stream per tenant (paymentAggregateId), so
|
|
@@ -51,10 +51,10 @@ export async function paymentTenantDestroyHook(ctx) {
|
|
|
51
51
|
});
|
|
52
52
|
const aggregateId = paymentAggregateId(ctx.tenantId);
|
|
53
53
|
if (profile.key === "de-hr-dsgvo-hgb") {
|
|
54
|
-
await ctx.db.updateMany(
|
|
54
|
+
await ctx.db.updateMany(paymentsProjectionMeta, { providerCustomerId: REDACTED_PII_VALUE }, { tenantId: ctx.tenantId });
|
|
55
55
|
}
|
|
56
56
|
else {
|
|
57
|
-
await ctx.db.deleteMany(
|
|
57
|
+
await ctx.db.deleteMany(paymentsProjectionMeta, {
|
|
58
58
|
tenantId: ctx.tenantId,
|
|
59
59
|
});
|
|
60
60
|
}
|
|
@@ -12,32 +12,31 @@ export type SubscriptionEvent = {
|
|
|
12
12
|
* `parsed.kind === BillingEventKinds.payment` correctly, because only
|
|
13
13
|
* PaymentEvent["kind"] can take that value. */
|
|
14
14
|
readonly kind?: typeof BillingEventKinds.subscription;
|
|
15
|
-
/** Provider-
|
|
16
|
-
* Stripe: "evt_..."; Mollie: payment-id
|
|
15
|
+
/** Provider-owned event ID — UNIQUE key for idempotency.
|
|
16
|
+
* Stripe: "evt_..."; Mollie: payment-id or subscription-id. */
|
|
17
17
|
readonly providerEventId: string;
|
|
18
18
|
/** Discriminator — welcher Plugin diesen Event geliefert hat. */
|
|
19
19
|
readonly providerName: string;
|
|
20
20
|
/** Normalisierter Event-Type. Plugin filtert provider-spezifische
|
|
21
21
|
* Sub-Types raus (Stripe hat ~80 Event-types, wir kennen 5). */
|
|
22
22
|
readonly type: SubscriptionEventType;
|
|
23
|
-
/**
|
|
24
|
-
*
|
|
23
|
+
/** Platform tenant ID (provider-customer metadata or lookup via
|
|
24
|
+
* providerCustomerId). The plugin performs the resolution. */
|
|
25
25
|
readonly tenantId: string;
|
|
26
26
|
/** Consent id echoed back from checkout metadata; omitted when absent or
|
|
27
27
|
* malformed. */
|
|
28
28
|
readonly consentId?: string;
|
|
29
|
-
/** Provider-
|
|
30
|
-
*
|
|
29
|
+
/** Provider-owned customer ID for later lookup when events lack
|
|
30
|
+
* metadata. */
|
|
31
31
|
readonly providerCustomerId: string;
|
|
32
32
|
/** Provider-eigene subscription-id. */
|
|
33
33
|
readonly providerSubscriptionId: string;
|
|
34
34
|
/** Normalisierter status. */
|
|
35
35
|
readonly status: SubscriptionStatus;
|
|
36
|
-
/** Resolved tier —
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* ignore"). */
|
|
36
|
+
/** Resolved tier — the plugin reads the price ID from the event and
|
|
37
|
+
* maps it through the plugin's `<plugin>:config:price-to-tier` to a
|
|
38
|
+
* tier name. If the price ID is absent from the mapping, the plugin
|
|
39
|
+
* returns null from verifyAndParseWebhook (= "unknown event, ignore"). */
|
|
41
40
|
readonly tier: string;
|
|
42
41
|
/** ISO-timestamp wann die aktuelle Billing-Period endet. */
|
|
43
42
|
readonly currentPeriodEnd: string;
|
|
@@ -106,30 +105,30 @@ export type SubscriptionProviderPlugin = {
|
|
|
106
105
|
*/
|
|
107
106
|
readonly verifyAndParseWebhook: (rawBody: string, headers: Record<string, string>, systemSecrets?: SecretsContext) => Promise<SubscriptionEvent | PaymentEvent | null>;
|
|
108
107
|
/**
|
|
109
|
-
* **Post-tenant-resolution** —
|
|
110
|
-
* `create-checkout-session
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
108
|
+
* **Post-tenant-resolution** — called from the
|
|
109
|
+
* `create-checkout-session` write handler. The plugin builds a
|
|
110
|
+
* provider-specific checkout session and returns its hosted-page URL;
|
|
111
|
+
* the tenant admin is redirected there to complete payment, and the
|
|
112
|
+
* provider sends a `subscription.created` webhook with
|
|
113
|
+
* `metadata.tenantId`.
|
|
115
114
|
*
|
|
116
|
-
* Optional: Apple-IAP
|
|
117
|
-
* Apps
|
|
115
|
+
* Optional: Apple-IAP has no web checkout (everything happens in the app).
|
|
116
|
+
* Apps that use only Apple-IAP omit this field.
|
|
118
117
|
*/
|
|
119
118
|
readonly createCheckoutSession?: (ctx: HandlerContext, options: {
|
|
120
|
-
/** Provider-
|
|
119
|
+
/** Provider-owned price/plan ID that the customer subscribes to. */
|
|
121
120
|
readonly priceId: string;
|
|
122
|
-
/**
|
|
123
|
-
*
|
|
124
|
-
* `verifyAndParseWebhook`
|
|
121
|
+
/** Platform tenant ID — stored as metadata in the checkout session
|
|
122
|
+
* so the subsequent webhook can resolve the tenant (see the
|
|
123
|
+
* `verifyAndParseWebhook` metadata.tenantId lookup). */
|
|
125
124
|
readonly tenantId: string;
|
|
126
|
-
/**
|
|
125
|
+
/** Where the customer lands after a successful checkout. */
|
|
127
126
|
readonly successUrl: string;
|
|
128
|
-
/**
|
|
127
|
+
/** Where the customer lands if they cancel. */
|
|
129
128
|
readonly cancelUrl: string;
|
|
130
|
-
/** Optional:
|
|
131
|
-
*
|
|
132
|
-
*
|
|
129
|
+
/** Optional: existing provider customer ID when the tenant already
|
|
130
|
+
* has an account with the provider. Otherwise, the provider
|
|
131
|
+
* creates a new customer during checkout. */
|
|
133
132
|
readonly providerCustomerId?: string;
|
|
134
133
|
/** Checkout mode. `"subscription"` (default) starts a recurring
|
|
135
134
|
* billing flow; `"payment"` a one-off checkout (e.g. pay-per-use
|
|
@@ -147,17 +146,17 @@ export type SubscriptionProviderPlugin = {
|
|
|
147
146
|
readonly url: string;
|
|
148
147
|
}>;
|
|
149
148
|
/**
|
|
150
|
-
* **Post-tenant-resolution** —
|
|
151
|
-
*
|
|
149
|
+
* **Post-tenant-resolution** — called from a write handler with a
|
|
150
|
+
* fully resolved ctx. Creates a self-service Portal link.
|
|
152
151
|
* Stripe: customer-portal-session, Mollie: hosted-management-page.
|
|
153
|
-
*
|
|
154
|
-
* (cancel, payment
|
|
152
|
+
* The tenant admin uses it to manage the subscription themselves
|
|
153
|
+
* (cancel, payment method, ...).
|
|
155
154
|
*
|
|
156
|
-
* Optional
|
|
157
|
-
* (Apple-IAP managed
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
155
|
+
* Optional because not every provider has a Portal pattern
|
|
156
|
+
* (Apple-IAP subscriptions are managed in the Apple app, with no web
|
|
157
|
+
* Portal). A plugin that does not support this can omit the field;
|
|
158
|
+
* the foundation then returns a "portal_not_supported" error when a
|
|
159
|
+
* tenant admin requests the Portal link.
|
|
161
160
|
*/
|
|
162
161
|
readonly createPortalSession?: (ctx: HandlerContext, options: {
|
|
163
162
|
readonly providerCustomerId: string;
|
|
@@ -166,10 +165,10 @@ export type SubscriptionProviderPlugin = {
|
|
|
166
165
|
readonly url: string;
|
|
167
166
|
}>;
|
|
168
167
|
/**
|
|
169
|
-
* Optional:
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
168
|
+
* Optional: in-app cancellation API. If not implemented, the tenant
|
|
169
|
+
* can cancel only through the Customer Portal link (or not at all if
|
|
170
|
+
* createPortalSession is also missing — the cancellation flow is then
|
|
171
|
+
* provider-dashboard-only).
|
|
173
172
|
*/
|
|
174
173
|
readonly cancelSubscription?: (ctx: HandlerContext, options: {
|
|
175
174
|
readonly providerSubscriptionId: string;
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
/// <reference types="temporal-polyfill/global" preserve="true" />
|
|
2
|
-
// Plugin
|
|
3
|
-
//
|
|
4
|
-
// `SubscriptionProviderPlugin`
|
|
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`
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// Stripe-/PayPal-
|
|
12
|
-
// secret
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
// SYSTEM_TENANT_ID. Plugins
|
|
17
|
-
//
|
|
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`
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
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
|
|
25
|
-
// proration, multi-currency, coupons etc.
|
|
26
|
-
//
|
|
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
|
import { SUBSCRIPTION_PROVIDER_EXTENSION, } from "./web/constants.js";
|
|
28
28
|
// =============================================================================
|
|
29
29
|
// Provider price + billing-plans catalog
|
|
@@ -46,10 +46,10 @@ function manageOrReactivateAction(canManage, subscription, t, onManage, redirect
|
|
|
46
46
|
disabled: redirecting,
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
-
/** `!canPurchase` hides every CTA outright (
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
49
|
+
/** `!canPurchase` hides every CTA outright (see `purchaseNotAllowed`) — distinct
|
|
50
|
+
* from the `unavailable` action's disabled CTA, which still shows a button
|
|
51
|
+
* (for example, when a plan's price failed to load), so this check runs
|
|
52
|
+
* before the general unavailable fallback. */
|
|
53
53
|
function planCta(plan, result, t, onAction, redirecting) {
|
|
54
54
|
if (plan.action === BillingPlanActions.current)
|
|
55
55
|
return undefined;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { v5 as uuidv5 } from "uuid";
|
|
2
|
-
// Fixed UUID
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// __tests__/drift.test.ts pinnt den UUID-Wert.
|
|
2
|
+
// Fixed UUID namespace for deriving cap-counter aggregate IDs.
|
|
3
|
+
// Generated once (2026-05-02) and immutable: changing it would re-key every
|
|
4
|
+
// existing aggregate stream, breaking event replay and counter history and
|
|
5
|
+
// losing the audit trail. The drift test in __tests__/drift.test.ts pins the UUID.
|
|
7
6
|
const CAP_COUNTER_NAMESPACE = "9c1bf2a3-6e4d-4f5b-8a9c-2d3e4f5a6b7c";
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
7
|
+
// Separate namespace for rolling-window counters. This prevents the aggregate ID
|
|
8
|
+
// from colliding with a calendar counter, even if "1970-01-01..." is passed as
|
|
9
|
+
// periodStart through the calendar path. The drift test in __tests__/drift.test.ts
|
|
10
|
+
// pins the UUID.
|
|
12
11
|
const CAP_COUNTER_ROLLING_NAMESPACE = "8b2ad0c6-1f3e-4f7c-9b8a-3c4d5e6f7a8b";
|
|
13
12
|
/**
|
|
14
13
|
* One aggregate per (tenantId, capName, periodStart-as-iso). A new calendar
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
// Feature name
|
|
2
2
|
export const CAP_COUNTER_FEATURE = "cap-counter";
|
|
3
3
|
export const CAP_COUNTER_LIST_SCREEN_ID = "cap-list";
|
|
4
|
-
// Aggregate types
|
|
5
|
-
// projection
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// muss.
|
|
4
|
+
// Aggregate types: calendar-period counters use CRUD events for the
|
|
5
|
+
// projection row. Rolling-window counters use a separate aggregate type
|
|
6
|
+
// with custom increment events (no projection—the read sums events from
|
|
7
|
+
// the last N days). They are separate so `r.entity-projection` does not
|
|
8
|
+
// also have to track rolling-counter rows.
|
|
10
9
|
export const CAP_COUNTER_ROLLING_AGGREGATE_TYPE = "cap-counter-rolling";
|
|
11
|
-
// Custom event
|
|
12
|
-
// _SHORT —
|
|
13
|
-
// (
|
|
14
|
-
// _QN —
|
|
15
|
-
//
|
|
16
|
-
//
|
|
10
|
+
// Custom event types for rolling-window counters. The pair is symmetric:
|
|
11
|
+
// _SHORT — matches `r.defineEvent(short, schema)` in the registrar
|
|
12
|
+
// (the framework automatically prefixes it to the QN)
|
|
13
|
+
// _QN — qualified form for `ctx.unsafeAppendEvent({type})`, the
|
|
14
|
+
// `events.type` column, and `registry.getEvent(qn)` lookups
|
|
15
|
+
// Both MUST stay consistent; the feature test pins against drift.
|
|
17
16
|
export const ROLLING_INCREMENTED_EVENT_SHORT = "rolling-incremented";
|
|
18
17
|
export const ROLLING_INCREMENTED_EVENT_QN = "cap-counter:event:rolling-incremented";
|
|
19
18
|
// Gives back a reserved rolling amount; the window sum is incremented minus released.
|