@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,14 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// CustomFieldsFormSection — extension-section component
|
|
3
|
-
//
|
|
4
|
-
// host
|
|
5
|
-
// `custom-fields:write:set-custom-field`
|
|
2
|
+
// CustomFieldsFormSection — extension-section component for entityEdit-
|
|
3
|
+
// screens. Loads the tenant's fieldDefinition list, filters it to the
|
|
4
|
+
// host entity, renders a typed input per definition, and dispatches
|
|
5
|
+
// `custom-fields:write:set-custom-field` for each non-empty value on save.
|
|
6
6
|
//
|
|
7
7
|
// Mount via createKumikoApp({ clientFeatures: [customFieldsClient()] })
|
|
8
|
-
// —
|
|
9
|
-
//
|
|
10
|
-
// `component: { react: { __component: CUSTOM_FIELDS_FORM_EXTENSION_NAME } }
|
|
11
|
-
// referenziert.
|
|
8
|
+
// — the clientFeature factory registers this component under the name
|
|
9
|
+
// `CustomFieldsFormSection`, which the app references in the screen schema
|
|
10
|
+
// via `component: { react: { __component: CUSTOM_FIELDS_FORM_EXTENSION_NAME } }`.
|
|
12
11
|
import { useDispatcher, useExtensionFormSubmit, usePrimitives, useQuery, useTranslation, } from "@cosmicdrift/kumiko-renderer";
|
|
13
12
|
import { useState } from "react";
|
|
14
13
|
import { CustomFieldsHandlers, CustomFieldsQueries } from "./constants.js";
|
|
@@ -20,11 +19,11 @@ export function CustomFieldsFormSection({ entityName, entityId, initialValues, }
|
|
|
20
19
|
const [pending, setPending] = useState({});
|
|
21
20
|
const [saving, setSaving] = useState(false);
|
|
22
21
|
const [errorKey, setErrorKey] = useState(null);
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
// false. Dirty
|
|
26
|
-
//
|
|
27
|
-
//
|
|
22
|
+
// Computed before the early returns because useExtensionFormSubmit (a Hook)
|
|
23
|
+
// must run before them. matchingFields is [] while loading, so dirty remains
|
|
24
|
+
// false. Dirty means differing from the SAVED value (not from ""); otherwise
|
|
25
|
+
// clearing an existing value would be invisible and skipped instead of
|
|
26
|
+
// cleared.
|
|
28
27
|
const matchingFields = (query.data?.rows ?? [])
|
|
29
28
|
.filter((f) => f.entityName === entityName)
|
|
30
29
|
.slice()
|
|
@@ -35,9 +34,10 @@ export function CustomFieldsFormSection({ entityName, entityId, initialValues, }
|
|
|
35
34
|
return raw !== undefined && raw !== initialDisplay(field);
|
|
36
35
|
});
|
|
37
36
|
const dirty = changedFields.length > 0;
|
|
38
|
-
//
|
|
39
|
-
// (
|
|
40
|
-
//
|
|
37
|
+
// Writes all changed fields via set/clear. Used by the composed submit
|
|
38
|
+
// (the main form calls the handler after the entity write) and by the
|
|
39
|
+
// standalone button when the section is mounted without a surrounding
|
|
40
|
+
// composed form.
|
|
41
41
|
const flushChanges = async (targetEntityId) => {
|
|
42
42
|
for (const field of changedFields) {
|
|
43
43
|
const raw = pending[field.fieldKey] ?? "";
|
|
@@ -63,9 +63,9 @@ export function CustomFieldsFormSection({ entityName, entityId, initialValues, }
|
|
|
63
63
|
setPending({});
|
|
64
64
|
return { isSuccess: true };
|
|
65
65
|
};
|
|
66
|
-
// composed =
|
|
67
|
-
//
|
|
68
|
-
//
|
|
66
|
+
// composed = inside an entityEdit form, so there is no separate Save button;
|
|
67
|
+
// the section writes along with the main save. Outside a composed form
|
|
68
|
+
// (composed === false), the standalone button remains available.
|
|
69
69
|
const composed = useExtensionFormSubmit({
|
|
70
70
|
dirty,
|
|
71
71
|
onSubmit: (ctx) => flushChanges(ctx.entityId),
|
|
@@ -120,9 +120,9 @@ function coerceValue(type, raw) {
|
|
|
120
120
|
return raw === "true";
|
|
121
121
|
return raw;
|
|
122
122
|
}
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
//
|
|
123
|
+
// Inverse of coerceValue: converts a stored jsonb value to the string form
|
|
124
|
+
// expected by the input. number/boolean/date/text are represented as their
|
|
125
|
+
// inputs expect; missing values become "".
|
|
126
126
|
function displayValue(type, value) {
|
|
127
127
|
if (value === undefined || value === null)
|
|
128
128
|
return "";
|
|
@@ -3,8 +3,7 @@ import { createJsonbField, isSystemTenant, } from "@cosmicdrift/kumiko-framework
|
|
|
3
3
|
import { clearCustomFieldKey, removeCustomFieldKeyForTenant, removeCustomFieldKeyFromAllTenants, setCustomFieldValue, } from "./db/queries/projection.js";
|
|
4
4
|
import { createCustomFieldsFeature } from "./feature.js";
|
|
5
5
|
import { CUSTOM_FIELDS_EXTENSION, FIELD_DEFINITION_AGGREGATE_TYPE } from "./web/constants.js";
|
|
6
|
-
//
|
|
7
|
-
// hinzu. Consumer:
|
|
6
|
+
// Adds a `customFields jsonb` column to an entity definition.
|
|
8
7
|
//
|
|
9
8
|
// const propertyEntity = createEntity({
|
|
10
9
|
// fields: {
|
|
@@ -13,77 +12,78 @@ import { CUSTOM_FIELDS_EXTENSION, FIELD_DEFINITION_AGGREGATE_TYPE } from "./web/
|
|
|
13
12
|
// },
|
|
14
13
|
// });
|
|
15
14
|
//
|
|
16
|
-
//
|
|
17
|
-
// NOT NULL
|
|
15
|
+
// `customFields` follows the same contract as regular fields: default `{}` and
|
|
16
|
+
// NOT NULL, like embedded columns.
|
|
18
17
|
// @wrapper-known semantic-alias
|
|
19
18
|
export function customFieldsField() {
|
|
20
19
|
return createJsonbField();
|
|
21
20
|
}
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
// search-payload
|
|
21
|
+
// Complete integration of the custom-fields bundle for a specific host
|
|
22
|
+
// entity. One call site per consumer registers all wiring aspects:
|
|
23
|
+
// extension tracking, the value-projection MSP, rebuild replay via
|
|
24
|
+
// extendEntityProjection, the postQuery hook for API flattening, and the
|
|
25
|
+
// search-payload extension for indexable customFields.
|
|
27
26
|
//
|
|
28
27
|
// Consumer-side:
|
|
29
28
|
//
|
|
30
29
|
// defineFeature("property-mgmt", (r) => {
|
|
31
|
-
// r.entity({ name: "property", ...propertyEntity }); //
|
|
30
|
+
// r.entity({ name: "property", ...propertyEntity }); // must have customFieldsField()
|
|
32
31
|
// r.requires({ features: [CUSTOM_FIELDS_FEATURE_NAME] });
|
|
33
32
|
// wireCustomFieldsFor(r, "property", propertyTable);
|
|
34
33
|
// });
|
|
35
34
|
//
|
|
36
|
-
//
|
|
37
|
-
// `buildEntityTable(name, entity)
|
|
38
|
-
//
|
|
35
|
+
// The `entityTable` parameter is the Drizzle table instance (typically the
|
|
36
|
+
// output of `buildEntityTable(name, entity)`). Closing over `entityTable`
|
|
37
|
+
// avoids a runtime table lookup through the registry in the MSP apply
|
|
38
|
+
// function.
|
|
39
39
|
//
|
|
40
|
-
// **
|
|
40
|
+
// **What is registered**:
|
|
41
41
|
//
|
|
42
|
-
// 1. r.useExtension("customFields", entityName) — opt-in marker
|
|
43
|
-
//
|
|
42
|
+
// 1. r.useExtension("customFields", entityName) — opt-in marker enabling
|
|
43
|
+
// boot validation and usage tracking through the registry.
|
|
44
44
|
//
|
|
45
45
|
// 2. r.multiStreamProjection — consumes customField.set/.cleared events
|
|
46
|
-
//
|
|
47
|
-
//
|
|
46
|
+
// emitted by the customer's set-custom-field / clear-custom-field write
|
|
47
|
+
// handlers. Updates entityTable.customFields jsonb through
|
|
48
48
|
// jsonb_set / jsonb-key-removal.
|
|
49
49
|
//
|
|
50
|
-
// 3. r.extendEntityProjection —
|
|
51
|
-
// implicit projection
|
|
52
|
-
// customField
|
|
53
|
-
//
|
|
50
|
+
// 3. r.extendEntityProjection — adds the same apply handlers to the host
|
|
51
|
+
// entity's implicit projection so rebuildProjection replays the
|
|
52
|
+
// customField events. Without this, customFields would reset to `{}` on
|
|
53
|
+
// every entity rebuild (for example, after a schema migration).
|
|
54
54
|
//
|
|
55
|
-
// 4. r.entityHook("postQuery", entity, flatten-fn) —
|
|
56
|
-
//
|
|
57
|
-
//
|
|
55
|
+
// 4. r.entityHook("postQuery", entity, flatten-fn) — on every read of
|
|
56
|
+
// this entity, expands `row.customFields` jsonb at the root level so
|
|
57
|
+
// the API response looks like it contains regular fields.
|
|
58
58
|
//
|
|
59
|
-
// 5. r.searchPayloadExtension(entity, contributor) —
|
|
60
|
-
// customFields
|
|
61
|
-
//
|
|
59
|
+
// 5. r.searchPayloadExtension(entity, contributor) — contributes
|
|
60
|
+
// searchable customFields keys as flat fields in the Meilisearch index
|
|
61
|
+
// document.
|
|
62
62
|
//
|
|
63
|
-
// 6. fieldDefinition.deleted
|
|
64
|
-
//
|
|
65
|
-
//
|
|
63
|
+
// 6. fieldDefinition.deleted event handler in the same MSP — removes
|
|
64
|
+
// orphaned values from all entity rows when a fieldDefinition is deleted
|
|
65
|
+
// (one key removal per fieldKey).
|
|
66
66
|
export function wireCustomFieldsFor(r, entityName, entityTable) {
|
|
67
67
|
// biome-ignore lint/correctness/useHookAtTopLevel: r.useExtension is a registrar-API method, not a React hook — false positive on the "use"-prefix heuristic.
|
|
68
68
|
r.useExtension(CUSTOM_FIELDS_EXTENSION, entityName);
|
|
69
69
|
// Qualified event-type-names — sourced from typed EventDef.name handles
|
|
70
|
-
// (compile-time literal-typed, no Template-Literal-Drift
|
|
71
|
-
// collapse
|
|
70
|
+
// (compile-time literal-typed, no Template-Literal-Drift from the toKebab-
|
|
71
|
+
// collapse bug that exposed it).
|
|
72
72
|
const setEventType = createCustomFieldsFeature().exports.setEvent.name;
|
|
73
73
|
const clearedEventType = createCustomFieldsFeature().exports.clearedEvent.name;
|
|
74
74
|
const fieldDefDeletedType = createCustomFieldsFeature().exports.fieldDefinitionDeletedEvent.name;
|
|
75
|
-
//
|
|
76
|
-
// entity-projection
|
|
77
|
-
//
|
|
78
|
-
//
|
|
75
|
+
// Shared apply bodies: the MSP supplies them live through an async cursor,
|
|
76
|
+
// while the entity-projection extension replays them in rebuildProjection.
|
|
77
|
+
// Both use the same idempotent SQL helpers. The two-parameter signature is
|
|
78
|
+
// the common subset of MultiStreamApplyFn and SingleStreamApplyFn.
|
|
79
79
|
const applyCustomFieldSet = async (event, tx) => {
|
|
80
|
-
// skip:
|
|
81
|
-
//
|
|
82
|
-
//
|
|
80
|
+
// skip: fires for every aggregate type that emits customField.set, but only
|
|
81
|
+
// events for the wired host entity should be processed. Other consumers
|
|
82
|
+
// have their own wiring for their entities.
|
|
83
83
|
if (event.aggregateType !== entityName)
|
|
84
84
|
return;
|
|
85
85
|
const payload = event.payload; // @cast-boundary engine-payload
|
|
86
|
-
// skip: a value-less customField.set is an anomaly
|
|
86
|
+
// skip: a value-less customField.set is an anomaly (every set
|
|
87
87
|
// carries its value; the sensitive self-projection path was removed) —
|
|
88
88
|
// warn and leave the row untouched instead of binding undefined.
|
|
89
89
|
if (payload.value === undefined) {
|
|
@@ -92,30 +92,29 @@ export function wireCustomFieldsFor(r, entityName, entityTable) {
|
|
|
92
92
|
// skip: warned above — leave the row untouched instead of binding undefined
|
|
93
93
|
return;
|
|
94
94
|
}
|
|
95
|
-
// jsonb_set:
|
|
96
|
-
//
|
|
97
|
-
// jsonb
|
|
95
|
+
// jsonb_set: assigns value to the key. If the key does not yet exist, it is
|
|
96
|
+
// created (`create_missing=true` is the default). value must be supplied
|
|
97
|
+
// as a jsonb literal.
|
|
98
98
|
const tableName = extractTableName(entityTable, "custom-fields/wire-for-entity");
|
|
99
99
|
await setCustomFieldValue(tx, tableName, payload.fieldKey, payload.value, event.aggregateId, event.tenantId);
|
|
100
100
|
};
|
|
101
101
|
const applyCustomFieldCleared = async (event, tx) => {
|
|
102
|
-
// skip:
|
|
103
|
-
// verarbeiten.
|
|
102
|
+
// skip: fires for all aggregate types; process only our host entity.
|
|
104
103
|
if (event.aggregateType !== entityName)
|
|
105
104
|
return;
|
|
106
105
|
const payload = event.payload; // @cast-boundary engine-payload
|
|
107
|
-
// jsonb minus operator (`-`)
|
|
106
|
+
// The jsonb minus operator (`-`) removes a key from a jsonb object.
|
|
108
107
|
const tableName = extractTableName(entityTable, "custom-fields/wire-for-entity");
|
|
109
108
|
await clearCustomFieldKey(tx, tableName, payload.fieldKey, event.aggregateId, event.tenantId);
|
|
110
109
|
};
|
|
111
110
|
const applyFieldDefinitionDeleted = async (event, tx) => {
|
|
112
|
-
// fieldDefinition.deleted fires
|
|
113
|
-
//
|
|
114
|
-
//
|
|
111
|
+
// fieldDefinition.deleted fires once per field-definition deletion, not once
|
|
112
|
+
// per entity. Remove the key from all rows of the host entity if the
|
|
113
|
+
// deleted field definition belonged to this entity.
|
|
115
114
|
const payload = event.payload; // @cast-boundary engine-payload
|
|
116
|
-
// skip: fieldDefinition.deleted
|
|
117
|
-
//
|
|
118
|
-
//
|
|
115
|
+
// skip: fieldDefinition.deleted fires for field definitions across all
|
|
116
|
+
// entities; clean rows only when the deleted definition belonged to this
|
|
117
|
+
// host entity.
|
|
119
118
|
if (payload.entityName !== entityName)
|
|
120
119
|
return;
|
|
121
120
|
const tableName = extractTableName(entityTable, "custom-fields/wire-for-entity");
|
|
@@ -141,13 +140,12 @@ export function wireCustomFieldsFor(r, entityName, entityTable) {
|
|
|
141
140
|
[fieldDefDeletedType]: applyFieldDefinitionDeleted,
|
|
142
141
|
},
|
|
143
142
|
});
|
|
144
|
-
// Rebuild
|
|
145
|
-
//
|
|
146
|
-
//
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
// kommt deshalb als extra source dazu.
|
|
143
|
+
// Rebuild wiring: without it, rebuildProjection replays only entity
|
|
144
|
+
// lifecycle events and resets each customFields jsonb value to its default
|
|
145
|
+
// `{}`. The values exist only in customField.set/.cleared events. set/
|
|
146
|
+
// cleared events use the HOST entity stream (aggregateType = entityName,
|
|
147
|
+
// already covered by the source); fieldDefinition.deleted belongs to the
|
|
148
|
+
// "field-definition" stream and is therefore added as an extra source.
|
|
151
149
|
r.extendEntityProjection(entityName, {
|
|
152
150
|
sources: [FIELD_DEFINITION_AGGREGATE_TYPE],
|
|
153
151
|
apply: {
|
|
@@ -156,8 +154,8 @@ export function wireCustomFieldsFor(r, entityName, entityTable) {
|
|
|
156
154
|
[fieldDefDeletedType]: applyFieldDefinitionDeleted,
|
|
157
155
|
},
|
|
158
156
|
});
|
|
159
|
-
// postQuery
|
|
160
|
-
//
|
|
157
|
+
// postQuery hook: expands row.customFields jsonb at the API response's root
|
|
158
|
+
// level so it is indistinguishable from regular fields.
|
|
161
159
|
r.hook({
|
|
162
160
|
type: "postQuery",
|
|
163
161
|
target: { allOf: entityName },
|
|
@@ -174,11 +172,11 @@ export function wireCustomFieldsFor(r, entityName, entityTable) {
|
|
|
174
172
|
}),
|
|
175
173
|
}),
|
|
176
174
|
});
|
|
177
|
-
// Search-
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
//
|
|
175
|
+
// Search-payload extension: flattens customFields keys into the index
|
|
176
|
+
// document. Unlike the postQuery hook, which merges ALL keys, the search
|
|
177
|
+
// contributor should include only fields defined with searchable=true. The
|
|
178
|
+
// current version conservatively contributes everything; a later change
|
|
179
|
+
// will filter by the fieldDefinition.searchable flag.
|
|
182
180
|
r.searchPayloadExtension(entityName, ({ state }) => {
|
|
183
181
|
const customFields = state["customFields"];
|
|
184
182
|
if (customFields && typeof customFields === "object" && !Array.isArray(customFields)) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// User-data-rights wiring for custom-fields.
|
|
2
2
|
import { extractTableName } from "@cosmicdrift/kumiko-framework/db";
|
|
3
3
|
import { EXT_USER_DATA } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
4
|
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
@@ -18,7 +18,7 @@ function asCustomFieldsHostRow(value) {
|
|
|
18
18
|
return null;
|
|
19
19
|
return { id, customFields: Object.fromEntries(Object.entries(cf)) };
|
|
20
20
|
}
|
|
21
|
-
//
|
|
21
|
+
// selectCustomFieldsHostRows runs raw SQL against a dynamic host
|
|
22
22
|
// table name (opts.entityTable varies per call site), so it can't go through
|
|
23
23
|
// TenantDb's typed method API (table param must be a known SchemaTable). The
|
|
24
24
|
// SQL text itself still filters `tenant_id = ctx.tenantId`, so this stays a
|
|
@@ -42,7 +42,7 @@ async function exportCustomFields(db, ctx, tableName, opts) {
|
|
|
42
42
|
return { entity: `${opts.entityName}.customFields`, rows: snippetRows };
|
|
43
43
|
}
|
|
44
44
|
// Export-only wiring: custom fields hold supplemental business data, not PII
|
|
45
|
-
//
|
|
45
|
+
// — there is nothing to redact on user-forget, only Art. 20 export.
|
|
46
46
|
export function wireCustomFieldsUserDataRightsFor(r, opts) {
|
|
47
47
|
const tableName = extractTableName(opts.entityTable, "custom-fields/wire-user-data-rights");
|
|
48
48
|
// biome-ignore lint/correctness/useHookAtTopLevel: r.useExtension is a registrar API, not a React hook.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// `feedback_bulk_patterns` — Drift-Risiko bei Schema-Aenderungen).
|
|
1
|
+
// Shared override parser for policy-for-Query and the resolve-for-tenant helper. It was
|
|
2
|
+
// duplicated 1:1 in both files, so schema changes could make the copies drift.
|
|
4
3
|
import { retentionOverrideSchema } from "../override-schema.js";
|
|
5
4
|
export function parseRetentionOverrideOrNull(raw, tenantId, callerLabel) {
|
|
6
5
|
if (!raw || raw.trim() === "")
|
|
@@ -10,25 +10,18 @@ export { resolveTenantRetentionPreset, } from "./resolve-tenant-preset.js";
|
|
|
10
10
|
export { resolveRetentionPolicy, } from "./resolver.js";
|
|
11
11
|
export { runRetentionCleanup, } from "./run-retention-cleanup.js";
|
|
12
12
|
export { tenantRetentionOverrideEntity, tenantRetentionOverrideTable, } from "./schema/tenant-retention-override.js";
|
|
13
|
-
// data-retention —
|
|
13
|
+
// data-retention — automated retention and deletion per entity.
|
|
14
14
|
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
// - Retention-Presets (dsgvo-basic, dsgvo-hgb, swiss-dsg, default)
|
|
18
|
-
// - tenantRetentionOverride-Entity für per-Tenant Edge-Cases
|
|
15
|
+
// Retention is resolved through three layers: entity default → tenant preset →
|
|
16
|
+
// tenant override stored in `tenantRetentionOverride`.
|
|
19
17
|
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
18
|
+
// The retention-cleanup cron performs batched hard deletes and soft deletes per
|
|
19
|
+
// tenant. The tenant preset can be derived from the compliance profile, while
|
|
20
|
+
// anonymization is deferred and uses an idempotency marker; see
|
|
21
|
+
// `run-retention-cleanup.ts`.
|
|
24
22
|
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
// Cross-Feature-Hinweis: Plan-Roadmap docs/plans/datenschutz/
|
|
29
|
-
// core-data-retention.md — Forget-Flow konsultiert blockDelete via
|
|
30
|
-
// retention.policyFor → anonymize statt hardDelete bei Aufbewahrungs-
|
|
31
|
-
// pflicht. Das Wiring kommt in Sprint 2.U5.
|
|
23
|
+
// The forget flow consults `retention.policyFor` and anonymizes records instead
|
|
24
|
+
// of hard-deleting them while a mandatory retention period applies.
|
|
32
25
|
export function createDataRetentionFeature() {
|
|
33
26
|
return defineFeature("data-retention", (r) => {
|
|
34
27
|
r.describe("Resolves the effective retention policy for any entity using a 3-layer stack: entity-level default \u2192 tenant preset (`dsgvo-basic`, `dsgvo-hgb`, `swiss-dsg`) \u2192 per-tenant override stored in `tenantRetentionOverride`. Other features query the resolved policy via the `retention.policyFor` cross-feature API \u2014 most notably `user-data-rights`, which uses it to decide whether to anonymize instead of hard-delete a record that is still within a mandatory retention window.");
|
|
@@ -38,10 +31,10 @@ export function createDataRetentionFeature() {
|
|
|
38
31
|
recommended: false,
|
|
39
32
|
});
|
|
40
33
|
r.entity({ name: "tenant-retention-override", ...tenantRetentionOverrideEntity });
|
|
41
|
-
//
|
|
34
|
+
// Cross-feature API for the forget flow and cleanup job
|
|
42
35
|
r.exposesApi("retention.policyFor");
|
|
43
36
|
r.queryHandler(policyForQuery);
|
|
44
|
-
//
|
|
37
|
+
// Autonomous retention cleanup. perTenant fan-out (one run per
|
|
45
38
|
// active tenant, like soft-delete-cleanup): runRetentionCleanup's raw
|
|
46
39
|
// query helpers need the unfiltered runner, so the handler declares
|
|
47
40
|
// escapeHatch and reaches for ctx.db.unsafeRaw(). Without this cron,
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { resolveRetentionPolicyForTenant } from "../resolve-for-tenant.js";
|
|
4
|
-
// retention:query:policy-for — Cross-
|
|
4
|
+
// retention:query:policy-for — Cross-feature API for the forget flow.
|
|
5
5
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
6
|
+
// The forget flow calls this for each entity to determine whether it should
|
|
7
|
+
// use "delete", "anonymize", or "blockDelete-bis-Frist". The cleanup job uses
|
|
8
|
+
// it for the same purpose.
|
|
9
9
|
//
|
|
10
10
|
// Delegates to resolveRetentionPolicyForTenant so forget, the cleanup cron and
|
|
11
11
|
// this query can never disagree about the tenant preset. Letting the resolver
|
|
12
12
|
// load the preset itself costs one read per call, fine for a single lookup.
|
|
13
13
|
//
|
|
14
|
-
// access: openToAll —
|
|
15
|
-
//
|
|
14
|
+
// access: openToAll — other features in the same tenant may retrieve this.
|
|
15
|
+
// The result contains no PII, only policy metadata.
|
|
16
16
|
export const policyForQuery = defineQueryHandler({
|
|
17
17
|
name: "policy-for",
|
|
18
18
|
schema: z.object({
|
|
@@ -4,17 +4,17 @@ export declare class InvalidKeepForError extends Error {
|
|
|
4
4
|
}
|
|
5
5
|
export type Instant = InstanceType<ReturnType<typeof getTemporal>["Instant"]>;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Computes the cutoff instant — rows with reference < cutoff are expired
|
|
8
|
+
* and removed by the cleanup job.
|
|
9
9
|
*
|
|
10
|
-
* @param spec keepFor
|
|
11
|
-
* @param now
|
|
12
|
-
*
|
|
10
|
+
* @param spec keepFor string such as "30d", "10y", "6m", "1w", "24h"
|
|
11
|
+
* @param now Current point in time (injection parameter for time-travel tests;
|
|
12
|
+
* not global Temporal.Now)
|
|
13
13
|
*/
|
|
14
14
|
export declare function computeCutoff(spec: string, now: Instant): Instant;
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* Determines whether referenceTimestamp is older than the keepFor cutoff at now.
|
|
17
|
+
* The cleanup job uses this for each row.
|
|
18
18
|
*/
|
|
19
19
|
export declare function isPastCutoff(args: {
|
|
20
20
|
readonly referenceTimestamp: Instant;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
// keepFor
|
|
1
|
+
// keepFor format parser: "30d" / "10y" / "6m" / "1w" / "24h" → cutoff instant.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// Not millisecond-precise — GDPR retention requirements use day/month
|
|
4
|
+
// granularity. "6m" = 6×30d, "10y" = 10×365d. The cleanup job runs daily,
|
|
5
|
+
// so a difference of a few days at the cutoff is acceptable.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
7
|
+
// The boot validator already checked the format against /^\d+[hdwmy]$/
|
|
8
|
+
// — validate defensively again here for migration edge cases.
|
|
9
9
|
//
|
|
10
|
-
// Temporal
|
|
11
|
-
// `getTemporal()`
|
|
10
|
+
// Temporal is provided via globalThis (the polyfill is installed during framework boot).
|
|
11
|
+
// `getTemporal()` from framework/time provides typed access.
|
|
12
12
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
13
13
|
const KEEP_FOR_PATTERN = /^(\d+)([hdwmy])$/;
|
|
14
14
|
const UNIT_TO_DAYS = {
|
|
@@ -23,12 +23,12 @@ export class InvalidKeepForError extends Error {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* Computes the cutoff instant — rows with reference < cutoff are expired
|
|
27
|
+
* and removed by the cleanup job.
|
|
28
28
|
*
|
|
29
|
-
* @param spec keepFor
|
|
30
|
-
* @param now
|
|
31
|
-
*
|
|
29
|
+
* @param spec keepFor string such as "30d", "10y", "6m", "1w", "24h"
|
|
30
|
+
* @param now Current point in time (injection parameter for time-travel tests;
|
|
31
|
+
* not global Temporal.Now)
|
|
32
32
|
*/
|
|
33
33
|
export function computeCutoff(spec, now) {
|
|
34
34
|
const match = KEEP_FOR_PATTERN.exec(spec);
|
|
@@ -47,8 +47,8 @@ export function computeCutoff(spec, now) {
|
|
|
47
47
|
return now.subtract({ hours: amount * daysFactor * 24 });
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
50
|
+
* Determines whether referenceTimestamp is older than the keepFor cutoff at now.
|
|
51
|
+
* The cleanup job uses this for each row.
|
|
52
52
|
*/
|
|
53
53
|
export function isPastCutoff(args) {
|
|
54
54
|
const T = getTemporal();
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* undefined behavior weiterzumachen.
|
|
3
|
+
* Strict Zod schema for RetentionOverride, used by the set-override handler
|
|
4
|
+
* and the cleanup job's DB loader. The loader logs invalid JSON from the
|
|
5
|
+
* config column and skips it instead of continuing with undefined behavior.
|
|
7
6
|
*/
|
|
8
7
|
export declare const retentionOverrideSchema: z.ZodObject<{
|
|
9
8
|
keepFor: z.ZodOptional<z.ZodString>;
|
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
// Zod
|
|
1
|
+
// Strict Zod schema for RetentionOverride.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// Symmetric with compliance-profiles override-schema.ts.
|
|
4
|
+
// Every user-configurable JSON override uses strict Zod validation
|
|
5
|
+
// with enum validation.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
// - Top-
|
|
9
|
-
// - Strategy
|
|
10
|
-
// - keepFor
|
|
7
|
+
// Protects against:
|
|
8
|
+
// - Top-level typos ("keepfor" instead of "keepFor") — strict() rejects them
|
|
9
|
+
// - Strategy enum drift ("delete" instead of "hardDelete") — z.enum rejects it
|
|
10
|
+
// - keepFor format drift ("30days" instead of "30d") — regex rejects it
|
|
11
11
|
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
// gueltig sein.
|
|
12
|
+
// A tenant override may omit all three properties (the resolver falls back
|
|
13
|
+
// to the preset/entity default), but every property that is set must be valid.
|
|
15
14
|
import * as z from "zod";
|
|
16
15
|
const KEEP_FOR_PATTERN = /^\d+[hdwmy]$/;
|
|
17
16
|
const retentionStrategySchema = z.enum(["hardDelete", "softDelete", "anonymize", "blockDelete"]);
|
|
18
17
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* undefined behavior weiterzumachen.
|
|
18
|
+
* Strict Zod schema for RetentionOverride, used by the set-override handler
|
|
19
|
+
* and the cleanup job's DB loader. The loader logs invalid JSON from the
|
|
20
|
+
* config column and skips it instead of continuing with undefined behavior.
|
|
23
21
|
*/
|
|
24
22
|
export const retentionOverrideSchema = z
|
|
25
23
|
.object({
|
|
@@ -8,13 +8,12 @@ import type { RetentionDef } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
8
8
|
export type RetentionPreset = Readonly<Record<string, RetentionDef>>;
|
|
9
9
|
export type RetentionPresetKey = "default" | "dsgvo-basic" | "dsgvo-hgb" | "swiss-dsg";
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
* pipeda-default, ca-quebec-l25)
|
|
11
|
+
* Available presets. Additional options (hipaa, ccpa, aggressive-gdpr,
|
|
12
|
+
* pipeda-default, ca-quebec-l25) can be added on demand.
|
|
13
13
|
*/
|
|
14
14
|
export declare const RETENTION_PRESETS: Readonly<Record<RetentionPresetKey, RetentionPreset>>;
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* echtes Preset.
|
|
16
|
+
* Presets available in the onboarding banner. `default` is a migration edge
|
|
17
|
+
* case and is not displayed; production tenants must choose an actual preset.
|
|
19
18
|
*/
|
|
20
19
|
export declare const SELECTABLE_RETENTION_PRESETS: readonly RetentionPresetKey[];
|