@cosmicdrift/kumiko-bundled-features 0.377.0 → 0.379.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/dist/account-security/feature.js +2 -2
- package/dist/account-security/index.d.ts +2 -2
- package/dist/account-security/index.js +2 -2
- package/dist/account-security/{constants.js → web/constants.js} +0 -1
- package/dist/account-security/{i18n.js → web/i18n.js} +0 -1
- package/dist/admin-shell/feature.js +4 -3
- package/dist/admin-shell/index.d.ts +2 -2
- package/dist/admin-shell/index.js +2 -2
- package/dist/admin-shell/web/client-plugin.js +2 -3
- package/dist/admin-shell/{constants.js → web/constants.js} +0 -1
- package/dist/admin-shell/web/default-translations.d.ts +2 -0
- package/dist/admin-shell/web/default-translations.js +4 -0
- package/dist/admin-shell/web/i18n.d.ts +5 -2
- package/dist/admin-shell/web/i18n.js +50 -5
- package/dist/admin-shell/web/index.js +0 -1
- package/dist/audit/feature.js +58 -59
- package/dist/audit/handlers/audit-events.d.ts +102 -0
- package/dist/audit/handlers/audit-events.js +112 -0
- package/dist/audit/handlers/audit-system-db.d.ts +1 -0
- package/dist/audit/handlers/audit-system-db.js +9 -0
- package/dist/audit/handlers/details-all-tenants.query.d.ts +15 -0
- package/dist/audit/handlers/details-all-tenants.query.js +20 -0
- package/dist/audit/handlers/details.query.d.ts +2 -1
- package/dist/audit/handlers/details.query.js +8 -24
- package/dist/audit/handlers/list-all-tenants.query.d.ts +41 -0
- package/dist/audit/handlers/list-all-tenants.query.js +32 -0
- package/dist/audit/handlers/list.query.d.ts +2 -1
- package/dist/audit/handlers/list.query.js +9 -99
- package/dist/audit/handlers/resolve-audit-tenant.d.ts +3 -1
- package/dist/audit/handlers/resolve-audit-tenant.js +21 -7
- package/dist/audit/index.d.ts +1 -1
- package/dist/audit/index.js +1 -1
- package/dist/audit/run-escape-hatch-retention.js +1 -1
- package/dist/audit/screens.d.ts +65 -0
- package/dist/audit/screens.js +73 -0
- package/dist/audit/web/client-plugin.js +2 -3
- package/dist/audit/{constants.d.ts → web/constants.d.ts} +8 -0
- package/dist/audit/{constants.js → web/constants.js} +8 -1
- package/dist/audit/web/default-translations.d.ts +2 -0
- package/dist/audit/web/default-translations.js +3 -0
- package/dist/audit/web/i18n.d.ts +5 -2
- package/dist/audit/web/i18n.js +31 -4
- package/dist/audit/web/index.js +0 -1
- package/dist/auth-email-password/bootstrap.d.ts +1 -1
- package/dist/auth-email-password/bootstrap.js +4 -4
- package/dist/auth-email-password/errors.js +1 -1
- package/dist/auth-email-password/feature.js +2 -2
- package/dist/auth-email-password/handlers/confirm-account-unlock.write.js +1 -1
- package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
- package/dist/auth-email-password/handlers/invite-create.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/invite-create.write.js +3 -3
- package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
- package/dist/auth-email-password/handlers/login.write.d.ts +1 -0
- package/dist/auth-email-password/handlers/login.write.js +26 -1
- package/dist/auth-email-password/handlers/request-account-unlock.write.js +1 -1
- package/dist/auth-email-password/handlers/request-email-verification.write.js +1 -1
- package/dist/auth-email-password/handlers/request-password-reset.write.js +1 -1
- package/dist/auth-email-password/handlers/reset-password.write.js +1 -1
- package/dist/auth-email-password/handlers/verify-email.write.js +1 -1
- package/dist/auth-email-password/index.d.ts +1 -1
- package/dist/auth-email-password/index.js +1 -1
- package/dist/auth-email-password/mail-notifications.js +1 -1
- package/dist/auth-email-password/signup-activation.js +1 -1
- package/dist/auth-email-password/web/auth-client.js +0 -1
- package/dist/auth-email-password/web/auth-form-logic.js +0 -1
- package/dist/auth-email-password/web/auth-form-primitives.js +0 -1
- package/dist/auth-email-password/web/auth-gate.js +0 -1
- package/dist/auth-email-password/web/auth-redirect.js +0 -1
- package/dist/auth-email-password/web/client-actions.js +0 -1
- package/dist/auth-email-password/web/client-plugin.js +1 -2
- package/dist/auth-email-password/web/confirm-account-unlock-screen.js +0 -1
- package/dist/auth-email-password/{constants.js → web/constants.js} +3 -6
- package/dist/auth-email-password/web/default-topbar-actions.js +0 -1
- package/dist/auth-email-password/web/forgot-password-screen.js +0 -1
- package/dist/auth-email-password/{i18n.js → web/i18n.js} +3 -4
- package/dist/auth-email-password/web/index.d.ts +1 -1
- package/dist/auth-email-password/web/index.js +1 -2
- package/dist/auth-email-password/web/invite-accept-screen.d.ts +2 -2
- package/dist/auth-email-password/web/invite-accept-screen.js +0 -1
- package/dist/auth-email-password/web/login-screen.js +0 -1
- package/dist/auth-email-password/{mail-i18n.js → web/mail-i18n.js} +0 -1
- package/dist/auth-email-password/web/request-account-unlock-screen.js +0 -1
- package/dist/auth-email-password/web/reset-password-screen.js +0 -1
- package/dist/auth-email-password/web/session-bootstrap-error.js +0 -1
- package/dist/auth-email-password/web/session.js +0 -1
- package/dist/auth-email-password/web/signup-complete-screen.d.ts +2 -2
- package/dist/auth-email-password/web/signup-complete-screen.js +0 -1
- package/dist/auth-email-password/web/signup-screen.js +0 -1
- package/dist/auth-email-password/web/tenant-menu-items.js +0 -1
- package/dist/auth-email-password/web/tenant-switcher.js +0 -1
- package/dist/auth-email-password/web/use-shell-user.js +0 -1
- package/dist/auth-email-password/web/user-menu.js +0 -1
- package/dist/auth-email-password/web/verify-email-screen.js +0 -1
- package/dist/auth-mfa/errors.d.ts +1 -1
- package/dist/auth-mfa/errors.js +2 -2
- package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +1 -1
- package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
- package/dist/auth-mfa/handlers/enable-start.write.js +1 -1
- package/dist/auth-mfa/handlers/verify.write.js +1 -1
- package/dist/auth-mfa/index.d.ts +1 -1
- package/dist/auth-mfa/index.js +1 -1
- package/dist/auth-mfa/mfa-status-checker.js +1 -1
- package/dist/auth-mfa/screens.js +1 -1
- package/dist/auth-mfa/web/client-plugin.js +0 -1
- package/dist/auth-mfa/{constants.js → web/constants.js} +0 -1
- package/dist/auth-mfa/web/i18n.js +0 -1
- package/dist/auth-mfa/web/index.js +0 -1
- package/dist/auth-mfa/web/mfa-client.js +0 -1
- package/dist/auth-mfa/web/mfa-disable-dialog.js +1 -2
- package/dist/auth-mfa/web/mfa-recovery-codes-reveal.js +0 -1
- package/dist/auth-mfa/web/mfa-regenerate-recovery-dialog.js +1 -2
- package/dist/auth-mfa/web/mfa-setup-preauth-screen.js +11 -18
- package/dist/auth-mfa/web/mfa-verify-screen.js +0 -1
- package/dist/billing-foundation/checkout-core.js +1 -1
- package/dist/billing-foundation/consumer-protection/consent-text.d.ts +2 -2
- package/dist/billing-foundation/consumer-protection/consent-text.js +1 -1
- package/dist/billing-foundation/consumer-protection/issue-confirmation.js +7 -3
- package/dist/billing-foundation/consumer-protection/mail-notifications.js +3 -1
- package/dist/billing-foundation/consumer-protection/register-consent.js +1 -1
- package/dist/billing-foundation/consumer-protection/register-termination.js +8 -2
- package/dist/billing-foundation/consumer-protection/stored-user-email.d.ts +1 -0
- package/dist/billing-foundation/consumer-protection/stored-user-email.js +8 -0
- package/dist/billing-foundation/consumer-protection/termination-mail.d.ts +5 -1
- package/dist/billing-foundation/consumer-protection/termination-mail.js +3 -1
- package/dist/billing-foundation/consumer-protection/termination-notify.js +1 -1
- package/dist/billing-foundation/consumer-protection/termination-pages.js +109 -15
- package/dist/billing-foundation/consumer-protection/termination-record.d.ts +8 -1
- package/dist/billing-foundation/consumer-protection/termination-record.js +76 -3
- package/dist/billing-foundation/consumer-protection/termination-request.js +33 -6
- package/dist/billing-foundation/consumer-protection/termination-revoke.d.ts +28 -0
- package/dist/billing-foundation/consumer-protection/termination-revoke.js +149 -0
- package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +17 -1
- package/dist/billing-foundation/consumer-protection/termination-texts.js +39 -0
- package/dist/billing-foundation/events.d.ts +9 -0
- package/dist/billing-foundation/events.js +14 -2
- package/dist/billing-foundation/feature.js +1 -1
- package/dist/billing-foundation/handlers/process-event.write.d.ts +5 -1
- package/dist/billing-foundation/handlers/process-event.write.js +57 -3
- package/dist/billing-foundation/handlers/switch-plan.write.js +1 -1
- package/dist/billing-foundation/handlers/sync-subscription.write.js +1 -1
- package/dist/billing-foundation/index.d.ts +2 -2
- package/dist/billing-foundation/index.js +2 -2
- package/dist/billing-foundation/plan-catalog.js +1 -1
- package/dist/billing-foundation/screens.js +1 -1
- package/dist/billing-foundation/subscription-tier-sync.js +1 -1
- package/dist/billing-foundation/types.d.ts +14 -2
- package/dist/billing-foundation/types.js +1 -1
- package/dist/billing-foundation/validate-options.js +3 -3
- package/dist/billing-foundation/web/billing-contact-plan.js +1 -2
- package/dist/billing-foundation/web/billing-plans-panel.js +1 -2
- package/dist/billing-foundation/web/cancel-contract-dialog.js +1 -2
- package/dist/billing-foundation/web/checkout-consent-dialog.js +1 -2
- package/dist/billing-foundation/web/client-plugin.js +1 -1
- package/dist/billing-foundation/{constants.d.ts → web/constants.d.ts} +21 -14
- package/dist/billing-foundation/{constants.js → web/constants.js} +35 -31
- package/dist/billing-foundation/{consumer-protection → web/consumer-protection}/consent-locale.js +0 -1
- package/dist/billing-foundation/{contact-card.js → web/contact-card.js} +0 -1
- package/dist/billing-foundation/web/index.d.ts +2 -2
- package/dist/billing-foundation/web/index.js +2 -3
- package/dist/billing-foundation/web/localized-params.js +0 -1
- package/dist/billing-foundation/webhook-handler.js +4 -1
- package/dist/cap-counter/stock-cap-guard.js +8 -0
- package/dist/cap-overview/feature.js +1 -1
- package/dist/cap-overview/handlers/caps-usage.query.js +1 -1
- package/dist/cap-overview/handlers/tenant-caps-list.query.js +2 -2
- package/dist/cap-overview/index.d.ts +2 -2
- package/dist/cap-overview/index.js +2 -2
- package/dist/cap-overview/screens.js +1 -1
- package/dist/cap-overview/web/cap-cards-panel.js +1 -1
- package/dist/cap-overview/web/cap-usage-bar.js +1 -2
- package/dist/cap-overview/web/client-plugin.js +1 -1
- package/dist/cap-overview/{constants.js → web/constants.js} +0 -1
- package/dist/cap-overview/web/index.js +0 -1
- package/dist/cap-overview/{usage-math.d.ts → web/usage-math.d.ts} +1 -1
- package/dist/compliance-profiles/feature.js +1 -1
- package/dist/compliance-profiles/index.d.ts +1 -1
- package/dist/compliance-profiles/index.js +1 -1
- package/dist/compliance-profiles/web/client-plugin.js +1 -2
- package/dist/compliance-profiles/web/compliance-profile-catalog.js +1 -2
- package/dist/compliance-profiles/{constants.js → web/constants.js} +0 -1
- package/dist/compliance-profiles/web/index.js +0 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/web/client-plugin.d.ts +1 -1
- package/dist/config/web/client-plugin.js +1 -2
- package/dist/config/{constants.js → web/constants.js} +0 -1
- package/dist/config/web/i18n.js +1 -1
- package/dist/config/web/index.d.ts +1 -1
- package/dist/config/web/index.js +1 -2
- package/dist/config/write-helpers.js +1 -1
- package/dist/custom-fields/feature.js +1 -1
- package/dist/custom-fields/handlers/clear-custom-field.write.js +1 -1
- package/dist/custom-fields/handlers/define-tenant-field.write.js +1 -1
- package/dist/custom-fields/handlers/delete-system-field.write.js +1 -1
- package/dist/custom-fields/handlers/delete-tenant-field.write.js +1 -1
- package/dist/custom-fields/handlers/set-custom-field.write.js +1 -1
- package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
- package/dist/custom-fields/index.d.ts +1 -1
- package/dist/custom-fields/index.js +1 -1
- package/dist/custom-fields/lib/value-schema.js +1 -1
- package/dist/custom-fields/schemas.js +1 -1
- package/dist/custom-fields/web/client-plugin.js +1 -2
- package/dist/custom-fields/{constants.js → web/constants.js} +18 -19
- package/dist/custom-fields/web/custom-fields-form-section.js +1 -2
- package/dist/custom-fields/web/i18n.js +0 -1
- package/dist/custom-fields/web/index.d.ts +1 -1
- package/dist/custom-fields/web/index.js +1 -2
- package/dist/custom-fields/wire-for-entity.js +1 -1
- package/dist/delivery/address-opt-out.js +1 -1
- package/dist/delivery/attempt-log-retention.js +21 -3
- package/dist/delivery/constants.d.ts +1 -1
- package/dist/delivery/constants.js +2 -2
- package/dist/delivery/i18n.js +1 -1
- package/dist/delivery/unsubscribe-page.js +1 -1
- package/dist/delivery/web/client-plugin.js +1 -1
- package/dist/delivery/web/delivery-channel-cell.js +0 -1
- package/dist/delivery/web/delivery-error-cell.js +0 -1
- package/dist/delivery/web/delivery-status-cell.js +1 -2
- package/dist/delivery/web/delivery-time-cell.js +0 -1
- package/dist/delivery/web/delivery-type-cell.js +0 -1
- package/dist/delivery/web/index.js +0 -1
- package/dist/delivery/{public-names.js → web/public-names.js} +0 -1
- package/dist/document-ingest-foundation/events.d.ts +1 -0
- package/dist/document-ingest-foundation/events.js +3 -0
- package/dist/document-ingest-foundation/executor.js +2 -1
- package/dist/document-ingest-foundation/feature.js +16 -5
- package/dist/document-ingest-foundation/index.d.ts +1 -1
- package/dist/document-ingest-foundation/index.js +1 -1
- package/dist/feature-toggles/feature.d.ts +1 -1
- package/dist/feature-toggles/feature.js +2 -2
- package/dist/feature-toggles/handlers/list.query.js +1 -1
- package/dist/feature-toggles/handlers/registered.query.js +1 -1
- package/dist/feature-toggles/handlers/set.write.js +1 -1
- package/dist/feature-toggles/index.d.ts +1 -1
- package/dist/feature-toggles/index.js +1 -1
- package/dist/feature-toggles/web/client-plugin.js +1 -2
- package/dist/feature-toggles/{constants.js → web/constants.js} +0 -1
- package/dist/feature-toggles/web/index.js +0 -1
- package/dist/folders/feature.js +1 -1
- package/dist/folders/handlers/clear-folder.write.js +1 -1
- package/dist/folders/handlers/delete-folder.write.js +1 -1
- package/dist/folders/handlers/set-folder.write.js +1 -1
- package/dist/folders/index.d.ts +1 -1
- package/dist/folders/index.js +1 -1
- package/dist/folders/web/client-plugin.js +1 -2
- package/dist/folders/{constants.js → web/constants.js} +0 -1
- package/dist/folders/web/folder-manager.js +1 -2
- package/dist/folders/web/folder-section.js +1 -2
- package/dist/folders/web/i18n.js +0 -1
- package/dist/folders/web/index.d.ts +1 -1
- package/dist/folders/web/index.js +1 -2
- package/dist/folders/web/tree.js +0 -1
- package/dist/form-draft/db/queries/cleanup.d.ts +3 -2
- package/dist/form-draft/db/queries/cleanup.js +18 -9
- package/dist/form-draft/decrypt-draft.d.ts +2 -0
- package/dist/form-draft/decrypt-draft.js +19 -0
- package/dist/form-draft/entity.js +6 -9
- package/dist/form-draft/feature.js +1 -1
- package/dist/form-draft/handlers/cleanup.job.d.ts +1 -0
- package/dist/form-draft/handlers/cleanup.job.js +17 -4
- package/dist/form-draft/handlers/discard.write.js +1 -1
- package/dist/form-draft/handlers/get.query.js +6 -7
- package/dist/form-draft/handlers/list.query.js +11 -7
- package/dist/form-draft/handlers/save.write.js +1 -1
- package/dist/form-draft/index.d.ts +1 -1
- package/dist/form-draft/index.js +1 -1
- package/dist/form-draft/lookup.d.ts +2 -2
- package/dist/form-draft/lookup.js +7 -2
- package/dist/form-draft/schemas.js +1 -1
- package/dist/form-draft/{constants.js → web/constants.js} +0 -1
- package/dist/form-draft-user-data/hooks.js +2 -2
- package/dist/inbound-mail-foundation/handlers/list-accounts.query.d.ts +1 -1
- package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +11 -3
- package/dist/inbound-mail-foundation/retention-sweep.js +7 -5
- package/dist/jobs/feature.js +2 -2
- package/dist/jobs/handlers/retry.write.js +1 -1
- package/dist/jobs/handlers/trigger.write.js +1 -1
- package/dist/jobs/index.d.ts +1 -1
- package/dist/jobs/index.js +1 -1
- package/dist/jobs/web/client-plugin.js +2 -3
- package/dist/jobs/{constants.js → web/constants.js} +0 -1
- package/dist/jobs/web/default-translations.d.ts +2 -0
- package/dist/jobs/web/default-translations.js +3 -0
- package/dist/jobs/web/i18n.d.ts +5 -2
- package/dist/jobs/web/i18n.js +51 -4
- package/dist/jobs/web/index.js +0 -1
- package/dist/ledger/entity.d.ts +1 -1
- package/dist/ledger/entity.js +1 -1
- package/dist/ledger/feature.js +1 -1
- package/dist/ledger/handlers/confirm-schedule-period.write.js +2 -5
- package/dist/ledger/handlers/create-transaction.write.js +1 -1
- package/dist/ledger/handlers/reports.query.js +1 -1
- package/dist/ledger/handlers/reverse-transaction.write.js +1 -1
- package/dist/ledger/index.d.ts +1 -1
- package/dist/ledger/index.js +1 -1
- package/dist/ledger/recurring.d.ts +1 -1
- package/dist/ledger/reports.d.ts +1 -1
- package/dist/ledger/schemas.js +1 -1
- package/dist/ledger/{constants.js → web/constants.js} +0 -1
- package/dist/ledger/web/index.d.ts +1 -1
- package/dist/ledger/web/index.js +1 -2
- package/dist/legal-pages/feature.d.ts +1 -1
- package/dist/legal-pages/feature.js +1 -1
- package/dist/legal-pages/index.d.ts +1 -1
- package/dist/legal-pages/index.js +1 -1
- package/dist/legal-pages/lib/boot-check.d.ts +1 -1
- package/dist/legal-pages/lib/boot-check.js +1 -1
- package/dist/legal-pages/lib/validate-routes.d.ts +1 -1
- package/dist/legal-pages/web/client-plugin.js +1 -2
- package/dist/legal-pages/{constants.js → web/constants.js} +6 -8
- package/dist/legal-pages/web/index.js +0 -1
- package/dist/mail-foundation/i18n.d.ts +5 -2
- package/dist/mail-foundation/i18n.js +3 -2
- package/dist/mail-transport-smtp/i18n.d.ts +1 -1
- package/dist/mail-transport-smtp/i18n.js +1 -1
- package/dist/managed-pages/feature.js +1 -1
- package/dist/managed-pages/web/client-plugin.js +1 -2
- package/dist/managed-pages/web/default-translations.d.ts +2 -0
- package/dist/managed-pages/web/default-translations.js +11 -0
- package/dist/managed-pages/web/i18n.d.ts +5 -2
- package/dist/managed-pages/web/i18n.js +53 -12
- package/dist/managed-pages/web/index.d.ts +1 -1
- package/dist/managed-pages/web/index.js +1 -2
- package/dist/metrics/compute.d.ts +1 -1
- package/dist/metrics/compute.js +1 -1
- package/dist/metrics/feature.js +1 -1
- package/dist/metrics/index.d.ts +1 -1
- package/dist/metrics/index.js +1 -1
- package/dist/metrics/types.d.ts +1 -1
- package/dist/metrics/validate.js +1 -1
- package/dist/metrics/{constants.js → web/constants.js} +0 -1
- package/dist/metrics/window.d.ts +1 -1
- package/dist/notes-history/feature.js +1 -1
- package/dist/notes-history/handlers/add-note.write.js +1 -1
- package/dist/notes-history/index.d.ts +1 -1
- package/dist/notes-history/index.js +1 -1
- package/dist/notes-history/web/client-plugin.js +1 -2
- package/dist/notes-history/{constants.js → web/constants.js} +0 -1
- package/dist/notes-history/web/i18n.js +0 -1
- package/dist/notes-history/web/index.d.ts +1 -1
- package/dist/notes-history/web/index.js +1 -2
- package/dist/notes-history/web/notes-section.js +2 -3
- package/dist/personal-access-tokens/feature.d.ts +2 -2
- package/dist/personal-access-tokens/feature.js +6 -4
- package/dist/personal-access-tokens/handlers/available-scopes.query.d.ts +1 -1
- package/dist/personal-access-tokens/handlers/create.write.js +1 -1
- package/dist/personal-access-tokens/handlers/revoke.write.js +1 -1
- package/dist/personal-access-tokens/hash.js +1 -1
- package/dist/personal-access-tokens/i18n.d.ts +1 -1
- package/dist/personal-access-tokens/i18n.js +1 -1
- package/dist/personal-access-tokens/index.d.ts +5 -5
- package/dist/personal-access-tokens/index.js +3 -3
- package/dist/personal-access-tokens/resolver.d.ts +1 -1
- package/dist/personal-access-tokens/resolver.js +1 -1
- package/dist/personal-access-tokens/schema/api-token.js +1 -1
- package/dist/personal-access-tokens/screens.d.ts +1 -1
- package/dist/personal-access-tokens/screens.js +1 -1
- package/dist/personal-access-tokens/{constants.js → web/constants.js} +0 -1
- package/dist/presets/index.d.ts +0 -1
- package/dist/presets/index.js +0 -1
- package/dist/presets/security-baseline.d.ts +1 -1
- package/dist/presets/security-baseline.js +1 -1
- package/dist/secrets/feature.js +1 -1
- package/dist/secrets/handlers/delete.write.js +1 -1
- package/dist/secrets/handlers/list.query.js +1 -1
- package/dist/secrets/handlers/set.write.js +1 -1
- package/dist/secrets/i18n.js +1 -1
- package/dist/secrets/index.d.ts +1 -1
- package/dist/secrets/index.js +1 -1
- package/dist/secrets/{constants.js → web/constants.js} +0 -1
- package/dist/secrets/write-gate.js +1 -1
- package/dist/sessions/feature.js +7 -4
- package/dist/sessions/{i18n.js → web/i18n.js} +0 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/purge-files-reaching-subject.js +7 -3
- package/dist/subscription-stripe/feature.js +2 -1
- package/dist/subscription-stripe/plugin-methods.d.ts +3 -0
- package/dist/subscription-stripe/plugin-methods.js +14 -0
- package/dist/subscription-stripe/verify-webhook.js +1 -0
- package/dist/tags/feature.js +1 -1
- package/dist/tags/handlers/assign-tag.write.js +11 -7
- package/dist/tags/handlers/create-tag.write.js +1 -1
- package/dist/tags/handlers/delete-tag.write.js +4 -1
- package/dist/tags/handlers/remove-tag.write.js +1 -1
- package/dist/tags/handlers/update-tag.write.js +1 -1
- package/dist/tags/index.d.ts +1 -1
- package/dist/tags/index.js +1 -1
- package/dist/tags/screens.js +1 -1
- package/dist/tags/web/client-plugin.js +1 -2
- package/dist/tags/{constants.d.ts → web/constants.d.ts} +1 -0
- package/dist/tags/{constants.js → web/constants.js} +3 -1
- package/dist/tags/web/entity-tags.js +1 -2
- package/dist/tags/web/i18n.js +2 -2
- package/dist/tags/web/index.d.ts +1 -1
- package/dist/tags/web/index.js +1 -2
- package/dist/tags/web/tag-filter.js +1 -2
- package/dist/tags/web/tag-manager.js +5 -4
- package/dist/tags/web/tag-picker.js +0 -1
- package/dist/tags/web/tag-section.js +1 -2
- package/dist/tags/web/tags-cell.js +1 -2
- package/dist/template-resolver/api.d.ts +21 -23
- package/dist/template-resolver/api.js +34 -6
- package/dist/template-resolver/compile-document-body.d.ts +3 -0
- package/dist/template-resolver/compile-document-body.js +51 -4
- package/dist/template-resolver/compile-steps-block.js +2 -2
- package/dist/template-resolver/document-ops.d.ts +1 -1
- package/dist/template-resolver/document-ops.js +3 -3
- package/dist/template-resolver/document-sanitizer.d.ts +2 -2
- package/dist/template-resolver/document-sanitizer.js +23 -3
- package/dist/template-resolver/feature.d.ts +11 -0
- package/dist/template-resolver/feature.js +68 -35
- package/dist/template-resolver/handlers/by-slug.query.js +6 -1
- package/dist/template-resolver/handlers/by-tenant.query.js +6 -2
- package/dist/template-resolver/handlers/collection-item.query.js +2 -1
- package/dist/template-resolver/handlers/collection-list.query.js +2 -1
- package/dist/template-resolver/handlers/collection-set.write.d.ts +2 -1
- package/dist/template-resolver/handlers/collection-set.write.js +15 -3
- package/dist/template-resolver/handlers/collection-shared.d.ts +1 -2
- package/dist/template-resolver/handlers/collection-shared.js +0 -4
- package/dist/template-resolver/handlers/copy-locale.write.d.ts +2 -1
- package/dist/template-resolver/handlers/copy-locale.write.js +69 -65
- package/dist/template-resolver/handlers/diff-to-system.query.js +5 -1
- package/dist/template-resolver/handlers/discard-draft.write.d.ts +3 -2
- package/dist/template-resolver/handlers/discard-draft.write.js +19 -7
- package/dist/template-resolver/handlers/document-base.d.ts +1 -1
- package/dist/template-resolver/handlers/document-base.js +6 -1
- package/dist/template-resolver/handlers/document-blocks.query.d.ts +1 -1
- package/dist/template-resolver/handlers/document-blocks.query.js +2 -2
- package/dist/template-resolver/handlers/export-bundle.query.js +5 -2
- package/dist/template-resolver/handlers/find-by-id.query.js +4 -2
- package/dist/template-resolver/handlers/import-bundle.write.d.ts +2 -1
- package/dist/template-resolver/handlers/import-bundle.write.js +30 -25
- package/dist/template-resolver/handlers/layout-source.query.js +5 -5
- package/dist/template-resolver/handlers/list.query.js +5 -2
- package/dist/template-resolver/handlers/overview.query.d.ts +12 -3
- package/dist/template-resolver/handlers/overview.query.js +87 -51
- package/dist/template-resolver/handlers/patch-draft.write.d.ts +2 -1
- package/dist/template-resolver/handlers/patch-draft.write.js +93 -87
- package/dist/template-resolver/handlers/reset-to-system.write.d.ts +2 -1
- package/dist/template-resolver/handlers/reset-to-system.write.js +51 -44
- package/dist/template-resolver/handlers/resource-link-pdf.write.d.ts +2 -1
- package/dist/template-resolver/handlers/resource-link-pdf.write.js +34 -28
- package/dist/template-resolver/handlers/resource-remove.write.d.ts +2 -1
- package/dist/template-resolver/handlers/resource-remove.write.js +39 -33
- package/dist/template-resolver/handlers/resource-shared.js +1 -1
- package/dist/template-resolver/handlers/resource-upload.write.d.ts +2 -1
- package/dist/template-resolver/handlers/resource-upload.write.js +105 -97
- package/dist/template-resolver/handlers/send-test-shared.d.ts +5 -0
- package/dist/template-resolver/handlers/send-test-shared.js +19 -0
- package/dist/template-resolver/handlers/send-test-status.query.d.ts +9 -0
- package/dist/template-resolver/handlers/send-test-status.query.js +18 -0
- package/dist/template-resolver/handlers/send-test.write.d.ts +2 -1
- package/dist/template-resolver/handlers/send-test.write.js +89 -91
- package/dist/template-resolver/handlers/set.write.d.ts +2 -1
- package/dist/template-resolver/handlers/set.write.js +95 -91
- package/dist/template-resolver/handlers/shared.js +1 -1
- package/dist/template-resolver/handlers/template-gates.d.ts +1 -1
- package/dist/template-resolver/handlers/template-gates.js +1 -1
- package/dist/template-resolver/handlers/template-write.d.ts +1 -1
- package/dist/template-resolver/handlers/template-write.js +1 -1
- package/dist/template-resolver/handlers/toggle-status.write.d.ts +6 -7
- package/dist/template-resolver/handlers/toggle-status.write.js +28 -10
- package/dist/template-resolver/handlers/upsert-tenant.write.d.ts +2 -1
- package/dist/template-resolver/handlers/upsert-tenant.write.js +30 -24
- package/dist/template-resolver/handlers/usage.query.js +3 -2
- package/dist/template-resolver/handlers/validate.query.d.ts +1 -1
- package/dist/template-resolver/handlers/validate.query.js +3 -1
- package/dist/template-resolver/i18n.d.ts +3 -0
- package/dist/template-resolver/i18n.js +24 -0
- package/dist/template-resolver/index.d.ts +8 -5
- package/dist/template-resolver/index.js +6 -4
- package/dist/template-resolver/layout-appearance.js +1 -1
- package/dist/template-resolver/layout-regions.d.ts +1 -1
- package/dist/template-resolver/seeding.d.ts +4 -1
- package/dist/template-resolver/seeding.js +13 -7
- package/dist/template-resolver/store-template-resource.js +2 -2
- package/dist/template-resolver/table.js +1 -1
- package/dist/template-resolver/template-bundle.js +2 -2
- package/dist/template-resolver/template-delivery-policy.d.ts +22 -0
- package/dist/template-resolver/template-delivery-policy.js +40 -0
- package/dist/template-resolver/template-draft.d.ts +1 -1
- package/dist/template-resolver/template-draft.js +1 -1
- package/dist/template-resolver/template-edit-policy.d.ts +22 -0
- package/dist/template-resolver/template-edit-policy.js +45 -0
- package/dist/template-resolver/template-meta.d.ts +2 -2
- package/dist/template-resolver/template-meta.js +2 -2
- package/dist/template-resolver/template-preview.d.ts +1 -1
- package/dist/template-resolver/template-preview.js +15 -6
- package/dist/template-resolver/template-usage.d.ts +1 -1
- package/dist/template-resolver/template-usage.js +1 -1
- package/dist/template-resolver/template-validation.js +34 -14
- package/dist/template-resolver/testing.js +1 -1
- package/dist/template-resolver/user-content-table.js +1 -1
- package/dist/template-resolver/web/client-plugin.js +1 -2
- package/dist/template-resolver/{constants.d.ts → web/constants.d.ts} +4 -1
- package/dist/template-resolver/{constants.js → web/constants.js} +9 -10
- package/dist/template-resolver/{document-blocks.d.ts → web/document-blocks.d.ts} +2 -2
- package/dist/template-resolver/{document-blocks.js → web/document-blocks.js} +1 -0
- package/dist/template-resolver/web/document-editor-extensions.d.ts +1 -0
- package/dist/template-resolver/web/document-editor-extensions.js +22 -2
- package/dist/template-resolver/web/document-editor.js +0 -1
- package/dist/template-resolver/web/document-images.d.ts +2 -0
- package/dist/template-resolver/web/document-images.js +27 -0
- package/dist/template-resolver/{document-schema.d.ts → web/document-schema.d.ts} +2 -1
- package/dist/template-resolver/{document-schema.js → web/document-schema.js} +4 -1
- package/dist/template-resolver/{document-steps.js → web/document-steps.js} +0 -1
- package/dist/template-resolver/web/document-tiptap-editor.d.ts +1 -1
- package/dist/template-resolver/web/document-tiptap-editor.js +24 -9
- package/dist/template-resolver/web/document-toolbar-blocks.d.ts +4 -2
- package/dist/template-resolver/web/document-toolbar-blocks.js +1 -1
- package/dist/template-resolver/web/editor-handle.js +1 -1
- package/dist/template-resolver/web/i18n.js +5 -1
- package/dist/template-resolver/web/index.d.ts +3 -3
- package/dist/template-resolver/web/index.js +3 -4
- package/dist/template-resolver/{mail-constants.js → web/mail-constants.js} +0 -1
- package/dist/template-resolver/{pdf-constants.js → web/pdf-constants.js} +0 -1
- package/dist/template-resolver/web/placeholder-line-editor-lazy.js +0 -1
- package/dist/template-resolver/web/placeholder-line-editor.js +6 -4
- package/dist/template-resolver/{qualified-names.d.ts → web/qualified-names.d.ts} +2 -0
- package/dist/template-resolver/{qualified-names.js → web/qualified-names.js} +2 -1
- package/dist/template-resolver/web/use-stable-by-key.js +0 -1
- package/dist/tenant/handlers/add-member.write.js +1 -1
- package/dist/tenant/index.d.ts +1 -1
- package/dist/tenant/index.js +1 -1
- package/dist/tenant/invitation-table.js +1 -1
- package/dist/tenant/invited-membership.js +1 -1
- package/dist/tenant/last-tenant-admin.js +1 -1
- package/dist/tenant/member-role-options.js +1 -1
- package/dist/tenant/screens.js +1 -1
- package/dist/tenant/web/client-plugin.js +1 -2
- package/dist/tenant/{constants.js → web/constants.js} +3 -6
- package/dist/tenant/web/index.js +0 -1
- package/dist/tenant/web/member-roles-cell.js +0 -1
- package/dist/tenant/web/member-status-cell.js +0 -1
- package/dist/tenant-lifecycle/stages.js +2 -3
- package/dist/tier-engine/entity.d.ts +1 -1
- package/dist/tier-engine/entity.js +1 -1
- package/dist/tier-engine/feature.js +2 -2
- package/dist/tier-engine/handlers/set-tenant-tier.write.js +1 -1
- package/dist/tier-engine/index.d.ts +1 -1
- package/dist/tier-engine/index.js +1 -1
- package/dist/tier-engine/web/client-plugin.js +2 -3
- package/dist/tier-engine/{constants.js → web/constants.js} +2 -3
- package/dist/tier-engine/{i18n.js → web/i18n.js} +0 -1
- package/dist/tier-engine/web/index.js +0 -1
- package/dist/user/handlers/create.write.js +1 -1
- package/dist/user/handlers/update-roles.js +1 -1
- package/dist/user/handlers/update.write.js +1 -1
- package/dist/user/index.d.ts +1 -1
- package/dist/user/index.js +1 -1
- package/dist/user/invited-global-roles.d.ts +1 -1
- package/dist/user/invited-global-roles.js +1 -1
- package/dist/user/schema/user.js +1 -1
- package/dist/user/{constants.js → web/constants.js} +0 -1
- package/dist/user-data-rights/env.js +1 -1
- package/dist/user-data-rights/feature.js +3 -3
- package/dist/user-data-rights/index.d.ts +1 -1
- package/dist/user-data-rights/index.js +1 -1
- package/dist/user-data-rights/lib/resolve-tenant-model.js +1 -1
- package/dist/user-data-rights/mail-notifications.js +1 -1
- package/dist/user-data-rights/web/client-plugin.js +2 -3
- package/dist/user-data-rights/web/confirm-deletion-screen.js +0 -1
- package/dist/user-data-rights/{constants.js → web/constants.js} +11 -12
- package/dist/user-data-rights/web/default-translations.d.ts +2 -0
- package/dist/user-data-rights/web/default-translations.js +59 -0
- package/dist/user-data-rights/web/i18n.d.ts +5 -2
- package/dist/user-data-rights/web/i18n.js +37 -59
- package/dist/user-data-rights/web/index.d.ts +1 -1
- package/dist/user-data-rights/web/index.js +1 -2
- package/dist/user-data-rights/web/privacy-center-screen.js +1 -2
- package/dist/user-data-rights/web/request-deletion-screen.js +0 -1
- package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +6 -1
- package/dist/user-profile/feature.js +1 -1
- package/dist/user-profile/handlers/change-email.write.js +1 -1
- package/dist/user-profile/index.d.ts +1 -1
- package/dist/user-profile/index.js +1 -1
- package/dist/user-profile/web/client-plugin.js +2 -3
- package/dist/user-profile/{constants.js → web/constants.js} +0 -1
- package/dist/user-profile/{i18n.js → web/i18n.js} +0 -1
- package/dist/user-profile/web/profile-screen.js +2 -3
- package/dist/waitlist/entity.js +1 -1
- package/dist/waitlist/feature.js +1 -1
- package/dist/waitlist/handlers/export-purge.write.js +1 -1
- package/dist/waitlist/handlers/invite.write.js +1 -1
- package/dist/waitlist/handlers/reject.write.js +1 -1
- package/dist/waitlist/handlers/submit.write.js +4 -3
- package/dist/waitlist/import.d.ts +1 -1
- package/dist/waitlist/index.d.ts +1 -1
- package/dist/waitlist/index.js +1 -1
- package/dist/waitlist/legacy-migrate.js +1 -1
- package/dist/waitlist/link-on-signup.js +1 -1
- package/dist/waitlist/mail.d.ts +0 -1
- package/dist/waitlist/mail.js +6 -4
- package/dist/waitlist/payloads.js +1 -1
- package/dist/waitlist/screens.js +1 -1
- package/dist/waitlist/{constants.js → web/constants.js} +0 -1
- package/kumiko-es-tables.json +102 -0
- package/package.json +30 -29
- package/src/audit/changes.json +7 -0
- package/src/auth-email-password/changes.json +6 -0
- package/src/auth-mfa/changes.json +6 -0
- package/src/billing-foundation/changes.json +18 -0
- package/src/cap-counter/changes.json +12 -0
- package/src/delivery/changes.json +6 -0
- package/src/document-ingest-foundation/changes.json +6 -0
- package/src/files/changes.json +7 -0
- package/src/form-draft/changes.json +7 -0
- package/src/inbound-mail-foundation/changes.json +6 -0
- package/src/ledger/changes.json +7 -0
- package/src/mail-foundation/changes.json +6 -0
- package/src/presets/changes.json +7 -0
- package/src/tags/changes.json +6 -0
- package/src/template-resolver/changes.json +63 -0
- package/src/user-data-rights/changes.json +14 -0
- package/src/waitlist/changes.json +6 -0
- package/dist/admin-shell/i18n.d.ts +0 -5
- package/dist/admin-shell/i18n.js +0 -51
- package/dist/audit/i18n.d.ts +0 -5
- package/dist/audit/i18n.js +0 -22
- package/dist/jobs/i18n.d.ts +0 -5
- package/dist/jobs/i18n.js +0 -52
- package/dist/managed-pages/i18n.d.ts +0 -5
- package/dist/managed-pages/i18n.js +0 -55
- package/dist/presets/dsgvo-self-service.d.ts +0 -10
- package/dist/presets/dsgvo-self-service.js +0 -24
- package/dist/user-data-rights/i18n.d.ts +0 -5
- package/dist/user-data-rights/i18n.js +0 -39
- /package/dist/account-security/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/account-security/{i18n.d.ts → web/i18n.d.ts} +0 -0
- /package/dist/admin-shell/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/auth-email-password/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/auth-email-password/{i18n.d.ts → web/i18n.d.ts} +0 -0
- /package/dist/auth-email-password/{mail-i18n.d.ts → web/mail-i18n.d.ts} +0 -0
- /package/dist/auth-mfa/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/billing-foundation/{consumer-protection → web/consumer-protection}/consent-locale.d.ts +0 -0
- /package/dist/billing-foundation/{contact-card.d.ts → web/contact-card.d.ts} +0 -0
- /package/dist/cap-overview/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/cap-overview/{usage-math.js → web/usage-math.js} +0 -0
- /package/dist/compliance-profiles/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/config/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/custom-fields/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/delivery/{public-names.d.ts → web/public-names.d.ts} +0 -0
- /package/dist/feature-toggles/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/folders/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/form-draft/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/jobs/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/ledger/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/legal-pages/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/metrics/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/notes-history/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/personal-access-tokens/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/personal-access-tokens/{scopes.d.ts → web/scopes.d.ts} +0 -0
- /package/dist/personal-access-tokens/{scopes.js → web/scopes.js} +0 -0
- /package/dist/secrets/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/sessions/{i18n.d.ts → web/i18n.d.ts} +0 -0
- /package/dist/template-resolver/{document-steps.d.ts → web/document-steps.d.ts} +0 -0
- /package/dist/template-resolver/{mail-constants.d.ts → web/mail-constants.d.ts} +0 -0
- /package/dist/template-resolver/{pdf-constants.d.ts → web/pdf-constants.d.ts} +0 -0
- /package/dist/template-resolver/{placeholder-text.d.ts → web/placeholder-text.d.ts} +0 -0
- /package/dist/template-resolver/{placeholder-text.js → web/placeholder-text.js} +0 -0
- /package/dist/tenant/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/tier-engine/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/tier-engine/{i18n.d.ts → web/i18n.d.ts} +0 -0
- /package/dist/user/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/user-data-rights/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/user-profile/{constants.d.ts → web/constants.d.ts} +0 -0
- /package/dist/user-profile/{i18n.d.ts → web/i18n.d.ts} +0 -0
- /package/dist/waitlist/{constants.d.ts → web/constants.d.ts} +0 -0
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
// 3. ctx.unsafeAppendEvent — Inline-projection materialisiert die
|
|
13
13
|
// `read_subscriptions`-row in derselben TX.
|
|
14
14
|
import { configuredPiiSubjectKms, encryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
|
|
15
|
+
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
16
|
+
import { propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
15
17
|
import * as z from "zod";
|
|
16
18
|
import { subscriptionAggregateId } from "../aggregate-id.js";
|
|
17
|
-
import { isSubscriptionBlockingCheckout, isSwitchableSubscriptionStatus, SubscriptionEventTypes, SubscriptionStatuses, } from "../constants.js";
|
|
18
19
|
import { SUBSCRIPTION_PII_FIELDS, subscriptionEntity } from "../entities.js";
|
|
19
20
|
import { INVOICE_PAID_EVENT_QN, INVOICE_PAYMENT_FAILED_EVENT_QN, SUBSCRIPTION_AGGREGATE_TYPE, SUBSCRIPTION_CANCELED_EVENT_QN, SUBSCRIPTION_CREATED_EVENT_QN, SUBSCRIPTION_UPDATED_EVENT_QN, } from "../events.js";
|
|
20
21
|
import { getSubscriptionForTenant } from "../get-subscription-for-tenant.js";
|
|
22
|
+
import { BILLING_SUBSCRIPTION_LOCK_NAMESPACE, isSubscriptionBlockingCheckout, isSwitchableSubscriptionStatus, SubscriptionEventTypes, SubscriptionStatuses, } from "../web/constants.js";
|
|
21
23
|
// =============================================================================
|
|
22
24
|
// Input-Schema = der normalisierte SubscriptionEvent (ohne tenantId, der
|
|
23
25
|
// kommt aus event.user.tenantId — der webhook-handler setzt den
|
|
@@ -47,6 +49,7 @@ export const processEventSchema = z.object({
|
|
|
47
49
|
tier: z.string().min(1).max(50),
|
|
48
50
|
currentPeriodEndIso: z.string().min(1),
|
|
49
51
|
cancelAtIso: z.string().min(1).nullable().optional(),
|
|
52
|
+
providerEventAtIso: z.iso.datetime().optional(),
|
|
50
53
|
consentId: z.string().min(1).max(100).optional(),
|
|
51
54
|
});
|
|
52
55
|
// Map normalized SubscriptionEventType → fully-qualified ES event-name.
|
|
@@ -57,14 +60,55 @@ const NORMALIZED_TO_ES_EVENT = {
|
|
|
57
60
|
[SubscriptionEventTypes.invoicePaid]: INVOICE_PAID_EVENT_QN,
|
|
58
61
|
[SubscriptionEventTypes.invoicePaymentFailed]: INVOICE_PAYMENT_FAILED_EVENT_QN,
|
|
59
62
|
};
|
|
63
|
+
const STATE_EVENT_TYPES = new Set([
|
|
64
|
+
SubscriptionEventTypes.created,
|
|
65
|
+
SubscriptionEventTypes.updated,
|
|
66
|
+
SubscriptionEventTypes.canceled,
|
|
67
|
+
]);
|
|
68
|
+
function isLateStateEvent(storedEvents, payload) {
|
|
69
|
+
if (payload.providerEventAtIso === undefined || !STATE_EVENT_TYPES.has(payload.type)) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
const incoming = Temporal.Instant.from(payload.providerEventAtIso);
|
|
73
|
+
return storedEvents.some((stored) => {
|
|
74
|
+
const storedAt = propertyOf(stored.payload, "providerEventAtIso");
|
|
75
|
+
if (stored.metadata.headers?.["providerName"] !== payload.providerName)
|
|
76
|
+
return false;
|
|
77
|
+
if (typeof storedAt !== "string")
|
|
78
|
+
return false;
|
|
79
|
+
// A stored value that does not parse can never prove a newer event; skip it instead of
|
|
80
|
+
// failing every later delivery of this tenant's stream.
|
|
81
|
+
try {
|
|
82
|
+
return Temporal.Instant.compare(Temporal.Instant.from(storedAt), incoming) > 0;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
60
89
|
// =============================================================================
|
|
61
90
|
// appendSubscriptionEvent — the append-body, shared by processEventHandler
|
|
62
91
|
// (webhook path) and sync-subscription.write.ts (backfill path). Both call
|
|
63
92
|
// this with the same normalized payload shape; the difference is only in
|
|
64
93
|
// who constructs `payload` and what `providerEventId` they use.
|
|
65
94
|
// =============================================================================
|
|
66
|
-
|
|
95
|
+
// A provider timestamp far in the future would make every later, genuine event look late.
|
|
96
|
+
const PROVIDER_EVENT_CLOCK_SKEW_SECONDS = 300;
|
|
97
|
+
export function clampProviderEventAt(payload, now) {
|
|
98
|
+
if (payload.providerEventAtIso === undefined)
|
|
99
|
+
return payload;
|
|
100
|
+
const ceiling = now.add({ seconds: PROVIDER_EVENT_CLOCK_SKEW_SECONDS });
|
|
101
|
+
return Temporal.Instant.compare(Temporal.Instant.from(payload.providerEventAtIso), ceiling) > 0
|
|
102
|
+
? { ...payload, providerEventAtIso: ceiling.toString() }
|
|
103
|
+
: payload;
|
|
104
|
+
}
|
|
105
|
+
export async function appendSubscriptionEvent(ctx, tenantId, rawPayload, now = Temporal.Now.instant()) {
|
|
67
106
|
const aggId = subscriptionAggregateId(tenantId);
|
|
107
|
+
const payload = clampProviderEventAt(rawPayload, now);
|
|
108
|
+
// Serialises the read (idempotency + late check) with the append: the append re-reads the
|
|
109
|
+
// stream version itself, so without the lock a concurrent delivery could slip in between and
|
|
110
|
+
// the late check would have judged an outdated stream.
|
|
111
|
+
await ctx.db.advisoryXactLock(BILLING_SUBSCRIPTION_LOCK_NAMESPACE, aggId);
|
|
68
112
|
// ---------------------------------------------------------------
|
|
69
113
|
// 1. Idempotency: load the subscription stream and check whether this
|
|
70
114
|
// providerEventId was already seen. A provider retry storm (Stripe
|
|
@@ -85,6 +129,13 @@ export async function appendSubscriptionEvent(ctx, tenantId, payload) {
|
|
|
85
129
|
if (alreadySeen) {
|
|
86
130
|
return { duplicate: true, subscriptionAggregateId: aggId };
|
|
87
131
|
}
|
|
132
|
+
// A state event the provider emitted before the newest one already stored is a
|
|
133
|
+
// late delivery: appending it would roll the row back (a canceled subscription
|
|
134
|
+
// would come back active). Invoice events carry the live state, not a snapshot.
|
|
135
|
+
if (isLateStateEvent(existingEvents, payload)) {
|
|
136
|
+
ctx.log?.warn(`[billing-foundation:process-event] dropped late ${payload.type} ${payload.providerEventId}: a newer provider event is already stored`);
|
|
137
|
+
return { duplicate: false, stale: true, subscriptionAggregateId: aggId };
|
|
138
|
+
}
|
|
88
139
|
// ---------------------------------------------------------------
|
|
89
140
|
// 2. Map normalized event-type → ES event-FQN.
|
|
90
141
|
// ---------------------------------------------------------------
|
|
@@ -131,6 +182,9 @@ export async function appendSubscriptionEvent(ctx, tenantId, payload) {
|
|
|
131
182
|
currentPeriodEndIso: payload.currentPeriodEndIso,
|
|
132
183
|
...(payload.cancelAtIso !== undefined && { cancelAtIso: payload.cancelAtIso }),
|
|
133
184
|
...(payload.consentId !== undefined && { consentId: payload.consentId }),
|
|
185
|
+
...(payload.providerEventAtIso !== undefined && {
|
|
186
|
+
providerEventAtIso: payload.providerEventAtIso,
|
|
187
|
+
}),
|
|
134
188
|
};
|
|
135
189
|
const headers = {
|
|
136
190
|
providerEventId: payload.providerEventId,
|
|
@@ -190,7 +244,7 @@ export function createProcessEventHandler(now) {
|
|
|
190
244
|
},
|
|
191
245
|
};
|
|
192
246
|
}
|
|
193
|
-
const result = await appendSubscriptionEvent(ctx, event.user.tenantId, payload);
|
|
247
|
+
const result = await appendSubscriptionEvent(ctx, event.user.tenantId, payload, now());
|
|
194
248
|
return { isSuccess: true, data: result };
|
|
195
249
|
},
|
|
196
250
|
};
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
import { ConflictError, UnprocessableError } from "@cosmicdrift/kumiko-framework/errors";
|
|
6
6
|
import * as z from "zod";
|
|
7
7
|
import { assertBillingEnabled, assertRedirectOrigins, isNonEmptyStringArray, joinBaseUrl, resolveCatalogProvider, } from "../checkout-core.js";
|
|
8
|
-
import { isSwitchableSubscriptionStatus } from "../constants.js";
|
|
9
8
|
import { getSubscriptionForTenant } from "../get-subscription-for-tenant.js";
|
|
10
9
|
import { purchaseRolesOf, resolvePlanPrices } from "../plan-catalog.js";
|
|
10
|
+
import { isSwitchableSubscriptionStatus } from "../web/constants.js";
|
|
11
11
|
export function createSwitchPlanHandler(options, catalog) {
|
|
12
12
|
const plans = catalog.plans;
|
|
13
13
|
if (!isNonEmptyStringArray(plans)) {
|
|
@@ -17,8 +17,8 @@ import { SYSTEM_ROLE } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
17
17
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
18
18
|
import * as z from "zod";
|
|
19
19
|
import { findProviderPlugin } from "../checkout-core.js";
|
|
20
|
-
import { isTerminalSubscriptionStatus, SubscriptionEventTypes } from "../constants.js";
|
|
21
20
|
import { getSubscriptionForTenant } from "../get-subscription-for-tenant.js";
|
|
21
|
+
import { isTerminalSubscriptionStatus, SubscriptionEventTypes } from "../web/constants.js";
|
|
22
22
|
import { appendSubscriptionEvent } from "./process-event.write.js";
|
|
23
23
|
export const syncSubscriptionSchema = z.object({}).strict();
|
|
24
24
|
// Parses both sides fresh via Temporal before comparing — tolerant of a
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
export { paymentAggregateId, subscriptionAggregateId } from "./aggregate-id.ts";
|
|
2
2
|
export { type BillingInfo, type BillingInfoQueryDeps, createBillingInfoQueryConfig, } from "./billing-info-query.ts";
|
|
3
3
|
export { isBillingEnabled, type ResolvedProvider, resolveProviderPlugin, } from "./checkout-core.ts";
|
|
4
|
-
export { BILLING_FOUNDATION_FEATURE, BILLING_PLANS_PANEL_COMPONENT, BILLING_PLANS_SCREEN_ID, type BillingEventKind, BillingEventKinds, type BillingPlanAction, BillingPlanActions, DEFAULT_PURCHASE_ROLES, isSwitchableSubscriptionStatus, isTerminalSubscriptionStatus, parseProviderConsentId, SUBSCRIPTION_PROVIDER_EXTENSION, type SubscriptionCancelTiming, SubscriptionCancelTimings, type SubscriptionEventType, SubscriptionEventTypes, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, type SubscriptionStatus, SubscriptionStatuses, } from "./constants.ts";
|
|
5
4
|
export { type ConsentPayload, consentPayloadSchema, type OrderItem, } from "./consumer-protection/consent-gate.ts";
|
|
6
|
-
export { CONSENT_LOCALES, type ConsentLocale, resolveConsentLocale, } from "./consumer-protection/consent-locale.ts";
|
|
7
5
|
export { type ContractTerminationRoutesOptions, createContractTerminationRoutes, } from "./consumer-protection/termination-pages.ts";
|
|
8
6
|
export { paymentEntity, subscriptionEntity } from "./entities.ts";
|
|
9
7
|
export { INVOICE_PAID_EVENT_QN, INVOICE_PAID_EVENT_SHORT, INVOICE_PAYMENT_FAILED_EVENT_QN, INVOICE_PAYMENT_FAILED_EVENT_SHORT, PAYMENT_AGGREGATE_TYPE, PAYMENT_RECEIVED_EVENT_QN, PAYMENT_RECEIVED_EVENT_SHORT, type PaymentEventHeaders, type PaymentEventPayload, paymentEventPayloadSchema, SUBSCRIPTION_AGGREGATE_TYPE, SUBSCRIPTION_CANCELED_EVENT_QN, SUBSCRIPTION_CANCELED_EVENT_SHORT, SUBSCRIPTION_CREATED_EVENT_QN, SUBSCRIPTION_CREATED_EVENT_SHORT, SUBSCRIPTION_UPDATED_EVENT_QN, SUBSCRIPTION_UPDATED_EVENT_SHORT, type SubscriptionEventHeaders, type SubscriptionEventPayload, subscriptionEventPayloadSchema, } from "./events.ts";
|
|
@@ -13,4 +11,6 @@ export { paymentsProjectionTable, subscriptionsProjectionTable } from "./project
|
|
|
13
11
|
export { billingPlansPanel, createBillingPlansScreen } from "./screens.ts";
|
|
14
12
|
export { createSubscriptionTierSync, effectiveTierFromSubscription, SUBSCRIPTION_WEBHOOK_PATH, type SubscriptionTierSyncDeps, type TierSyncResult, } from "./subscription-tier-sync.ts";
|
|
15
13
|
export { type BillingFoundationOptions, type BillingPlanBenefit, type BillingPlanCatalog, type BillingPlanContactCard, type BillingPlanPrice, type BillingPlansResult, type BillingPlanView, type ConsumerProtectionOptions, KNOWN_RECURRING_INTERVALS, type LegalLinkSet, type PaymentEvent, type ProviderPrice, type ProviderSubscriptionSnapshot, type RecurringInterval, type SubscriptionEvent, type SubscriptionProviderPlugin, } from "./types.ts";
|
|
14
|
+
export { BILLING_FOUNDATION_FEATURE, BILLING_PLANS_PANEL_COMPONENT, BILLING_PLANS_SCREEN_ID, type BillingEventKind, BillingEventKinds, type BillingPlanAction, BillingPlanActions, DEFAULT_PURCHASE_ROLES, isSwitchableSubscriptionStatus, isTerminalSubscriptionStatus, parseProviderConsentId, SUBSCRIPTION_PROVIDER_EXTENSION, type SubscriptionCancelTiming, SubscriptionCancelTimings, type SubscriptionEventType, SubscriptionEventTypes, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, type SubscriptionStatus, SubscriptionStatuses, } from "./web/constants.ts";
|
|
15
|
+
export { CONSENT_LOCALES, type ConsentLocale, resolveConsentLocale, } from "./web/consumer-protection/consent-locale.ts";
|
|
16
16
|
export { createSubscriptionWebhookRoute, type SubscriptionWebhookRouteOptions, } from "./webhook-handler.ts";
|
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
export { paymentAggregateId, subscriptionAggregateId } from "./aggregate-id.js";
|
|
3
3
|
export { createBillingInfoQueryConfig, } from "./billing-info-query.js";
|
|
4
4
|
export { isBillingEnabled, resolveProviderPlugin, } from "./checkout-core.js";
|
|
5
|
-
export { BILLING_FOUNDATION_FEATURE, BILLING_PLANS_PANEL_COMPONENT, BILLING_PLANS_SCREEN_ID, BillingEventKinds, BillingPlanActions, DEFAULT_PURCHASE_ROLES, isSwitchableSubscriptionStatus, isTerminalSubscriptionStatus, parseProviderConsentId, SUBSCRIPTION_PROVIDER_EXTENSION, SubscriptionCancelTimings, SubscriptionEventTypes, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, SubscriptionStatuses, } from "./constants.js";
|
|
6
5
|
export { consentPayloadSchema, } from "./consumer-protection/consent-gate.js";
|
|
7
|
-
export { CONSENT_LOCALES, resolveConsentLocale, } from "./consumer-protection/consent-locale.js";
|
|
8
6
|
export { createContractTerminationRoutes, } from "./consumer-protection/termination-pages.js";
|
|
9
7
|
export { paymentEntity, subscriptionEntity } from "./entities.js";
|
|
10
8
|
export { INVOICE_PAID_EVENT_QN, INVOICE_PAID_EVENT_SHORT, INVOICE_PAYMENT_FAILED_EVENT_QN, INVOICE_PAYMENT_FAILED_EVENT_SHORT, PAYMENT_AGGREGATE_TYPE, PAYMENT_RECEIVED_EVENT_QN, PAYMENT_RECEIVED_EVENT_SHORT, paymentEventPayloadSchema, SUBSCRIPTION_AGGREGATE_TYPE, SUBSCRIPTION_CANCELED_EVENT_QN, SUBSCRIPTION_CANCELED_EVENT_SHORT, SUBSCRIPTION_CREATED_EVENT_QN, SUBSCRIPTION_CREATED_EVENT_SHORT, SUBSCRIPTION_UPDATED_EVENT_QN, SUBSCRIPTION_UPDATED_EVENT_SHORT, subscriptionEventPayloadSchema, } from "./events.js";
|
|
@@ -14,4 +12,6 @@ export { paymentsProjectionTable, subscriptionsProjectionTable } from "./project
|
|
|
14
12
|
export { billingPlansPanel, createBillingPlansScreen } from "./screens.js";
|
|
15
13
|
export { createSubscriptionTierSync, effectiveTierFromSubscription, SUBSCRIPTION_WEBHOOK_PATH, } from "./subscription-tier-sync.js";
|
|
16
14
|
export { KNOWN_RECURRING_INTERVALS, } from "./types.js";
|
|
15
|
+
export { BILLING_FOUNDATION_FEATURE, BILLING_PLANS_PANEL_COMPONENT, BILLING_PLANS_SCREEN_ID, BillingEventKinds, BillingPlanActions, DEFAULT_PURCHASE_ROLES, isSwitchableSubscriptionStatus, isTerminalSubscriptionStatus, parseProviderConsentId, SUBSCRIPTION_PROVIDER_EXTENSION, SubscriptionCancelTimings, SubscriptionEventTypes, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, SubscriptionStatuses, } from "./web/constants.js";
|
|
16
|
+
export { CONSENT_LOCALES, resolveConsentLocale, } from "./web/consumer-protection/consent-locale.js";
|
|
17
17
|
export { createSubscriptionWebhookRoute, } from "./webhook-handler.js";
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// caller's current tier + subscription, and the action available per plan.
|
|
4
4
|
// Internal — not re-exported from index.ts.
|
|
5
5
|
import { isPluginBillingEnabled } from "./checkout-core.js";
|
|
6
|
-
import { BillingPlanActions, DEFAULT_PURCHASE_ROLES, isSubscriptionBlockingCheckout, isSwitchableSubscriptionStatus, SubscriptionStatuses, } from "./constants.js";
|
|
7
6
|
import { getSubscriptionForTenant } from "./get-subscription-for-tenant.js";
|
|
7
|
+
import { BillingPlanActions, DEFAULT_PURCHASE_ROLES, isSubscriptionBlockingCheckout, isSwitchableSubscriptionStatus, SubscriptionStatuses, } from "./web/constants.js";
|
|
8
8
|
function userHasAnyRole(userRoles, allowedRoles) {
|
|
9
9
|
return allowedRoles.some((role) => userRoles.includes(role));
|
|
10
10
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BILLING_PLANS_PANEL_COMPONENT, BILLING_PLANS_SCREEN_ID } from "./constants.js";
|
|
1
|
+
import { BILLING_PLANS_PANEL_COMPONENT, BILLING_PLANS_SCREEN_ID } from "./web/constants.js";
|
|
2
2
|
/** The billing-plans panel, meant to be dropped into an app's own dashboard
|
|
3
3
|
* screen alongside its own panels — not just the dormant single-panel
|
|
4
4
|
* screen below. */
|
|
@@ -5,7 +5,7 @@
|
|
|
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";
|
|
8
|
-
import { SubscriptionFoundationQueries, SubscriptionStatuses } from "./constants.js";
|
|
8
|
+
import { SubscriptionFoundationQueries, SubscriptionStatuses } from "./web/constants.js";
|
|
9
9
|
import { createSubscriptionWebhookRoute } from "./webhook-handler.js";
|
|
10
10
|
// Outside /api — signature routes carry their own auth (verify()) and are
|
|
11
11
|
// not JWT-guarded, so provider dashboards (Stripe, PayPal, ...) point here.
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import type { TenantDb } from "@cosmicdrift/kumiko-framework/db";
|
|
3
3
|
import type { HandlerContext, TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
4
|
import type { SecretsContext } from "@cosmicdrift/kumiko-framework/secrets";
|
|
5
|
-
import { type BillingEventKinds, type BillingPlanAction, SUBSCRIPTION_PROVIDER_EXTENSION, type SubscriptionCancelTiming, type SubscriptionEventType, type SubscriptionStatus, type TerminationScope } from "./constants.ts";
|
|
6
5
|
import type { OrderItem } from "./consumer-protection/consent-gate.ts";
|
|
7
|
-
import type
|
|
6
|
+
import { type BillingEventKinds, type BillingPlanAction, SUBSCRIPTION_PROVIDER_EXTENSION, type SubscriptionCancelTiming, type SubscriptionEventType, type SubscriptionStatus, type TerminationScope } from "./web/constants.ts";
|
|
7
|
+
import type { ConsentLocale } from "./web/consumer-protection/consent-locale.ts";
|
|
8
8
|
export type SubscriptionEvent = {
|
|
9
9
|
/** Discriminator against PaymentEvent. Optional (instead of required) so
|
|
10
10
|
* existing plugins like subscription-mollie, which don't set this field,
|
|
@@ -46,6 +46,10 @@ export type SubscriptionEvent = {
|
|
|
46
46
|
* Mollie), so projection.ts leaves the column unchanged instead of
|
|
47
47
|
* nulling it. */
|
|
48
48
|
readonly cancelAt?: string | null;
|
|
49
|
+
/** ISO instant the provider emitted this event. process-event drops a
|
|
50
|
+
* state event older than the newest one already stored, since providers
|
|
51
|
+
* do not guarantee delivery order. Omitted by providers that report none. */
|
|
52
|
+
readonly providerEventAt?: string;
|
|
49
53
|
};
|
|
50
54
|
export type PaymentEvent = {
|
|
51
55
|
/** Required — distinguishes this union member at runtime from
|
|
@@ -171,6 +175,14 @@ export type SubscriptionProviderPlugin = {
|
|
|
171
175
|
readonly providerSubscriptionId: string;
|
|
172
176
|
readonly when: SubscriptionCancelTiming;
|
|
173
177
|
}) => Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* Optional: takes back a `period-end` cancellation that has not taken effect
|
|
180
|
+
* yet. Without it, a revoked public termination is reported to the operator
|
|
181
|
+
* to undo by hand.
|
|
182
|
+
*/
|
|
183
|
+
readonly resumeSubscription?: (ctx: HandlerContext, options: {
|
|
184
|
+
readonly providerSubscriptionId: string;
|
|
185
|
+
}) => Promise<void>;
|
|
174
186
|
/**
|
|
175
187
|
* The provider's own price/plan-id → app-tier-name mapping. This is the
|
|
176
188
|
* one source `checkout-core`/`plan-catalog` derive both hardening
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
// Foundation nutzt nur den common-subset der Provider-Funktionalität —
|
|
25
25
|
// proration, multi-currency, coupons etc. bleiben provider-spezifisch
|
|
26
26
|
// und sind über den Customer-Portal-Link erreichbar.
|
|
27
|
-
import { SUBSCRIPTION_PROVIDER_EXTENSION, } from "./constants.js";
|
|
27
|
+
import { SUBSCRIPTION_PROVIDER_EXTENSION, } from "./web/constants.js";
|
|
28
28
|
// =============================================================================
|
|
29
29
|
// Provider price + billing-plans catalog
|
|
30
30
|
// =============================================================================
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
// concerns (app-feature-structure guard's 300-line budget). Internal — not
|
|
4
4
|
// re-exported from index.ts.
|
|
5
5
|
import * as z from "zod";
|
|
6
|
-
import { isTerminationScope, TERMINATION_SCOPES } from "./constants.js";
|
|
7
|
-
import { CONSENT_LOCALES } from "./consumer-protection/consent-locale.js";
|
|
8
|
-
import { isContactCardHref } from "./contact-card.js";
|
|
9
6
|
import { isLegalLinkSet, } from "./types.js";
|
|
7
|
+
import { isTerminationScope, TERMINATION_SCOPES } from "./web/constants.js";
|
|
8
|
+
import { CONSENT_LOCALES } from "./web/consumer-protection/consent-locale.js";
|
|
9
|
+
import { isContactCardHref } from "./web/contact-card.js";
|
|
10
10
|
function isRootRelativePath(path) {
|
|
11
11
|
return path.startsWith("/") && !path.startsWith("//");
|
|
12
12
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
// @runtime client
|
|
3
2
|
import { useLocale, useTranslation } from "@cosmicdrift/kumiko-renderer";
|
|
4
3
|
import { PlanCard } from "@cosmicdrift/kumiko-renderer/web";
|
|
5
|
-
import { isContactCardHref } from "
|
|
4
|
+
import { isContactCardHref } from "./contact-card.js";
|
|
6
5
|
import { localizedParams } from "./localized-params.js";
|
|
7
6
|
export function BillingContactPlan({ contact, }) {
|
|
8
7
|
const t = useTranslation();
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// @runtime client
|
|
3
2
|
import { useLocale, useMutation, usePrimitives, useQuery, useTranslation, } from "@cosmicdrift/kumiko-renderer";
|
|
4
3
|
import { toInstant } from "@cosmicdrift/kumiko-renderer/headless";
|
|
5
4
|
import { formatMoney, PlanCard, PlanGrid, } from "@cosmicdrift/kumiko-renderer/web";
|
|
6
5
|
import { useState } from "react";
|
|
7
|
-
import { BillingPlanActions, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, SubscriptionStatuses, } from "../constants.js";
|
|
8
6
|
import { BillingContactPlan } from "./billing-contact-plan.js";
|
|
9
7
|
import { CancelContractDialog } from "./cancel-contract-dialog.js";
|
|
10
8
|
import { CheckoutConsentDialog } from "./checkout-consent-dialog.js";
|
|
9
|
+
import { BillingPlanActions, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, SubscriptionStatuses, } from "./constants.js";
|
|
11
10
|
import { localizedParams } from "./localized-params.js";
|
|
12
11
|
function intervalKey(price) {
|
|
13
12
|
if (price === null || price.interval === null)
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// @runtime client
|
|
3
2
|
import { useLocale, useMutation, usePrimitives, useTranslation, } from "@cosmicdrift/kumiko-renderer";
|
|
4
3
|
import { toInstant } from "@cosmicdrift/kumiko-renderer/headless";
|
|
5
4
|
import { ModeSwitch } from "@cosmicdrift/kumiko-renderer/web";
|
|
6
5
|
import { useState } from "react";
|
|
7
|
-
import { SubscriptionFoundationHandlers } from "
|
|
6
|
+
import { SubscriptionFoundationHandlers } from "./constants.js";
|
|
8
7
|
const DECLARATION_TYPES = [
|
|
9
8
|
"termination",
|
|
10
9
|
"withdrawal",
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// @runtime client
|
|
3
2
|
import { useLocale, usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
|
|
4
3
|
import { useState } from "react";
|
|
5
|
-
import { resolveConsentLocale } from "
|
|
4
|
+
import { resolveConsentLocale } from "./consumer-protection/consent-locale.js";
|
|
6
5
|
export const CONSENT_TEXT_OUTDATED_CODE = "consent_text_outdated";
|
|
7
6
|
// kumiko-lint-ignore no-custom-primitives Uses usePrimitives().Modal internally, name is a billing domain action, not a primitive reimplementation
|
|
8
7
|
export function CheckoutConsentDialog({ open, onOpenChange, planName, price, consumerProtection, onOrder, onConsentTextOutdated, }) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BILLING_FOUNDATION_FEATURE, BILLING_PLANS_PANEL_COMPONENT } from "../constants.js";
|
|
2
1
|
import { BillingPlansPanel } from "./billing-plans-panel.js";
|
|
2
|
+
import { BILLING_FOUNDATION_FEATURE, BILLING_PLANS_PANEL_COMPONENT } from "./constants.js";
|
|
3
3
|
export function billingFoundationClient(options) {
|
|
4
4
|
return {
|
|
5
5
|
name: BILLING_FOUNDATION_FEATURE,
|
|
@@ -9,19 +9,18 @@ export declare const CONTRACT_CONFIRMATION_NOTIFICATION_TYPE: "billing-foundatio
|
|
|
9
9
|
export declare const CONTRACT_TERMINATION_RECEIPT_NOTIFICATION_TYPE: "billing-foundation:notify:contract-termination-receipt";
|
|
10
10
|
export declare const CONTRACT_TERMINATION_OPERATOR_NOTIFICATION_TYPE: "billing-foundation:notify:contract-termination-operator-notice";
|
|
11
11
|
export declare const SubscriptionFoundationHandlers: {
|
|
12
|
-
/** Programmatic entry
|
|
13
|
-
* parsed SubscriptionEvent (
|
|
14
|
-
* insert-event + upsert-subscription + tier-sync
|
|
12
|
+
/** Programmatic entry point for the webhook handler. Receives the
|
|
13
|
+
* parsed SubscriptionEvent (already verified by the plugin) and does
|
|
14
|
+
* insert-event + upsert-subscription + tier-sync atomically. */
|
|
15
15
|
readonly processEvent: "billing-foundation:write:process-event";
|
|
16
|
-
/** Tenant
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* subscription. */
|
|
16
|
+
/** Tenant admin clicks "Upgrade to Pro": the handler finds the chosen
|
|
17
|
+
* provider plugin, calls its createCheckoutSession and returns the
|
|
18
|
+
* hosted-page URL. The admin is redirected there; the subsequent
|
|
19
|
+
* provider webhook creates the subscription. */
|
|
21
20
|
readonly createCheckoutSession: "billing-foundation:write:create-checkout-session";
|
|
22
|
-
/** Tenant
|
|
23
|
-
* current subscription,
|
|
24
|
-
* hosted-portal
|
|
21
|
+
/** Tenant admin clicks "Manage Subscription": the handler finds the
|
|
22
|
+
* current subscription, calls plugin.createPortalSession and returns the
|
|
23
|
+
* hosted-portal URL. */
|
|
25
24
|
readonly createPortalSession: "billing-foundation:write:create-portal-session";
|
|
26
25
|
/** Programmatic entry-point for the webhook-handler on a one-off-payment
|
|
27
26
|
* (checkout mode "payment"). Its own per-tenant aggregate-stream
|
|
@@ -45,6 +44,12 @@ export declare const SubscriptionFoundationHandlers: {
|
|
|
45
44
|
/** Anonymous § 312k cancellation/withdrawal declaration (consumerProtection
|
|
46
45
|
* only). */
|
|
47
46
|
readonly requestContractTermination: "billing-foundation:write:request-contract-termination";
|
|
47
|
+
/** Anonymous "this was not me" revocation of a public declaration, by the
|
|
48
|
+
* link of the receipt mail (consumerProtection only). */
|
|
49
|
+
readonly revokeContractTermination: "billing-foundation:write:revoke-contract-termination";
|
|
50
|
+
/** System-only: checks the revocation token against the tenant's declaration
|
|
51
|
+
* and takes the cancellation back (consumerProtection only). */
|
|
52
|
+
readonly recordContractTerminationRevocation: "billing-foundation:write:record-contract-termination-revocation";
|
|
48
53
|
/** Tenant-Admin terminates or withdraws from the contract of their own
|
|
49
54
|
* tenant (consumerProtection only). */
|
|
50
55
|
readonly terminateContract: "billing-foundation:write:terminate-contract";
|
|
@@ -65,9 +70,9 @@ export declare const SubscriptionFoundationHandlers: {
|
|
|
65
70
|
readonly syncSubscription: "billing-foundation:write:sync-subscription";
|
|
66
71
|
};
|
|
67
72
|
export declare const SubscriptionFoundationQueries: {
|
|
68
|
-
/** Sysadmin
|
|
69
|
-
* read_subscriptions
|
|
70
|
-
*
|
|
73
|
+
/** Sysadmin cross-tenant and tenant-scoped self-list on the
|
|
74
|
+
* read_subscriptions projection. A tenant admin only sees their own row
|
|
75
|
+
* because ctx.db is tenant-scoped. */
|
|
71
76
|
readonly listSubscriptions: "billing-foundation:query:subscription:list";
|
|
72
77
|
/** Lists the catalog's plans with live price, benefits, the caller's
|
|
73
78
|
* current tier and per-plan action. Only registered when a `catalog` is
|
|
@@ -135,3 +140,5 @@ export declare const DEFAULT_PURCHASE_ROLES: readonly ["TenantAdmin", "SystemAdm
|
|
|
135
140
|
export declare const TERMINATION_SCOPES: readonly ["tenant-host", "platform"];
|
|
136
141
|
export type TerminationScope = (typeof TERMINATION_SCOPES)[number];
|
|
137
142
|
export declare function isTerminationScope(value: unknown): value is TerminationScope;
|
|
143
|
+
/** Advisory-lock namespace serialising appends onto one tenant's subscription stream. */
|
|
144
|
+
export declare const BILLING_SUBSCRIPTION_LOCK_NAMESPACE = 1651076204;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/// <reference types="temporal-polyfill/global" preserve="true" />
|
|
2
|
-
// @runtime client
|
|
3
2
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
4
3
|
import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
5
4
|
// Feature name
|
|
6
5
|
export const BILLING_FOUNDATION_FEATURE = "billing-foundation";
|
|
7
|
-
// Extension-point name
|
|
6
|
+
// Extension-point name for provider plugins (subscription-stripe,
|
|
8
7
|
// subscription-mollie, ...).
|
|
9
8
|
export const SUBSCRIPTION_PROVIDER_EXTENSION = "subscriptionProvider";
|
|
10
9
|
/** delivery notification type of the § 312f contract confirmation mail. */
|
|
@@ -15,19 +14,18 @@ export const CONTRACT_TERMINATION_RECEIPT_NOTIFICATION_TYPE = "billing-foundatio
|
|
|
15
14
|
export const CONTRACT_TERMINATION_OPERATOR_NOTIFICATION_TYPE = "billing-foundation:notify:contract-termination-operator-notice";
|
|
16
15
|
// Qualified write handler names (QN format: scope:type:name).
|
|
17
16
|
export const SubscriptionFoundationHandlers = {
|
|
18
|
-
/** Programmatic entry
|
|
19
|
-
* parsed SubscriptionEvent (
|
|
20
|
-
* insert-event + upsert-subscription + tier-sync
|
|
17
|
+
/** Programmatic entry point for the webhook handler. Receives the
|
|
18
|
+
* parsed SubscriptionEvent (already verified by the plugin) and does
|
|
19
|
+
* insert-event + upsert-subscription + tier-sync atomically. */
|
|
21
20
|
processEvent: "billing-foundation:write:process-event",
|
|
22
|
-
/** Tenant
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* subscription. */
|
|
21
|
+
/** Tenant admin clicks "Upgrade to Pro": the handler finds the chosen
|
|
22
|
+
* provider plugin, calls its createCheckoutSession and returns the
|
|
23
|
+
* hosted-page URL. The admin is redirected there; the subsequent
|
|
24
|
+
* provider webhook creates the subscription. */
|
|
27
25
|
createCheckoutSession: "billing-foundation:write:create-checkout-session",
|
|
28
|
-
/** Tenant
|
|
29
|
-
* current subscription,
|
|
30
|
-
* hosted-portal
|
|
26
|
+
/** Tenant admin clicks "Manage Subscription": the handler finds the
|
|
27
|
+
* current subscription, calls plugin.createPortalSession and returns the
|
|
28
|
+
* hosted-portal URL. */
|
|
31
29
|
createPortalSession: "billing-foundation:write:create-portal-session",
|
|
32
30
|
/** Programmatic entry-point for the webhook-handler on a one-off-payment
|
|
33
31
|
* (checkout mode "payment"). Its own per-tenant aggregate-stream
|
|
@@ -51,6 +49,12 @@ export const SubscriptionFoundationHandlers = {
|
|
|
51
49
|
/** Anonymous § 312k cancellation/withdrawal declaration (consumerProtection
|
|
52
50
|
* only). */
|
|
53
51
|
requestContractTermination: "billing-foundation:write:request-contract-termination",
|
|
52
|
+
/** Anonymous "this was not me" revocation of a public declaration, by the
|
|
53
|
+
* link of the receipt mail (consumerProtection only). */
|
|
54
|
+
revokeContractTermination: "billing-foundation:write:revoke-contract-termination",
|
|
55
|
+
/** System-only: checks the revocation token against the tenant's declaration
|
|
56
|
+
* and takes the cancellation back (consumerProtection only). */
|
|
57
|
+
recordContractTerminationRevocation: "billing-foundation:write:record-contract-termination-revocation",
|
|
54
58
|
/** Tenant-Admin terminates or withdraws from the contract of their own
|
|
55
59
|
* tenant (consumerProtection only). */
|
|
56
60
|
terminateContract: "billing-foundation:write:terminate-contract",
|
|
@@ -72,9 +76,9 @@ export const SubscriptionFoundationHandlers = {
|
|
|
72
76
|
};
|
|
73
77
|
// Qualified query handler names.
|
|
74
78
|
export const SubscriptionFoundationQueries = {
|
|
75
|
-
/** Sysadmin
|
|
76
|
-
* read_subscriptions
|
|
77
|
-
*
|
|
79
|
+
/** Sysadmin cross-tenant and tenant-scoped self-list on the
|
|
80
|
+
* read_subscriptions projection. A tenant admin only sees their own row
|
|
81
|
+
* because ctx.db is tenant-scoped. */
|
|
78
82
|
listSubscriptions: "billing-foundation:query:subscription:list",
|
|
79
83
|
/** Lists the catalog's plans with live price, benefits, the caller's
|
|
80
84
|
* current tier and per-plan action. Only registered when a `catalog` is
|
|
@@ -85,9 +89,9 @@ export const SubscriptionFoundationQueries = {
|
|
|
85
89
|
terminableSubscription: "billing-foundation:query:terminable-subscription",
|
|
86
90
|
};
|
|
87
91
|
// Normalized subscription-event types — provider-agnostic.
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
92
|
+
// All provider plugins normalize their own event types onto one of these.
|
|
93
|
+
// Whitelist of what the foundation knows; anything else must be filtered by
|
|
94
|
+
// the plugin, which returns null from verifyAndParseWebhook.
|
|
91
95
|
export const SubscriptionEventTypes = {
|
|
92
96
|
created: "subscription.created",
|
|
93
97
|
updated: "subscription.updated",
|
|
@@ -96,8 +100,8 @@ export const SubscriptionEventTypes = {
|
|
|
96
100
|
invoicePaymentFailed: "invoice.payment-failed",
|
|
97
101
|
};
|
|
98
102
|
// Normalized subscription-status values — provider-agnostic.
|
|
99
|
-
// Stripe
|
|
100
|
-
//
|
|
103
|
+
// Stripe and Mollie have different status sets; the plugin maps onto this
|
|
104
|
+
// common subset.
|
|
101
105
|
export const SubscriptionStatuses = {
|
|
102
106
|
active: "active",
|
|
103
107
|
trialing: "trialing",
|
|
@@ -183,18 +187,18 @@ export function isSwitchableSubscriptionStatus(status) {
|
|
|
183
187
|
// override `purchaseRoles` — matches create-checkout-session's existing
|
|
184
188
|
// TenantAdmin/SystemAdmin-only access.
|
|
185
189
|
export const DEFAULT_PURCHASE_ROLES = ["TenantAdmin", "SystemAdmin"];
|
|
186
|
-
// **Multi-
|
|
187
|
-
//
|
|
188
|
-
//
|
|
189
|
-
//
|
|
190
|
-
//
|
|
191
|
-
// subscription.providerName, kommt aus dem checkout-flow.
|
|
190
|
+
// **Multi-provider from day one:** subscription-foundation has NO `provider`
|
|
191
|
+
// config key. All mounted plugins are active in parallel; the end customer
|
|
192
|
+
// picks between card/PayPal/Apple Pay/Klarna/SEPA at subscribe time
|
|
193
|
+
// (Disney+ pattern). Which provider currently holds the tenant's
|
|
194
|
+
// subscription is stored in subscription.providerName, set by the checkout flow.
|
|
192
195
|
//
|
|
193
|
-
// price-to-tier
|
|
194
|
-
// Stripe
|
|
195
|
-
//
|
|
196
|
-
// `<plugin-name>:config:price-to-tier`-Key.
|
|
196
|
+
// The price-to-tier map is NOT foundation config: it is per plugin, because
|
|
197
|
+
// Stripe priceIds, PayPal plan ids and Apple product ids are different IDs.
|
|
198
|
+
// Each plugin defines its own `<plugin-name>:config:price-to-tier` key.
|
|
197
199
|
export const TERMINATION_SCOPES = ["tenant-host", "platform"];
|
|
198
200
|
export function isTerminationScope(value) {
|
|
199
201
|
return isOneOf(TERMINATION_SCOPES, value);
|
|
200
202
|
}
|
|
203
|
+
/** Advisory-lock namespace serialising appends onto one tenant's subscription stream. */
|
|
204
|
+
export const BILLING_SUBSCRIPTION_LOCK_NAMESPACE = 0x62_69_6c_6c; // 'bill'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { BILLING_PLANS_SCREEN_ID, type BillingPlanAction, BillingPlanActions, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, type SubscriptionStatus, SubscriptionStatuses, } from "../constants.ts";
|
|
2
|
-
export { CONSENT_LOCALES, type ConsentLocale, resolveConsentLocale, } from "../consumer-protection/consent-locale.ts";
|
|
3
1
|
export type { BillingPlanBenefit, BillingPlanCatalog, BillingPlansResult, BillingPlanView, LegalLinkSet, } from "../types.ts";
|
|
4
2
|
export { BillingPlansPanel } from "./billing-plans-panel.tsx";
|
|
5
3
|
export { CheckoutConsentDialog, type CheckoutConsentDialogProps, type CheckoutConsentPayload, CONSENT_TEXT_OUTDATED_CODE, } from "./checkout-consent-dialog.tsx";
|
|
6
4
|
export { type BillingFoundationClientOptions, billingFoundationClient } from "./client-plugin.tsx";
|
|
5
|
+
export { BILLING_PLANS_SCREEN_ID, type BillingPlanAction, BillingPlanActions, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, type SubscriptionStatus, SubscriptionStatuses, } from "./constants.ts";
|
|
6
|
+
export { CONSENT_LOCALES, type ConsentLocale, resolveConsentLocale, } from "./consumer-protection/consent-locale.ts";
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
// @runtime client
|
|
2
1
|
// Public exports for the browser side of the billing-foundation feature.
|
|
3
2
|
// Consumed via `@cosmicdrift/kumiko-bundled-features/billing-foundation/web` —
|
|
4
3
|
// the server side (createBillingFoundationFeature) lives under
|
|
5
4
|
// `@cosmicdrift/kumiko-bundled-features/billing-foundation` and has no React deps.
|
|
6
|
-
export { BILLING_PLANS_SCREEN_ID, BillingPlanActions, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, SubscriptionStatuses, } from "../constants.js";
|
|
7
|
-
export { CONSENT_LOCALES, resolveConsentLocale, } from "../consumer-protection/consent-locale.js";
|
|
8
5
|
export { BillingPlansPanel } from "./billing-plans-panel.js";
|
|
9
6
|
export { CheckoutConsentDialog, CONSENT_TEXT_OUTDATED_CODE, } from "./checkout-consent-dialog.js";
|
|
10
7
|
export { billingFoundationClient } from "./client-plugin.js";
|
|
8
|
+
export { BILLING_PLANS_SCREEN_ID, BillingPlanActions, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, SubscriptionStatuses, } from "./constants.js";
|
|
9
|
+
export { CONSENT_LOCALES, resolveConsentLocale, } from "./consumer-protection/consent-locale.js";
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// signature check needs the exact bytes. No JWT/cookie auth: the provider's
|
|
5
5
|
// webhook signature in verify() IS the auth, so no c.get("user") here.
|
|
6
6
|
import { ExtraRouteRejection, signatureRoute } from "@cosmicdrift/kumiko-framework/api";
|
|
7
|
-
import { BILLING_FOUNDATION_FEATURE, BillingEventKinds, SUBSCRIPTION_PROVIDER_EXTENSION, SubscriptionFoundationHandlers, } from "./constants.js";
|
|
7
|
+
import { BILLING_FOUNDATION_FEATURE, BillingEventKinds, SUBSCRIPTION_PROVIDER_EXTENSION, SubscriptionFoundationHandlers, } from "./web/constants.js";
|
|
8
8
|
const DEFAULT_WEBHOOK_PATH = "/api/subscription/webhook/:providerName";
|
|
9
9
|
function resolveProvider(registry, providerName) {
|
|
10
10
|
return registry
|
|
@@ -84,6 +84,9 @@ export function createSubscriptionWebhookRoute(options = {}) {
|
|
|
84
84
|
tier: parsed.tier,
|
|
85
85
|
currentPeriodEndIso: parsed.currentPeriodEnd,
|
|
86
86
|
...(parsed.cancelAt !== undefined && { cancelAtIso: parsed.cancelAt }),
|
|
87
|
+
...(parsed.providerEventAt !== undefined && {
|
|
88
|
+
providerEventAtIso: parsed.providerEventAt,
|
|
89
|
+
}),
|
|
87
90
|
...(parsed.consentId !== undefined && { consentId: parsed.consentId }),
|
|
88
91
|
},
|
|
89
92
|
});
|
|
@@ -4,8 +4,12 @@
|
|
|
4
4
|
// tenant, so both are now factory parameters.
|
|
5
5
|
import { UnprocessableError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
|
|
6
6
|
import { enforceStockCap } from "./enforce-cap.js";
|
|
7
|
+
// pg_advisory_xact_lock namespace (int4): 'scap' as ASCII, disjoint from the
|
|
8
|
+
// framework's other fixed advisory-lock keys.
|
|
9
|
+
const STOCK_CAP_LOCK_NAMESPACE = 0x73636170;
|
|
7
10
|
export function createStockCapGuard(resolveTierCaps) {
|
|
8
11
|
async function checkStockCap(db, spec, context = {}) {
|
|
12
|
+
// Lock-free on its own: a direct call outside withStockCap is not atomic.
|
|
9
13
|
const caps = await resolveTierCaps(db, context);
|
|
10
14
|
const current = await db.count(spec.table, { ...spec.where, tenantId: db.tenantId });
|
|
11
15
|
const { state, limit } = enforceStockCap({
|
|
@@ -24,6 +28,10 @@ export function createStockCapGuard(resolveTierCaps) {
|
|
|
24
28
|
return {
|
|
25
29
|
...handler,
|
|
26
30
|
handler: async (event, ctx) => {
|
|
31
|
+
// ctx.db is the handler's transaction, so the xact lock releases with its commit or
|
|
32
|
+
// rollback. A handler wrapped in several caps must list them in the same order
|
|
33
|
+
// everywhere; Postgres aborts one side of an inverse order with a deadlock error.
|
|
34
|
+
await ctx.db.advisoryXactLock(STOCK_CAP_LOCK_NAMESPACE, spec.code);
|
|
27
35
|
const failure = await checkStockCap(ctx.db, spec, { config: ctx.config });
|
|
28
36
|
return failure ?? handler.handler(event, ctx);
|
|
29
37
|
},
|