@cosmicdrift/kumiko-samples 0.386.0 → 0.387.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -57
- package/README.md +1 -1
- package/package.json +2 -2
- package/packages/bundled-features/package.json +2 -2
- package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
- package/packages/bundled-features/src/audit/screens.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
- package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
- package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
- package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
- package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
- package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +34 -37
- package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
- package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
- package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
- package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
- package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
- package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
- package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
- package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
- package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
- package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
- package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
- package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
- package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
- package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
- package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
- package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
- package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
- package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
- package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
- package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
- package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
- package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/web/i18n.ts +3 -3
- package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
- package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +6 -6
- package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
- package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
- package/packages/bundled-features/src/billing-foundation/events.ts +22 -21
- package/packages/bundled-features/src/billing-foundation/feature.ts +42 -43
- package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
- package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +18 -17
- package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
- package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +20 -20
- package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
- package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
- package/packages/bundled-features/src/billing-foundation/types.ts +64 -65
- package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +4 -4
- package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
- package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
- package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
- package/packages/bundled-features/src/cap-counter/enforce-cap.ts +64 -67
- package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
- package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
- package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
- package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
- package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +1 -1
- package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
- package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
- package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
- package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
- package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
- package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
- package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
- package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
- package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
- package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
- package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
- package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
- package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
- package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
- package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
- package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
- package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
- package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
- package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
- package/packages/bundled-features/src/config/resolver.ts +4 -4
- package/packages/bundled-features/src/config/table.ts +10 -10
- package/packages/bundled-features/src/config/write-helpers.ts +1 -1
- package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +13 -12
- package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
- package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
- package/packages/bundled-features/src/custom-fields/events.ts +7 -8
- package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
- package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
- package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
- package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
- package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
- package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
- package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
- package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
- package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.ts +1 -1
- package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
- package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -12
- package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
- package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
- package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
- package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
- package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
- package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
- package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
- package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
- package/packages/bundled-features/src/data-retention/feature.ts +11 -18
- package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
- package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
- package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
- package/packages/bundled-features/src/data-retention/presets.ts +18 -23
- package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
- package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
- package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
- package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
- package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
- package/packages/bundled-features/src/delivery/feature.ts +3 -3
- package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
- package/packages/bundled-features/src/delivery/tables.ts +9 -8
- package/packages/bundled-features/src/delivery/unsubscribe.ts +4 -4
- package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
- package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
- package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +4 -4
- package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/feature.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
- package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
- package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
- package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
- package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
- package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
- package/packages/bundled-features/src/files/feature.ts +6 -6
- package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
- package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
- package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
- package/packages/bundled-features/src/folders/feature.ts +1 -1
- package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
- package/packages/bundled-features/src/folders/web/tree.ts +5 -5
- package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
- package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
- package/packages/bundled-features/src/form-draft/entity.ts +3 -3
- package/packages/bundled-features/src/form-draft/feature.ts +4 -5
- package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
- package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
- package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
- package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
- package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
- package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
- package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
- package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
- package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
- package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +11 -11
- package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
- package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
- package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
- package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
- package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
- package/packages/bundled-features/src/inbound-mail-foundation/types.ts +66 -67
- package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +69 -68
- package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
- package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
- package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
- package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
- package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
- package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
- package/packages/bundled-features/src/jobs/events.ts +1 -1
- package/packages/bundled-features/src/jobs/feature.ts +6 -7
- package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
- package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
- package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
- package/packages/bundled-features/src/jobs/job-run-logger.ts +14 -15
- package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
- package/packages/bundled-features/src/jobs/screens.ts +1 -1
- package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
- package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
- package/packages/bundled-features/src/ledger/entity.ts +5 -5
- package/packages/bundled-features/src/ledger/feature.ts +3 -3
- package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
- package/packages/bundled-features/src/ledger/recurring.ts +12 -12
- package/packages/bundled-features/src/ledger/schemas.ts +1 -1
- package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
- package/packages/bundled-features/src/ledger/web/index.ts +7 -7
- package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
- package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
- package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
- package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
- package/packages/bundled-features/src/mail-foundation/feature.ts +26 -27
- package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
- package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
- package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
- package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
- package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
- package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
- package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
- package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
- package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
- package/packages/bundled-features/src/managed-pages/table.ts +16 -15
- package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
- package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
- package/packages/bundled-features/src/notes-history/entity.ts +4 -4
- package/packages/bundled-features/src/notes-history/feature.ts +2 -2
- package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
- package/packages/bundled-features/src/page-render/layout.ts +9 -9
- package/packages/bundled-features/src/page-render/markdown.ts +11 -11
- package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
- package/packages/bundled-features/src/personal-access-tokens/feature.ts +5 -5
- package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
- package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
- package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
- package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
- package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
- package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
- package/packages/bundled-features/src/secrets/feature.ts +9 -9
- package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
- package/packages/bundled-features/src/seo/feature.ts +3 -3
- package/packages/bundled-features/src/sessions/constants.ts +1 -1
- package/packages/bundled-features/src/sessions/feature.ts +9 -9
- package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
- package/packages/bundled-features/src/sessions/screens.ts +2 -2
- package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
- package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
- package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
- package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +1 -1
- package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
- package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
- package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
- package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
- package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
- package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
- package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
- package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
- package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
- package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
- package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
- package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
- package/packages/bundled-features/src/subscription-stripe/feature.ts +44 -43
- package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
- package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
- package/packages/bundled-features/src/subscription-stripe/runtime.ts +2 -2
- package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
- package/packages/bundled-features/src/tags/feature.ts +3 -3
- package/packages/bundled-features/src/tags/screens.ts +1 -1
- package/packages/bundled-features/src/template-resolver/api.ts +10 -10
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +5 -5
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
- package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
- package/packages/bundled-features/src/template-resolver/seeding.ts +4 -4
- package/packages/bundled-features/src/template-resolver/table.ts +13 -14
- package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/tenant/feature.ts +7 -7
- package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
- package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
- package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
- package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
- package/packages/bundled-features/src/tenant/screens.ts +1 -1
- package/packages/bundled-features/src/tenant/seeding.ts +19 -18
- package/packages/bundled-features/src/tenant/testing.ts +5 -6
- package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
- package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
- package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
- package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
- package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
- package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +2 -2
- package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
- package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
- package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
- package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
- package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
- package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
- package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
- package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
- package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
- package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +8 -8
- package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
- package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
- package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
- package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
- package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
- package/packages/bundled-features/src/user/schema/user.ts +45 -44
- package/packages/bundled-features/src/user/seeding.ts +40 -40
- package/packages/bundled-features/src/user/testing.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
- package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/feature.ts +112 -113
- package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
- package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
- package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
- package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
- package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +4 -4
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
- package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
- package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
- package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
- package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
- package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +166 -276
- package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +85 -107
- package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
- package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
- package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
- package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
- package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
- package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
- package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
- package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
- package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
- package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
- package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
- package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
- package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +1 -1
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
- package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
- package/packages/bundled-features/src/user-profile/index.ts +3 -3
- package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
- package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
- package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
- package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
- package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
- package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
- package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
- package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
- package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
- package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
- package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
|
@@ -1,37 +1,39 @@
|
|
|
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
|
|
|
19
21
|
import { createTransport, type Transporter } from "nodemailer";
|
|
20
22
|
import addressparser from "nodemailer/lib/addressparser";
|
|
21
23
|
import type { EmailAttachment, EmailMessage, EmailTransport } from "./types.ts";
|
|
22
24
|
|
|
23
25
|
export type SmtpTransportOptions = {
|
|
24
|
-
/** SMTP
|
|
25
|
-
* "localhost"
|
|
26
|
+
/** SMTP server host (for example, "smtp.gmail.com", "in-v3.mailjet.com",
|
|
27
|
+
* or "localhost" for Mailhog/MailCatcher in development). */
|
|
26
28
|
readonly host: string;
|
|
27
|
-
/** Default 587 (STARTTLS). 465
|
|
28
|
-
* (
|
|
29
|
+
/** Default 587 (STARTTLS). 465 uses implicit TLS; 25 is unencrypted
|
|
30
|
+
* (for local/internal use only, never public). */
|
|
29
31
|
readonly port?: number;
|
|
30
|
-
/** TLS
|
|
31
|
-
* 587 (
|
|
32
|
+
/** TLS mode: true = implicit TLS on port 465, false = STARTTLS on
|
|
33
|
+
* 587 (or plain on 25). The default is false (STARTTLS). */
|
|
32
34
|
readonly secure?: boolean;
|
|
33
|
-
/** Optional
|
|
34
|
-
*
|
|
35
|
+
/** Optional authentication — some internal relays use IP allowlisting
|
|
36
|
+
* instead of login. When set, both fields are required. */
|
|
35
37
|
readonly auth?: {
|
|
36
38
|
readonly user: string;
|
|
37
39
|
readonly pass: string;
|
|
@@ -120,8 +122,8 @@ export function createSmtpTransport(options: SmtpTransportOptions): EmailTranspo
|
|
|
120
122
|
};
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
/**
|
|
124
|
-
*
|
|
125
|
+
/** Environment fields read by `createSmtpTransportFromEnv`. Apps that use
|
|
126
|
+
* SMTP should extend their environment schema with exactly these keys. */
|
|
125
127
|
export type SmtpEnv = {
|
|
126
128
|
readonly SMTP_HOST?: string;
|
|
127
129
|
readonly SMTP_PORT?: string;
|
|
@@ -132,14 +134,15 @@ export type SmtpEnv = {
|
|
|
132
134
|
};
|
|
133
135
|
|
|
134
136
|
/**
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
137
|
+
* Creates a transport at boot time from the environment. Without
|
|
138
|
+
* `SMTP_HOST`, returns `null` so the caller can treat this as no mail
|
|
139
|
+
* delivery instead of crashing. The port is coerced to a number (default
|
|
140
|
+
* 587); `secure` is `SMTP_SECURE === "true"`; authentication is included
|
|
141
|
+
* only when both the user and password are set.
|
|
139
142
|
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* From
|
|
143
|
+
* Replaces the repeated `env.SMTP_HOST ? createSmtpTransport({...}) : null`
|
|
144
|
+
* block that each app previously implemented in bin/main.ts and
|
|
145
|
+
* bin/server.ts. Only the From default (`fallbackFrom`) varies by app.
|
|
143
146
|
*/
|
|
144
147
|
export function createSmtpTransportFromEnv(
|
|
145
148
|
env: SmtpEnv,
|
|
@@ -16,10 +16,9 @@ export const unreadCountQuery = defineQueryHandler({
|
|
|
16
16
|
description:
|
|
17
17
|
"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.",
|
|
18
18
|
handler: async (query, ctx) => {
|
|
19
|
-
// The query helpers in db/query.ts have no aggregate helper
|
|
20
|
-
// count() in JS.
|
|
21
|
-
// scoped,
|
|
22
|
-
// mit COUNT(*).
|
|
19
|
+
// The query helpers in db/query.ts have no aggregate helper, so selectMany returns all matching
|
|
20
|
+
// rows and count() runs in JS. This is acceptable because unread counts are low-cardinality and
|
|
21
|
+
// user-scoped, with at most a few hundred rows; use raw .unsafe() with COUNT(*) if that grows.
|
|
23
22
|
const rows = await selectMany(ctx.db, inAppMessagesTable, {
|
|
24
23
|
userId: query.user.id,
|
|
25
24
|
isRead: false,
|
|
@@ -22,24 +22,23 @@ export {
|
|
|
22
22
|
tenantComplianceProfileTable,
|
|
23
23
|
} from "./schema/profile-selection.ts";
|
|
24
24
|
|
|
25
|
-
// compliance-profiles — Tenant-
|
|
25
|
+
// compliance-profiles — Tenant-wide GDPR/compliance profile selection.
|
|
26
26
|
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
27
|
+
// Required during tenant onboarding. Each profile bundles user-rights grace
|
|
28
|
+
// periods, notification language, breach-disclosure rules, audit retention,
|
|
29
|
+
// and sub-processor requirements.
|
|
30
30
|
//
|
|
31
|
-
// Cross-
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
// text-content fuer Pattern-Beispiel).
|
|
31
|
+
// Cross-feature API: r.exposesApi("compliance.forTenant") — other features
|
|
32
|
+
// resolve the profile through the QN pattern (see legal-pages → text-content
|
|
33
|
+
// for an example).
|
|
35
34
|
//
|
|
36
|
-
//
|
|
37
|
-
// (tenantComplianceProfile),
|
|
38
|
-
//
|
|
35
|
+
// Architectural note: Profile selection is stored as a separate entity
|
|
36
|
+
// (tenantComplianceProfile), not as a config key in the tenant feature.
|
|
37
|
+
// The reason is documented in schema/profile-selection.ts.
|
|
39
38
|
export type ComplianceProfilesFeatureOptions = {
|
|
40
39
|
// Access gate for the profile-picker screen and the `set-profile` write it
|
|
41
40
|
// submits to — both move together so the nav entry a role sees always
|
|
42
|
-
// matches a callable handler
|
|
41
|
+
// matches a callable handler. Default access.admin includes
|
|
43
42
|
// TenantAdmin, who in a line-of-business app is the operator, not the
|
|
44
43
|
// platform — pass access.systemAdmin to keep this platform-only and out
|
|
45
44
|
// of their nav.
|
|
@@ -59,10 +58,10 @@ export function createComplianceProfilesFeature(
|
|
|
59
58
|
category: "compliance",
|
|
60
59
|
recommended: false,
|
|
61
60
|
});
|
|
62
|
-
// Standalone —
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
61
|
+
// Standalone — r.requires is not needed: tenantId comes from the user
|
|
62
|
+
// context, profile selection is a separate entity, and the sub-processor
|
|
63
|
+
// list consists of constants. Add r.requires if cross-feature reads are
|
|
64
|
+
// introduced.
|
|
66
65
|
r.entity({ name: "tenant-compliance-profile", ...tenantComplianceProfileEntity });
|
|
67
66
|
|
|
68
67
|
r.exposesApi("compliance.forTenant");
|
|
@@ -9,13 +9,10 @@ import * as z from "zod";
|
|
|
9
9
|
import { parseComplianceProfileOverride } from "../_internal/parse-override.ts";
|
|
10
10
|
import { tenantComplianceProfileTable } from "../schema/profile-selection.ts";
|
|
11
11
|
|
|
12
|
-
//
|
|
13
|
-
// Macht den exposesApi-Marker aus feature.ts mit echtem Inhalt.
|
|
12
|
+
// Returns the effective compliance profile for the current tenant.
|
|
14
13
|
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
// Caller (z.B. user-data-rights in Sprint 2) sieht das warning und
|
|
18
|
-
// kann Onboarding-Banner triggern.
|
|
14
|
+
// If no profile is selected, returns minimal-no-region with
|
|
15
|
+
// warning="no-profile-selected" so callers can trigger an onboarding banner.
|
|
19
16
|
export const forTenantQuery = defineQueryHandler({
|
|
20
17
|
name: "for-tenant",
|
|
21
18
|
schema: z.object({}),
|
|
@@ -7,12 +7,12 @@ import {
|
|
|
7
7
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
8
8
|
import * as z from "zod";
|
|
9
9
|
|
|
10
|
-
//
|
|
11
|
-
// Pure
|
|
12
|
-
//
|
|
10
|
+
// Returns all selectable compliance profiles for tenant onboarding.
|
|
11
|
+
// Pure in-memory read of the constants—no database query or caching is needed
|
|
12
|
+
// because they are already resolved before boot.
|
|
13
13
|
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
14
|
+
// Excludes minimal-no-region because it is the default fallback, not selectable;
|
|
15
|
+
// production must make an explicit choice.
|
|
16
16
|
export const listProfilesQuery = defineQueryHandler({
|
|
17
17
|
name: "list-profiles",
|
|
18
18
|
schema: z.object({}),
|
|
@@ -7,7 +7,7 @@ import { tenantComplianceProfileTable } from "../schema/profile-selection.ts";
|
|
|
7
7
|
|
|
8
8
|
// Onboarding banner trigger for tenant admin.
|
|
9
9
|
//
|
|
10
|
-
//
|
|
10
|
+
// Minimal API endpoint, the UI banner comes in a later UI
|
|
11
11
|
// sprint. Pure read query: does an entry exist in tenantComplianceProfile
|
|
12
12
|
// for the current tenant?
|
|
13
13
|
//
|
|
@@ -20,7 +20,7 @@ import { tenantComplianceProfileTable } from "../schema/profile-selection.ts";
|
|
|
20
20
|
// option of createComplianceProfilesFeature) — passing the option through
|
|
21
21
|
// would widen call access by default to all three access.admin roles
|
|
22
22
|
// (including SystemAdmin). Instead the handler takes `pickerReachableRoles`
|
|
23
|
-
// and deliberately resolves the
|
|
23
|
+
// and deliberately resolves the special case: if the *caller's*
|
|
24
24
|
// roles no longer intersect the picker's `access` option, the query stops
|
|
25
25
|
// reporting needsSelection — otherwise a tenant admin would be told to
|
|
26
26
|
// open a screen they can't reach.
|
|
@@ -37,8 +37,8 @@ export function createNeedsProfileQuery(pickerReachableRoles: readonly string[])
|
|
|
37
37
|
})) as { profileKey: ComplianceProfileKey } | null; // @cast-boundary db-runner
|
|
38
38
|
|
|
39
39
|
if (row) {
|
|
40
|
-
//
|
|
41
|
-
// (Zod). If
|
|
40
|
+
// Minimal-no-region is no longer settable via set-profile
|
|
41
|
+
// (Zod). If a seedComplianceProfile helper ships that
|
|
42
42
|
// reintroduces the migration edge case, a defensive path belongs
|
|
43
43
|
// here again — until then, every existing entry is a deliberately
|
|
44
44
|
// chosen production profile.
|
|
@@ -20,10 +20,10 @@ const crud = createEventStoreExecutor(tenantComplianceProfileTable, tenantCompli
|
|
|
20
20
|
entityName: "tenant-compliance-profile",
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
// SELECTABLE_PROFILE_KEYS
|
|
23
|
+
// The schema is limited to the three publicly selectable profiles.
|
|
24
|
+
// `minimal-no-region` is the default fallback while no choice has been
|
|
25
|
+
// made yet, not a selectable production option. This mirrors
|
|
26
|
+
// SELECTABLE_PROFILE_KEYS from the framework/compliance list.
|
|
27
27
|
const profileKeySchema = z.enum(SELECTABLE_PROFILE_KEYS);
|
|
28
28
|
|
|
29
29
|
// Upsert: the first call inserts, later calls update, so repeating the same values
|
|
@@ -43,8 +43,8 @@ export const setProfileWrite = defineWriteHandler({
|
|
|
43
43
|
override: z.string().nullable().optional(),
|
|
44
44
|
tenantIdOverride: z.string().min(1).optional(),
|
|
45
45
|
}),
|
|
46
|
-
// SystemAdmin
|
|
47
|
-
//
|
|
46
|
+
// SystemAdmin can set profiles for customer setup through the platform-
|
|
47
|
+
// operator path; TenantAdmin can set them only for their own tenant.
|
|
48
48
|
access: { roles: access.admin },
|
|
49
49
|
description:
|
|
50
50
|
"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.",
|
|
@@ -52,15 +52,14 @@ export const setProfileWrite = defineWriteHandler({
|
|
|
52
52
|
const tenantId = (event.payload.tenantIdOverride ?? event.user.tenantId) as TenantId; // @cast-boundary engine-payload
|
|
53
53
|
const { db, streamTenantId } = requireForTenant(ctx, tenantId);
|
|
54
54
|
|
|
55
|
-
//
|
|
56
|
-
// ComplianceProfileOverride
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
// deepMerge
|
|
55
|
+
// The override must be parseable JSON representing an object and must
|
|
56
|
+
// conform to the ComplianceProfileOverride schema. The strict Zod
|
|
57
|
+
// top-level and nested allowlists reject typos such as
|
|
58
|
+
// `{ userRights: { weeks: 3 } }` instead of silently letting
|
|
59
|
+
// deepMerge splice them into the profile.
|
|
60
60
|
//
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
// generic internal_error.
|
|
61
|
+
// writeFailure and Kumiko error classes preserve path details in the
|
|
62
|
+
// response body instead of producing a generic internal_error.
|
|
64
63
|
if (event.payload.override) {
|
|
65
64
|
let parsed: unknown;
|
|
66
65
|
try {
|
|
@@ -8,19 +8,17 @@ import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
8
8
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
9
9
|
import * as z from "zod";
|
|
10
10
|
|
|
11
|
-
// Public
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
// (typisch verlinkt aus Datenschutzerklaerung + AVV).
|
|
11
|
+
// Public sub-processor list, accessible anonymously. This satisfies the GDPR Art. 28(2) requirement
|
|
12
|
+
// that the list of processors be publicly accessible, typically linked from
|
|
13
|
+
// the privacy policy and data-processing agreement.
|
|
15
14
|
//
|
|
16
|
-
// Format: JSON
|
|
17
|
-
//
|
|
18
|
-
// oder S9 compliance-as-product). RSS-Feed kommt in S9.
|
|
15
|
+
// Format: JSON with separate active/planned sections. Tenant admins receive
|
|
16
|
+
// change notifications via a cron job.
|
|
19
17
|
//
|
|
20
|
-
//
|
|
21
|
-
// - `active`:
|
|
22
|
-
// - `planned`:
|
|
23
|
-
//
|
|
18
|
+
// Two lists are used instead of one flat list:
|
|
19
|
+
// - `active`: sub-processors currently in use
|
|
20
|
+
// - `planned`: known future sub-processors, giving tenant admins lead time
|
|
21
|
+
// before activation, as is typical for AI and Stripe providers.
|
|
24
22
|
export const subProcessorsQuery = defineQueryHandler({
|
|
25
23
|
name: "sub-processors",
|
|
26
24
|
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
|
|
|
11
11
|
import {
|
|
12
12
|
type ComplianceProfileKey,
|
|
@@ -5,24 +5,19 @@ import {
|
|
|
5
5
|
createSelectField,
|
|
6
6
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
7
7
|
|
|
8
|
-
//
|
|
8
|
+
// One-to-one relationship: each tenant has exactly one profile selection.
|
|
9
9
|
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
// automatisch fuer Entity-Writes
|
|
17
|
-
// (c) Plan-Files in docs/plans/datenschutz/compliance-profiles.md
|
|
18
|
-
// nennen sie explizit als tenantComplianceProfile-Entity
|
|
10
|
+
// Profile selection is a separate entity in the compliance-profiles feature,
|
|
11
|
+
// not a config key in the tenant feature, because:
|
|
12
|
+
// (a) override is structured JSON, while the config-key pattern
|
|
13
|
+
// (timezone/locale) is flat key-value data
|
|
14
|
+
// (b) profile changes are audit-relevant, which the event store handles
|
|
15
|
+
// automatically for entity writes
|
|
19
16
|
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
// Zod-Validation beim set-profile-Handler stellt Schema-Konformitaet
|
|
25
|
-
// sicher.
|
|
17
|
+
// override is stored as a JSON string in longText because the framework has
|
|
18
|
+
// no dedicated jsonField type; embedded has a fixed schema, while this schema
|
|
19
|
+
// is dynamic. Zod validation in the set-profile handler ensures schema
|
|
20
|
+
// conformity.
|
|
26
21
|
export const tenantComplianceProfileEntity = createEntity({
|
|
27
22
|
table: "read_tenant_compliance_profiles",
|
|
28
23
|
fields: {
|
|
@@ -30,19 +25,19 @@ export const tenantComplianceProfileEntity = createEntity({
|
|
|
30
25
|
required: true,
|
|
31
26
|
options: ["eu-dsgvo", "swiss-dsg", "de-hr-dsgvo-hgb", "minimal-no-region"] as const,
|
|
32
27
|
}),
|
|
33
|
-
// override: JSON
|
|
34
|
-
//
|
|
35
|
-
// set-profile
|
|
28
|
+
// override: JSON string containing a partial ComplianceProfile. NULL/empty
|
|
29
|
+
// means "default profile, no override". Validated by the
|
|
30
|
+
// set-profile handler via Zod.
|
|
36
31
|
override: createLongTextField({
|
|
37
32
|
personal: false,
|
|
38
33
|
reason: "is_business_data",
|
|
39
34
|
}),
|
|
40
35
|
},
|
|
41
36
|
indexes: [
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
37
|
+
// Only one profile record is allowed per tenant. Although the boot validator
|
|
38
|
+
// warns that a single-column tenantId index is redundant, the UNIQUE
|
|
39
|
+
// constraint is semantically required here for the one-to-one relationship,
|
|
40
|
+
// not merely a performance hint, so it is declared explicitly.
|
|
46
41
|
{ unique: true, columns: ["tenantId"] },
|
|
47
42
|
],
|
|
48
43
|
});
|
|
@@ -1,14 +1,14 @@
|
|
|
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
|
|
|
13
13
|
import type {
|
|
14
14
|
ComplianceProfileKey,
|
|
@@ -50,9 +50,8 @@ export async function seedComplianceProfile(
|
|
|
50
50
|
db: DbConnection,
|
|
51
51
|
opts: SeedComplianceProfileOptions,
|
|
52
52
|
): Promise<{ id: string }> {
|
|
53
|
-
// user.tenantId
|
|
54
|
-
//
|
|
55
|
-
// feedback_event_store_tenant_consistency).
|
|
53
|
+
// user.tenantId must equal opts.tenantId so the Event Store stream
|
|
54
|
+
// and projection remain in the same tenant bucket.
|
|
56
55
|
const by = opts.by ?? { ...TestUsers.systemAdmin, tenantId: opts.tenantId };
|
|
57
56
|
const tdb = createTenantDb({ db, tenantId: opts.tenantId, mode: "system" });
|
|
58
57
|
const overrideJson = opts.override !== undefined ? JSON.stringify(opts.override) : null;
|
|
@@ -77,9 +76,9 @@ export async function seedComplianceProfile(
|
|
|
77
76
|
if (!result.isSuccess) {
|
|
78
77
|
throw new Error(`seedComplianceProfile create failed: ${JSON.stringify(result)}`);
|
|
79
78
|
}
|
|
80
|
-
// @cast-boundary db-row: executor.create result.data
|
|
81
|
-
// inserted
|
|
82
|
-
// INSERT
|
|
79
|
+
// @cast-boundary db-row: executor.create result.data is the
|
|
80
|
+
// inserted projection row (Record<string, unknown>); id is guaranteed
|
|
81
|
+
// after INSERT (runtime check directly below).
|
|
83
82
|
const data = result.data as { id?: string };
|
|
84
83
|
if (data.id === undefined) {
|
|
85
84
|
throw new Error("seedComplianceProfile: executor.create did not return an id");
|
|
@@ -5,12 +5,12 @@ import * as z from "zod";
|
|
|
5
5
|
import { tenantComplianceProfileTable } from "../../compliance-profiles/index.ts";
|
|
6
6
|
import { decryptTenantNames, tenantTable } from "../../tenant/index.ts";
|
|
7
7
|
|
|
8
|
-
// SystemAdmin platform-wide counterpart to needs-profile
|
|
8
|
+
// SystemAdmin platform-wide counterpart to needs-profile.
|
|
9
9
|
//
|
|
10
|
-
//
|
|
10
|
+
// The change stopped needs-profile from nagging a TenantAdmin who can no longer
|
|
11
11
|
// reach a picker narrowed to access.systemAdmin — correct, but it left no
|
|
12
12
|
// one else able to notice: needs-profile stays TenantAdmin-only on purpose
|
|
13
|
-
// (widening its call-access was explicitly rejected
|
|
13
|
+
// (widening its call-access was explicitly rejected), so a
|
|
14
14
|
// SystemAdmin who owns the platform-only picker has no way to see which
|
|
15
15
|
// tenants still run on minimal-no-region. This query fills that gap
|
|
16
16
|
// instead of touching needs-profile: every enabled tenant that has no row
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// compliance-profiles-ops — platform-wide SystemAdmin visibility into
|
|
2
|
-
// tenants missing a compliance-profile selection
|
|
2
|
+
// tenants missing a compliance-profile selection.
|
|
3
3
|
//
|
|
4
4
|
// needs-profile (compliance-profiles) tells a TenantAdmin they must pick a
|
|
5
|
-
// profile, but stays TenantAdmin-only by design
|
|
5
|
+
// profile, but stays TenantAdmin-only by design — a SystemAdmin who
|
|
6
6
|
// owns a picker narrowed to access.systemAdmin has no query at all. Kept as
|
|
7
7
|
// a separate feature (mirrors folders-user-data/notes-history-user-data)
|
|
8
8
|
// rather than folded into compliance-profiles: this is the one genuinely
|
|
@@ -74,17 +74,17 @@ export async function collectMissingRequiredConfig(
|
|
|
74
74
|
db: TenantDb,
|
|
75
75
|
gate?: RequiredKeyGate,
|
|
76
76
|
options?: {
|
|
77
|
-
/** Verdict
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
77
|
+
/** Verdict paths (rollup, themselves role-gated) MUST count without filtering:
|
|
78
|
+
* the per-key read filter protects the openToAll handler from information
|
|
79
|
+
* disclosure, but in the verdict it dropped SystemAdmin-gated required keys
|
|
80
|
+
* and incorrectly reported ready:true despite the gap. */
|
|
81
81
|
readonly skipAccessFilter?: boolean;
|
|
82
82
|
},
|
|
83
83
|
): Promise<ReadinessMissingKey[]> {
|
|
84
84
|
const resolver = requireConfigResolver(ctx, callerQn);
|
|
85
85
|
const effectiveGate = gate ?? (await buildProviderSelectionGate(ctx, callerQn, user, db));
|
|
86
|
-
//
|
|
87
|
-
// resolver.get
|
|
86
|
+
// Collect candidates first, then perform ONE batch resolve — the sequential
|
|
87
|
+
// resolver.get loop was an N+1 operation across all required keys (272/1).
|
|
88
88
|
type KeyDef =
|
|
89
89
|
ReturnType<typeof ctx.registry.getAllConfigKeys> extends ReadonlyMap<string, infer D>
|
|
90
90
|
? D
|
|
@@ -153,7 +153,7 @@ export const readinessQuery = defineQueryHandler({
|
|
|
153
153
|
db,
|
|
154
154
|
);
|
|
155
155
|
// Additive, display-ready fields for the admin-shell dashboard stat
|
|
156
|
-
// panel
|
|
156
|
+
// panel — `missing` itself stays untouched for existing
|
|
157
157
|
// consumers that read the array directly.
|
|
158
158
|
return {
|
|
159
159
|
missing,
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
// the NEW envelope: after a full run even a from-scratch rebuild only
|
|
17
17
|
// ever sees the current-KEK envelope.
|
|
18
18
|
//
|
|
19
|
-
// systemScope() fail-closed pattern
|
|
20
|
-
//
|
|
19
|
+
// systemScope() fail-closed pattern: the initial scan is intentionally
|
|
20
|
+
// cross-tenant (system-wide key rotation), acknowledged via
|
|
21
21
|
// UncheckedSystemDb.acknowledgeCrossTenant(). Rows are bucketed by tenant,
|
|
22
22
|
// and assertRowsTenant() re-verifies each row against its bucket's tenant
|
|
23
23
|
// right before the write — both checks are built locally from the exported
|
|
@@ -226,9 +226,8 @@ export const reencryptJob: JobHandlerFn = async (rawPayload, ctx): Promise<void>
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
// Re-verify the row's own tenantId against the bucket it was scanned
|
|
229
|
-
// into, right before the write
|
|
230
|
-
//
|
|
231
|
-
// whole job.
|
|
229
|
+
// into, right before the write — a mismatch here fails this row only
|
|
230
|
+
// (via onRowError below), it does not abort the whole job.
|
|
232
231
|
sdbFor(tenantId).assertRowsTenant([row], "tenantId");
|
|
233
232
|
|
|
234
233
|
const plaintext = await cipher.decrypt(row.value, { tenantId });
|
|
@@ -74,7 +74,8 @@ export const setWrite = defineWriteHandler({
|
|
|
74
74
|
// rejected), but an admin override write can still target scope=
|
|
75
75
|
// "system" for a tenant/user-scoped key (validateScope allows any
|
|
76
76
|
// requestedScope <= definedScope) — system-row has no subject.
|
|
77
|
-
|
|
77
|
+
const piiScope = keyDef.piiEncrypted && scope !== ConfigScopes.system ? scope : undefined;
|
|
78
|
+
if (keyDef.piiEncrypted && piiScope === undefined) {
|
|
78
79
|
return writeFailure(
|
|
79
80
|
new UnprocessableError("invalid_scope", {
|
|
80
81
|
i18nKey: "config.errors.invalidScope",
|
|
@@ -153,7 +154,7 @@ export const setWrite = defineWriteHandler({
|
|
|
153
154
|
if (keyDef.encrypted) {
|
|
154
155
|
const cipher = requireConfigEncryption(ctx, "config:write:set");
|
|
155
156
|
serialized = await cipher.encrypt(serialized, { tenantId });
|
|
156
|
-
} else if (
|
|
157
|
+
} else if (piiScope !== undefined) {
|
|
157
158
|
const kms = configuredPiiSubjectKms();
|
|
158
159
|
if (!kms) {
|
|
159
160
|
throw new InternalError({
|
|
@@ -163,8 +164,7 @@ export const setWrite = defineWriteHandler({
|
|
|
163
164
|
`configurePiiSubjectKms(adapter) at boot.`,
|
|
164
165
|
});
|
|
165
166
|
}
|
|
166
|
-
|
|
167
|
-
const subject = resolvePiiSubject(scope as Exclude<typeof scope, "system">, tenantId, userId);
|
|
167
|
+
const subject = resolvePiiSubject(piiScope, tenantId, userId);
|
|
168
168
|
const kmsCtx: KmsContext = {
|
|
169
169
|
requestId: requestContext.get()?.requestId ?? "config:write:set",
|
|
170
170
|
tenantId,
|
|
@@ -583,10 +583,10 @@ export function validateAppOverrides(
|
|
|
583
583
|
);
|
|
584
584
|
}
|
|
585
585
|
|
|
586
|
-
//
|
|
587
|
-
// `typeof value !== typeForKey(...)
|
|
588
|
-
//
|
|
589
|
-
//
|
|
586
|
+
// Narrow by keyDef.type inline because TypeScript cannot narrow through
|
|
587
|
+
// `typeof value !== typeForKey(...)`, whose return type is string rather
|
|
588
|
+
// than a discriminator. This avoids `value as string|number` casts below;
|
|
589
|
+
// value is correctly typed within each branch.
|
|
590
590
|
if (keyDef.type === "number") {
|
|
591
591
|
if (typeof value !== "number") {
|
|
592
592
|
throw new Error(`App-Boot-Override for "${key}": expected number, got ${typeof value}`);
|