@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.388.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.d.ts +7 -7
- package/dist/agent-tools/tool-dispatch.js +9 -9
- package/dist/audit/handlers/audit-events.js +1 -1
- package/dist/audit/screens.js +1 -1
- package/dist/auth-email-password/feature.js +1 -1
- package/dist/auth-email-password/handlers/change-password.write.js +3 -3
- package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
- package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
- package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
- package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
- package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
- package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
- package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
- package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/login.write.js +1 -1
- package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
- package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
- package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
- package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
- package/dist/auth-email-password/index.js +5 -5
- package/dist/auth-email-password/lockout-store.js +1 -1
- package/dist/auth-email-password/seeding.d.ts +42 -45
- package/dist/auth-email-password/seeding.js +51 -53
- package/dist/auth-email-password/signup-token-store.js +8 -8
- package/dist/auth-email-password/testing.js +3 -3
- package/dist/auth-email-password/web/auth-client.d.ts +2 -2
- package/dist/auth-email-password/web/auth-client.js +36 -37
- package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
- package/dist/auth-email-password/web/auth-gate.js +15 -16
- package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
- package/dist/auth-email-password/web/client-plugin.js +4 -5
- package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
- package/dist/auth-email-password/web/constants.js +3 -3
- package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
- package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
- package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
- package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
- package/dist/auth-email-password/web/index.js +5 -5
- package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
- package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
- package/dist/auth-email-password/web/login-screen.d.ts +1 -1
- package/dist/auth-email-password/web/login-screen.js +2 -3
- package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
- package/dist/auth-email-password/web/reset-password-screen.js +12 -13
- package/dist/auth-email-password/web/session.d.ts +10 -9
- package/dist/auth-email-password/web/session.js +28 -29
- package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
- package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
- package/dist/auth-email-password/web/signup-screen.js +13 -13
- package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
- package/dist/auth-email-password/web/tenant-switcher.js +21 -22
- package/dist/auth-email-password/web/use-shell-user.js +12 -13
- package/dist/auth-email-password/web/user-menu.d.ts +4 -4
- package/dist/auth-email-password/web/user-menu.js +12 -13
- package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
- package/dist/auth-email-password/web/verify-email-screen.js +9 -10
- package/dist/auth-foundation/boot-checks.js +4 -4
- package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
- package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
- package/dist/auth-foundation/types.js +2 -2
- package/dist/auth-mfa/feature-exports.d.ts +2 -2
- package/dist/auth-mfa/feature.js +8 -0
- 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 +8 -4
- 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-code-or-recovery-field.d.ts +11 -0
- package/dist/auth-mfa/web/mfa-code-or-recovery-field.js +12 -0
- package/dist/auth-mfa/web/mfa-disable-dialog.js +14 -3
- package/dist/auth-mfa/web/mfa-regenerate-recovery-dialog.js +14 -3
- package/dist/auth-mfa/web/mfa-setup-preauth-screen.js +10 -5
- package/dist/auth-mfa/web/mfa-verify-screen.js +32 -11
- package/dist/billing-foundation/aggregate-id.d.ts +5 -5
- package/dist/billing-foundation/aggregate-id.js +10 -11
- package/dist/billing-foundation/checkout-core.d.ts +9 -14
- package/dist/billing-foundation/checkout-core.js +24 -39
- package/dist/billing-foundation/consumer-protection/confirmation-mail.js +8 -2
- package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +1 -0
- package/dist/billing-foundation/consumer-protection/consent-gate.js +1 -0
- package/dist/billing-foundation/consumer-protection/issue-confirmation.js +9 -3
- package/dist/billing-foundation/consumer-protection/mail-notifications.js +3 -1
- package/dist/billing-foundation/consumer-protection/termination-receipt-limit.d.ts +4 -2
- package/dist/billing-foundation/consumer-protection/termination-receipt-limit.js +6 -5
- package/dist/billing-foundation/consumer-protection/termination-record.d.ts +5 -1
- package/dist/billing-foundation/consumer-protection/termination-record.js +27 -17
- package/dist/billing-foundation/consumer-protection/termination-request.js +12 -7
- package/dist/billing-foundation/consumer-protection/termination-revoke.js +12 -7
- package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +1 -1
- package/dist/billing-foundation/consumer-protection/termination-texts.js +3 -0
- package/dist/billing-foundation/consumer-protection/withdrawal-period.d.ts +5 -2
- package/dist/billing-foundation/consumer-protection/withdrawal-period.js +8 -9
- package/dist/billing-foundation/entities.js +27 -27
- package/dist/billing-foundation/events.d.ts +1 -0
- package/dist/billing-foundation/events.js +19 -17
- package/dist/billing-foundation/feature.js +45 -44
- 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/billing-plans.query.js +35 -5
- package/dist/billing-foundation/handlers/create-checkout-session.write.js +19 -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/plan-switch-preview.query.d.ts +13 -0
- package/dist/billing-foundation/handlers/plan-switch-preview.query.js +48 -0
- package/dist/billing-foundation/handlers/process-event.write.d.ts +6 -0
- package/dist/billing-foundation/handlers/process-event.write.js +28 -22
- package/dist/billing-foundation/handlers/start-plan-checkout.write.js +32 -5
- package/dist/billing-foundation/handlers/switch-plan.write.d.ts +2 -2
- package/dist/billing-foundation/handlers/switch-plan.write.js +56 -64
- package/dist/billing-foundation/handlers/sync-subscription.write.js +12 -1
- package/dist/billing-foundation/i18n.js +22 -0
- package/dist/billing-foundation/index.d.ts +1 -1
- package/dist/billing-foundation/plan-catalog.d.ts +21 -5
- package/dist/billing-foundation/plan-catalog.js +25 -16
- package/dist/billing-foundation/plan-switch.d.ts +12 -0
- package/dist/billing-foundation/plan-switch.js +60 -0
- 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 +97 -42
- package/dist/billing-foundation/types.js +29 -20
- package/dist/billing-foundation/validate-options.js +17 -0
- package/dist/billing-foundation/web/billing-plans-panel.js +82 -36
- package/dist/billing-foundation/web/checkout-consent-dialog.d.ts +17 -3
- package/dist/billing-foundation/web/checkout-consent-dialog.js +14 -10
- package/dist/billing-foundation/web/constants.d.ts +4 -0
- package/dist/billing-foundation/web/constants.js +4 -0
- package/dist/billing-foundation/web/plan-price.d.ts +15 -0
- package/dist/billing-foundation/web/plan-price.js +32 -0
- package/dist/billing-foundation/web/plan-switch-confirm-dialog.d.ts +15 -0
- package/dist/billing-foundation/web/plan-switch-confirm-dialog.js +66 -0
- package/dist/cap-counter/aggregate-id.js +8 -9
- package/dist/cap-counter/cap-reservation.js +5 -1
- 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 +49 -49
- 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 +8 -2
- package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
- package/dist/channel-email/feature.js +1 -1
- 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/cascade.query.d.ts +5 -0
- package/dist/config/handlers/cascade.query.js +4 -3
- 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/handlers/values.query.d.ts +5 -0
- package/dist/config/handlers/values.query.js +4 -3
- package/dist/config/resolver.js +4 -4
- package/dist/config/table.js +10 -10
- package/dist/config/write-helpers.d.ts +1 -0
- package/dist/config/write-helpers.js +19 -10
- package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
- package/dist/crypto-shredding/handlers/forget-subject.write.js +25 -21
- 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/channel-context.js +6 -3
- package/dist/delivery/db/queries/preferences.js +2 -2
- package/dist/delivery/delivery-service.js +22 -7
- package/dist/delivery/feature.js +2 -2
- package/dist/delivery/handlers/log.query.js +1 -1
- package/dist/delivery/handlers/preferences.query.d.ts +1 -1
- package/dist/delivery/handlers/preferences.query.js +20 -1
- package/dist/delivery/handlers/unsubscribe-page-chrome.query.js +1 -1
- package/dist/delivery/tables.js +9 -8
- package/dist/delivery/unsubscribe-link.d.ts +3 -1
- package/dist/delivery/unsubscribe-page-strings.d.ts +1 -0
- package/dist/delivery/unsubscribe-page-strings.js +1 -0
- package/dist/delivery/unsubscribe-page.d.ts +2 -0
- package/dist/delivery/unsubscribe-page.js +5 -0
- package/dist/delivery/unsubscribe.js +29 -11
- 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-foundation/index.d.ts +1 -1
- package/dist/file-foundation/index.js +1 -1
- package/dist/file-foundation/read-file-ref-content.d.ts +3 -0
- package/dist/file-foundation/read-file-ref-content.js +6 -1
- package/dist/file-provider-inmemory/feature.d.ts +1 -1
- package/dist/file-provider-inmemory/feature.js +16 -16
- package/dist/file-provider-s3/env-named-feature.d.ts +0 -2
- 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 +3 -3
- package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
- package/dist/form-draft/decrypt-draft.js +5 -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/host-routing/dispatch.js +11 -20
- 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.d.ts +2 -2
- package/dist/inbound-mail-foundation/handlers/update-account.write.js +22 -14
- package/dist/inbound-mail-foundation/i18n.js +0 -1
- 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/screens.js +0 -3
- package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
- package/dist/inbound-mail-foundation/types.d.ts +49 -49
- 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 +85 -67
- 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.d.ts +1 -0
- package/dist/jobs/feature.js +13 -10
- 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/handlers/tenant-failures.query.d.ts +1 -1
- package/dist/jobs/handlers/tenant-failures.query.js +45 -41
- package/dist/jobs/handlers/tenant-runs.query.d.ts +1 -1
- package/dist/jobs/handlers/tenant-runs.query.js +54 -50
- package/dist/jobs/job-instant.js +1 -1
- package/dist/jobs/job-run-logger.js +15 -15
- 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 +5 -5
- package/dist/mail-foundation/feature.js +27 -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.d.ts +1 -1
- package/dist/personal-access-tokens/feature.js +9 -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/renderer-pdf/render-table-pdf.d.ts +1 -1
- package/dist/renderer-pdf/render-table-pdf.js +22 -10
- 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.d.ts +2 -2
- package/dist/sessions/feature.js +12 -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.d.ts +1 -0
- package/dist/shared/decrypt-stored-pii.js +7 -2
- package/dist/shared/encrypt-for-direct-write.js +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/mail-template-body.d.ts +6 -2
- package/dist/shared/mail-template-body.js +7 -4
- 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/step-dispatcher/feature.js +1 -0
- package/dist/subscription-dodo/client.d.ts +17 -0
- package/dist/subscription-dodo/client.js +31 -0
- package/dist/subscription-dodo/constants.d.ts +12 -0
- package/dist/subscription-dodo/constants.js +19 -0
- package/dist/subscription-dodo/feature.d.ts +37 -0
- package/dist/subscription-dodo/feature.js +144 -0
- package/dist/subscription-dodo/index.d.ts +2 -0
- package/dist/subscription-dodo/index.js +4 -0
- package/dist/subscription-dodo/plugin-methods.d.ts +23 -0
- package/dist/subscription-dodo/plugin-methods.js +260 -0
- package/dist/subscription-dodo/runtime.d.ts +27 -0
- package/dist/subscription-dodo/runtime.js +89 -0
- package/dist/subscription-dodo/verify-webhook.d.ts +37 -0
- package/dist/subscription-dodo/verify-webhook.js +189 -0
- 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 +36 -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 +8 -7
- 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.d.ts +3 -2
- package/dist/template-resolver/api.js +34 -12
- package/dist/template-resolver/compile-document-body.js +1 -0
- package/dist/template-resolver/feature.js +2 -2
- package/dist/template-resolver/handlers/bundle-import.js +3 -3
- package/dist/template-resolver/handlers/copy-locale.write.d.ts +5 -1
- package/dist/template-resolver/handlers/copy-locale.write.js +22 -7
- package/dist/template-resolver/handlers/diff-to-system.query.js +3 -2
- package/dist/template-resolver/handlers/document-base.js +3 -2
- package/dist/template-resolver/handlers/find-by-id.query.js +8 -7
- package/dist/template-resolver/handlers/list.query.js +6 -7
- package/dist/template-resolver/handlers/overview.query.d.ts +3 -0
- package/dist/template-resolver/handlers/overview.query.js +6 -3
- package/dist/template-resolver/handlers/shared.js +2 -2
- package/dist/template-resolver/handlers/template-write.js +3 -3
- package/dist/template-resolver/handlers/tenant-override-counts.query.js +1 -3
- package/dist/template-resolver/handlers/tenant-override-selection.d.ts +2 -1
- package/dist/template-resolver/handlers/tenant-overrides.query.js +28 -5
- 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/handlers/usage.query.d.ts +2 -1
- package/dist/template-resolver/handlers/usage.query.js +26 -16
- package/dist/template-resolver/handlers/validate.query.js +7 -2
- package/dist/template-resolver/seeding.js +30 -14
- package/dist/template-resolver/store-template-resource.d.ts +1 -0
- package/dist/template-resolver/store-template-resource.js +19 -4
- package/dist/template-resolver/table.js +10 -11
- package/dist/template-resolver/template-delivery-policy.d.ts +0 -5
- package/dist/template-resolver/template-delivery-policy.js +0 -6
- package/dist/template-resolver/template-meta.js +7 -4
- package/dist/template-resolver/template-preview.js +4 -3
- package/dist/template-resolver/web/client-plugin.js +2 -2
- package/dist/template-resolver/web/constants.d.ts +2 -2
- package/dist/template-resolver/web/constants.js +3 -3
- package/dist/template-resolver/web/index.d.ts +1 -0
- package/dist/template-resolver/web/index.js +1 -0
- package/dist/template-resolver/web/mail-layout-constants.d.ts +5 -0
- package/dist/template-resolver/web/mail-layout-constants.js +7 -0
- package/dist/tenant/feature.js +7 -7
- package/dist/tenant/handlers/member-directory.query.d.ts +1 -0
- package/dist/tenant/handlers/member-directory.query.js +11 -4
- 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.d.ts +1 -0
- package/dist/tenant/handlers/tenant-directory.query.js +9 -5
- 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/constants.d.ts +1 -0
- package/dist/tenant-lifecycle/constants.js +4 -0
- package/dist/tenant-lifecycle/feature.js +1 -1
- package/dist/tenant-lifecycle/run-tenant-destroy.js +2 -2
- 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 +7 -8
- package/dist/tier-engine/handlers/set-tenant-tier.write.js +7 -4
- package/dist/tier-engine/tier-resolver.js +2 -2
- package/dist/tier-engine/trial.js +8 -8
- package/dist/tier-engine/web/constants.js +2 -2
- 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 +130 -237
- package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
- package/dist/user-data-rights/run-forget-cleanup.js +65 -83
- 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/waitlist/handlers/export-purge.write.js +2 -1
- package/dist/waitlist/handlers/submit.write.js +5 -5
- package/dist/waitlist/import.d.ts +1 -0
- package/dist/waitlist/import.js +4 -0
- package/dist/waitlist/legacy-migrate.js +17 -6
- package/dist/waitlist/link-on-signup.js +18 -6
- package/dist/waitlist/options.d.ts +3 -0
- 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 +20 -10
- package/src/agent-tools/changes.json +6 -0
- package/src/audit/changes.json +12 -0
- package/src/auth-mfa/changes.json +6 -0
- package/src/billing-foundation/changes.json +55 -0
- package/src/cap-counter/changes.json +18 -0
- package/src/channel-email/changes.json +6 -0
- package/src/config/changes.json +12 -0
- package/src/crypto-shredding/changes.json +6 -0
- package/src/delivery/changes.json +30 -0
- package/src/form-draft/changes.json +6 -0
- package/src/host-routing/changes.json +6 -0
- package/src/inbound-mail-foundation/changes.json +18 -0
- package/src/jobs/changes.json +13 -0
- package/src/mail-foundation/changes.json +6 -0
- package/src/renderer-pdf/changes.json +6 -0
- package/src/step-dispatcher/changes.json +6 -0
- package/src/subscription-dodo/changes.json +14 -0
- package/src/subscription-stripe/changes.json +12 -0
- package/src/template-resolver/changes.json +48 -0
- package/src/tenant/changes.json +6 -0
- package/src/tenant-lifecycle/changes.json +6 -0
- package/src/tier-engine/changes.json +6 -0
- package/src/waitlist/changes.json +18 -0
- package/dist/billing-foundation/consumer-protection/stored-user-email.d.ts +0 -1
- package/dist/billing-foundation/consumer-protection/stored-user-email.js +0 -8
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
import { createBooleanField, createEntity, createNumberField, createTextField, } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
-
// fieldDefinition — Tenant-
|
|
2
|
+
// fieldDefinition — Tenant- or system-scoped custom-field definition.
|
|
3
3
|
//
|
|
4
|
-
// **Tenant
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
4
|
+
// **Tenant scope:** The `tenantId` base column is set automatically by the
|
|
5
|
+
// framework. For system-scope definitions, `tenantId = SYSTEM_TENANT_ID`;
|
|
6
|
+
// for tenant-scope definitions, it is the current tenant. Both use the same
|
|
7
|
+
// table; the scope is determined by the tenantId value (no separate `scope`
|
|
8
|
+
// column).
|
|
8
9
|
//
|
|
9
|
-
// **Conflict
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
10
|
+
// **Conflict rule:** only one definition may exist per (entityName, fieldKey)
|
|
11
|
+
// — either system or tenant, not both. Resolution on read = `WHERE tenantId IN
|
|
12
|
+
// (SYSTEM_TENANT_ID, <current-tenant>)`. The conflict check is performed by
|
|
13
|
+
// the write handler, NOT enforced by a DB constraint (the DB has a natural
|
|
14
|
+
// UNIQUE constraint on (tenantId, entityName, fieldKey) through aggregate-ID
|
|
15
|
+
// construction).
|
|
15
16
|
//
|
|
16
|
-
// **Spec
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
17
|
+
// **Spec drift**: Spec Z.40-54 defines a separate `custom_field_value` table.
|
|
18
|
+
// Plan-Doc v2 replaced it with jsonb on the host entity (pure jsonb storage).
|
|
19
|
+
// This defines ONLY the definition entity; values land in
|
|
20
|
+
// `read_<entity>.customFields` jsonb via MSP.
|
|
20
21
|
//
|
|
21
|
-
// **
|
|
22
|
-
// - `defaultValue`, `options`, `fieldAccess`, `label` —
|
|
23
|
-
// `serializedField` jsonb
|
|
24
|
-
// r.field.X()-
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
// - `version` (optimistic
|
|
28
|
-
// stream
|
|
29
|
-
// - `createdAt/updatedAt/createdBy/updatedBy` — automatic
|
|
30
|
-
// columns
|
|
22
|
+
// **What is NOT stored as a base-field column here**:
|
|
23
|
+
// - `defaultValue`, `options`, `fieldAccess`, `label` — all packed into
|
|
24
|
+
// `serializedField` jsonb (builder reuse: dehydrated
|
|
25
|
+
// r.field.X()-output). Spec Z.18-38 lists them as separate columns, but
|
|
26
|
+
// builder reuse makes that redundant — the serialized builder contains all
|
|
27
|
+
// these aspects in a type-safe form.
|
|
28
|
+
// - `version` (optimistic lock) — redundant with event sourcing; we use the
|
|
29
|
+
// aggregate stream version.
|
|
30
|
+
// - `createdAt/updatedAt/createdBy/updatedBy` — automatic through base
|
|
31
|
+
// columns and events.
|
|
31
32
|
export const fieldDefinitionEntity = createEntity({
|
|
32
33
|
table: "read_custom_field_definitions",
|
|
33
34
|
description: "One custom-field definition: the host entity it extends, the field key, its type and required/searchable flags, a display order, and the serialized field builder that carries the type options, default value and labels. Rows owned by the system tenant apply to every tenant; all others belong to the tenant that defined them.",
|
|
@@ -40,55 +41,56 @@ export const fieldDefinitionEntity = createEntity({
|
|
|
40
41
|
// NB: `retention.strategy` below is the data-retention purge policy, a
|
|
41
42
|
// SEPARATE knob from this executor flag — it does not drive executor.delete.
|
|
42
43
|
softDelete: true,
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
44
|
+
// Retention policy — field definitions are tenant-schema metadata, not PII.
|
|
45
|
+
// Long retention supports audits (compliance can ask when a tenant defined,
|
|
46
|
+
// changed, or deleted the field).
|
|
46
47
|
//
|
|
47
|
-
// 10-
|
|
48
|
-
// tenantRetentionOverride
|
|
49
|
-
// (
|
|
48
|
+
// The 10-year keepFor is a conservative default; tenants can override it
|
|
49
|
+
// through tenantRetentionOverride for their own edge cases
|
|
50
|
+
// (e.g. shorter retention for test tenants).
|
|
50
51
|
retention: {
|
|
51
52
|
keepFor: "10y",
|
|
52
53
|
strategy: "softDelete",
|
|
53
54
|
},
|
|
54
55
|
fields: {
|
|
55
|
-
//
|
|
56
|
-
// "customer").
|
|
56
|
+
// The entity name for which this field is defined (e.g. "property",
|
|
57
|
+
// "customer"). The 64-character maximum follows Kumiko's entity-name
|
|
58
|
+
// convention.
|
|
57
59
|
entityName: createTextField({
|
|
58
60
|
required: true,
|
|
59
61
|
maxLength: 64,
|
|
60
62
|
personal: false,
|
|
61
63
|
reason: "technical_reference",
|
|
62
64
|
}),
|
|
63
|
-
// Field
|
|
64
|
-
//
|
|
65
|
+
// Field key (e.g. "internalNumber", "vipFlag") — kebab-case and camelCase
|
|
66
|
+
// are allowed; UI rendering uses label instead of fieldKey.
|
|
65
67
|
fieldKey: createTextField({
|
|
66
68
|
required: true,
|
|
67
69
|
maxLength: 64,
|
|
68
70
|
personal: false,
|
|
69
71
|
reason: "technical_reference",
|
|
70
72
|
}),
|
|
71
|
-
// Field
|
|
72
|
-
// write
|
|
73
|
+
// Field type from the SUPPORTED_FIELD_TYPES set. Validated with Zod in the
|
|
74
|
+
// write handler.
|
|
73
75
|
type: createTextField({
|
|
74
76
|
required: true,
|
|
75
77
|
maxLength: 16,
|
|
76
78
|
personal: false,
|
|
77
79
|
reason: "technical_reference",
|
|
78
80
|
}),
|
|
79
|
-
// Required
|
|
80
|
-
// (
|
|
81
|
+
// Required flag — checked against the value during entity writes
|
|
82
|
+
// (the same semantics as a base field).
|
|
81
83
|
required: createBooleanField({ required: true }),
|
|
82
|
-
// Searchable
|
|
83
|
-
//
|
|
84
|
+
// Searchable flag — when true, the field contributes to the search document
|
|
85
|
+
// through the search-payload extension.
|
|
84
86
|
searchable: createBooleanField({ required: true }),
|
|
85
|
-
// UI
|
|
87
|
+
// UI display order, allowing tenants to sort their fields in the UI.
|
|
86
88
|
displayOrder: createNumberField({ required: true, integer: true }),
|
|
87
|
-
// Builder
|
|
88
|
-
//
|
|
89
|
-
// defaultValue, fieldAccess, i18n
|
|
90
|
-
//
|
|
91
|
-
//
|
|
89
|
+
// Builder reuse: serialized r.field.X(opts) output stored as jsonb.
|
|
90
|
+
// It includes type options (enum values, money currency, embedded schema),
|
|
91
|
+
// defaultValue, fieldAccess, and i18n labels. During write validation, the
|
|
92
|
+
// handler dehydrates this back into an r.field.X() instance and uses its
|
|
93
|
+
// .schema for value validation.
|
|
92
94
|
serializedField: createTextField({
|
|
93
95
|
required: true,
|
|
94
96
|
maxLength: 65536,
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
-
// Domain
|
|
3
|
-
//
|
|
4
|
-
// auf demselben Stream wie die host-entity's eigene Events).
|
|
2
|
+
// Domain events for custom-field values. customField.set and .cleared live
|
|
3
|
+
// on the host aggregate stream, alongside the host entity's own events.
|
|
5
4
|
//
|
|
6
|
-
//
|
|
7
|
-
// aggregate
|
|
8
|
-
//
|
|
9
|
-
// aggregate-type
|
|
5
|
+
// The event's aggregate type is the host entity name (for example, "property"),
|
|
6
|
+
// and its aggregate ID is the host entity row ID (for example, property-uuid).
|
|
7
|
+
// This ensures customFields-MSPs consume only events for their wired entities,
|
|
8
|
+
// filtered by aggregate-type match in each consumer-side-MSP registration.
|
|
10
9
|
export const customFieldSetSchema = z.object({
|
|
11
10
|
fieldKey: z.string().min(1).max(64),
|
|
12
|
-
// Every set carries its value (custom fields hold no PII
|
|
11
|
+
// Every set carries its value (custom fields hold no PII) — replay
|
|
13
12
|
// reproduces the projection fully. Stays optional at the type layer only
|
|
14
13
|
// because z.unknown() is inherently optional; the apply side treats
|
|
15
14
|
// `value === undefined` as an anomaly and warns.
|
|
@@ -15,24 +15,24 @@ declare const defaultCustomFieldsFeature: import("@cosmicdrift/kumiko-types/feat
|
|
|
15
15
|
};
|
|
16
16
|
};
|
|
17
17
|
export type CustomFieldsFeatureOptions = {
|
|
18
|
-
/**
|
|
18
|
+
/** Quota for define-tenant-field. */
|
|
19
19
|
readonly fieldDefinitionLimitPerTenant?: number;
|
|
20
|
-
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
20
|
+
/** Roles for set-/clear-custom-field, used by the save paths in
|
|
21
|
+
* CustomFieldsFormSection. Default ["TenantAdmin","TenantMember"];
|
|
22
|
+
* apps with their own role vocabulary (for example ["Admin","Editor"])
|
|
23
|
+
* MUST set this, otherwise value saving is access_denied for every app user
|
|
24
|
+
* (role-naming drift). */
|
|
25
25
|
readonly valueWriteRoles?: readonly string[];
|
|
26
|
-
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
26
|
+
/** Roles for custom-fields:query:field-definition:list, used by the loading
|
|
27
|
+
* path in CustomFieldsFormSection. Default ["TenantAdmin"]. If
|
|
28
|
+
* valueWriteRoles is set but this is not, the value roles are inherited here
|
|
29
|
+
* (unioned with the default so admins retain list access); otherwise the
|
|
30
|
+
* FormSection cannot load for value writers (access_denied) while the save
|
|
31
|
+
* path remains open (an asymmetric break). */
|
|
32
32
|
readonly fieldDefinitionListRoles?: readonly string[];
|
|
33
33
|
/** Access roles for the definition-CRUD triad (`define-tenant-field`,
|
|
34
|
-
* `update-tenant-field`, `delete-tenant-field`) — hard-wired to ["TenantAdmin"]
|
|
35
|
-
*
|
|
34
|
+
* `update-tenant-field`, `delete-tenant-field`) — hard-wired to ["TenantAdmin"].
|
|
35
|
+
* Apps with their own role vocabulary (e.g. ["Admin","Editor"])
|
|
36
36
|
* MUST set this, else field-definition management is access_denied for every
|
|
37
37
|
* app-user without a "TenantAdmin" role. Only covers the tenant-scope triad —
|
|
38
38
|
* define-/delete-system-field stay hard-wired to ["SystemAdmin"], since
|
|
@@ -1,50 +1,49 @@
|
|
|
1
|
-
// custom-fields —
|
|
2
|
-
//
|
|
1
|
+
// custom-fields — tenant- and system-scoped custom-field definitions plus
|
|
2
|
+
// generic custom-field value write-handlers (host-stream events).
|
|
3
3
|
//
|
|
4
|
-
// **Scope: supplemental business data, NO PII
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
4
|
+
// **Scope: supplemental business data, NO PII.** Custom fields are for
|
|
5
|
+
// tenant-specific additional data (reference numbers, flags, categories),
|
|
6
|
+
// not personally identifiable information. The former `sensitive` flag was
|
|
7
|
+
// removed; the schema rejects it and `parseSerializedField` throws for legacy
|
|
8
|
+
// definitions. Values are stored entirely in the event log (rebuild-safe).
|
|
9
9
|
// PII belongs in schema-entity fields with a `personal` annotation
|
|
10
10
|
// (crypto-shredding, event ciphertext, forget pipeline).
|
|
11
11
|
//
|
|
12
|
-
// **
|
|
13
|
-
// 1. r.entity({ name: "field-definition" }) —
|
|
14
|
-
// 2. define-tenant-field / define-system-field — RBAC write-handlers
|
|
15
|
-
//
|
|
12
|
+
// **This feature provides:**
|
|
13
|
+
// 1. r.entity({ name: "field-definition" }) — event-sourced definition storage.
|
|
14
|
+
// 2. define-tenant-field / define-system-field — RBAC write-handlers for
|
|
15
|
+
// definition CRUD.
|
|
16
16
|
// 3. delete-tenant-field / delete-system-field — RBAC write-handlers.
|
|
17
|
-
// 3b. update-tenant-field —
|
|
18
|
-
// 4. set-custom-field / clear-custom-field — write-handlers
|
|
19
|
-
//
|
|
20
|
-
// 5. r.defineEvent
|
|
21
|
-
// 6. r.extendsRegistrar("customFields") —
|
|
22
|
-
//
|
|
23
|
-
// 7. defineEntityListHandler —
|
|
24
|
-
//
|
|
17
|
+
// 3b. update-tenant-field — full-replacement edit; type is immutable.
|
|
18
|
+
// 4. set-custom-field / clear-custom-field — write-handlers for VALUES.
|
|
19
|
+
// They emit customField.set/.cleared events on the host aggregate stream.
|
|
20
|
+
// 5. r.defineEvent for customField.set/.cleared + fieldDefinition.deleted.
|
|
21
|
+
// 6. r.extendsRegistrar("customFields") — registers the extension name so
|
|
22
|
+
// consumers can opt in via r.useExtension("customFields", "<entity>").
|
|
23
|
+
// 7. defineEntityListHandler — reads fieldDefinitions (currently tenant-
|
|
24
|
+
// scoped; a system+tenant UNION requires a custom query).
|
|
25
25
|
//
|
|
26
|
-
// **Consumer-side
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
// + postQuery
|
|
26
|
+
// **Consumer-side wiring** (see wire-for-entity.ts):
|
|
27
|
+
// The consumer calls `wireCustomFieldsFor(r, entityName, entityTable)`,
|
|
28
|
+
// which registers per host entity: useExtension + MSP (JSONB projection)
|
|
29
|
+
// + postQuery hook (flattening) + search-payload extension.
|
|
30
30
|
//
|
|
31
|
-
// **Host-
|
|
32
|
-
//
|
|
33
|
-
// `customFieldsField()` (
|
|
31
|
+
// **Host-entity requirement**:
|
|
32
|
+
// The consumer MUST declare a `customFields` column as
|
|
33
|
+
// `customFieldsField()` (JSONB) in the entity definition.
|
|
34
34
|
//
|
|
35
|
-
// **Exports
|
|
35
|
+
// **Exports pattern**:
|
|
36
36
|
// `createCustomFieldsFeature().exports.{setEvent,clearedEvent,fieldDefinitionDeletedEvent}`
|
|
37
|
-
//
|
|
38
|
-
// `<event>.name`
|
|
39
|
-
// hand-
|
|
40
|
-
//
|
|
37
|
+
// provides typed EventDef handles. Handlers and wire-for-entity use
|
|
38
|
+
// `<event>.name` as a compile-time literal-typed qualified string instead of
|
|
39
|
+
// hand-built template literals, which drifted from the real names once
|
|
40
|
+
// toKebab collapsed them.
|
|
41
41
|
//
|
|
42
|
-
// **
|
|
43
|
-
// - Cross-scope
|
|
44
|
-
// - Cross-
|
|
45
|
-
// (cap-counter
|
|
46
|
-
//
|
|
47
|
-
// alle erledigt.)
|
|
42
|
+
// **Still open:**
|
|
43
|
+
// - Cross-scope conflict detection (a tenant overriding a system fieldKey)
|
|
44
|
+
// - Cross-scope read UNION (system + tenant fieldDefinitions in one list)
|
|
45
|
+
// (cap-counter quota, user-data-rights anonymization, and value validation
|
|
46
|
+
// against serializedField via fieldToZod in set-custom-field are complete.)
|
|
48
47
|
import { defineEntityListHandler, defineFeature, } from "@cosmicdrift/kumiko-framework/engine";
|
|
49
48
|
import * as z from "zod";
|
|
50
49
|
import { fieldDefinitionEntity } from "./entity.js";
|
|
@@ -76,9 +75,9 @@ function registerCustomFields(r, variant) {
|
|
|
76
75
|
recommended: false,
|
|
77
76
|
});
|
|
78
77
|
r.entity({ name: "field-definition", ...fieldDefinitionEntity });
|
|
79
|
-
// Event
|
|
80
|
-
// Returned EventDefs
|
|
81
|
-
//
|
|
78
|
+
// Event types — qualified as "custom-fields:event:<short-name>".
|
|
79
|
+
// Returned EventDefs expose .name as a compile-time literal-typed string,
|
|
80
|
+
// which handlers and MSP keys consume instead of constructing template literals.
|
|
82
81
|
// `value: z.unknown()` has no field-level schema to catalog under piiFields
|
|
83
82
|
// (event PII covers string fields only), so "no PII" is a convention here,
|
|
84
83
|
// not an enforced guarantee.
|
|
@@ -89,28 +88,28 @@ function registerCustomFields(r, variant) {
|
|
|
89
88
|
piiFields: "none",
|
|
90
89
|
});
|
|
91
90
|
const fieldDefinitionDeletedEvent = r.defineEvent(FIELD_DEFINITION_DELETED_EVENT, fieldDefinitionDeletedSchema, { piiFields: "none" });
|
|
92
|
-
//
|
|
93
|
-
// Consumer-side: r.useExtension("customFields", "<entity>")
|
|
94
|
-
//
|
|
95
|
-
// `wireCustomFieldsFor(r, entity, table)`
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
// wiring
|
|
99
|
-
//
|
|
100
|
-
//
|
|
91
|
+
// Registers that this extension exists.
|
|
92
|
+
// Consumer-side: r.useExtension("customFields", "<entity>") marks opt-in,
|
|
93
|
+
// but does not wire anything automatically. The consumer MUST also call
|
|
94
|
+
// `wireCustomFieldsFor(r, entity, table)` to register the MSP, postQuery hook,
|
|
95
|
+
// and search extension.
|
|
96
|
+
// The empty-options pattern (`{}`) is intentional: boot-time onRegister
|
|
97
|
+
// wiring would require a closure over the Drizzle table, which the consumer
|
|
98
|
+
// does not provide during extendsRegistrar registration. Explicit consumer-
|
|
99
|
+
// side wiring therefore avoids implicit magic.
|
|
101
100
|
r.extendsRegistrar(CUSTOM_FIELDS_EXTENSION, {});
|
|
102
|
-
// Definition
|
|
101
|
+
// Definition CRUD handlers.
|
|
103
102
|
r.writeHandler(variant.defineTenantHandler);
|
|
104
103
|
r.writeHandler(defineSystemFieldHandler);
|
|
105
104
|
r.writeHandler(variant.updateTenantHandler);
|
|
106
105
|
r.writeHandler(variant.deleteTenantHandler);
|
|
107
106
|
r.writeHandler(deleteSystemFieldHandler);
|
|
108
|
-
// Value
|
|
107
|
+
// Value write handlers. They emit events on the host aggregate stream.
|
|
109
108
|
r.writeHandler(variant.setHandler);
|
|
110
109
|
r.writeHandler(variant.clearHandler);
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
//
|
|
110
|
+
// The list query is tenant-scoped. CustomFieldsFormSection dispatches this
|
|
111
|
+
// query name directly, so apps with their own role vocabulary must override
|
|
112
|
+
// the roles through fieldDefinitionListRoles.
|
|
114
113
|
r.queryHandler(defineEntityListHandler("field-definition", fieldDefinitionEntity, {
|
|
115
114
|
access: { roles: variant.fieldDefinitionListRoles },
|
|
116
115
|
description: "Lists the custom-field definitions of the caller's own tenant; use it to discover which extra fields an entity accepts before setting or clearing a value on it.",
|
|
@@ -7,6 +7,7 @@ export declare const clearCustomFieldPayloadSchema: z.ZodObject<{
|
|
|
7
7
|
}, z.core.$strip>;
|
|
8
8
|
export type ClearCustomFieldPayload = z.infer<typeof clearCustomFieldPayloadSchema>;
|
|
9
9
|
export declare const clearCustomFieldHandler: WriteHandlerDef;
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
10
|
+
/** Companion to createSetCustomFieldHandler: set and clear use the same roles;
|
|
11
|
+
* allowing a value to be set without allowing it to be cleared would leave
|
|
12
|
+
* access control incomplete. */
|
|
12
13
|
export declare function createClearCustomFieldHandler(roles?: readonly string[]): WriteHandlerDef;
|
|
@@ -13,13 +13,13 @@ export const clearCustomFieldPayloadSchema = z.object({
|
|
|
13
13
|
.regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/),
|
|
14
14
|
});
|
|
15
15
|
const CLEAR_CUSTOM_FIELD_REASON = "reads custom field definitions with an explicit tenant_id = caller tenant via raw SQL with read retry";
|
|
16
|
-
// clear-custom-field —
|
|
17
|
-
//
|
|
18
|
-
// jsonb
|
|
16
|
+
// clear-custom-field — removes a custom-field value from a host entity.
|
|
17
|
+
// Emits the customField.cleared event; MSP removes the key from the
|
|
18
|
+
// jsonb column (key removal, not setting it to null).
|
|
19
19
|
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
20
|
+
// Per-field fieldAccess.write gate: the caller must hold one of the defined
|
|
21
|
+
// roles when fieldDefinition.serializedField.fieldAccess.write is set.
|
|
22
|
+
// Handler-level RBAC (TenantAdmin/Member) still applies as well.
|
|
23
23
|
export const clearCustomFieldHandler = {
|
|
24
24
|
name: "clear-custom-field",
|
|
25
25
|
schema: clearCustomFieldPayloadSchema,
|
|
@@ -56,8 +56,9 @@ export const clearCustomFieldHandler = {
|
|
|
56
56
|
};
|
|
57
57
|
},
|
|
58
58
|
};
|
|
59
|
-
/**
|
|
60
|
-
*
|
|
59
|
+
/** Companion to createSetCustomFieldHandler: set and clear use the same roles;
|
|
60
|
+
* allowing a value to be set without allowing it to be cleared would leave
|
|
61
|
+
* access control incomplete. */
|
|
61
62
|
export function createClearCustomFieldHandler(roles = DEFAULT_VALUE_WRITE_ROLES) {
|
|
62
63
|
return { ...clearCustomFieldHandler, access: { roles } };
|
|
63
64
|
}
|
|
@@ -2,7 +2,7 @@ import { type WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
2
2
|
export interface DefineTenantFieldOptions {
|
|
3
3
|
/** Soft cap — `>= limit` definitions per tenant rejects further defines (see header: concurrent defines may overshoot). */
|
|
4
4
|
readonly fieldDefinitionLimitPerTenant?: number;
|
|
5
|
-
/** Access roles for this handler. Default ["TenantAdmin"]
|
|
5
|
+
/** Access roles for this handler. Default ["TenantAdmin"] — apps with
|
|
6
6
|
* their own role vocabulary pass this via createCustomFieldsFeature({
|
|
7
7
|
* fieldDefinitionWriteRoles }), which threads the same roles into
|
|
8
8
|
* update-/delete-tenant-field too (the definition-CRUD triad shares one gate). */
|
|
@@ -21,7 +21,7 @@ export function createDefineTenantFieldHandler(opts = {}) {
|
|
|
21
21
|
handler: async (event, ctx) => {
|
|
22
22
|
const payload = event.payload; // @cast-boundary engine-payload
|
|
23
23
|
const tenantId = event.user.tenantId;
|
|
24
|
-
// TenantAdmin
|
|
24
|
+
// TenantAdmin MUST NOT write to the system scope — strict guard.
|
|
25
25
|
if (isSystemTenant(tenantId)) {
|
|
26
26
|
throw new Error("define-tenant-field: tenantId is SYSTEM_TENANT_ID — use define-system-field for system-scope definitions");
|
|
27
27
|
}
|
|
@@ -41,5 +41,5 @@ export function createDefineTenantFieldHandler(opts = {}) {
|
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
// Backwards-compat: existing imports of `defineTenantFieldHandler` keep
|
|
44
|
-
// working — the handler has no quota, identical to
|
|
44
|
+
// working — the handler has no quota, identical to behavior before the quota.
|
|
45
45
|
export const defineTenantFieldHandler = createDefineTenantFieldHandler();
|
|
@@ -5,11 +5,10 @@ import { fieldDefinitionExecutor } from "../executor.js";
|
|
|
5
5
|
import { createCustomFieldsFeature } from "../feature.js";
|
|
6
6
|
import { deleteFieldPayloadSchema } from "../schemas.js";
|
|
7
7
|
import { FIELD_DEFINITION_AGGREGATE_TYPE } from "../web/constants.js";
|
|
8
|
-
// delete-system-field — SystemAdmin
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// Events bleiben für Audit.
|
|
8
|
+
// delete-system-field — SystemAdmin deletes a system-wide field definition.
|
|
9
|
+
// Tenants can no longer set new values for it, but existing values remain in
|
|
10
|
+
// read_<entity>.customFields jsonb until host-entity MSPs remove them in
|
|
11
|
+
// response to the customFieldDefinition.deleted event. Events remain for audit.
|
|
13
12
|
export const deleteSystemFieldHandler = {
|
|
14
13
|
name: "delete-system-field",
|
|
15
14
|
schema: deleteFieldPayloadSchema,
|
|
@@ -23,8 +22,8 @@ export const deleteSystemFieldHandler = {
|
|
|
23
22
|
const result = await fieldDefinitionExecutor.delete({ id: aggregateId }, event.user, db, {
|
|
24
23
|
streamTenantId,
|
|
25
24
|
});
|
|
26
|
-
// Cascade-cleanup
|
|
27
|
-
//
|
|
25
|
+
// Cascade-cleanup event — host-entity MSPs remove orphaned values from their
|
|
26
|
+
// customFields jsonb in the same transaction for atomicity.
|
|
28
27
|
if (result.isSuccess) {
|
|
29
28
|
await ctx.unsafeAppendEvent({
|
|
30
29
|
aggregateId,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
export interface DeleteTenantFieldOptions {
|
|
3
|
-
/** Access roles for this handler. Default ["TenantAdmin"]
|
|
3
|
+
/** Access roles for this handler. Default ["TenantAdmin"] — see
|
|
4
4
|
* DefineTenantFieldOptions.roles, the definition-CRUD triad shares one gate. */
|
|
5
5
|
readonly roles?: readonly string[];
|
|
6
6
|
}
|
|
@@ -19,9 +19,9 @@ export function createDeleteTenantFieldHandler(opts = {}) {
|
|
|
19
19
|
}
|
|
20
20
|
const aggregateId = fieldDefinitionAggregateId(tenantId, payload.entityName, payload.fieldKey);
|
|
21
21
|
const result = await fieldDefinitionExecutor.delete({ id: aggregateId }, event.user, ctx.db);
|
|
22
|
-
// Emit cascade-cleanup
|
|
23
|
-
//
|
|
24
|
-
//
|
|
22
|
+
// Emit the cascade-cleanup event after a successful delete. Host-entity MSPs
|
|
23
|
+
// registered via wireCustomFieldsFor consume it and remove orphaned values
|
|
24
|
+
// from their customFields jsonb. The same transaction makes cleanup atomic.
|
|
25
25
|
if (result.isSuccess) {
|
|
26
26
|
await ctx.unsafeAppendEvent({
|
|
27
27
|
aggregateId,
|
|
@@ -8,7 +8,7 @@ export declare const setCustomFieldPayloadSchema: z.ZodObject<{
|
|
|
8
8
|
}, z.core.$strip>;
|
|
9
9
|
export type SetCustomFieldPayload = z.infer<typeof setCustomFieldPayloadSchema>;
|
|
10
10
|
export declare const setCustomFieldHandler: WriteHandlerDef;
|
|
11
|
-
/** Value
|
|
12
|
-
*
|
|
13
|
-
* createCustomFieldsFeature({ valueWriteRoles })
|
|
11
|
+
/** Value writes use app roles instead of the bundle defaults — apps with a
|
|
12
|
+
* custom role vocabulary (e.g. "Admin"/"Editor") pass their roles here via
|
|
13
|
+
* createCustomFieldsFeature({ valueWriteRoles }). */
|
|
14
14
|
export declare function createSetCustomFieldHandler(roles?: readonly string[]): WriteHandlerDef;
|
|
@@ -19,30 +19,27 @@ export const setCustomFieldPayloadSchema = z.object({
|
|
|
19
19
|
.refine((v) => v !== undefined, "value is required (use clear-custom-field to remove a value)"),
|
|
20
20
|
});
|
|
21
21
|
const SET_CUSTOM_FIELD_REASON = "reads custom field definitions with an explicit tenant_id = caller tenant via raw SQL with read retry";
|
|
22
|
-
// set-custom-field —
|
|
22
|
+
// set-custom-field — writes a custom-field value to a host entity.
|
|
23
23
|
//
|
|
24
|
-
//
|
|
24
|
+
// Emits a customField.set event on the host-aggregate
|
|
25
25
|
// stream (aggregateType = host-entity-name, aggregateId = host-entity-id).
|
|
26
|
-
// Last-
|
|
27
|
-
// concurrent writes
|
|
28
|
-
// Concurrency-Tabelle).
|
|
26
|
+
// Last-wins semantics: customField.set is appended WITHOUT expectedVersion,
|
|
27
|
+
// so concurrent writes to the same field both succeed.
|
|
29
28
|
//
|
|
30
|
-
// **Write
|
|
31
|
-
// 1. Definition
|
|
32
|
-
// 2. field-access
|
|
33
|
-
// 403/422. Handler-level RBAC (TenantAdmin/Member)
|
|
34
|
-
// 3. Value
|
|
35
|
-
//
|
|
36
|
-
// 422,
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
// dient clear-custom-field.
|
|
29
|
+
// **Write path (single fetch)** — one fieldDefinition load, three gates:
|
|
30
|
+
// 1. Definition missing → 404.
|
|
31
|
+
// 2. field-access: fieldAccess.write roles must intersect, otherwise
|
|
32
|
+
// 403/422. Handler-level RBAC (TenantAdmin/Member) also applies.
|
|
33
|
+
// 3. Value validation (builder reuse): the value is parsed against the
|
|
34
|
+
// fieldToZod schema rehydrated from serializedField. Type mismatch →
|
|
35
|
+
// 422, NO event is created (the projection remains typed). `value: null`
|
|
36
|
+
// OR `value: undefined` on a typed field are type mismatches → 422; use
|
|
37
|
+
// clear-custom-field to remove a value.
|
|
40
38
|
//
|
|
41
|
-
// Scope:
|
|
42
|
-
// `maxLength`, `format
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
// (Plan-Doc "Stammfeld-Identität" listet sie als eigene Zeilen).
|
|
39
|
+
// Scope: TRUE type-only validation. value-schema.ts strips `required`,
|
|
40
|
+
// `maxLength`, `format`, and `default` from serializedField before building
|
|
41
|
+
// a schema from fieldToZod — we check only the type shape. Required-on-set,
|
|
42
|
+
// default application, and length/format enforcement remain out of scope.
|
|
46
43
|
export const setCustomFieldHandler = {
|
|
47
44
|
name: "set-custom-field",
|
|
48
45
|
schema: setCustomFieldPayloadSchema,
|
|
@@ -79,11 +76,11 @@ export const setCustomFieldHandler = {
|
|
|
79
76
|
});
|
|
80
77
|
}
|
|
81
78
|
}
|
|
82
|
-
// Emit customField.set on host-aggregate stream. unsafeAppendEvent
|
|
83
|
-
//
|
|
84
|
-
// augmentation
|
|
85
|
-
//
|
|
86
|
-
//
|
|
79
|
+
// Emit customField.set on the host-aggregate stream. unsafeAppendEvent
|
|
80
|
+
// is used instead of strict appendEvent because event-type-map has no
|
|
81
|
+
// cross-feature augmentation for this event type; the qualified string
|
|
82
|
+
// name is used directly. The value is ALWAYS included in the event
|
|
83
|
+
// (custom fields carry no PII), so replay fully reproduces the projection.
|
|
87
84
|
await ctx.unsafeAppendEvent({
|
|
88
85
|
aggregateId: payload.entityId,
|
|
89
86
|
aggregateType: payload.entityName,
|
|
@@ -96,9 +93,9 @@ export const setCustomFieldHandler = {
|
|
|
96
93
|
};
|
|
97
94
|
},
|
|
98
95
|
};
|
|
99
|
-
/** Value
|
|
100
|
-
*
|
|
101
|
-
* createCustomFieldsFeature({ valueWriteRoles })
|
|
96
|
+
/** Value writes use app roles instead of the bundle defaults — apps with a
|
|
97
|
+
* custom role vocabulary (e.g. "Admin"/"Editor") pass their roles here via
|
|
98
|
+
* createCustomFieldsFeature({ valueWriteRoles }). */
|
|
102
99
|
export function createSetCustomFieldHandler(roles = DEFAULT_VALUE_WRITE_ROLES) {
|
|
103
100
|
return { ...setCustomFieldHandler, access: { roles } };
|
|
104
101
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
export interface UpdateTenantFieldOptions {
|
|
3
|
-
/** Access roles for this handler. Default ["TenantAdmin"]
|
|
3
|
+
/** Access roles for this handler. Default ["TenantAdmin"] — see
|
|
4
4
|
* DefineTenantFieldOptions.roles, the definition-CRUD triad shares one gate. */
|
|
5
5
|
readonly roles?: readonly string[];
|
|
6
6
|
}
|