@cosmicdrift/kumiko-bundled-features 0.385.0 → 0.387.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -57
- package/dist/agent-tools/tool-catalog.js +1 -1
- package/dist/agent-tools/tool-dispatch.js +0 -2
- 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,22 +1,21 @@
|
|
|
1
|
-
// increment-rolling — Rolling-
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// increment-rolling — Rolling-window counter increment via a custom
|
|
2
|
+
// event instead of CRUD/projection. Designed for caps whose values
|
|
3
|
+
// continuously renew (AI tokens over 7 days, egress over 24 hours).
|
|
4
4
|
//
|
|
5
|
-
// **
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
// `amount`-Feld; CRUD-Events tragen nur den kumulativen value.
|
|
5
|
+
// **Why not r.entity / CRUD like the calendar counter:** The calendar
|
|
6
|
+
// counter stores the cumulative value in its projection row. At the
|
|
7
|
+
// period rollover, the aggregate ID changes to the new period start;
|
|
8
|
+
// that is the "reset". A rolling window has no rollover point—the
|
|
9
|
+
// counter continuously rolls out. A single cumulative value would be
|
|
10
|
+
// incorrect because it would grow monotonically without expiration.
|
|
11
|
+
// The correct read semantics are SUM of all increment amounts from the
|
|
12
|
+
// last N days. Therefore, each increment must be a separate event with
|
|
13
|
+
// its own `amount` field; CRUD events carry only the cumulative value.
|
|
15
14
|
//
|
|
16
|
-
// **Aggregate
|
|
17
|
-
// `rollingCapAggregateId`.
|
|
18
|
-
//
|
|
19
|
-
// N
|
|
15
|
+
// **Aggregate stream:** one stream per (tenant, capName)—see
|
|
16
|
+
// `rollingCapAggregateId`. All increments use the same stream in
|
|
17
|
+
// monotonically increasing version order. enforceRollingCap reads the
|
|
18
|
+
// last N days from this stream.
|
|
20
19
|
import * as z from "zod";
|
|
21
20
|
import { rollingCapAggregateId } from "../aggregate-id.js";
|
|
22
21
|
import { CAP_COUNTER_ROLLING_AGGREGATE_TYPE, ROLLING_INCREMENTED_EVENT_QN } from "../constants.js";
|
|
@@ -28,8 +27,8 @@ const incrementRollingSchema = z.object({
|
|
|
28
27
|
* Window-Sum is exact. */
|
|
29
28
|
amount: z.number().int().positive().default(1),
|
|
30
29
|
});
|
|
31
|
-
/** Schema
|
|
32
|
-
*
|
|
30
|
+
/** Schema of the emitted custom event. Identical to the input schema:
|
|
31
|
+
* the caller supplies amount, which we append unchanged to the stream. */
|
|
33
32
|
export const rollingIncrementedSchema = incrementRollingSchema;
|
|
34
33
|
/** Payload of the event that gives a reserved rolling amount back. */
|
|
35
34
|
export const rollingReleasedSchema = incrementRollingSchema.extend({
|
|
@@ -37,27 +36,28 @@ export const rollingReleasedSchema = incrementRollingSchema.extend({
|
|
|
37
36
|
/** When the released increment was booked; absent on events written before it was recorded. */
|
|
38
37
|
incrementedAt: z.string().optional(),
|
|
39
38
|
});
|
|
40
|
-
// Rolling-
|
|
41
|
-
//
|
|
42
|
-
//
|
|
39
|
+
// Rolling-increment handler — append-only. Race-free: two parallel
|
|
40
|
+
// increments for (tenant, cap) attach to the same aggregate stream at
|
|
41
|
+
// different versions, and the event store orders them.
|
|
43
42
|
//
|
|
44
|
-
// **
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
//
|
|
43
|
+
// **No version_conflict path** as with the calendar counter: nothing
|
|
44
|
+
// reads projection state before writing. The expectedVersion is
|
|
45
|
+
// implicitly "next-after-current", which the event store determines
|
|
46
|
+
// atomically.
|
|
48
47
|
export const incrementRollingCapHandler = {
|
|
49
48
|
name: "increment-rolling",
|
|
50
49
|
agent: { expose: false },
|
|
51
50
|
schema: incrementRollingSchema,
|
|
52
|
-
// Internal handler —
|
|
53
|
-
//
|
|
54
|
-
//
|
|
51
|
+
// Internal handler — a system caller (platform foundations after a
|
|
52
|
+
// successful side effect) invokes it. Tenant end users must never
|
|
53
|
+
// call it directly. The audit row shows which subsystem call site
|
|
54
|
+
// attached the operation.
|
|
55
55
|
access: { roles: ["SystemAdmin"] },
|
|
56
56
|
handler: async (event, ctx) => {
|
|
57
57
|
// @cast-boundary engine-payload — dispatcher hands handler the
|
|
58
58
|
// already-Zod-validated payload as `unknown`; cast to the typed
|
|
59
|
-
// shape
|
|
60
|
-
// existing increment.write.ts
|
|
59
|
+
// shape declared via incrementRollingSchema. Mirror the cast in
|
|
60
|
+
// existing increment.write.ts—the same dispatcher boundary.
|
|
61
61
|
const payload = event.payload;
|
|
62
62
|
const aggregateId = rollingCapAggregateId(event.user.tenantId, payload.capName);
|
|
63
63
|
// unsafeAppendEvent: the strict appendEvent is bound to an app's own event map, which
|
|
@@ -2,12 +2,11 @@ import * as z from "zod";
|
|
|
2
2
|
import { markCapSoftWarned } from "../book-cap-usage.js";
|
|
3
3
|
// mark-soft-warned — sets lastSoftWarnedAt on the counter so subsequent
|
|
4
4
|
// soft-cap-hits in the same period don't re-trigger notifications.
|
|
5
|
-
//
|
|
5
|
+
// This prevents notification storms.
|
|
6
6
|
//
|
|
7
|
-
// **Caller
|
|
8
|
-
// soft threshold
|
|
9
|
-
// emits
|
|
10
|
-
// emit-side is app-specific; this handler only sets the flag.
|
|
7
|
+
// **Caller pattern:** enforceCap-Helper checks whether the value crosses the
|
|
8
|
+
// soft threshold while lastSoftWarnedAt is null, then calls this handler and
|
|
9
|
+
// emits the application-specific notification. This handler only sets the flag.
|
|
11
10
|
const markSoftWarnedSchema = z.object({
|
|
12
11
|
capName: z.string().min(1).max(100),
|
|
13
12
|
periodStartIso: z.string().min(1),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Generic stock-cap write-guard factory. Extracted from the near-identical
|
|
2
|
-
// cap-guard.ts app copies in show-pony and publicstatus
|
|
2
|
+
// cap-guard.ts app copies in show-pony and publicstatus — the
|
|
3
3
|
// only per-app variable was the Caps shape and how to resolve it for a
|
|
4
4
|
// tenant, so both are now factory parameters.
|
|
5
5
|
import { UnprocessableError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { HandlerContext, WriteEvent, WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import { type CapToleranceProfileName, type SoftHitNotifier } from "./enforce-cap.ts";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* events); für byte/token-cap übergibt der Caller die Größe aus
|
|
8
|
-
* `event.payload`.
|
|
4
|
+
* Dynamic cap definition resolved for each handler invocation. A typical caller reads the tenant
|
|
5
|
+
* tier from `ctx` and maps it to a limit. `amount` defaults to 1 (counting events); for byte or
|
|
6
|
+
* token caps, the caller supplies the size from `event.payload`.
|
|
9
7
|
*/
|
|
10
8
|
export type CalendarCapDef = {
|
|
11
9
|
readonly capName: string;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import type { EmailTransport } from "./types.ts";
|
|
2
2
|
export type SmtpTransportOptions = {
|
|
3
|
-
/** SMTP
|
|
4
|
-
* "localhost"
|
|
3
|
+
/** SMTP server host (for example, "smtp.gmail.com", "in-v3.mailjet.com",
|
|
4
|
+
* or "localhost" for Mailhog/MailCatcher in development). */
|
|
5
5
|
readonly host: string;
|
|
6
|
-
/** Default 587 (STARTTLS). 465
|
|
7
|
-
* (
|
|
6
|
+
/** Default 587 (STARTTLS). 465 uses implicit TLS; 25 is unencrypted
|
|
7
|
+
* (for local/internal use only, never public). */
|
|
8
8
|
readonly port?: number;
|
|
9
|
-
/** TLS
|
|
10
|
-
* 587 (
|
|
9
|
+
/** TLS mode: true = implicit TLS on port 465, false = STARTTLS on
|
|
10
|
+
* 587 (or plain on 25). The default is false (STARTTLS). */
|
|
11
11
|
readonly secure?: boolean;
|
|
12
|
-
/** Optional
|
|
13
|
-
*
|
|
12
|
+
/** Optional authentication — some internal relays use IP allowlisting
|
|
13
|
+
* instead of login. When set, both fields are required. */
|
|
14
14
|
readonly auth?: {
|
|
15
15
|
readonly user: string;
|
|
16
16
|
readonly pass: string;
|
|
@@ -28,8 +28,8 @@ export type SmtpTransportOptions = {
|
|
|
28
28
|
readonly servername?: string;
|
|
29
29
|
};
|
|
30
30
|
export declare function createSmtpTransport(options: SmtpTransportOptions): EmailTransport;
|
|
31
|
-
/**
|
|
32
|
-
*
|
|
31
|
+
/** Environment fields read by `createSmtpTransportFromEnv`. Apps that use
|
|
32
|
+
* SMTP should extend their environment schema with exactly these keys. */
|
|
33
33
|
export type SmtpEnv = {
|
|
34
34
|
readonly SMTP_HOST?: string;
|
|
35
35
|
readonly SMTP_PORT?: string;
|
|
@@ -39,14 +39,15 @@ export type SmtpEnv = {
|
|
|
39
39
|
readonly SMTP_FROM?: string;
|
|
40
40
|
};
|
|
41
41
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
42
|
+
* Creates a transport at boot time from the environment. Without
|
|
43
|
+
* `SMTP_HOST`, returns `null` so the caller can treat this as no mail
|
|
44
|
+
* delivery instead of crashing. The port is coerced to a number (default
|
|
45
|
+
* 587); `secure` is `SMTP_SECURE === "true"`; authentication is included
|
|
46
|
+
* only when both the user and password are set.
|
|
46
47
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* From
|
|
48
|
+
* Replaces the repeated `env.SMTP_HOST ? createSmtpTransport({...}) : null`
|
|
49
|
+
* block that each app previously implemented in bin/main.ts and
|
|
50
|
+
* bin/server.ts. Only the From default (`fallbackFrom`) varies by app.
|
|
50
51
|
*/
|
|
51
52
|
export declare function createSmtpTransportFromEnv(env: SmtpEnv, opts: {
|
|
52
53
|
readonly fallbackFrom: string;
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
// SMTP
|
|
2
|
-
// (battle-tested, TLS
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// Office 365, Mailhog
|
|
1
|
+
// SMTP transport for the EmailTransport interface, based on nodemailer
|
|
2
|
+
// (battle-tested, handles TLS, auth and pool reconnects). It is the universal
|
|
3
|
+
// default for apps that do not need a vendor-specific sender and works with
|
|
4
|
+
// any SMTP server (Gmail, a private
|
|
5
|
+
// Postfix server, a Brevo SMTP relay, Office 365, or Mailhog for local
|
|
6
|
+
// testing).
|
|
6
7
|
//
|
|
7
|
-
// Why SMTP
|
|
8
|
-
// 1. EU
|
|
9
|
-
//
|
|
8
|
+
// Why SMTP instead of a vendor API as the default:
|
|
9
|
+
// 1. EU data control: the app owner chooses the server instead of sending
|
|
10
|
+
// data to a US vendor.
|
|
11
|
+
// 2. Self-hosting: customers can use their own mail server without an
|
|
10
12
|
// external account.
|
|
11
|
-
// 3.
|
|
12
|
-
//
|
|
13
|
+
// 3. Universality: every vendor (Brevo, Resend, Mailgun, Postmark) also
|
|
14
|
+
// offers SMTP, so Brevo users can provide Brevo SMTP credentials.
|
|
13
15
|
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
16
|
+
// The transport pool (createTransport({ pool: true })) keeps up to 5
|
|
17
|
+
// connections open and reuses them. That is enough for small apps; for
|
|
18
|
+
// high-volume apps the caller must layer its own implementation with a
|
|
19
|
+
// dedicated queue (BullMQ + retry) on top.
|
|
18
20
|
import { createTransport } from "nodemailer";
|
|
19
21
|
import addressparser from "nodemailer/lib/addressparser";
|
|
20
22
|
function isControlCharacter(char) {
|
|
@@ -80,14 +82,15 @@ export function createSmtpTransport(options) {
|
|
|
80
82
|
};
|
|
81
83
|
}
|
|
82
84
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
85
|
+
* Creates a transport at boot time from the environment. Without
|
|
86
|
+
* `SMTP_HOST`, returns `null` so the caller can treat this as no mail
|
|
87
|
+
* delivery instead of crashing. The port is coerced to a number (default
|
|
88
|
+
* 587); `secure` is `SMTP_SECURE === "true"`; authentication is included
|
|
89
|
+
* only when both the user and password are set.
|
|
87
90
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* From
|
|
91
|
+
* Replaces the repeated `env.SMTP_HOST ? createSmtpTransport({...}) : null`
|
|
92
|
+
* block that each app previously implemented in bin/main.ts and
|
|
93
|
+
* bin/server.ts. Only the From default (`fallbackFrom`) varies by app.
|
|
91
94
|
*/
|
|
92
95
|
export function createSmtpTransportFromEnv(env, opts) {
|
|
93
96
|
if (!env.SMTP_HOST)
|
|
@@ -13,10 +13,9 @@ export const unreadCountQuery = defineQueryHandler({
|
|
|
13
13
|
},
|
|
14
14
|
description: "Counts the calling user's unread in-app notification messages; use it for an inbox badge or to check whether a user has pending notifications.",
|
|
15
15
|
handler: async (query, ctx) => {
|
|
16
|
-
// The query helpers in db/query.ts have no aggregate helper
|
|
17
|
-
// count() in JS.
|
|
18
|
-
// scoped,
|
|
19
|
-
// mit COUNT(*).
|
|
16
|
+
// The query helpers in db/query.ts have no aggregate helper, so selectMany returns all matching
|
|
17
|
+
// rows and count() runs in JS. This is acceptable because unread counts are low-cardinality and
|
|
18
|
+
// user-scoped, with at most a few hundred rows; use raw .unsafe() with COUNT(*) if that grows.
|
|
20
19
|
const rows = await selectMany(ctx.db, inAppMessagesTable, {
|
|
21
20
|
userId: query.user.id,
|
|
22
21
|
isRead: false,
|
|
@@ -18,10 +18,10 @@ export function createComplianceProfilesFeature(options) {
|
|
|
18
18
|
category: "compliance",
|
|
19
19
|
recommended: false,
|
|
20
20
|
});
|
|
21
|
-
// Standalone —
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
21
|
+
// Standalone — r.requires is not needed: tenantId comes from the user
|
|
22
|
+
// context, profile selection is a separate entity, and the sub-processor
|
|
23
|
+
// list consists of constants. Add r.requires if cross-feature reads are
|
|
24
|
+
// introduced.
|
|
25
25
|
r.entity({ name: "tenant-compliance-profile", ...tenantComplianceProfileEntity });
|
|
26
26
|
r.exposesApi("compliance.forTenant");
|
|
27
27
|
const handlers = {
|
|
@@ -4,13 +4,10 @@ import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
4
4
|
import * as z from "zod";
|
|
5
5
|
import { parseComplianceProfileOverride } from "../_internal/parse-override.js";
|
|
6
6
|
import { tenantComplianceProfileTable } from "../schema/profile-selection.js";
|
|
7
|
-
//
|
|
8
|
-
// Macht den exposesApi-Marker aus feature.ts mit echtem Inhalt.
|
|
7
|
+
// Returns the effective compliance profile for the current tenant.
|
|
9
8
|
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// Caller (z.B. user-data-rights in Sprint 2) sieht das warning und
|
|
13
|
-
// kann Onboarding-Banner triggern.
|
|
9
|
+
// If no profile is selected, returns minimal-no-region with
|
|
10
|
+
// warning="no-profile-selected" so callers can trigger an onboarding banner.
|
|
14
11
|
export const forTenantQuery = defineQueryHandler({
|
|
15
12
|
name: "for-tenant",
|
|
16
13
|
schema: z.object({}),
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { COMPLIANCE_PROFILES, SELECTABLE_PROFILE_KEYS, } from "@cosmicdrift/kumiko-framework/compliance";
|
|
2
2
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import * as z from "zod";
|
|
4
|
-
//
|
|
5
|
-
// Pure
|
|
6
|
-
//
|
|
4
|
+
// Returns all selectable compliance profiles for tenant onboarding.
|
|
5
|
+
// Pure in-memory read of the constants—no database query or caching is needed
|
|
6
|
+
// because they are already resolved before boot.
|
|
7
7
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
8
|
+
// Excludes minimal-no-region because it is the default fallback, not selectable;
|
|
9
|
+
// production must make an explicit choice.
|
|
10
10
|
export const listProfilesQuery = defineQueryHandler({
|
|
11
11
|
name: "list-profiles",
|
|
12
12
|
schema: z.object({}),
|
|
@@ -5,7 +5,7 @@ import * as z from "zod";
|
|
|
5
5
|
import { tenantComplianceProfileTable } from "../schema/profile-selection.js";
|
|
6
6
|
// Onboarding banner trigger for tenant admin.
|
|
7
7
|
//
|
|
8
|
-
//
|
|
8
|
+
// Minimal API endpoint, the UI banner comes in a later UI
|
|
9
9
|
// sprint. Pure read query: does an entry exist in tenantComplianceProfile
|
|
10
10
|
// for the current tenant?
|
|
11
11
|
//
|
|
@@ -18,7 +18,7 @@ import { tenantComplianceProfileTable } from "../schema/profile-selection.js";
|
|
|
18
18
|
// option of createComplianceProfilesFeature) — passing the option through
|
|
19
19
|
// would widen call access by default to all three access.admin roles
|
|
20
20
|
// (including SystemAdmin). Instead the handler takes `pickerReachableRoles`
|
|
21
|
-
// and deliberately resolves the
|
|
21
|
+
// and deliberately resolves the special case: if the *caller's*
|
|
22
22
|
// roles no longer intersect the picker's `access` option, the query stops
|
|
23
23
|
// reporting needsSelection — otherwise a tenant admin would be told to
|
|
24
24
|
// open a screen they can't reach.
|
|
@@ -33,8 +33,8 @@ export function createNeedsProfileQuery(pickerReachableRoles) {
|
|
|
33
33
|
tenantId: query.user.tenantId,
|
|
34
34
|
})); // @cast-boundary db-runner
|
|
35
35
|
if (row) {
|
|
36
|
-
//
|
|
37
|
-
// (Zod). If
|
|
36
|
+
// Minimal-no-region is no longer settable via set-profile
|
|
37
|
+
// (Zod). If a seedComplianceProfile helper ships that
|
|
38
38
|
// reintroduces the migration edge case, a defensive path belongs
|
|
39
39
|
// here again — until then, every existing entry is a deliberately
|
|
40
40
|
// chosen production profile.
|
|
@@ -8,10 +8,10 @@ import { tenantComplianceProfileEntity, tenantComplianceProfileTable, } from "..
|
|
|
8
8
|
const crud = createEventStoreExecutor(tenantComplianceProfileTable, tenantComplianceProfileEntity, {
|
|
9
9
|
entityName: "tenant-compliance-profile",
|
|
10
10
|
});
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
// SELECTABLE_PROFILE_KEYS
|
|
11
|
+
// The schema is limited to the three publicly selectable profiles.
|
|
12
|
+
// `minimal-no-region` is the default fallback while no choice has been
|
|
13
|
+
// made yet, not a selectable production option. This mirrors
|
|
14
|
+
// SELECTABLE_PROFILE_KEYS from the framework/compliance list.
|
|
15
15
|
const profileKeySchema = z.enum(SELECTABLE_PROFILE_KEYS);
|
|
16
16
|
// Upsert: the first call inserts, later calls update, so repeating the same values
|
|
17
17
|
// is idempotent apart from the extra audit events.
|
|
@@ -30,22 +30,21 @@ export const setProfileWrite = defineWriteHandler({
|
|
|
30
30
|
override: z.string().nullable().optional(),
|
|
31
31
|
tenantIdOverride: z.string().min(1).optional(),
|
|
32
32
|
}),
|
|
33
|
-
// SystemAdmin
|
|
34
|
-
//
|
|
33
|
+
// SystemAdmin can set profiles for customer setup through the platform-
|
|
34
|
+
// operator path; TenantAdmin can set them only for their own tenant.
|
|
35
35
|
access: { roles: access.admin },
|
|
36
36
|
description: "Sets or replaces a tenant's compliance profile key plus an optional JSON override, for onboarding or a later region change; a system admin may target a different tenant through tenantIdOverride.",
|
|
37
37
|
handler: async (event, ctx) => {
|
|
38
38
|
const tenantId = (event.payload.tenantIdOverride ?? event.user.tenantId); // @cast-boundary engine-payload
|
|
39
39
|
const { db, streamTenantId } = requireForTenant(ctx, tenantId);
|
|
40
|
-
//
|
|
41
|
-
// ComplianceProfileOverride
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
// deepMerge
|
|
40
|
+
// The override must be parseable JSON representing an object and must
|
|
41
|
+
// conform to the ComplianceProfileOverride schema. The strict Zod
|
|
42
|
+
// top-level and nested allowlists reject typos such as
|
|
43
|
+
// `{ userRights: { weeks: 3 } }` instead of silently letting
|
|
44
|
+
// deepMerge splice them into the profile.
|
|
45
45
|
//
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
// generic internal_error.
|
|
46
|
+
// writeFailure and Kumiko error classes preserve path details in the
|
|
47
|
+
// response body instead of producing a generic internal_error.
|
|
49
48
|
if (event.payload.override) {
|
|
50
49
|
let parsed;
|
|
51
50
|
try {
|
|
@@ -2,19 +2,17 @@ import { getActiveSubProcessors, getPlannedSubProcessors, KUMIKO_SUB_PROCESSORS,
|
|
|
2
2
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
4
4
|
import * as z from "zod";
|
|
5
|
-
// Public
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// (typisch verlinkt aus Datenschutzerklaerung + AVV).
|
|
5
|
+
// Public sub-processor list, accessible anonymously. This satisfies the GDPR Art. 28(2) requirement
|
|
6
|
+
// that the list of processors be publicly accessible, typically linked from
|
|
7
|
+
// the privacy policy and data-processing agreement.
|
|
9
8
|
//
|
|
10
|
-
// Format: JSON
|
|
11
|
-
//
|
|
12
|
-
// oder S9 compliance-as-product). RSS-Feed kommt in S9.
|
|
9
|
+
// Format: JSON with separate active/planned sections. Tenant admins receive
|
|
10
|
+
// change notifications via a cron job.
|
|
13
11
|
//
|
|
14
|
-
//
|
|
15
|
-
// - `active`:
|
|
16
|
-
// - `planned`:
|
|
17
|
-
//
|
|
12
|
+
// Two lists are used instead of one flat list:
|
|
13
|
+
// - `active`: sub-processors currently in use
|
|
14
|
+
// - `planned`: known future sub-processors, giving tenant admins lead time
|
|
15
|
+
// before activation, as is typical for AI and Stripe providers.
|
|
18
16
|
export const subProcessorsQuery = defineQueryHandler({
|
|
19
17
|
name: "sub-processors",
|
|
20
18
|
schema: z.object({}),
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Direct resolver helper for bulk iteration without a dispatcher round trip.
|
|
2
2
|
//
|
|
3
|
-
// `for-tenant
|
|
4
|
-
// API
|
|
5
|
-
//
|
|
3
|
+
// The `for-tenant` query (handlers/for-tenant.query.ts) is the cross-feature
|
|
4
|
+
// API for handler paths. Workers run in JobContext (without `queryAs`), so
|
|
5
|
+
// they need a direct database lookup followed by `resolveComplianceProfile`.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
7
|
+
// This follows data-retention's `resolveRetentionPolicyForTenant` pattern.
|
|
8
|
+
// Both paths use `resolveComplianceProfile` from framework/compliance, keeping
|
|
9
|
+
// the query API and worker path consistent.
|
|
10
10
|
import { resolveComplianceProfile, } from "@cosmicdrift/kumiko-framework/compliance";
|
|
11
11
|
import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
12
12
|
import { isTenantDb } from "../shared/index.js";
|
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { createEntity, createLongTextField, createSelectField, } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
-
//
|
|
3
|
+
// One-to-one relationship: each tenant has exactly one profile selection.
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// automatisch fuer Entity-Writes
|
|
12
|
-
// (c) Plan-Files in docs/plans/datenschutz/compliance-profiles.md
|
|
13
|
-
// nennen sie explizit als tenantComplianceProfile-Entity
|
|
5
|
+
// Profile selection is a separate entity in the compliance-profiles feature,
|
|
6
|
+
// not a config key in the tenant feature, because:
|
|
7
|
+
// (a) override is structured JSON, while the config-key pattern
|
|
8
|
+
// (timezone/locale) is flat key-value data
|
|
9
|
+
// (b) profile changes are audit-relevant, which the event store handles
|
|
10
|
+
// automatically for entity writes
|
|
14
11
|
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
// Zod-Validation beim set-profile-Handler stellt Schema-Konformitaet
|
|
20
|
-
// sicher.
|
|
12
|
+
// override is stored as a JSON string in longText because the framework has
|
|
13
|
+
// no dedicated jsonField type; embedded has a fixed schema, while this schema
|
|
14
|
+
// is dynamic. Zod validation in the set-profile handler ensures schema
|
|
15
|
+
// conformity.
|
|
21
16
|
export const tenantComplianceProfileEntity = createEntity({
|
|
22
17
|
table: "read_tenant_compliance_profiles",
|
|
23
18
|
fields: {
|
|
@@ -25,19 +20,19 @@ export const tenantComplianceProfileEntity = createEntity({
|
|
|
25
20
|
required: true,
|
|
26
21
|
options: ["eu-dsgvo", "swiss-dsg", "de-hr-dsgvo-hgb", "minimal-no-region"],
|
|
27
22
|
}),
|
|
28
|
-
// override: JSON
|
|
29
|
-
//
|
|
30
|
-
// set-profile
|
|
23
|
+
// override: JSON string containing a partial ComplianceProfile. NULL/empty
|
|
24
|
+
// means "default profile, no override". Validated by the
|
|
25
|
+
// set-profile handler via Zod.
|
|
31
26
|
override: createLongTextField({
|
|
32
27
|
personal: false,
|
|
33
28
|
reason: "is_business_data",
|
|
34
29
|
}),
|
|
35
30
|
},
|
|
36
31
|
indexes: [
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
32
|
+
// Only one profile record is allowed per tenant. Although the boot validator
|
|
33
|
+
// warns that a single-column tenantId index is redundant, the UNIQUE
|
|
34
|
+
// constraint is semantically required here for the one-to-one relationship,
|
|
35
|
+
// not merely a performance hint, so it is declared explicitly.
|
|
41
36
|
{ unique: true, columns: ["tenantId"] },
|
|
42
37
|
],
|
|
43
38
|
});
|
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
// Test
|
|
2
|
-
//
|
|
3
|
-
// set-profile
|
|
4
|
-
// minimal-no-region
|
|
5
|
-
//
|
|
1
|
+
// Test helper for compliance-profiles. Creates a profile entry directly
|
|
2
|
+
// through the Event Store executor—the same path as the real
|
|
3
|
+
// set-profile handler, but without Zod schema restrictions (accepts
|
|
4
|
+
// minimal-no-region for migration edge-case tests) and without an access
|
|
5
|
+
// check. Default ifExists="skip": creates only missing profiles.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
7
|
+
// user-data-rights uses this for test setup ("user can export data with
|
|
8
|
+
// profile X": a fresh tenant and profile selection per test in one helper
|
|
9
|
+
// call).
|
|
10
10
|
//
|
|
11
|
-
//
|
|
11
|
+
// The pattern matches seedTextBlock in template-resolver/seeding.ts.
|
|
12
12
|
import { createEventStoreExecutor, createTenantDb, fetchOne, } from "@cosmicdrift/kumiko-framework/db";
|
|
13
13
|
import { runEventStoreSeed, TestUsers, } from "@cosmicdrift/kumiko-framework/seeding";
|
|
14
14
|
import { tenantComplianceProfileEntity, tenantComplianceProfileTable, } from "./schema/profile-selection.js";
|
|
15
15
|
const executor = createEventStoreExecutor(tenantComplianceProfileTable, tenantComplianceProfileEntity, { entityName: "tenant-compliance-profile" });
|
|
16
16
|
export async function seedComplianceProfile(db, opts) {
|
|
17
|
-
// user.tenantId
|
|
18
|
-
//
|
|
19
|
-
// feedback_event_store_tenant_consistency).
|
|
17
|
+
// user.tenantId must equal opts.tenantId so the Event Store stream
|
|
18
|
+
// and projection remain in the same tenant bucket.
|
|
20
19
|
const by = opts.by ?? { ...TestUsers.systemAdmin, tenantId: opts.tenantId };
|
|
21
20
|
const tdb = createTenantDb({ db, tenantId: opts.tenantId, mode: "system" });
|
|
22
21
|
const overrideJson = opts.override !== undefined ? JSON.stringify(opts.override) : null;
|
|
@@ -35,9 +34,9 @@ export async function seedComplianceProfile(db, opts) {
|
|
|
35
34
|
if (!result.isSuccess) {
|
|
36
35
|
throw new Error(`seedComplianceProfile create failed: ${JSON.stringify(result)}`);
|
|
37
36
|
}
|
|
38
|
-
// @cast-boundary db-row: executor.create result.data
|
|
39
|
-
// inserted
|
|
40
|
-
// INSERT
|
|
37
|
+
// @cast-boundary db-row: executor.create result.data is the
|
|
38
|
+
// inserted projection row (Record<string, unknown>); id is guaranteed
|
|
39
|
+
// after INSERT (runtime check directly below).
|
|
41
40
|
const data = result.data;
|
|
42
41
|
if (data.id === undefined) {
|
|
43
42
|
throw new Error("seedComplianceProfile: executor.create did not return an id");
|
|
@@ -4,12 +4,12 @@ import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
|
4
4
|
import * as z from "zod";
|
|
5
5
|
import { tenantComplianceProfileTable } from "../../compliance-profiles/index.js";
|
|
6
6
|
import { decryptTenantNames, tenantTable } from "../../tenant/index.js";
|
|
7
|
-
// SystemAdmin platform-wide counterpart to needs-profile
|
|
7
|
+
// SystemAdmin platform-wide counterpart to needs-profile.
|
|
8
8
|
//
|
|
9
|
-
//
|
|
9
|
+
// The change stopped needs-profile from nagging a TenantAdmin who can no longer
|
|
10
10
|
// reach a picker narrowed to access.systemAdmin — correct, but it left no
|
|
11
11
|
// one else able to notice: needs-profile stays TenantAdmin-only on purpose
|
|
12
|
-
// (widening its call-access was explicitly rejected
|
|
12
|
+
// (widening its call-access was explicitly rejected), so a
|
|
13
13
|
// SystemAdmin who owns the platform-only picker has no way to see which
|
|
14
14
|
// tenants still run on minimal-no-region. This query fills that gap
|
|
15
15
|
// instead of touching needs-profile: every enabled tenant that has no row
|