@wildo-ai/saas-models 1.1.7 → 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/__tests__/setup.d.ts.map +1 -1
- package/dist/esm/__tests__/setup.js.map +1 -1
- package/dist/esm/_inspect.d.ts.map +1 -1
- package/dist/esm/_inspect.js.map +1 -1
- package/dist/esm/applications/application-metadata.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/applications/application-metadata.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/applications/application-subject.shared.schemas.d.ts.map +1 -1
- package/dist/esm/applications/application-subject.shared.schemas.js.map +1 -1
- package/dist/esm/applications/application-versions.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/applications/application-versions.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/applications/applications-context.schemas.d.ts.map +1 -1
- package/dist/esm/applications/applications-context.schemas.js.map +1 -1
- package/dist/esm/applications/applications.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/applications/applications.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/applications/applications.shared.schemas.d.ts.map +1 -1
- package/dist/esm/applications/applications.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-account.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/billing-account.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-account.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-configuration.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-configuration.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-enums.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-enums.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-types.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-types.shared.schemas.js.map +1 -1
- package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/credit-pool.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/credit-pool.shared.schemas.js.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.schemas.js.map +1 -1
- package/dist/esm/billing/price.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/price.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/price.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/price.shared.schemas.js.map +1 -1
- package/dist/esm/billing/product-behavior-policy.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product-behavior-policy.shared.schemas.js.map +1 -1
- package/dist/esm/billing/product-definition.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product-definition.shared.schemas.js.map +1 -1
- package/dist/esm/billing/product.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/product.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product.shared.schemas.js.map +1 -1
- package/dist/esm/billing/promotions.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/promotions.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/promotions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/promotions.shared.schemas.js.map +1 -1
- package/dist/esm/billing/public-pricing-catalog.shared.atoms.d.ts.map +1 -1
- package/dist/esm/billing/public-pricing-catalog.shared.atoms.js.map +1 -1
- package/dist/esm/billing/public-pricing-catalog.shared.d.ts.map +1 -1
- package/dist/esm/billing/public-pricing-catalog.shared.js.map +1 -1
- package/dist/esm/billing/referral-reward.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/referral-reward.shared.schemas.js.map +1 -1
- package/dist/esm/billing/referral.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/referral.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/referral.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/referral.shared.schemas.js.map +1 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/subscription.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/subscription.shared.schemas.js.map +1 -1
- package/dist/esm/billing/usage-flush-evidence.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/usage-flush-evidence.shared.schemas.js.map +1 -1
- package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/usage-record.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/usage-record.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/usage-record.shared.schemas.js.map +1 -1
- package/dist/esm/charts/aggregation-query.shared.schemas.d.ts.map +1 -1
- package/dist/esm/charts/aggregation-query.shared.schemas.js.map +1 -1
- package/dist/esm/charts/aggregation.shared.definitions.d.ts.map +1 -1
- package/dist/esm/charts/aggregation.shared.definitions.js.map +1 -1
- package/dist/esm/charts/chart-definition-builder.shared.d.ts.map +1 -1
- package/dist/esm/charts/chart-definition-builder.shared.js.map +1 -1
- package/dist/esm/companion/artifact-placement.shared.definitions.d.ts.map +1 -1
- package/dist/esm/companion/artifact-placement.shared.definitions.js.map +1 -1
- package/dist/esm/companion/provider-discovery.shared.schemas.d.ts.map +1 -1
- package/dist/esm/companion/provider-discovery.shared.schemas.js.map +1 -1
- package/dist/esm/companion/shared-library-companion.shared.definitions.d.ts.map +1 -1
- package/dist/esm/companion/shared-library-companion.shared.definitions.js.map +1 -1
- package/dist/esm/companion-exports.d.ts.map +1 -1
- package/dist/esm/companion-exports.js.map +1 -1
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-actor.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-actor.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-export-projection.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-export-projection.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-log-sink.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-log-sink.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js.map +1 -1
- package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js.map +1 -1
- package/dist/esm/compliance/data-classification/data-classification.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/data-classification/data-classification.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/documents/governed-document-interactions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/documents/governed-document-interactions.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/documents/governed-documents.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/documents/governed-documents.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/ai-use-posture.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/ai-use-posture.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/capability-consent-purposes.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/capability-consent-purposes.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/client-storage.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/client-storage.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/consent-gate-vocabulary.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/consent-gate-vocabulary.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/consent-purposes.shared.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/consent-purposes.shared.js.map +1 -1
- package/dist/esm/compliance/privacy/data-subject-rights.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/data-subject-rights.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/legal-hold-subject-attribution.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/legal-hold-subject-attribution.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/legal-holds.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/legal-holds.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/legal-holds.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/legal-holds.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/personal-data-category.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/personal-data-category.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/personal-data-declaration.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/personal-data-declaration.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/privacy.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/privacy.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/provider-capability-disclosure.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/provider-capability-disclosure.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/purpose-ref.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/purpose-ref.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/redaction.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/retention-binding.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/retention-binding.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/retention-enforcement-records.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/retention-enforcement-records.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/retention-enforcement-records.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/retention-enforcement-records.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/retention-schedule.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/retention-schedule.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/retention-scope-deleted.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/retention-scope-deleted.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/sharing.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/sharing.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-data-recipients.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-data-recipients.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-erasure-lane-evidence.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-erasure-lane-evidence.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-erasure.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-erasure.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-export-render.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-export-render.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-export.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-export.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/review-cadence.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/review-cadence.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/risk-posture.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/risk-posture.shared.schemas.js.map +1 -1
- package/dist/esm/config/analytics-value-moments.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/analytics-value-moments.shared.schemas.js.map +1 -1
- package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/app-configuration-shared.shared.schemas.js.map +1 -1
- package/dist/esm/config/app-frontend-type.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/app-frontend-type.shared.schemas.js.map +1 -1
- package/dist/esm/config/auth-config-resolution.shared.utils.d.ts.map +1 -1
- package/dist/esm/config/auth-config-resolution.shared.utils.js.map +1 -1
- package/dist/esm/config/brand-assets.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/brand-assets.shared.schemas.js.map +1 -1
- package/dist/esm/config/configuration-validation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/configuration-validation.shared.schemas.js.map +1 -1
- package/dist/esm/config/entity-identity-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/entity-identity-config.shared.schemas.js.map +1 -1
- package/dist/esm/config/frontend/chart-definition.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/frontend/chart-definition.shared.schemas.js.map +1 -1
- package/dist/esm/config/frontend/chart-registration-alignment.shared.d.ts.map +1 -1
- package/dist/esm/config/frontend/chart-registration-alignment.shared.js.map +1 -1
- package/dist/esm/config/frontend/navigation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/frontend/navigation.shared.schemas.js.map +1 -1
- package/dist/esm/config/frontend/onboarding.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/frontend/onboarding.shared.schemas.js.map +1 -1
- package/dist/esm/config/postgresql.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/postgresql.shared.schemas.js.map +1 -1
- package/dist/esm/config/registration-acquisition-policy.shared.utils.d.ts.map +1 -1
- package/dist/esm/config/registration-acquisition-policy.shared.utils.js.map +1 -1
- package/dist/esm/config-authoring.entry.d.ts.map +1 -1
- package/dist/esm/config-authoring.entry.js.map +1 -1
- package/dist/esm/crdt/crdt-merge.shared.utils.d.ts.map +1 -1
- package/dist/esm/crdt/crdt-merge.shared.utils.js.map +1 -1
- package/dist/esm/data-seeding/data-seeding-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/data-seeding/data-seeding-config.shared.schemas.js.map +1 -1
- package/dist/esm/errors/caught-error-description.shared.utils.d.ts.map +1 -1
- package/dist/esm/errors/caught-error-description.shared.utils.js.map +1 -1
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts.map +1 -1
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js.map +1 -1
- package/dist/esm/errors/errors.shared.definitions.d.ts.map +1 -1
- package/dist/esm/errors/errors.shared.definitions.js.map +1 -1
- package/dist/esm/errors/errors.shared.schemas.d.ts.map +1 -1
- package/dist/esm/errors/errors.shared.schemas.js.map +1 -1
- package/dist/esm/errors/errors.shared.utils.d.ts.map +1 -1
- package/dist/esm/errors/errors.shared.utils.js.map +1 -1
- package/dist/esm/errors/resource-access-forbidden.shared.error.d.ts.map +1 -1
- package/dist/esm/errors/resource-access-forbidden.shared.error.js.map +1 -1
- package/dist/esm/errors/thrown-value-description.shared.utils.d.ts.map +1 -1
- package/dist/esm/errors/thrown-value-description.shared.utils.js.map +1 -1
- package/dist/esm/errors/zod-issue-formatting.shared.utils.d.ts.map +1 -1
- package/dist/esm/errors/zod-issue-formatting.shared.utils.js.map +1 -1
- package/dist/esm/exports/tabular-csv.shared.utils.d.ts.map +1 -1
- package/dist/esm/exports/tabular-csv.shared.utils.js.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-description.shared.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-description.shared.js.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-pass-mode.shared.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-pass-mode.shared.js.map +1 -1
- package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline.shared.schemas.js.map +1 -1
- package/dist/esm/external-data/external-data-provenance.shared.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-provenance.shared.js.map +1 -1
- package/dist/esm/external-data.exports.d.ts.map +1 -1
- package/dist/esm/external-data.exports.js.map +1 -1
- package/dist/esm/external-providers/compose-provider-registry.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/compose-provider-registry.shared.js.map +1 -1
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js.map +1 -1
- package/dist/esm/external-providers/engine-capability-surface.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/engine-capability-surface.shared.js.map +1 -1
- package/dist/esm/external-providers/external-providers.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/external-providers.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.js.map +1 -1
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/frontend-provider-public-config.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-provider-public-config.shared.js.map +1 -1
- package/dist/esm/external-providers/model-cost-accounting-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/model-cost-accounting-config.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-address-lookup-contract.shared.types.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-address-lookup-contract.shared.types.js.map +1 -1
- package/dist/esm/external-providers/provider-augmentation-opt-ins.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-augmentation-opt-ins.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-authentication-assurance.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-authentication-assurance.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-browser-operations.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-browser-operations.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-capability.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-frontend-component-contract.shared.types.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-frontend-component-contract.shared.types.js.map +1 -1
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-metadata.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-metadata.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-package-allow-list.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-package-allow-list.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-protocol.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-protocol.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-scope-reauthorization.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-scope-reauthorization.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-shared-connections.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-shared-connections.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.js.map +1 -1
- package/dist/esm/external-providers/provider-usage-cost.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-usage-cost.shared.js.map +1 -1
- package/dist/esm/external-providers/provider-usage-pricing.example.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-usage-pricing.example.js.map +1 -1
- package/dist/esm/external-providers/provider-usage-pricing.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-usage-pricing.shared.schemas.js.map +1 -1
- package/dist/esm/features/application-features.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/features/application-features.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/features/connected-feature.example.d.ts.map +1 -1
- package/dist/esm/features/connected-feature.example.js.map +1 -1
- package/dist/esm/features/core-feature-definitions.shared.d.ts.map +1 -1
- package/dist/esm/features/core-feature-definitions.shared.js.map +1 -1
- package/dist/esm/features/feature-builders.shared.d.ts.map +1 -1
- package/dist/esm/features/feature-builders.shared.js.map +1 -1
- package/dist/esm/features/feature-definition.shared.schemas.d.ts.map +1 -1
- package/dist/esm/features/feature-definition.shared.schemas.js.map +1 -1
- package/dist/esm/features/feature-registry.shared.d.ts.map +1 -1
- package/dist/esm/features/feature-registry.shared.js.map +1 -1
- package/dist/esm/features/feature-resolution.shared.schemas.d.ts.map +1 -1
- package/dist/esm/features/feature-resolution.shared.schemas.js.map +1 -1
- package/dist/esm/features/scope-features.shared.schemas.d.ts.map +1 -1
- package/dist/esm/features/scope-features.shared.schemas.js.map +1 -1
- package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/features/user-features.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/files/file-remote-reference-link.shared.schemas.d.ts.map +1 -1
- package/dist/esm/files/file-remote-reference-link.shared.schemas.js.map +1 -1
- package/dist/esm/files/file-upload-grant.shared.schemas.d.ts.map +1 -1
- package/dist/esm/files/file-upload-grant.shared.schemas.js.map +1 -1
- package/dist/esm/files/files.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/files/files.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/files/files.shared.schemas.d.ts.map +1 -1
- package/dist/esm/files/files.shared.schemas.js.map +1 -1
- package/dist/esm/files/files.shared.utils.d.ts.map +1 -1
- package/dist/esm/files/files.shared.utils.js.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/actors.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/actors.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/agent-traceability.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/agent-traceability.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/agent-work-decisions.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/agent-work-decisions.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/agent-work-decisions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/agent-work-decisions.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/agents.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/agents.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/autonomous-agents.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/autonomous-agents.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/deliberation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/deliberation.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/execution-plan-readiness.shared.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/execution-plan-readiness.shared.utils.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.configuration.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.configuration.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.frontend.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.frontend.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.definitions.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/human-decision.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/human-decision.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/model-call-attributions.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/model-call-attributions.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/model-call-attributions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/model-call-attributions.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/model-cost-period-aggregates.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/model-cost-period-aggregates.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/model-cost-period-aggregates.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/model-cost-period-aggregates.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/model-cost-summary.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/model-cost-summary.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/prompt-ir.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/prompt-ir.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/provider-call-records.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/provider-call-records.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/provider-call-records.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/provider-call-records.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/review-deadlines.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/review-deadlines.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/tasks.actors.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/tasks.actors.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/work-attribution.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/work-attribution.shared.schemas.js.map +1 -1
- package/dist/esm/frontend-definitions/frontend-notification-custom-message-ref.definitions.d.ts.map +1 -1
- package/dist/esm/frontend-definitions/frontend-notification-custom-message-ref.definitions.js.map +1 -1
- package/dist/esm/frontend-definitions/settings-destination-ref.definitions.d.ts.map +1 -1
- package/dist/esm/frontend-definitions/settings-destination-ref.definitions.js.map +1 -1
- package/dist/esm/guidance/guidance-flow.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-flow.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.utils.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.utils.js.map +1 -1
- package/dist/esm/guidance/lifecycle-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/lifecycle-config.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/milestone-builders.shared.d.ts.map +1 -1
- package/dist/esm/guidance/milestone-builders.shared.js.map +1 -1
- package/dist/esm/guidance/milestone-definition.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/milestone-definition.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/progression-presentation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/progression-presentation.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/guidance/progression-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/progression-state.shared.schemas.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding-id.shared.utils.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding-id.shared.utils.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-erasure-stance.shared.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-erasure-stance.shared.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-rest-write-operations.shared.schemas.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-rest-write-operations.shared.schemas.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-transport-dialect.shared.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-transport-dialect.shared.js.map +1 -1
- package/dist/esm/http-api-binding/read-through-engine-anchors.shared.d.ts.map +1 -1
- package/dist/esm/http-api-binding/read-through-engine-anchors.shared.js.map +1 -1
- package/dist/esm/i18n/application-config-vocabulary.shared.d.ts.map +1 -1
- package/dist/esm/i18n/application-config-vocabulary.shared.js.map +1 -1
- package/dist/esm/i18n/engine-open-vocabulary-values.shared.d.ts.map +1 -1
- package/dist/esm/i18n/engine-open-vocabulary-values.shared.js.map +1 -1
- package/dist/esm/i18n/engine-open-vocabulary.shared.d.ts.map +1 -1
- package/dist/esm/i18n/engine-open-vocabulary.shared.js.map +1 -1
- package/dist/esm/i18n/interpolate-label-params.shared.utils.d.ts.map +1 -1
- package/dist/esm/i18n/interpolate-label-params.shared.utils.js.map +1 -1
- package/dist/esm/i18n/labelling.dto.shared.schemas.d.ts.map +1 -1
- package/dist/esm/i18n/labelling.dto.shared.schemas.js.map +1 -1
- package/dist/esm/inbound/conversation-threads.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/inbound/conversation-threads.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/inbound/conversation-threads.shared.schemas.d.ts.map +1 -1
- package/dist/esm/inbound/conversation-threads.shared.schemas.js.map +1 -1
- package/dist/esm/inbound/inbound-channels.shared.schemas.d.ts.map +1 -1
- package/dist/esm/inbound/inbound-channels.shared.schemas.js.map +1 -1
- package/dist/esm/inbound/inbound-delivery.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/inbound/inbound-delivery.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/inbound/inbound-delivery.shared.schemas.d.ts.map +1 -1
- package/dist/esm/inbound/inbound-delivery.shared.schemas.js.map +1 -1
- package/dist/esm/inbound/inbound-endpoint-env.shared.d.ts.map +1 -1
- package/dist/esm/inbound/inbound-endpoint-env.shared.js.map +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/meta-workflows/actions.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/actions.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/catalog.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/catalog.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/coding-tasks.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/coding-tasks.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/context-selection.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/context-selection.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/decisions.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/decisions.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/orchestration.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/orchestration.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows/portable-primitives.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/meta-workflows/portable-primitives.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/meta-workflows.exports.d.ts.map +1 -1
- package/dist/esm/meta-workflows.exports.js.map +1 -1
- package/dist/esm/monitoring/monitoring.shared.schemas.d.ts.map +1 -1
- package/dist/esm/monitoring/monitoring.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/email/email-context.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-context.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/email/email-submission.shared.enums.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-submission.shared.enums.js.map +1 -1
- package/dist/esm/notifications/email/email-template-registry.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-template-registry.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/email/email-template.shared.enums.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-template.shared.enums.js.map +1 -1
- package/dist/esm/notifications/inbound-email/inbound-email.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/inbound-email/inbound-email.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/notifications/inbound-email/inbound-email.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/inbound-email/inbound-email.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/notification-badges.core.definitions.d.ts.map +1 -1
- package/dist/esm/notifications/notification-badges.core.definitions.js.map +1 -1
- package/dist/esm/notifications/notification-badges.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/notification-badges.schemas.js.map +1 -1
- package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/notifications/notifications.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/notifications.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/application-owner-organization.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/application-owner-organization.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-features.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-features.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-features.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-features.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-members.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-members.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-unit-inheritance.shared.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-inheritance.shared.js.map +1 -1
- package/dist/esm/organizations/organization-unit-members.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-members.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-unit-members.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-members.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing-decision.shared.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing-decision.shared.js.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.example.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.example.js.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.shared.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.shared.js.map +1 -1
- package/dist/esm/organizations/organization-units.shared.path.d.ts.map +1 -1
- package/dist/esm/organizations/organization-units.shared.path.js.map +1 -1
- package/dist/esm/organizations/organization-units.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-units.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-units.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-units.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organizations.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organizations.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organizations.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organizations.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-activity-feed.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-activity-feed.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-activity-feed.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-activity-feed.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-capability-grants.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-capability-grants.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-capability-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-capability-grants.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-client-controls.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-client-controls.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-relationships.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-relationships.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/service-provider-relationships.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/service-provider-relationships.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/tenant-teardown-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/tenant-teardown-config.shared.schemas.js.map +1 -1
- package/dist/esm/provider-registration-runtime.exports.d.ts.map +1 -1
- package/dist/esm/provider-registration-runtime.exports.js.map +1 -1
- package/dist/esm/public-runtime/index.d.ts.map +1 -1
- package/dist/esm/public-runtime/index.js.map +1 -1
- package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/queue/jobs.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/queue/jobs.shared.schemas.d.ts.map +1 -1
- package/dist/esm/queue/jobs.shared.schemas.js.map +1 -1
- package/dist/esm/queue/jobs.shared.utils.d.ts.map +1 -1
- package/dist/esm/queue/jobs.shared.utils.js.map +1 -1
- package/dist/esm/queue/queues.shared.schemas.d.ts.map +1 -1
- package/dist/esm/queue/queues.shared.schemas.js.map +1 -1
- package/dist/esm/queue/queues.shared.utils.d.ts.map +1 -1
- package/dist/esm/queue/queues.shared.utils.js.map +1 -1
- package/dist/esm/queue/rabbitmq-queue-args.shared.d.ts.map +1 -1
- package/dist/esm/queue/rabbitmq-queue-args.shared.js.map +1 -1
- package/dist/esm/rag/rag-retrieval-health.shared.d.ts.map +1 -1
- package/dist/esm/rag/rag-retrieval-health.shared.js.map +1 -1
- package/dist/esm/requests/header-keys.shared.d.ts.map +1 -1
- package/dist/esm/requests/header-keys.shared.js.map +1 -1
- package/dist/esm/requests/http-requests.shared.d.ts.map +1 -1
- package/dist/esm/requests/http-requests.shared.js.map +1 -1
- package/dist/esm/requests/idempotency-key.shared.d.ts.map +1 -1
- package/dist/esm/requests/idempotency-key.shared.js.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-documentation.d.ts.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-documentation.js.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-urls.d.ts.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-urls.js.map +1 -1
- package/dist/esm/requests/rate-limits.shared.schemas.d.ts.map +1 -1
- package/dist/esm/requests/rate-limits.shared.schemas.js.map +1 -1
- package/dist/esm/requests/websocket.shared.schemas.d.ts.map +1 -1
- package/dist/esm/requests/websocket.shared.schemas.js.map +1 -1
- package/dist/esm/resources/child-operations.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/child-operations.shared.schemas.js.map +1 -1
- package/dist/esm/resources/collection-query-parameters.shared.d.ts.map +1 -1
- package/dist/esm/resources/collection-query-parameters.shared.js.map +1 -1
- package/dist/esm/resources/context-policy.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/context-policy.shared.schemas.js.map +1 -1
- package/dist/esm/resources/embedded-resource-mark.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/embedded-resource-mark.shared.utils.js.map +1 -1
- package/dist/esm/resources/relationship-display.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/relationship-display.shared.schemas.js.map +1 -1
- package/dist/esm/resources/resources-config.shared.factory.d.ts.map +1 -1
- package/dist/esm/resources/resources-config.shared.factory.js.map +1 -1
- package/dist/esm/resources/resources-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/resources-config.shared.schemas.js.map +1 -1
- package/dist/esm/resources/resources-registry.shared.core.definitions.d.ts.map +1 -1
- package/dist/esm/resources/resources-registry.shared.core.definitions.js.map +1 -1
- package/dist/esm/resources/resources-relationships.shared.factory.d.ts.map +1 -1
- package/dist/esm/resources/resources-relationships.shared.factory.js.map +1 -1
- package/dist/esm/resources/resources-serialization.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/resources-serialization.shared.schemas.js.map +1 -1
- package/dist/esm/resources/resources.shared.core.definitions.d.ts.map +1 -1
- package/dist/esm/resources/resources.shared.core.definitions.js.map +1 -1
- package/dist/esm/resources/resources.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/resources.shared.schemas.js.map +1 -1
- package/dist/esm/resources/resources.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/resources.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/collection-export.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/collection-export.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/composition-cascade-deletability.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/composition-cascade-deletability.validation.js.map +1 -1
- package/dist/esm/resources/utils/composition-seedability.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/composition-seedability.validation.js.map +1 -1
- package/dist/esm/resources/utils/context-addressed-composition-singleton.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/context-addressed-composition-singleton.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/dependent-lifecycle-classification.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/dependent-lifecycle-classification.validation.js.map +1 -1
- package/dist/esm/resources/utils/duplicate-relationship-registration.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/duplicate-relationship-registration.validation.js.map +1 -1
- package/dist/esm/resources/utils/field-value-disclosure.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/field-value-disclosure.utils.js.map +1 -1
- package/dist/esm/resources/utils/http-api-write-declaration.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/http-api-write-declaration.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/initiator-stamped-field-satisfiability.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/initiator-stamped-field-satisfiability.validation.js.map +1 -1
- package/dist/esm/resources/utils/no-subject-data-stance-coherence.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/no-subject-data-stance-coherence.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/persistence-adapter-discrimination.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/persistence-adapter-discrimination.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/populated-file-fields.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/populated-file-fields.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/repository-dto-builder.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/repository-dto-builder.utils.js.map +1 -1
- package/dist/esm/resources/utils/request-schema-field-carriage.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/request-schema-field-carriage.shared.utils.js.map +1 -1
- package/dist/esm/resources/utils/required-fk-fillability.validation.d.ts.map +1 -1
- package/dist/esm/resources/utils/required-fk-fillability.validation.js.map +1 -1
- package/dist/esm/resources/utils/resource-operation-type-guards.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-operation-type-guards.utils.js.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.factory.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.factory.js.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.relationships.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.relationships.js.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.schemas.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.schemas.js.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-polymorphism.utils.js.map +1 -1
- package/dist/esm/resources/utils/resource-subtree.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resource-subtree.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-context-needs.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-context-needs.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-naming.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-naming.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.path.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.path.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.urls-builder.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.urls-builder.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-serialization.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-serialization.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-summary.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-summary.utils.js.map +1 -1
- package/dist/esm/resources/utils/schema-family-builder.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/schema-family-builder.utils.js.map +1 -1
- package/dist/esm/resources/utils/schema-type-inference.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/schema-type-inference.utils.js.map +1 -1
- package/dist/esm/resources/utils/schema-type-utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/schema-type-utils.js.map +1 -1
- package/dist/esm/resources/utils/schema-variant-resolver.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/schema-variant-resolver.utils.js.map +1 -1
- package/dist/esm/resources/utils/shared-persistence-collection.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/shared-persistence-collection.utils.js.map +1 -1
- package/dist/esm/resources/utils/templatable-file-fields.shared.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/templatable-file-fields.shared.utils.js.map +1 -1
- package/dist/esm/resources/work-unit.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/work-unit.shared.schemas.js.map +1 -1
- package/dist/esm/runtime/domain-module.shared.definitions.d.ts.map +1 -1
- package/dist/esm/runtime/domain-module.shared.definitions.js.map +1 -1
- package/dist/esm/runtime/execution-context.shared.schemas.d.ts.map +1 -1
- package/dist/esm/runtime/execution-context.shared.schemas.js.map +1 -1
- package/dist/esm/runtime/runtime.shared.schemas.d.ts.map +1 -1
- package/dist/esm/runtime/runtime.shared.schemas.js.map +1 -1
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/api-keys/api-keys.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/anonymous-session/anonymous-session.shared.contract.d.ts.map +1 -1
- package/dist/esm/security/authentications/anonymous-session/anonymous-session.shared.contract.js.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.utils.js.map +1 -1
- package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/consumable-token.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/cross-frontend-handoff.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/cross-frontend-handoff.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts.map +1 -1
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js.map +1 -1
- package/dist/esm/security/authentications/password-blocklist.shared.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/password-blocklist.shared.utils.js.map +1 -1
- package/dist/esm/security/authentications/password-reset.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/password-reset.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/registration.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/registration.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/same-origin-redirect-path.shared.d.ts.map +1 -1
- package/dist/esm/security/authentications/same-origin-redirect-path.shared.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-organization-unit-mapping.shared.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-organization-unit-mapping.shared.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-tokens.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-tokens.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-tokens.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-tokens.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/service-provider-client-authentication.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/service-provider-client-authentication.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-export-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-export-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-export-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/siem/siem-export-config.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/administrative-continuity.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/administrative-continuity.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/application-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/application-access-grants.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/application-access-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/application-access-grants.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.defaults.d.ts.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.defaults.js.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.utils.js.map +1 -1
- package/dist/esm/security/connected-accounts/provider-connection-listing.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/provider-connection-listing.shared.schemas.js.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.js.map +1 -1
- package/dist/esm/security/credential-rotation-grace.shared.utils.d.ts.map +1 -1
- package/dist/esm/security/credential-rotation-grace.shared.utils.js.map +1 -1
- package/dist/esm/security/crypto-keys/crypto-keys.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/crypto-keys/crypto-keys.shared.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-resource-server.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-resource-server.shared.schemas.js.map +1 -1
- package/dist/esm/security/outbound-target-control.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/outbound-target-control.shared.schemas.js.map +1 -1
- package/dist/esm/security/submission-challenge/submission-challenge.shared.d.ts.map +1 -1
- package/dist/esm/security/submission-challenge/submission-challenge.shared.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-actions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-actions.shared.schemas.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-credential-kind.shared.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-credential-kind.shared.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-declaration.shared.schemas.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-declaration.shared.schemas.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-env.shared.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-env.shared.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-error-codes.shared.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-error-codes.shared.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-facet.shared.schemas.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-facet.shared.schemas.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.schemas.d.ts.map +1 -1
- package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.schemas.js.map +1 -1
- package/dist/esm/testing/resource-config-builders.d.ts.map +1 -1
- package/dist/esm/testing/resource-config-builders.js.map +1 -1
- package/dist/esm/testing.d.ts.map +1 -1
- package/dist/esm/testing.js.map +1 -1
- package/dist/esm/users/anonymous-user-marketing-metadata.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/anonymous-user-marketing-metadata.shared.schemas.js.map +1 -1
- package/dist/esm/users/anonymous-users.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/anonymous-users.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/anonymous-users.shared.schema.d.ts.map +1 -1
- package/dist/esm/users/anonymous-users.shared.schema.js.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-consent-decision.shared.utils.d.ts.map +1 -1
- package/dist/esm/users/user-consent-decision.shared.utils.js.map +1 -1
- package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-credentials.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-credentials.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-credentials.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-identity-links.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-identity-links.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-preferences-reset.shared.utils.d.ts.map +1 -1
- package/dist/esm/users/user-preferences-reset.shared.utils.js.map +1 -1
- package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-preferences.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-profiles.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-self.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-self.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/users.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/users.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/users.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/users.shared.schemas.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.shared.schemas.js","sourceRoot":"","sources":["../../../src/notifications/notifications.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAG7E;;;;;;;;;GASG;AACH,MAAM,CAAN,IAAY,2BAIX;AAJD,WAAY,2BAA2B;IACrC,8CAAe,CAAA;IACf,sDAAuB,CAAA;IACvB,sEAAuC,CAAA;AACzC,CAAC,EAJW,2BAA2B,KAA3B,2BAA2B,QAItC;AAED,MAAM,CAAN,IAAY,qBAKX;AALD,WAAY,qBAAqB;IAC/B,sCAAa,CAAA;IACb,4CAAmB,CAAA;IACnB,4CAAmB,CAAA;IACnB,wCAAe,CAAA;AACjB,CAAC,EALW,qBAAqB,KAArB,qBAAqB,QAKhC;AAED,yFAAyF;AACzF,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;AAGjF,iHAAiH;AACjH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,MAAM,CAAN,IAAY,0BAiBX;AAjBD,WAAY,0BAA0B;IAClC,qFAAuD,CAAA;IACvD,yEAA2C,CAAA;IAC3C,yFAA2D,CAAA;IAC3D,2EAA6C,CAAA;IAC7C,yEAA2C,CAAA;IAC3C,qEAAuC,CAAA;IACvC,mFAAqD,CAAA;IACrD,2DAA6B,CAAA;IAC7B,uEAAyC,CAAA;IACzC,2EAA6C,CAAA;IAC7C,2FAA6D,CAAA;IAC7D,yFAA2D,CAAA;IAC3D,6EAA+C,CAAA;IAC/C,qDAAuB,CAAA;IACvB,2DAA6B,CAAA;IAC7B,iEAAmC,CAAA;AACvC,CAAC,EAjBW,0BAA0B,KAA1B,0BAA0B,QAiBrC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,yDAAyD,CAAC,MAAc;IACtF,OAAO,MAAM,KAAK,0BAA0B,CAAC,SAAS;WACjD,MAAM,KAAK,0BAA0B,CAAC,YAAY,CAAC;AAC1D,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,oCAAoC,CAAC,MAAc,EAAE,OAAe;IAClF,IAAI,MAAM,KAAK,0BAA0B,CAAC,eAAe,EAAE,CAAC;QAC1D,OAAO,OAAO,KAAK,2BAA2B,CAAC,KAAK,CAAC;IACvD,CAAC;IACD,OAAO,MAAM,KAAK,0BAA0B,CAAC,oBAAoB;WAC5D,MAAM,KAAK,0BAA0B,CAAC,4BAA4B;WAClE,MAAM,KAAK,0BAA0B,CAAC,2BAA2B;WACjE,MAAM,KAAK,0BAA0B,CAAC,qBAAqB;WAC3D,MAAM,KAAK,0BAA0B,CAAC,yBAAyB;WAC/D,MAAM,KAAK,0BAA0B,CAAC,mBAAmB;WACzD,MAAM,KAAK,0BAA0B,CAAC,2BAA2B;WACjE,MAAM,KAAK,0BAA0B,CAAC,oBAAoB;WAC1D,MAAM,KAAK,0BAA0B,CAAC,mBAAmB;WACzD,MAAM,KAAK,0BAA0B,CAAC,iBAAiB;WACvD,MAAM,KAAK,0BAA0B,CAAC,wBAAwB,CAAC;AACtE,CAAC;AACD,+DAA+D;AAE/D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;AAI/E,wDAAwD;AACxD,2CAA2C;AAC3C,wDAAwD;AAExD,iEAAiE;AACjE;;;;;;;;;;;GAWG;AACH,MAAM,CAAN,IAAY,sBAIX;AAJD,WAAY,sBAAsB;IAChC,6CAAmB,CAAA;IACnB,+CAAqB,CAAA;IACrB,2CAAiB,CAAA;AACnB,CAAC,EAJW,sBAAsB,KAAtB,sBAAsB,QAIjC;AACD,+DAA+D;AAE/D;;;;GAIG;AACH,MAAM,CAAN,IAAY,wBAGX;AAHD,WAAY,wBAAwB;IAClC,mDAAuB,CAAA;IACvB,uCAAW,CAAA;AACb,CAAC,EAHW,wBAAwB,KAAxB,wBAAwB,QAGnC;AAED,wDAAwD;AACxD,2CAA2C;AAC3C,wDAAwD;AAExD,MAAM,CAAC,MAAM,qCAAqC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5D,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC;CAC7E,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,CAAC,MAAM,CAAC;IACzD,2DAA2D;IAC3D,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC,SAAS,CAAC;CACnF,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,WAAW,EAAE,qCAAqC,CAAC,QAAQ,EAAE;IAC7D,QAAQ,EAAE,kCAAkC,CAAC,QAAQ,EAAE;CACxD,CAAC,CAAC;AAGH,wDAAwD;AACxD,gEAAgE;AAChE,wDAAwD;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,MAAM,EAAE,4BAA4B;IACpC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;IAC/C,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC;IAC1C;;;OAGG;IACH,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACzC,eAAe,EAAE,CAAC,CAAC,MAAM,CAOvB,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,UAAU,CAAC,CAAC,QAAQ,EAAE;IAChD;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,EAAE,CAAC,CAAC,MAAM,CAOjB,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,UAAU,CAAC,CAAC,QAAQ,EAAE;IAChD;;;;;;;;;;;;OAYG;IACH,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACnD;;;;;;;;;;;;;;;OAeG;IACH,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC;AAEH,oCAAoC;AAEpC,2FAA2F;AAC3F,MAAM,CAAC,MAAM,sCAAsC,GAAG,qCAAqC,CAAC,MAAM,CAAC;IAC/F,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,KAAK,CAAC;IACrD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC3D,CAAC,CAAC;AAEH,oEAAoE;AACpE,MAAM,CAAC,MAAM,0CAA0C,GAAG,qCAAqC,CAAC,MAAM,CAAC;IACnG,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,SAAS,CAAC;CAC5D,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,gDAAgD,GAAG,qCAAqC,CAAC,MAAM,CAAC;IACzG,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,iBAAiB,CAAC;IACjE,8FAA8F;IAC9F,WAAW,EAAE,qCAAqC,CAAC,QAAQ,EAAE;IAC7D,gGAAgG;IAChG,QAAQ,EAAE,kCAAkC,CAAC,QAAQ,EAAE;CAC1D,CAAC,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CAAC;IACpD,sCAAsC;IACtC,0CAA0C;IAC1C,gDAAgD;CACnD,CAAC;IACA;;;;;;;;;;;;;;;;;;;OAmBG;KACF,WAAW,CAAC,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE;IACrC,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,KAAK,2BAA2B,CAAC,KAAK,IAAI,CAAC,CAAC,YAAY,CAAC,mBAAmB,CAAC;IACvH,IAAI,YAAY,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,aAAa,IAAI,CAAC,oCAAoC,CAAC,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QAChJ,OAAO,CAAC,QAAQ,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,WAAW,CAAC;YACnB,OAAO,EAAE,aAAa;gBACpB,CAAC,CAAC,uGAAuG;gBACzG,CAAC,CAAC,0EAA0E,YAAY,CAAC,MAAM,IAAI;sBAC/F,aAAa,YAAY,CAAC,OAAO,uEAAuE;sBACxG,4GAA4G;SACnH,CAAC,CAAC;IACL,CAAC;IACD,IAAI,YAAY,CAAC,eAAe,KAAK,SAAS,IAAI,CAAC,aAAa,IAAI,YAAY,CAAC,MAAM,KAAK,0BAA0B,CAAC,YAAY,CAAC,EAAE,CAAC;QACrI,OAAO,CAAC,QAAQ,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,iBAAiB,CAAC;YACzB,OAAO,EAAE,aAAa;gBACpB,CAAC,CAAC,qFAAqF;gBACvF,CAAC,CAAC,2CAA2C,0BAA0B,CAAC,YAAY,iCAAiC;sBACjH,IAAI,YAAY,CAAC,MAAM,iDAAiD,0BAA0B,CAAC,YAAY,IAAI;SAC1H,CAAC,CAAC;IACL,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,KAAK,0BAA0B,CAAC,YAAY,IAAI,CAAC,aAAa,IAAI,YAAY,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QACpI,OAAO,CAAC,QAAQ,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,iBAAiB,CAAC;YACzB,OAAO,EAAE,QAAQ,0BAA0B,CAAC,YAAY,kFAAkF;SAC3I,CAAC,CAAC;IACL,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,KAAK,0BAA0B,CAAC,eAAe,IAAI,YAAY,CAAC,OAAO,KAAK,2BAA2B,CAAC,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;QACvJ,OAAO,CAAC,QAAQ,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,qBAAqB,CAAC;YAC7B,OAAO,EAAE,oBAAoB,0BAA0B,CAAC,eAAe,oDAAoD;kBACvH,6FAA6F;SAClG,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,oFAAoF;AAEpF;;GAEG;AAIH,MAAM,CAAN,IAAY,oBAIT;AAJH,WAAY,oBAAoB;IAC5B,qCAAa,CAAA;IACb,2CAAmB,CAAA;IACnB,uCAAe,CAAA;AACjB,CAAC,EAJS,oBAAoB,KAApB,oBAAoB,QAI7B;AAEH,MAAM,CAAN,IAAY,0BAGX;AAHD,WAAY,0BAA0B;IAClC,2EAA6C,CAAA;IAC7C,yEAA2C,CAAA;AAC/C,CAAC,EAHW,0BAA0B,KAA1B,0BAA0B,QAGrC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;AAE/E,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,OAAO,EAAE,4BAA4B;IACrC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE;CACjD,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\nimport { ResourcePrimaryScope } from \"../resources/resources.shared.schemas\";\n\n\n/**\n * The channels the dispatcher delivers a user notification through.\n *\n * `SMS` and `PUSH` were members until #1799 and neither delivered: the dispatcher logged \"not yet\n * implemented\" and returned, no notification in the engine or its applications declared either, and a\n * notification definition had no text to send. They are removed rather than kept as channels an author\n * could declare and never have sent. An SMS channel is buildable on the existing SMS provider — it\n * needs a per-notification text contract and the verified phone — and returns when it is built; push\n * has no infrastructure at all.\n */\nexport enum CoreUserNotificationChannel {\n EMAIL = 'email',\n WEBSOCKET = 'websocket',\n FRONT_END_SUCCESS = 'front_end_success',\n}\n\nexport enum UserNotificationLevel {\n INFO = 'info',\n SUCCESS = 'success',\n WARNING = 'warning',\n ERROR = 'error',\n}\n\n/** A user notification channel: exactly the channels the dispatcher delivers (#1874). */\nexport const UserNotificationChannelSchema = z.enum(CoreUserNotificationChannel);\n\n\n/** @wildo_source:part:start saas.models.notifications.targets facet:layer:shared facet:audience:app-developer */\n/**\n * WHO a declared `userNotifications` entry reaches — and, on the EMAIL channel, whether the tenant\n * gets to redirect or silence it.\n *\n * Imported from `@wildo-ai/saas-models`. The target is the single most consequential field of a\n * notification declaration, because it decides three separate things at once:\n *\n * 1. **the recipients** — resolved per member below;\n * 2. **whether the recipient's own channel preference can suppress it** — only `USER_SELF` and\n * `USERS_CUSTOM` are suppressible, because only they reach a person about their own affairs. Every\n * other target reaches somebody because of a ROLE they hold, and a personal switch must not\n * silently disable a tenant's administrative monitoring. See\n * {@link userNotificationTargetIsSuppressibleByRecipientPreference};\n * 3. **whether `userRoles` is read at all** — see {@link userNotificationTargetReadsUserRoles}. Where it\n * is not read it is REFUSED rather than ignored — on the two tenant-wide targets because \"everyone\n * in the tenant\" is not a set a role list may narrow, and everywhere else because a filter that\n * does nothing misleads whoever reads the declaration.\n *\n * ## Who each target resolves to\n *\n * | target | recipients |\n * |---|---|\n * | `USER_SELF` | the initiator of the operation |\n * | `USERS_CUSTOM` | whatever your `userIdsSelector` returns. The function is required |\n * | `ORGANIZATION`, `ORGANIZATION_USERS` | every member of the initiator's tenant. `userRoles` is refused here |\n * | `ORGANIZATION_BILLING`, `ORGANIZATION_SECURITY`, `ORGANIZATION_USER_MANAGEMENT`, `ORGANIZATION_ADMINISTRATIVE` | members of the tenant holding `ORG_OWNER` or `ORG_ADMIN`, unless `userRoles` names a different set |\n * | `APPLICATION_BILLING` | holders of `APP_ADMIN_BILLING_MANAGER` or `APP_ADMIN_SUPER_ADMIN`, application-wide |\n * | `APPLICATION_ADMIN_VIEWER` | holders of `APP_ADMIN_VIEWER` or `APP_ADMIN_SUPER_ADMIN` |\n * | every other `APPLICATION_*` | holders of `APP_ADMIN_SUPER_ADMIN` |\n * | `INBOUND_CONTACT` | on EMAIL, the contact themselves, through `recipientEmailField` (required: the contact is not a user of your application, so no target resolves them). On WEBSOCKET and FRONT_END_SUCCESS, an in-app alert to holders of `APP_ADMIN_SUPER_ADMIN`, unless `userRoles` names a different set |\n *\n * The target must be one of these members, and a declaration that would reach nobody — `USERS_CUSTOM`\n * without a `userIdsSelector`, `INBOUND_CONTACT` on EMAIL without `recipientEmailField` — is refused\n * when the resource configuration is built, as is a `userRoles` or `userIdsSelector` the target never\n * reads.\n *\n * ## The tenant can redirect or silence an ORGANIZATION-flavoured EMAIL, and you cannot override it\n *\n * Each tenant owns a notification-settings record with a per-category switch and a per-category\n * address, and the category is DERIVED from the target — `ORGANIZATION_BILLING` to `billing`,\n * `ORGANIZATION_SECURITY` to `security`, and so on. Two consequences to design around:\n *\n * - **a configured address REPLACES the member fan-out**, it does not add to it. A tenant routing\n * security mail to a monitoring address is saying where that mail goes, not asking for a copy;\n * - **the category switch suppresses the notification entirely**, whether or not an address is\n * configured. A tenant that turns billing notifications off means it for the members too.\n *\n * `ORGANIZATION` belongs to no category, so no category switch silences it; the tenant-wide\n * `defaultEmailAddress` can redirect it. `ORGANIZATION_USERS` always keeps its member fan-out:\n * neither a category switch nor the tenant-wide default address redirects or suppresses that target.\n *\n * This applies to EMAIL only. The websocket and in-product paths always fan out to the members.\n */\nexport enum CoreUserNotificationTarget {\n APPLICATION_ADMINISTRATOR = 'application_administrator',\n APPLICATION_BILLING = 'application_billing',\n APPLICATION_USER_MANAGEMENT = 'application_user_management',\n APPLICATION_SECURITY = 'application_security',\n APPLICATION_SUPPORT = 'application_support',\n APPLICATION_OTHER = 'application_other',\n APPLICATION_ADMIN_VIEWER = 'application_admin_viewer',\n ORGANIZATION = 'organization',\n ORGANIZATION_USERS = 'organization_users',\n ORGANIZATION_BILLING = 'organization_billing',\n ORGANIZATION_USER_MANAGEMENT = 'organization_user_management',\n ORGANIZATION_ADMINISTRATIVE = 'organization_administrative',\n ORGANIZATION_SECURITY = 'organization_security',\n USER_SELF = 'user_self',\n USERS_CUSTOM = 'users_custom',\n INBOUND_CONTACT = 'inbound_contact',\n}\n\n/**\n * Whether a notification aimed at this target may be SUPPRESSED by the recipient's own channel\n * preference (`UserPreferences.notifications.email` / `.inApp`).\n *\n * DERIVED from the target rather than declared per notification, because the target already carries\n * the distinction and a second field would be one more thing to get wrong on 87 declarations.\n *\n * `USER_SELF` and `USERS_CUSTOM` reach a PERSON about their own affairs — those are the messages a\n * person is choosing about when they turn a channel off, and honouring that choice is the whole\n * point of the switch existing (#409).\n *\n * Every other target reaches somebody because of a ROLE they hold: an application administrator, an\n * organization's security or billing contact. A personal channel preference must not silently\n * disable a tenant's or an application's administrative monitoring — the recipient did not choose to\n * receive those as a person and cannot switch them off as one. A tenant that wants role mail\n * elsewhere routes it, which is what the organization notification-settings record is for.\n *\n * Nothing here reaches account RECOVERY. Password reset, magic link and email verification are sent\n * directly through the email service and never pass through the notification dispatcher, so no\n * channel preference can lock a person out of their own account. That measurement is what made\n * suppression safe to implement at all.\n */\nexport function userNotificationTargetIsSuppressibleByRecipientPreference(target: string): boolean {\n return target === CoreUserNotificationTarget.USER_SELF\n || target === CoreUserNotificationTarget.USERS_CUSTOM;\n}\n\n/**\n * The targets on which `userRoles` MEANS anything (#495).\n *\n * `userRoles` is not a recipient FILTER, which is how its name reads and how it has been authored. It\n * is the role-SELECTION override for the eleven role-scoped targets — `mapOrganizationTargetToRoles`\n * and `mapApplicationTargetToRoles` take it in place of their per-target default — and for\n * `INBOUND_CONTACT` on the in-app channels, where it names the application roles alerted about a new\n * contact in place of the default `APP_ADMIN_SUPER_ADMIN`. On EMAIL that target reaches the contact\n * through `recipientEmailField` and reads no role, hence the `channel` parameter.\n *\n * On every other target it is inert, and inert in three different ways that all looked the same to an\n * author: `USER_SELF` addresses the initiator, `USERS_CUSTOM` goes straight to `userIdsSelector`, and\n * `ORGANIZATION`/`ORGANIZATION_USERS` mean everyone in the tenant by definition. Declaring it there\n * is a filter that silently does nothing, which is what the refinement below now refuses.\n *\n * Scoped as a POSITIVE list of targets that read it rather than a rule about one target, because the\n * defect was never specific to `USERS_CUSTOM` — refusing it there alone would leave the other three\n * free to mislead the next author in exactly the same way.\n */\nexport function userNotificationTargetReadsUserRoles(target: string, channel: string): boolean {\n if (target === CoreUserNotificationTarget.INBOUND_CONTACT) {\n return channel !== CoreUserNotificationChannel.EMAIL;\n }\n return target === CoreUserNotificationTarget.ORGANIZATION_BILLING\n || target === CoreUserNotificationTarget.ORGANIZATION_USER_MANAGEMENT\n || target === CoreUserNotificationTarget.ORGANIZATION_ADMINISTRATIVE\n || target === CoreUserNotificationTarget.ORGANIZATION_SECURITY\n || target === CoreUserNotificationTarget.APPLICATION_ADMINISTRATOR\n || target === CoreUserNotificationTarget.APPLICATION_BILLING\n || target === CoreUserNotificationTarget.APPLICATION_USER_MANAGEMENT\n || target === CoreUserNotificationTarget.APPLICATION_SECURITY\n || target === CoreUserNotificationTarget.APPLICATION_SUPPORT\n || target === CoreUserNotificationTarget.APPLICATION_OTHER\n || target === CoreUserNotificationTarget.APPLICATION_ADMIN_VIEWER;\n}\n/** @wildo_source:part:end saas.models.notifications.targets */\n\n/**\n * A user notification target: exactly the members of {@link CoreUserNotificationTarget}.\n *\n * This accepted any string beside the enum, and a string the dispatcher had no rule for resolved nobody — a\n * notification that type-checked, built, and reached no one. Every member has an arm in the dispatcher, so the\n * vocabulary IS the set of targets that can be delivered, and a declaration naming anything else is refused when\n * the resource configuration is built.\n */\nexport const UserNotificationTargetSchema = z.enum(CoreUserNotificationTarget);\n\n\n\n// =====================================================\n// Celebration & Next-Step Enums (Phase 1a)\n// =====================================================\n\n/** @wildo_source:part:start saas.models.milestone-celebration */\n/**\n * How the frontend renders a celebration after a successful operation — the value a milestone's\n * `celebrationMode` takes. Import from `@wildo-ai/saas-models`.\n * - CONFETTI: a lightweight, non-blocking confetti burst over the page. Decorative only: no message,\n * no next step, nothing to dismiss.\n * - OVERLAY: a dialog carrying the celebration animation, the milestone's title, the message, an\n * optional next-step action and a dismiss.\n * - LOTTIE: in the framework's DEFAULT celebration overlay, identical to OVERLAY — the same dialog\n * and the same animation. It is the mode to use when the application's OWN celebration-overlay\n * preset draws something distinct for it, such as a per-milestone animation chosen from the\n * notification identifier the preset receives.\n */\nexport enum CelebrationDisplayMode {\n OVERLAY = 'overlay',\n CONFETTI = 'confetti',\n LOTTIE = 'lottie',\n}\n/** @wildo_source:part:end saas.models.milestone-celebration */\n\n/**\n * Type of next-step suggestion attached to a notification.\n * - OPERATION: Navigate to and/or trigger a resource operation\n * - URL: Navigate to an arbitrary URL (internal or external)\n */\nexport enum NotificationNextStepType {\n OPERATION = 'operation',\n URL = 'url',\n}\n\n// =====================================================\n// Frontend Display Hints Schema (reusable)\n// =====================================================\n\nexport const FrontendDisplayHintsCelebrationSchema = z.object({\n mode: z.enum(CelebrationDisplayMode).default(CelebrationDisplayMode.OVERLAY),\n});\nexport type FrontendDisplayHintsCelebration = z.infer<typeof FrontendDisplayHintsCelebrationSchema>;\n\nexport const FrontendDisplayHintsNextStepSchema = z.object({\n /** Operation path (e.g., \"TASKS.CREATE.default\") or URL */\n operationRef: z.string(),\n type: z.enum(NotificationNextStepType).default(NotificationNextStepType.OPERATION),\n});\nexport type FrontendDisplayHintsNextStep = z.infer<typeof FrontendDisplayHintsNextStepSchema>;\n\nexport const FrontendDisplayHintsSchema = z.object({\n celebration: FrontendDisplayHintsCelebrationSchema.optional(),\n nextStep: FrontendDisplayHintsNextStepSchema.optional(),\n});\nexport type FrontendDisplayHints = z.infer<typeof FrontendDisplayHintsSchema>;\n\n// =====================================================\n// UserNotificationDefinition — Discriminated Union on `channel`\n// =====================================================\n\n/**\n * @wildo_source:part:start saas.models.notifications.user-notification-definition facet:layer:shared facet:audience:app-developer\n *\n * One notification an operation sends. Declared as `userNotifications` on a resource operation, in\n * the resource config — an array, so one operation may send several.\n *\n * ```ts\n * userNotifications: [\n * { target: CoreUserNotificationTarget.USER_SELF, channel: CoreUserNotificationChannel.EMAIL,\n * condition: ({ currentObject }) => currentObject.status === 'INVITED' },\n * { target: CoreUserNotificationTarget.ORGANIZATION_USERS, channel: CoreUserNotificationChannel.WEBSOCKET },\n * ]\n * ```\n *\n * ## What actually sends\n *\n * `EMAIL`, `WEBSOCKET` and `FRONT_END_SUCCESS` are the channels, and all three deliver. There is no\n * SMS or push notification channel: both were declaration vocabulary that the dispatcher logged and\n * dropped, and were removed. The framework's SMS transport serves authentication's one-time codes, not\n * resource notifications.\n *\n * For an EMAIL, create the template directory the reference names. The startup validator resolves\n * every declared reference through the configured locale chain before the application takes traffic,\n * and prints the exact directory to create when one is missing.\n *\n * ## The recipient's preferences are honoured, and three things override them\n *\n * A recipient who has switched a channel off does not receive it. Three deliberate exceptions:\n *\n * - a ROLE-addressed target — the recipient did not choose to receive it as a person;\n * - `alwaysDeliver: true` — declare it on a security notice a compromised account's owner must still\n * receive;\n * - a recipient with NO preferences row at all, because preferences are created lazily and a missing\n * record must never read as \"everything off\".\n *\n * The `inApp` switch suppresses optional personal message presentation (toast, centre and celebration),\n * not the socket frame. Declarative frames carry target and alwaysDeliver to the frontend gate;\n * required and responsibility-addressed messages remain visible. Local operation feedback and\n * resource refresh events are independent of this personal-message preference.\n *\n * ## `condition` gates the notification, not the operation\n *\n * The predicate goes on the notification. It decides only whether this one message is sent; refusing\n * the CALL is a separate declaration on the operation variant, and the two are independent — a\n * variant can be enabled while its notification is gated off, and the reverse. The form deliberately\n * matches an operation variant's `enabledCondition` so both read the same way.\n *\n * ## Emailing somebody who is not a user\n *\n * `recipientEmailField` names a TOP-LEVEL field on the record holding the address. There is no\n * recipient, so there are no recipient preferences and no recipient language: the message goes out in\n * the application's default locale. A nested address cannot be named, nor a list — the path sends\n * exactly one message per notification. Pair it with a `condition` when the same operation also\n * serves rows whose address belongs to somebody who must not be written to.\n *\n * Base fields shared by all user notification channel variants.\n */\nexport const UserNotificationDefinition_BaseSchema = z.object({\n identifier: z.string().min(1),\n target: UserNotificationTargetSchema,\n level: z.enum(UserNotificationLevel).optional(),\n primaryScope: z.enum(ResourcePrimaryScope),\n /**\n * Role-SELECTION override for a role-scoped target — NOT a recipient filter. See\n * {@link userNotificationTargetReadsUserRoles}, which is also what refuses it elsewhere.\n */\n userRoles: z.array(z.string()).optional(),\n userIdsSelector: z.custom<\n (params: {\n currentObject: any;\n inputDto: any;\n objectContext: { parents: Record<string, any>; children: Record<string, any> };\n initiatorIds: { userId?: string; organizationId?: string; applicationId?: string };\n }) => string[]\n >((val) => typeof val === 'function').optional(),\n /**\n * Optional gate — dispatch this notification ONLY when the predicate returns truthy\n * against the post-operation context. Absent = always dispatches (backward compatible).\n * Evaluated per-notification BEFORE channel resolution, so it uniformly gates every\n * channel (email/websocket/front-end-success/…).\n *\n * The canonical use is a POLYMORPHIC operation whose notification must fire for only one\n * branch: the org-member CREATE op serves both INVITE (`status` INVITED — send the invite\n * email to `userEmail`) and DIRECT-ADD (`status` ACTIVE — founder / SSO-JIT / SCIM, whose\n * `userEmail` is the member's OWN address, so an \"you've been invited\" email is a\n * misdelivery). Keying on `currentObject.status === INVITED` fires the invite email for\n * invites only.\n *\n * Params mirror `userIdsSelector` (its sibling), so an author writes the same\n * `({ currentObject }) => …` form used by the operation-variant `enabledCondition`.\n *\n * @example `({ currentObject }) => currentObject.status === OrganizationMemberStatus.INVITED`\n */\n condition: z.custom<\n (params: {\n currentObject: any;\n inputDto: any;\n objectContext: { parents: Record<string, any>; children: Record<string, any> };\n initiatorIds: { userId?: string; organizationId?: string; applicationId?: string };\n }) => boolean\n >((val) => typeof val === 'function').optional(),\n /**\n * Custom notification reference for disambiguating multiple notifications of the same type.\n *\n * REQUIRED when:\n * - There are 2+ notifications with the same target in the same operation\n * - Example: 2+ USERS_CUSTOM notifications (one for creator, one for assignee)\n *\n * This allows distinguishing between multiple similar notifications\n * in the same operation (e.g., \"notify-creator\" vs \"notify-assignee\").\n *\n * Format: lowercase-kebab-case (e.g., \"notify-creator\", \"task-assigned\")\n * Will be appended to auto-generated identifier for notification/template lookup.\n */\n customNotificationRef: z.string().min(1).optional(),\n /**\n * Deliver this notification even when the recipient has switched its channel OFF.\n *\n * Only meaningful on a target that is suppressible in the first place — `USER_SELF` and\n * `USERS_CUSTOM` (see `userNotificationTargetIsSuppressibleByRecipientPreference`). On a\n * role-addressed target the preference never applied, so this flag changes nothing there.\n *\n * The narrow escape, for the case the target axis cannot express: a message that reaches a\n * person about their OWN affairs and is nevertheless a security notice they should not be able\n * to silence — a credential minted or destroyed on their account, an authentication factor\n * changed. Those are the alerts a person most needs when they did NOT perform the action.\n *\n * Author it with the reason at the site. It is deliberately not a default and deliberately not\n * derived: \"is this alert one a compromised account's owner must still receive?\" is a judgement\n * about the message, and inventing a rule for it would be a rule nobody could check.\n */\n alwaysDeliver: z.boolean().optional(),\n});\n\n// --- Channel-specific variants ---\n\n/** EMAIL channel — template-oriented (email-specific fields handled by email templates) */\nexport const UserNotificationDefinition_EmailSchema = UserNotificationDefinition_BaseSchema.extend({\n channel: z.literal(CoreUserNotificationChannel.EMAIL),\n /**\n * Deliver this email to a raw address read from the current object, rather than\n * to a resolved platform user.\n *\n * When set, the recipient is `currentObject[recipientEmailField]` (a top-level\n * string field — e.g. `'email'`). The dispatcher sends a single email directly to\n * that address using the application's default locale, BYPASSING the `userId`-based\n * `target` resolution entirely.\n *\n * This is the framework's mechanism for notifying a party who is **not (yet) a\n * platform user** — an organization-invitation invitee, an inbound lead — for whom\n * no `userId` exists. Without it, the only email recipients the dispatcher can\n * resolve are members/initiators by id (`fetchUserContext(userId).email`).\n *\n * When this is set, `target` no longer selects the recipient; it is retained only\n * to (a) classify the notification, (b) drive the email `templateRef` derivation,\n * and (c) route the dashboard URL (admin app vs main app). Choose a `target` whose\n * dashboard-routing class matches the recipient (e.g. `USER_SELF` for a main-app\n * link).\n *\n * All other context is built identically to a user-targeted email (organization\n * name, initiator name, and the token `acceptUrl` enricher), so token-bearing\n * emails such as invitations still carry their `<frontendBase><emailLinkPath>?token=`\n * acceptance link.\n */\n recipientEmailField: z.string().trim().min(1).optional(),\n});\n\n/** WEBSOCKET channel — pure WebSocket push (no frontend display) */\nexport const UserNotificationDefinition_WebSocketSchema = UserNotificationDefinition_BaseSchema.extend({\n channel: z.literal(CoreUserNotificationChannel.WEBSOCKET),\n});\n\n/**\n * FRONT_END_SUCCESS channel — frontend display with optional celebration + nextStep.\n *\n * `celebration`: Tells the frontend to render richer feedback than a simple toast.\n * `nextStep`: Suggested next action rendered as a CTA button in the toast or celebration overlay.\n *\n * Example usage in operation config:\n * ```\n * userNotifications: [{\n * identifier: 'first-document-created',\n * target: CoreUserNotificationTarget.USER_SELF,\n * channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n * primaryScope: ResourcePrimaryScope.ORGANIZATIONS,\n * celebration: { mode: CelebrationDisplayMode.OVERLAY },\n * nextStep: { operationRef: 'DOCUMENTS.LIST.default', type: NotificationNextStepType.OPERATION },\n * }]\n * ```\n */\nexport const UserNotificationDefinition_FrontEndSuccessSchema = UserNotificationDefinition_BaseSchema.extend({\n channel: z.literal(CoreUserNotificationChannel.FRONT_END_SUCCESS),\n /** Celebration display hints — triggers richer frontend feedback (overlay/confetti/lottie) */\n celebration: FrontendDisplayHintsCelebrationSchema.optional(),\n /** Suggested next action after operation completes — rendered as CTA in toast or celebration */\n nextStep: FrontendDisplayHintsNextStepSchema.optional(),\n});\n\n/**\n * Final union of all notification channel variants — exactly the channels the dispatcher delivers (#1874).\n *\n * There used to be a fourth member, a catch-all `channel: z.string()` \"for custom channels\". Nothing delivered a\n * custom channel: the dispatcher's `default` arm logged at debug and sent nothing, so `channel: 'slack'` passed\n * validation and every dispatch was silently empty — the class #1799 removed for SMS and push. A channel is now one\n * of `CoreUserNotificationChannel`, and the resource factory parses every declared notification against this schema\n * (`processUserNotifications`), so an unknown one is refused when the configuration is built. A new channel is\n * added by giving it a member here AND a delivery arm in the dispatcher, never by naming it.\n */\nexport const UserNotificationDefinitionSchema = z.union([\n UserNotificationDefinition_EmailSchema,\n UserNotificationDefinition_WebSocketSchema,\n UserNotificationDefinition_FrontEndSuccessSchema,\n])\n /**\n * A declaration must reach somebody, and every field it carries must be read.\n *\n * Each rule below is a declaration the schema used to accept and the dispatcher then ignored, silently:\n *\n * - `userRoles` on a target that never reads it is a filter that does nothing (#495). An email sent by\n * address (`recipientEmailField`) resolves no target at all, so it reads neither `userRoles` nor\n * `userIdsSelector`.\n * - `userIdsSelector` is read by `USERS_CUSTOM` alone; on any other target it is a function nothing calls.\n * - `USERS_CUSTOM` without a `userIdsSelector` resolves nobody.\n * - `INBOUND_CONTACT` on EMAIL resolves nobody by target: the contact is not a user, and is reached only\n * through `recipientEmailField`.\n *\n * The resource factory parses every declaration against this schema, so each is refused when the\n * configuration is built rather than discovered as an email nobody received.\n *\n * Refined on the UNION rather than on the base object, deliberately: the base is `.extend()`ed by\n * every channel variant, and a refinement there would be dropped by each of them — the shape of bug\n * this refinement exists to prevent.\n */\n .superRefine((notification, context) => {\n const sentByAddress = notification.channel === CoreUserNotificationChannel.EMAIL && !!notification.recipientEmailField;\n if (notification.userRoles !== undefined && (sentByAddress || !userNotificationTargetReadsUserRoles(notification.target, notification.channel))) {\n context.addIssue({\n code: 'custom',\n path: ['userRoles'],\n message: sentByAddress\n ? 'userRoles is never read on an email sent to recipientEmailField, which resolves no target. Remove it.'\n : `userRoles is only read for a role-scoped target and would be inert on \"${notification.target}\" `\n + `(channel \"${notification.channel}\"). It selects WHICH roles a role-scoped target reaches; it does not `\n + 'filter the recipients of any other target. Remove it, or address the notification to a role-scoped target.',\n });\n }\n if (notification.userIdsSelector !== undefined && (sentByAddress || notification.target !== CoreUserNotificationTarget.USERS_CUSTOM)) {\n context.addIssue({\n code: 'custom',\n path: ['userIdsSelector'],\n message: sentByAddress\n ? 'userIdsSelector is never called on an email sent to recipientEmailField. Remove it.'\n : `userIdsSelector is only called for the \"${CoreUserNotificationTarget.USERS_CUSTOM}\" target and would be inert on `\n + `\"${notification.target}\". Remove it, or address the notification to \"${CoreUserNotificationTarget.USERS_CUSTOM}\".`,\n });\n }\n if (notification.target === CoreUserNotificationTarget.USERS_CUSTOM && !sentByAddress && notification.userIdsSelector === undefined) {\n context.addIssue({\n code: 'custom',\n path: ['userIdsSelector'],\n message: `The \"${CoreUserNotificationTarget.USERS_CUSTOM}\" target reaches whoever userIdsSelector returns; without one it reaches nobody.`,\n });\n }\n if (notification.target === CoreUserNotificationTarget.INBOUND_CONTACT && notification.channel === CoreUserNotificationChannel.EMAIL && !sentByAddress) {\n context.addIssue({\n code: 'custom',\n path: ['recipientEmailField'],\n message: `An email to the \"${CoreUserNotificationTarget.INBOUND_CONTACT}\" target reaches nobody by target: the contact is `\n + 'not a user of the application. Name the field holding their address in recipientEmailField.',\n });\n }\n });\nexport type UserNotificationDefinition = z.infer<typeof UserNotificationDefinitionSchema>;\n/** @wildo_source:part:end saas.models.notifications.user-notification-definition */\n\n/**\n * M2M Notification Channels\n */\n\n\n\nexport enum M2MNotificationLevel {\n INFO = 'info',\n SUCCESS = 'success',\n ERROR = 'error',\n }\n\nexport enum CoreM2MNotificationChannel {\n WEBHOOK_ORGANIZATION = 'webhook_organization',\n WEBHOOK_APPLICATION = 'webhook_application',\n}\n\n/**\n * An M2M notification channel: exactly the two webhook channels the dispatcher delivers.\n *\n * This accepted any string, and the dispatcher threw \"not implemented\" for anything but the two webhooks — at\n * dispatch, after the write, where the throw also skipped every later M2M notification of the same operation. The\n * resource factory now refuses any other channel when the configuration is built.\n */\nexport const M2MNotificationChannelSchema = z.enum(CoreM2MNotificationChannel);\n\nexport const M2MNotificationDefinitionSchema = z.object({\n identifier: z.string().min(1),\n channel: M2MNotificationChannelSchema,\n level: z.enum(M2MNotificationLevel).optional(),\n});\nexport type M2MNotificationDefinition = z.infer<typeof M2MNotificationDefinitionSchema>;\n\n"]}
|
|
1
|
+
{"version":3,"file":"notifications.shared.schemas.js","sourceRoot":"","sources":["../../../../src/notifications/notifications.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport { ResourcePrimaryScope } from \"../resources/resources.shared.schemas\";\n\n\n/**\n * The channels the dispatcher delivers a user notification through.\n *\n * `SMS` and `PUSH` were members until #1799 and neither delivered: the dispatcher logged \"not yet\n * implemented\" and returned, no notification in the engine or its applications declared either, and a\n * notification definition had no text to send. They are removed rather than kept as channels an author\n * could declare and never have sent. An SMS channel is buildable on the existing SMS provider — it\n * needs a per-notification text contract and the verified phone — and returns when it is built; push\n * has no infrastructure at all.\n */\nexport enum CoreUserNotificationChannel {\n EMAIL = 'email',\n WEBSOCKET = 'websocket',\n FRONT_END_SUCCESS = 'front_end_success',\n}\n\nexport enum UserNotificationLevel {\n INFO = 'info',\n SUCCESS = 'success',\n WARNING = 'warning',\n ERROR = 'error',\n}\n\n/** A user notification channel: exactly the channels the dispatcher delivers (#1874). */\nexport const UserNotificationChannelSchema = z.enum(CoreUserNotificationChannel);\n\n\n/** @wildo_source:part:start saas.models.notifications.targets facet:layer:shared facet:audience:app-developer */\n/**\n * WHO a declared `userNotifications` entry reaches — and, on the EMAIL channel, whether the tenant\n * gets to redirect or silence it.\n *\n * Imported from `@wildo-ai/saas-models`. The target is the single most consequential field of a\n * notification declaration, because it decides three separate things at once:\n *\n * 1. **the recipients** — resolved per member below;\n * 2. **whether the recipient's own channel preference can suppress it** — only `USER_SELF` and\n * `USERS_CUSTOM` are suppressible, because only they reach a person about their own affairs. Every\n * other target reaches somebody because of a ROLE they hold, and a personal switch must not\n * silently disable a tenant's administrative monitoring. See\n * {@link userNotificationTargetIsSuppressibleByRecipientPreference};\n * 3. **whether `userRoles` is read at all** — see {@link userNotificationTargetReadsUserRoles}. Where it\n * is not read it is REFUSED rather than ignored — on the two tenant-wide targets because \"everyone\n * in the tenant\" is not a set a role list may narrow, and everywhere else because a filter that\n * does nothing misleads whoever reads the declaration.\n *\n * ## Who each target resolves to\n *\n * | target | recipients |\n * |---|---|\n * | `USER_SELF` | the initiator of the operation |\n * | `USERS_CUSTOM` | whatever your `userIdsSelector` returns. The function is required |\n * | `ORGANIZATION`, `ORGANIZATION_USERS` | every member of the initiator's tenant. `userRoles` is refused here |\n * | `ORGANIZATION_BILLING`, `ORGANIZATION_SECURITY`, `ORGANIZATION_USER_MANAGEMENT`, `ORGANIZATION_ADMINISTRATIVE` | members of the tenant holding `ORG_OWNER` or `ORG_ADMIN`, unless `userRoles` names a different set |\n * | `APPLICATION_BILLING` | holders of `APP_ADMIN_BILLING_MANAGER` or `APP_ADMIN_SUPER_ADMIN`, application-wide |\n * | `APPLICATION_ADMIN_VIEWER` | holders of `APP_ADMIN_VIEWER` or `APP_ADMIN_SUPER_ADMIN` |\n * | every other `APPLICATION_*` | holders of `APP_ADMIN_SUPER_ADMIN` |\n * | `INBOUND_CONTACT` | on EMAIL, the contact themselves, through `recipientEmailField` (required: the contact is not a user of your application, so no target resolves them). On WEBSOCKET and FRONT_END_SUCCESS, an in-app alert to holders of `APP_ADMIN_SUPER_ADMIN`, unless `userRoles` names a different set |\n *\n * The target must be one of these members, and a declaration that would reach nobody — `USERS_CUSTOM`\n * without a `userIdsSelector`, `INBOUND_CONTACT` on EMAIL without `recipientEmailField` — is refused\n * when the resource configuration is built, as is a `userRoles` or `userIdsSelector` the target never\n * reads.\n *\n * ## The tenant can redirect or silence an ORGANIZATION-flavoured EMAIL, and you cannot override it\n *\n * Each tenant owns a notification-settings record with a per-category switch and a per-category\n * address, and the category is DERIVED from the target — `ORGANIZATION_BILLING` to `billing`,\n * `ORGANIZATION_SECURITY` to `security`, and so on. Two consequences to design around:\n *\n * - **a configured address REPLACES the member fan-out**, it does not add to it. A tenant routing\n * security mail to a monitoring address is saying where that mail goes, not asking for a copy;\n * - **the category switch suppresses the notification entirely**, whether or not an address is\n * configured. A tenant that turns billing notifications off means it for the members too.\n *\n * `ORGANIZATION` belongs to no category, so no category switch silences it; the tenant-wide\n * `defaultEmailAddress` can redirect it. `ORGANIZATION_USERS` always keeps its member fan-out:\n * neither a category switch nor the tenant-wide default address redirects or suppresses that target.\n *\n * This applies to EMAIL only. The websocket and in-product paths always fan out to the members.\n */\nexport enum CoreUserNotificationTarget {\n APPLICATION_ADMINISTRATOR = 'application_administrator',\n APPLICATION_BILLING = 'application_billing',\n APPLICATION_USER_MANAGEMENT = 'application_user_management',\n APPLICATION_SECURITY = 'application_security',\n APPLICATION_SUPPORT = 'application_support',\n APPLICATION_OTHER = 'application_other',\n APPLICATION_ADMIN_VIEWER = 'application_admin_viewer',\n ORGANIZATION = 'organization',\n ORGANIZATION_USERS = 'organization_users',\n ORGANIZATION_BILLING = 'organization_billing',\n ORGANIZATION_USER_MANAGEMENT = 'organization_user_management',\n ORGANIZATION_ADMINISTRATIVE = 'organization_administrative',\n ORGANIZATION_SECURITY = 'organization_security',\n USER_SELF = 'user_self',\n USERS_CUSTOM = 'users_custom',\n INBOUND_CONTACT = 'inbound_contact',\n}\n\n/**\n * Whether a notification aimed at this target may be SUPPRESSED by the recipient's own channel\n * preference (`UserPreferences.notifications.email` / `.inApp`).\n *\n * DERIVED from the target rather than declared per notification, because the target already carries\n * the distinction and a second field would be one more thing to get wrong on 87 declarations.\n *\n * `USER_SELF` and `USERS_CUSTOM` reach a PERSON about their own affairs — those are the messages a\n * person is choosing about when they turn a channel off, and honouring that choice is the whole\n * point of the switch existing (#409).\n *\n * Every other target reaches somebody because of a ROLE they hold: an application administrator, an\n * organization's security or billing contact. A personal channel preference must not silently\n * disable a tenant's or an application's administrative monitoring — the recipient did not choose to\n * receive those as a person and cannot switch them off as one. A tenant that wants role mail\n * elsewhere routes it, which is what the organization notification-settings record is for.\n *\n * Nothing here reaches account RECOVERY. Password reset, magic link and email verification are sent\n * directly through the email service and never pass through the notification dispatcher, so no\n * channel preference can lock a person out of their own account. That measurement is what made\n * suppression safe to implement at all.\n */\nexport function userNotificationTargetIsSuppressibleByRecipientPreference(target: string): boolean {\n return target === CoreUserNotificationTarget.USER_SELF\n || target === CoreUserNotificationTarget.USERS_CUSTOM;\n}\n\n/**\n * The targets on which `userRoles` MEANS anything (#495).\n *\n * `userRoles` is not a recipient FILTER, which is how its name reads and how it has been authored. It\n * is the role-SELECTION override for the eleven role-scoped targets — `mapOrganizationTargetToRoles`\n * and `mapApplicationTargetToRoles` take it in place of their per-target default — and for\n * `INBOUND_CONTACT` on the in-app channels, where it names the application roles alerted about a new\n * contact in place of the default `APP_ADMIN_SUPER_ADMIN`. On EMAIL that target reaches the contact\n * through `recipientEmailField` and reads no role, hence the `channel` parameter.\n *\n * On every other target it is inert, and inert in three different ways that all looked the same to an\n * author: `USER_SELF` addresses the initiator, `USERS_CUSTOM` goes straight to `userIdsSelector`, and\n * `ORGANIZATION`/`ORGANIZATION_USERS` mean everyone in the tenant by definition. Declaring it there\n * is a filter that silently does nothing, which is what the refinement below now refuses.\n *\n * Scoped as a POSITIVE list of targets that read it rather than a rule about one target, because the\n * defect was never specific to `USERS_CUSTOM` — refusing it there alone would leave the other three\n * free to mislead the next author in exactly the same way.\n */\nexport function userNotificationTargetReadsUserRoles(target: string, channel: string): boolean {\n if (target === CoreUserNotificationTarget.INBOUND_CONTACT) {\n return channel !== CoreUserNotificationChannel.EMAIL;\n }\n return target === CoreUserNotificationTarget.ORGANIZATION_BILLING\n || target === CoreUserNotificationTarget.ORGANIZATION_USER_MANAGEMENT\n || target === CoreUserNotificationTarget.ORGANIZATION_ADMINISTRATIVE\n || target === CoreUserNotificationTarget.ORGANIZATION_SECURITY\n || target === CoreUserNotificationTarget.APPLICATION_ADMINISTRATOR\n || target === CoreUserNotificationTarget.APPLICATION_BILLING\n || target === CoreUserNotificationTarget.APPLICATION_USER_MANAGEMENT\n || target === CoreUserNotificationTarget.APPLICATION_SECURITY\n || target === CoreUserNotificationTarget.APPLICATION_SUPPORT\n || target === CoreUserNotificationTarget.APPLICATION_OTHER\n || target === CoreUserNotificationTarget.APPLICATION_ADMIN_VIEWER;\n}\n/** @wildo_source:part:end saas.models.notifications.targets */\n\n/**\n * A user notification target: exactly the members of {@link CoreUserNotificationTarget}.\n *\n * This accepted any string beside the enum, and a string the dispatcher had no rule for resolved nobody — a\n * notification that type-checked, built, and reached no one. Every member has an arm in the dispatcher, so the\n * vocabulary IS the set of targets that can be delivered, and a declaration naming anything else is refused when\n * the resource configuration is built.\n */\nexport const UserNotificationTargetSchema = z.enum(CoreUserNotificationTarget);\n\n\n\n// =====================================================\n// Celebration & Next-Step Enums (Phase 1a)\n// =====================================================\n\n/** @wildo_source:part:start saas.models.milestone-celebration */\n/**\n * How the frontend renders a celebration after a successful operation — the value a milestone's\n * `celebrationMode` takes. Import from `@wildo-ai/saas-models`.\n * - CONFETTI: a lightweight, non-blocking confetti burst over the page. Decorative only: no message,\n * no next step, nothing to dismiss.\n * - OVERLAY: a dialog carrying the celebration animation, the milestone's title, the message, an\n * optional next-step action and a dismiss.\n * - LOTTIE: in the framework's DEFAULT celebration overlay, identical to OVERLAY — the same dialog\n * and the same animation. It is the mode to use when the application's OWN celebration-overlay\n * preset draws something distinct for it, such as a per-milestone animation chosen from the\n * notification identifier the preset receives.\n */\nexport enum CelebrationDisplayMode {\n OVERLAY = 'overlay',\n CONFETTI = 'confetti',\n LOTTIE = 'lottie',\n}\n/** @wildo_source:part:end saas.models.milestone-celebration */\n\n/**\n * Type of next-step suggestion attached to a notification.\n * - OPERATION: Navigate to and/or trigger a resource operation\n * - URL: Navigate to an arbitrary URL (internal or external)\n */\nexport enum NotificationNextStepType {\n OPERATION = 'operation',\n URL = 'url',\n}\n\n// =====================================================\n// Frontend Display Hints Schema (reusable)\n// =====================================================\n\nexport const FrontendDisplayHintsCelebrationSchema = z.object({\n mode: z.enum(CelebrationDisplayMode).default(CelebrationDisplayMode.OVERLAY),\n});\nexport type FrontendDisplayHintsCelebration = z.infer<typeof FrontendDisplayHintsCelebrationSchema>;\n\nexport const FrontendDisplayHintsNextStepSchema = z.object({\n /** Operation path (e.g., \"TASKS.CREATE.default\") or URL */\n operationRef: z.string(),\n type: z.enum(NotificationNextStepType).default(NotificationNextStepType.OPERATION),\n});\nexport type FrontendDisplayHintsNextStep = z.infer<typeof FrontendDisplayHintsNextStepSchema>;\n\nexport const FrontendDisplayHintsSchema = z.object({\n celebration: FrontendDisplayHintsCelebrationSchema.optional(),\n nextStep: FrontendDisplayHintsNextStepSchema.optional(),\n});\nexport type FrontendDisplayHints = z.infer<typeof FrontendDisplayHintsSchema>;\n\n// =====================================================\n// UserNotificationDefinition — Discriminated Union on `channel`\n// =====================================================\n\n/**\n * @wildo_source:part:start saas.models.notifications.user-notification-definition facet:layer:shared facet:audience:app-developer\n *\n * One notification an operation sends. Declared as `userNotifications` on a resource operation, in\n * the resource config — an array, so one operation may send several.\n *\n * ```ts\n * userNotifications: [\n * { target: CoreUserNotificationTarget.USER_SELF, channel: CoreUserNotificationChannel.EMAIL,\n * condition: ({ currentObject }) => currentObject.status === 'INVITED' },\n * { target: CoreUserNotificationTarget.ORGANIZATION_USERS, channel: CoreUserNotificationChannel.WEBSOCKET },\n * ]\n * ```\n *\n * ## What actually sends\n *\n * `EMAIL`, `WEBSOCKET` and `FRONT_END_SUCCESS` are the channels, and all three deliver. There is no\n * SMS or push notification channel: both were declaration vocabulary that the dispatcher logged and\n * dropped, and were removed. The framework's SMS transport serves authentication's one-time codes, not\n * resource notifications.\n *\n * For an EMAIL, create the template directory the reference names. The startup validator resolves\n * every declared reference through the configured locale chain before the application takes traffic,\n * and prints the exact directory to create when one is missing.\n *\n * ## The recipient's preferences are honoured, and three things override them\n *\n * A recipient who has switched a channel off does not receive it. Three deliberate exceptions:\n *\n * - a ROLE-addressed target — the recipient did not choose to receive it as a person;\n * - `alwaysDeliver: true` — declare it on a security notice a compromised account's owner must still\n * receive;\n * - a recipient with NO preferences row at all, because preferences are created lazily and a missing\n * record must never read as \"everything off\".\n *\n * The `inApp` switch suppresses optional personal message presentation (toast, centre and celebration),\n * not the socket frame. Declarative frames carry target and alwaysDeliver to the frontend gate;\n * required and responsibility-addressed messages remain visible. Local operation feedback and\n * resource refresh events are independent of this personal-message preference.\n *\n * ## `condition` gates the notification, not the operation\n *\n * The predicate goes on the notification. It decides only whether this one message is sent; refusing\n * the CALL is a separate declaration on the operation variant, and the two are independent — a\n * variant can be enabled while its notification is gated off, and the reverse. The form deliberately\n * matches an operation variant's `enabledCondition` so both read the same way.\n *\n * ## Emailing somebody who is not a user\n *\n * `recipientEmailField` names a TOP-LEVEL field on the record holding the address. There is no\n * recipient, so there are no recipient preferences and no recipient language: the message goes out in\n * the application's default locale. A nested address cannot be named, nor a list — the path sends\n * exactly one message per notification. Pair it with a `condition` when the same operation also\n * serves rows whose address belongs to somebody who must not be written to.\n *\n * Base fields shared by all user notification channel variants.\n */\nexport const UserNotificationDefinition_BaseSchema = z.object({\n identifier: z.string().min(1),\n target: UserNotificationTargetSchema,\n level: z.enum(UserNotificationLevel).optional(),\n primaryScope: z.enum(ResourcePrimaryScope),\n /**\n * Role-SELECTION override for a role-scoped target — NOT a recipient filter. See\n * {@link userNotificationTargetReadsUserRoles}, which is also what refuses it elsewhere.\n */\n userRoles: z.array(z.string()).optional(),\n userIdsSelector: z.custom<\n (params: {\n currentObject: any;\n inputDto: any;\n objectContext: { parents: Record<string, any>; children: Record<string, any> };\n initiatorIds: { userId?: string; organizationId?: string; applicationId?: string };\n }) => string[]\n >((val) => typeof val === 'function').optional(),\n /**\n * Optional gate — dispatch this notification ONLY when the predicate returns truthy\n * against the post-operation context. Absent = always dispatches (backward compatible).\n * Evaluated per-notification BEFORE channel resolution, so it uniformly gates every\n * channel (email/websocket/front-end-success/…).\n *\n * The canonical use is a POLYMORPHIC operation whose notification must fire for only one\n * branch: the org-member CREATE op serves both INVITE (`status` INVITED — send the invite\n * email to `userEmail`) and DIRECT-ADD (`status` ACTIVE — founder / SSO-JIT / SCIM, whose\n * `userEmail` is the member's OWN address, so an \"you've been invited\" email is a\n * misdelivery). Keying on `currentObject.status === INVITED` fires the invite email for\n * invites only.\n *\n * Params mirror `userIdsSelector` (its sibling), so an author writes the same\n * `({ currentObject }) => …` form used by the operation-variant `enabledCondition`.\n *\n * @example `({ currentObject }) => currentObject.status === OrganizationMemberStatus.INVITED`\n */\n condition: z.custom<\n (params: {\n currentObject: any;\n inputDto: any;\n objectContext: { parents: Record<string, any>; children: Record<string, any> };\n initiatorIds: { userId?: string; organizationId?: string; applicationId?: string };\n }) => boolean\n >((val) => typeof val === 'function').optional(),\n /**\n * Custom notification reference for disambiguating multiple notifications of the same type.\n *\n * REQUIRED when:\n * - There are 2+ notifications with the same target in the same operation\n * - Example: 2+ USERS_CUSTOM notifications (one for creator, one for assignee)\n *\n * This allows distinguishing between multiple similar notifications\n * in the same operation (e.g., \"notify-creator\" vs \"notify-assignee\").\n *\n * Format: lowercase-kebab-case (e.g., \"notify-creator\", \"task-assigned\")\n * Will be appended to auto-generated identifier for notification/template lookup.\n */\n customNotificationRef: z.string().min(1).optional(),\n /**\n * Deliver this notification even when the recipient has switched its channel OFF.\n *\n * Only meaningful on a target that is suppressible in the first place — `USER_SELF` and\n * `USERS_CUSTOM` (see `userNotificationTargetIsSuppressibleByRecipientPreference`). On a\n * role-addressed target the preference never applied, so this flag changes nothing there.\n *\n * The narrow escape, for the case the target axis cannot express: a message that reaches a\n * person about their OWN affairs and is nevertheless a security notice they should not be able\n * to silence — a credential minted or destroyed on their account, an authentication factor\n * changed. Those are the alerts a person most needs when they did NOT perform the action.\n *\n * Author it with the reason at the site. It is deliberately not a default and deliberately not\n * derived: \"is this alert one a compromised account's owner must still receive?\" is a judgement\n * about the message, and inventing a rule for it would be a rule nobody could check.\n */\n alwaysDeliver: z.boolean().optional(),\n});\n\n// --- Channel-specific variants ---\n\n/** EMAIL channel — template-oriented (email-specific fields handled by email templates) */\nexport const UserNotificationDefinition_EmailSchema = UserNotificationDefinition_BaseSchema.extend({\n channel: z.literal(CoreUserNotificationChannel.EMAIL),\n /**\n * Deliver this email to a raw address read from the current object, rather than\n * to a resolved platform user.\n *\n * When set, the recipient is `currentObject[recipientEmailField]` (a top-level\n * string field — e.g. `'email'`). The dispatcher sends a single email directly to\n * that address using the application's default locale, BYPASSING the `userId`-based\n * `target` resolution entirely.\n *\n * This is the framework's mechanism for notifying a party who is **not (yet) a\n * platform user** — an organization-invitation invitee, an inbound lead — for whom\n * no `userId` exists. Without it, the only email recipients the dispatcher can\n * resolve are members/initiators by id (`fetchUserContext(userId).email`).\n *\n * When this is set, `target` no longer selects the recipient; it is retained only\n * to (a) classify the notification, (b) drive the email `templateRef` derivation,\n * and (c) route the dashboard URL (admin app vs main app). Choose a `target` whose\n * dashboard-routing class matches the recipient (e.g. `USER_SELF` for a main-app\n * link).\n *\n * All other context is built identically to a user-targeted email (organization\n * name, initiator name, and the token `acceptUrl` enricher), so token-bearing\n * emails such as invitations still carry their `<frontendBase><emailLinkPath>?token=`\n * acceptance link.\n */\n recipientEmailField: z.string().trim().min(1).optional(),\n});\n\n/** WEBSOCKET channel — pure WebSocket push (no frontend display) */\nexport const UserNotificationDefinition_WebSocketSchema = UserNotificationDefinition_BaseSchema.extend({\n channel: z.literal(CoreUserNotificationChannel.WEBSOCKET),\n});\n\n/**\n * FRONT_END_SUCCESS channel — frontend display with optional celebration + nextStep.\n *\n * `celebration`: Tells the frontend to render richer feedback than a simple toast.\n * `nextStep`: Suggested next action rendered as a CTA button in the toast or celebration overlay.\n *\n * Example usage in operation config:\n * ```\n * userNotifications: [{\n * identifier: 'first-document-created',\n * target: CoreUserNotificationTarget.USER_SELF,\n * channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n * primaryScope: ResourcePrimaryScope.ORGANIZATIONS,\n * celebration: { mode: CelebrationDisplayMode.OVERLAY },\n * nextStep: { operationRef: 'DOCUMENTS.LIST.default', type: NotificationNextStepType.OPERATION },\n * }]\n * ```\n */\nexport const UserNotificationDefinition_FrontEndSuccessSchema = UserNotificationDefinition_BaseSchema.extend({\n channel: z.literal(CoreUserNotificationChannel.FRONT_END_SUCCESS),\n /** Celebration display hints — triggers richer frontend feedback (overlay/confetti/lottie) */\n celebration: FrontendDisplayHintsCelebrationSchema.optional(),\n /** Suggested next action after operation completes — rendered as CTA in toast or celebration */\n nextStep: FrontendDisplayHintsNextStepSchema.optional(),\n});\n\n/**\n * Final union of all notification channel variants — exactly the channels the dispatcher delivers (#1874).\n *\n * There used to be a fourth member, a catch-all `channel: z.string()` \"for custom channels\". Nothing delivered a\n * custom channel: the dispatcher's `default` arm logged at debug and sent nothing, so `channel: 'slack'` passed\n * validation and every dispatch was silently empty — the class #1799 removed for SMS and push. A channel is now one\n * of `CoreUserNotificationChannel`, and the resource factory parses every declared notification against this schema\n * (`processUserNotifications`), so an unknown one is refused when the configuration is built. A new channel is\n * added by giving it a member here AND a delivery arm in the dispatcher, never by naming it.\n */\nexport const UserNotificationDefinitionSchema = z.union([\n UserNotificationDefinition_EmailSchema,\n UserNotificationDefinition_WebSocketSchema,\n UserNotificationDefinition_FrontEndSuccessSchema,\n])\n /**\n * A declaration must reach somebody, and every field it carries must be read.\n *\n * Each rule below is a declaration the schema used to accept and the dispatcher then ignored, silently:\n *\n * - `userRoles` on a target that never reads it is a filter that does nothing (#495). An email sent by\n * address (`recipientEmailField`) resolves no target at all, so it reads neither `userRoles` nor\n * `userIdsSelector`.\n * - `userIdsSelector` is read by `USERS_CUSTOM` alone; on any other target it is a function nothing calls.\n * - `USERS_CUSTOM` without a `userIdsSelector` resolves nobody.\n * - `INBOUND_CONTACT` on EMAIL resolves nobody by target: the contact is not a user, and is reached only\n * through `recipientEmailField`.\n *\n * The resource factory parses every declaration against this schema, so each is refused when the\n * configuration is built rather than discovered as an email nobody received.\n *\n * Refined on the UNION rather than on the base object, deliberately: the base is `.extend()`ed by\n * every channel variant, and a refinement there would be dropped by each of them — the shape of bug\n * this refinement exists to prevent.\n */\n .superRefine((notification, context) => {\n const sentByAddress = notification.channel === CoreUserNotificationChannel.EMAIL && !!notification.recipientEmailField;\n if (notification.userRoles !== undefined && (sentByAddress || !userNotificationTargetReadsUserRoles(notification.target, notification.channel))) {\n context.addIssue({\n code: 'custom',\n path: ['userRoles'],\n message: sentByAddress\n ? 'userRoles is never read on an email sent to recipientEmailField, which resolves no target. Remove it.'\n : `userRoles is only read for a role-scoped target and would be inert on \"${notification.target}\" `\n + `(channel \"${notification.channel}\"). It selects WHICH roles a role-scoped target reaches; it does not `\n + 'filter the recipients of any other target. Remove it, or address the notification to a role-scoped target.',\n });\n }\n if (notification.userIdsSelector !== undefined && (sentByAddress || notification.target !== CoreUserNotificationTarget.USERS_CUSTOM)) {\n context.addIssue({\n code: 'custom',\n path: ['userIdsSelector'],\n message: sentByAddress\n ? 'userIdsSelector is never called on an email sent to recipientEmailField. Remove it.'\n : `userIdsSelector is only called for the \"${CoreUserNotificationTarget.USERS_CUSTOM}\" target and would be inert on `\n + `\"${notification.target}\". Remove it, or address the notification to \"${CoreUserNotificationTarget.USERS_CUSTOM}\".`,\n });\n }\n if (notification.target === CoreUserNotificationTarget.USERS_CUSTOM && !sentByAddress && notification.userIdsSelector === undefined) {\n context.addIssue({\n code: 'custom',\n path: ['userIdsSelector'],\n message: `The \"${CoreUserNotificationTarget.USERS_CUSTOM}\" target reaches whoever userIdsSelector returns; without one it reaches nobody.`,\n });\n }\n if (notification.target === CoreUserNotificationTarget.INBOUND_CONTACT && notification.channel === CoreUserNotificationChannel.EMAIL && !sentByAddress) {\n context.addIssue({\n code: 'custom',\n path: ['recipientEmailField'],\n message: `An email to the \"${CoreUserNotificationTarget.INBOUND_CONTACT}\" target reaches nobody by target: the contact is `\n + 'not a user of the application. Name the field holding their address in recipientEmailField.',\n });\n }\n });\nexport type UserNotificationDefinition = z.infer<typeof UserNotificationDefinitionSchema>;\n/** @wildo_source:part:end saas.models.notifications.user-notification-definition */\n\n/**\n * M2M Notification Channels\n */\n\n\n\nexport enum M2MNotificationLevel {\n INFO = 'info',\n SUCCESS = 'success',\n ERROR = 'error',\n }\n\nexport enum CoreM2MNotificationChannel {\n WEBHOOK_ORGANIZATION = 'webhook_organization',\n WEBHOOK_APPLICATION = 'webhook_application',\n}\n\n/**\n * An M2M notification channel: exactly the two webhook channels the dispatcher delivers.\n *\n * This accepted any string, and the dispatcher threw \"not implemented\" for anything but the two webhooks — at\n * dispatch, after the write, where the throw also skipped every later M2M notification of the same operation. The\n * resource factory now refuses any other channel when the configuration is built.\n */\nexport const M2MNotificationChannelSchema = z.enum(CoreM2MNotificationChannel);\n\nexport const M2MNotificationDefinitionSchema = z.object({\n identifier: z.string().min(1),\n channel: M2MNotificationChannelSchema,\n level: z.enum(M2MNotificationLevel).optional(),\n});\nexport type M2MNotificationDefinition = z.infer<typeof M2MNotificationDefinitionSchema>;\n\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-owner-organization.shared.schemas.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"application-owner-organization.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/organizations/application-owner-organization.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,iIAAiI;AACjI;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,oBAAY,qCAAqC;IAC/C;;;;;;;;;OASG;IACH,qCAAqC,0CAA0C;IAE/E;;;;;;;;;;;;;;;;OAgBG;IACH,oCAAoC,yCAAyC;IAE7E;;;;;;;;;;;;;;;OAeG;IACH,qCAAqC,0CAA0C;IAE/E;;;;;;;;;;;;OAYG;IACH,+CAA+C,oDAAoD;IAEnG;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,6CAA6C,kDAAkD;CAChG;AACD,+EAA+E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-owner-organization.shared.schemas.js","sourceRoot":"","sources":["../../../src/organizations/application-owner-organization.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,iIAAiI;AACjI;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAN,IAAY,qCA2FX;AA3FD,WAAY,qCAAqC;IAC/C;;;;;;;;;OASG;IACH,wHAA+E,CAAA;IAE/E;;;;;;;;;;;;;;;;OAgBG;IACH,sHAA6E,CAAA;IAE7E;;;;;;;;;;;;;;;OAeG;IACH,wHAA+E,CAAA;IAE/E;;;;;;;;;;;;OAYG;IACH,4IAAmG,CAAA;IAEnG;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,wIAA+F,CAAA;AACjG,CAAC,EA3FW,qCAAqC,KAArC,qCAAqC,QA2FhD;AACD,+EAA+E","sourcesContent":["/**\n * The application-owner organization — refusal codes and the operator promotion contract (#1054).\n *\n * An application whose `organizationTypes` declare `ownsApplication` on one type has an OWNER\n * ORGANIZATION: the single organization of that type, the one that operates the application. Its\n * singularity is protected at three moments — it cannot be created through an ordinary door, it\n * cannot be promoted into while one exists, and it cannot be deleted — and every refusal carries a\n * stable, client-branchable code declared here.\n *\n * assurance-control: WILDO.ACCESS.ADMINISTRATIVE_CONTINUITY — the organization that operates the\n * application is singular, and the doors that could create a second one, or destroy the only one,\n * refuse rather than leave the application with no operator.\n *\n * ## Why these codes are a shared enum rather than a `reason` string\n *\n * The refusals are `ErrorType.CONFLICT`, and `sanitizeErrorForClient` keeps only an ALLOWLIST of\n * context keys on a CONFLICT — `reason` is not on it. The backend-side `reason` stays (it is the log\n * and audit identity, richer than the wire and free to stay so), but a CLIENT wanting to tell these\n * apart from any other 409 has only the stable `code` key, sourced from an enum in\n * `@wildo-ai/saas-models` so backend and frontend share one definition.\n *\n * This is the trap `organizationMembers.grantOwnership` fell into and the reason the allowlist's own\n * documented rule exists: its two CONFLICTs carry only `reason`, so they are invisible to every\n * client and a caller must regex-parse a message that is free to be reworded.\n *\n * @see AdministrativeContinuityErrorCode — the sibling enum for the two authority floors. Distinct\n * populations: those protect a scope's ADMINISTRATORS, these protect the identity of the\n * organization that owns the application itself.\n */\n\n/** @wildo_source:part:start saas.models.organizations.application-owner-codes facet:layer:shared facet:audience:app-developer */\n/**\n * Why a write against the application-owner organization was refused.\n *\n * Imported from `@wildo-ai/saas-models`. A closed vocabulary with one named runtime source: the\n * refusals, the resource specification's error scenarios and any client branch all derive from this\n * enum rather than re-typing the literals.\n *\n * ## Where you meet it\n *\n * Each refusal is HTTP **409 CONFLICT** and the value rides under the response's stable `code` key.\n * Branch on `code`, never on the message — the message is a human remedy and is free to be reworded,\n * and every other field a backend might have used to carry the reason is stripped from a CONFLICT\n * before it reaches a client.\n *\n * `409` and not `403`/`400` in every case, deliberately: the caller IS authorised and the payload IS\n * valid — the type named is declared, the organization addressed exists. What forbids the write is a\n * fact about the APPLICATION: it is operated by exactly one organization, and that singularity is what\n * each of these writes would break.\n *\n * `403` was the alternative for the creation refusal and is wrong twice over. It would say the caller\n * lacks authority, which is false — a super-administrator is refused by the same rule as a registrant,\n * because the door is the thing that is shut and not the principal. And `sanitizeErrorForClient`\n * strips the whole context from an AUTHORIZATION error, so the `code` below would never reach a\n * client and this enum would be decorative.\n */\nexport enum ApplicationOwnerOrganizationErrorCode {\n /**\n * The application already has an organization of the type that declares `ownsApplication`, and this\n * write would produce a second one.\n *\n * An application is operated by ONE organization; two would make every question that resolves\n * through the marker — whose rows these are, whose credentials were spent — a choice nobody\n * declared. Remedy: use the existing owner organization. If the existing one is the wrong one, that\n * is a data-repair question rather than a creation question, and there is no operation that\n * demotes an owner.\n */\n APPLICATION_OWNER_ORGANIZATION_EXISTS = 'APPLICATION_OWNER_ORGANIZATION_EXISTS',\n\n /**\n * The organization is the application's owner and may not be put on the deletion path.\n *\n * Refused for `requestDeletion` (both variants), for the purge `delete` (both variants), and by the\n * purge batch. Everything the application owns as an operator — the rows its systems of record\n * project, the pipelines that load them — belongs to this organization, so purging it strands them\n * with no tenant and nothing that could re-create one: `Organization.type` is creation-time\n * identity, and there is no door that mints a second owner.\n *\n * SUSPENSION is deliberately NOT refused. Halting the owner organization is incident response, and\n * every read through it then refuses at the ordinary status gate — the same asymmetry the\n * organization-owner floor is built on: a suspended tenant is recoverable, a purged one is not, so\n * the refusal belongs on the irreversible act only.\n *\n * Remedy: if the application is genuinely being decommissioned, remove the `ownsApplication` marker\n * from the declaration first — the refusal is about what the application currently says it needs.\n */\n OWNER_ORGANIZATION_CANNOT_BE_DELETED = 'OWNER_ORGANIZATION_CANNOT_BE_DELETED',\n\n /**\n * An organization of the owner type cannot be created through this door.\n *\n * The refusal is by DOOR, not by count: **no** service-tier `CREATE` may produce the owner\n * organization, whether or not one exists yet. Two doors make one — the platform's bootstrap, which\n * seeds the first administrator's organization when the application is initialised, and\n * `organizations.promoteToOwnerOrganization`, which re-types an existing organization under audit.\n *\n * Counting instead would have left a real hole: the marked type declares no `creationPolicy` (the\n * configuration refuses one), the default `CREATE` variant is open to `APP_USER`, and the creation\n * prefix restricts only types that HAVE a creation policy. So before the bootstrap ran, any\n * registrant could have created the owner organization and become its founding owner.\n *\n * Remedy: create an ordinary organization of a non-owner type, or ask a super-administrator to\n * promote an existing organization.\n */\n OWNER_ORGANIZATION_TYPE_NOT_CREATABLE = 'OWNER_ORGANIZATION_TYPE_NOT_CREATABLE',\n\n /**\n * A promotion was asked for and the declaration does not name exactly ONE owner organization type, so\n * there is nothing unambiguous to promote INTO.\n *\n * Its own code rather than a reuse of the three above, because the remedy is in a different place:\n * those are about which ROWS exist, this is about what the DECLARATION says.\n *\n * ONE code, two opposite remedies, and the refusal message says which one you hit: either NO type\n * carries `ownsApplication` (declare one) or SEVERAL do (remove the marker from all but one). They\n * share a code because a client branches identically on both — the declaration is wrong and no\n * promotion can proceed — while a human needs the distinction, which is what the message carries.\n * Reporting the second as \"no type declares it\" would send an operator to add a third.\n */\n APPLICATION_DECLARES_NO_OWNER_ORGANIZATION_TYPE = 'APPLICATION_DECLARES_NO_OWNER_ORGANIZATION_TYPE',\n\n /**\n * The organization cannot be promoted because the owner type would change what its members are or\n * may hold — a dependent policy surface the promotion refuses rather than reconciles.\n *\n * Three mismatches carry this code, and the refusal names which one it hit and the exact values:\n * the owner type grants fewer `userTypes` than the organization's current type (promoting would\n * revoke a global grant from every member); a membership holds a role the owner type does not list\n * in `availableOrgRoles`; or THIS organization is actively managed by a directory — the\n * `DIRECTORY_PROVISIONING` feature is enabled for it and a live SCIM token exists — and the owner\n * type does not declare `scimProvisioning`, so promoting would stop it being reconciled by its IdP.\n *\n * Note the third asks about the ORGANIZATION, not about the two type definitions.\n * `scimProvisioning.enabled` on a type is only the application-wide MOUNT gate (the engine mounts the\n * SCIM controllers when at least one declared type carries it) and says nothing about whether any one\n * tenant is directory-managed — so comparing the two flags would refuse a promotion for every tenant\n * with no directory wired at all, which is most of them.\n *\n * Why refuse rather than revoke-and-regrant: a promotion that changed what people can do while\n * calling itself a re-typing is the kind of silent authority change an access review cannot see.\n * The operation changes the tenant's identity and touches nobody's authority, and this refusal is\n * what keeps that true.\n *\n * Remedy: widen the owner type in `organizationTypes` (add the user types, the roles, or the SCIM\n * binding), run `wildo config reapply-declaration`, then retry.\n */\n OWNER_PROMOTION_INCOMPATIBLE_WITH_TARGET_TYPE = 'OWNER_PROMOTION_INCOMPATIBLE_WITH_TARGET_TYPE',\n}\n/** @wildo_source:part:end saas.models.organizations.application-owner-codes */\n"]}
|
|
1
|
+
{"version":3,"file":"application-owner-organization.shared.schemas.js","sourceRoot":"","sources":["../../../../src/organizations/application-owner-organization.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,iIAAiI;AACjI;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAN,IAAY,qCA2FX;AA3FD,WAAY,qCAAqC;IAC/C;;;;;;;;;OASG;IACH,wHAA+E,CAAA;IAE/E;;;;;;;;;;;;;;;;OAgBG;IACH,sHAA6E,CAAA;IAE7E;;;;;;;;;;;;;;;OAeG;IACH,wHAA+E,CAAA;IAE/E;;;;;;;;;;;;OAYG;IACH,4IAAmG,CAAA;IAEnG;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,wIAA+F,CAAA;AACjG,CAAC,EA3FW,qCAAqC,KAArC,qCAAqC,QA2FhD;AACD,+EAA+E","sourcesContent":["/**\n * The application-owner organization — refusal codes and the operator promotion contract (#1054).\n *\n * An application whose `organizationTypes` declare `ownsApplication` on one type has an OWNER\n * ORGANIZATION: the single organization of that type, the one that operates the application. Its\n * singularity is protected at three moments — it cannot be created through an ordinary door, it\n * cannot be promoted into while one exists, and it cannot be deleted — and every refusal carries a\n * stable, client-branchable code declared here.\n *\n * assurance-control: WILDO.ACCESS.ADMINISTRATIVE_CONTINUITY — the organization that operates the\n * application is singular, and the doors that could create a second one, or destroy the only one,\n * refuse rather than leave the application with no operator.\n *\n * ## Why these codes are a shared enum rather than a `reason` string\n *\n * The refusals are `ErrorType.CONFLICT`, and `sanitizeErrorForClient` keeps only an ALLOWLIST of\n * context keys on a CONFLICT — `reason` is not on it. The backend-side `reason` stays (it is the log\n * and audit identity, richer than the wire and free to stay so), but a CLIENT wanting to tell these\n * apart from any other 409 has only the stable `code` key, sourced from an enum in\n * `@wildo-ai/saas-models` so backend and frontend share one definition.\n *\n * This is the trap `organizationMembers.grantOwnership` fell into and the reason the allowlist's own\n * documented rule exists: its two CONFLICTs carry only `reason`, so they are invisible to every\n * client and a caller must regex-parse a message that is free to be reworded.\n *\n * @see AdministrativeContinuityErrorCode — the sibling enum for the two authority floors. Distinct\n * populations: those protect a scope's ADMINISTRATORS, these protect the identity of the\n * organization that owns the application itself.\n */\n\n/** @wildo_source:part:start saas.models.organizations.application-owner-codes facet:layer:shared facet:audience:app-developer */\n/**\n * Why a write against the application-owner organization was refused.\n *\n * Imported from `@wildo-ai/saas-models`. A closed vocabulary with one named runtime source: the\n * refusals, the resource specification's error scenarios and any client branch all derive from this\n * enum rather than re-typing the literals.\n *\n * ## Where you meet it\n *\n * Each refusal is HTTP **409 CONFLICT** and the value rides under the response's stable `code` key.\n * Branch on `code`, never on the message — the message is a human remedy and is free to be reworded,\n * and every other field a backend might have used to carry the reason is stripped from a CONFLICT\n * before it reaches a client.\n *\n * `409` and not `403`/`400` in every case, deliberately: the caller IS authorised and the payload IS\n * valid — the type named is declared, the organization addressed exists. What forbids the write is a\n * fact about the APPLICATION: it is operated by exactly one organization, and that singularity is what\n * each of these writes would break.\n *\n * `403` was the alternative for the creation refusal and is wrong twice over. It would say the caller\n * lacks authority, which is false — a super-administrator is refused by the same rule as a registrant,\n * because the door is the thing that is shut and not the principal. And `sanitizeErrorForClient`\n * strips the whole context from an AUTHORIZATION error, so the `code` below would never reach a\n * client and this enum would be decorative.\n */\nexport enum ApplicationOwnerOrganizationErrorCode {\n /**\n * The application already has an organization of the type that declares `ownsApplication`, and this\n * write would produce a second one.\n *\n * An application is operated by ONE organization; two would make every question that resolves\n * through the marker — whose rows these are, whose credentials were spent — a choice nobody\n * declared. Remedy: use the existing owner organization. If the existing one is the wrong one, that\n * is a data-repair question rather than a creation question, and there is no operation that\n * demotes an owner.\n */\n APPLICATION_OWNER_ORGANIZATION_EXISTS = 'APPLICATION_OWNER_ORGANIZATION_EXISTS',\n\n /**\n * The organization is the application's owner and may not be put on the deletion path.\n *\n * Refused for `requestDeletion` (both variants), for the purge `delete` (both variants), and by the\n * purge batch. Everything the application owns as an operator — the rows its systems of record\n * project, the pipelines that load them — belongs to this organization, so purging it strands them\n * with no tenant and nothing that could re-create one: `Organization.type` is creation-time\n * identity, and there is no door that mints a second owner.\n *\n * SUSPENSION is deliberately NOT refused. Halting the owner organization is incident response, and\n * every read through it then refuses at the ordinary status gate — the same asymmetry the\n * organization-owner floor is built on: a suspended tenant is recoverable, a purged one is not, so\n * the refusal belongs on the irreversible act only.\n *\n * Remedy: if the application is genuinely being decommissioned, remove the `ownsApplication` marker\n * from the declaration first — the refusal is about what the application currently says it needs.\n */\n OWNER_ORGANIZATION_CANNOT_BE_DELETED = 'OWNER_ORGANIZATION_CANNOT_BE_DELETED',\n\n /**\n * An organization of the owner type cannot be created through this door.\n *\n * The refusal is by DOOR, not by count: **no** service-tier `CREATE` may produce the owner\n * organization, whether or not one exists yet. Two doors make one — the platform's bootstrap, which\n * seeds the first administrator's organization when the application is initialised, and\n * `organizations.promoteToOwnerOrganization`, which re-types an existing organization under audit.\n *\n * Counting instead would have left a real hole: the marked type declares no `creationPolicy` (the\n * configuration refuses one), the default `CREATE` variant is open to `APP_USER`, and the creation\n * prefix restricts only types that HAVE a creation policy. So before the bootstrap ran, any\n * registrant could have created the owner organization and become its founding owner.\n *\n * Remedy: create an ordinary organization of a non-owner type, or ask a super-administrator to\n * promote an existing organization.\n */\n OWNER_ORGANIZATION_TYPE_NOT_CREATABLE = 'OWNER_ORGANIZATION_TYPE_NOT_CREATABLE',\n\n /**\n * A promotion was asked for and the declaration does not name exactly ONE owner organization type, so\n * there is nothing unambiguous to promote INTO.\n *\n * Its own code rather than a reuse of the three above, because the remedy is in a different place:\n * those are about which ROWS exist, this is about what the DECLARATION says.\n *\n * ONE code, two opposite remedies, and the refusal message says which one you hit: either NO type\n * carries `ownsApplication` (declare one) or SEVERAL do (remove the marker from all but one). They\n * share a code because a client branches identically on both — the declaration is wrong and no\n * promotion can proceed — while a human needs the distinction, which is what the message carries.\n * Reporting the second as \"no type declares it\" would send an operator to add a third.\n */\n APPLICATION_DECLARES_NO_OWNER_ORGANIZATION_TYPE = 'APPLICATION_DECLARES_NO_OWNER_ORGANIZATION_TYPE',\n\n /**\n * The organization cannot be promoted because the owner type would change what its members are or\n * may hold — a dependent policy surface the promotion refuses rather than reconciles.\n *\n * Three mismatches carry this code, and the refusal names which one it hit and the exact values:\n * the owner type grants fewer `userTypes` than the organization's current type (promoting would\n * revoke a global grant from every member); a membership holds a role the owner type does not list\n * in `availableOrgRoles`; or THIS organization is actively managed by a directory — the\n * `DIRECTORY_PROVISIONING` feature is enabled for it and a live SCIM token exists — and the owner\n * type does not declare `scimProvisioning`, so promoting would stop it being reconciled by its IdP.\n *\n * Note the third asks about the ORGANIZATION, not about the two type definitions.\n * `scimProvisioning.enabled` on a type is only the application-wide MOUNT gate (the engine mounts the\n * SCIM controllers when at least one declared type carries it) and says nothing about whether any one\n * tenant is directory-managed — so comparing the two flags would refuse a promotion for every tenant\n * with no directory wired at all, which is most of them.\n *\n * Why refuse rather than revoke-and-regrant: a promotion that changed what people can do while\n * calling itself a re-typing is the kind of silent authority change an access review cannot see.\n * The operation changes the tenant's identity and touches nobody's authority, and this refusal is\n * what keeps that true.\n *\n * Remedy: widen the owner type in `organizationTypes` (add the user types, the roles, or the SCIM\n * binding), run `wildo config reapply-declaration`, then retry.\n */\n OWNER_PROMOTION_INCOMPATIBLE_WITH_TARGET_TYPE = 'OWNER_PROMOTION_INCOMPATIBLE_WITH_TARGET_TYPE',\n}\n/** @wildo_source:part:end saas.models.organizations.application-owner-codes */\n"]}
|
package/dist/esm/organizations/organization-features.shared.resources-config.schemas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organization-features.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"organization-features.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/organizations/organization-features.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAGrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAAoF,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAW/J,oBAAY,+BAA+B;IACzC,cAAc,mBAAmB;IACjC,eAAe,oBAAoB;IACnC,cAAc,mBAAmB;CAClC;AAED,eAAO,MAAM,iDAAiD;;;iBAG5D,CAAC;AAEH,eAAO,MAAM,kDAAkD;;;iBAG7D,CAAC;AAEH,eAAO,MAAM,iDAAiD;;iBAE5D,CAAC;AAQH,KAAK,kCAAkC,GACnC,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,CAAC;AAKjC,eAAO,MAAM,+DAA+D,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;kBAiL5H,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organization-features.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../src/organizations/organization-features.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Organization Features Shared Resource Configuration\n *\n * Resource configuration for organization feature management.\n * Controls which features are available to organizations.\n */\n\nimport { z } from 'zod';\nimport { CoreFeature } from './organization-features.shared.schemas';\nimport { OrganizationFeaturesSchema, ScopeFeaturesWithOverridesSchema } from '../features/scope-features.shared.schemas';\n\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceOperationReversibility, ResourcePrimaryScope, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { CoreUserNotificationTarget, CoreUserNotificationChannel } from '../notifications/notifications.shared.schemas';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\n\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\n\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\n\n// Custom operations enum for organization features\nexport enum OrganizationFeatures_Operations {\n ENABLE_FEATURE = 'enable_feature',\n DISABLE_FEATURE = 'disable_feature',\n RESET_FEATURES = 'reset_features', // Reset to default features\n}\n\nexport const OrganizationFeaturesEnableFeatureRequestDtoSchema = z.object({\n featureId: z.enum(CoreFeature).describe('The feature to switch on. It is added to this scope\\'s manual overrides and taken off its removed list, so it stays on through billing changes.'),\n reason: z.string().max(500).optional().describe('Why the feature is being switched on. Recorded on the audit trail with the change.')\n});\n\nexport const OrganizationFeaturesDisableFeatureRequestDtoSchema = z.object({\n featureId: z.enum(CoreFeature).describe('The feature to switch off. It is added to this scope\\'s removed list and taken off its added list, so it stays off through billing changes.'),\n reason: z.string().min(1).max(500).describe('Why the feature is being switched off. Recorded on the audit trail with the change.')\n});\n\nexport const OrganizationFeaturesResetFeaturesRequestDtoSchema = z.object({\n reason: z.string().min(1).max(500).describe('Why every manual override is being cleared. Recorded on the audit trail with the change.')\n});\n\nconst ORGANIZATION_FEATURES_SORT_FIELDS = ['features'];\n\nconst ORGANIZATION_FEATURES_FILTER_FIELDS = {\n features: z.enum(CoreFeature),\n};\n\ntype OrganizationFeaturesCoreOperations =\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.DELETE;\n\n/*\nOrganization Features Resource Configuration Factory\n*/\nexport const organizationFeaturesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n typeof OrganizationFeatures_Operations,\n OrganizationFeaturesCoreOperations,\n typeof OrganizationFeaturesSchema\n>({\n mainSchema: OrganizationFeaturesSchema,\n resourceIdentifier: CoreResourceType.ORGANIZATION_FEATURES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.ORGANIZATION_FEATURES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n /*\n * The framework may materialise this scope's row on a caller's behalf — the same opt-in, for the\n * same reason, as the APPLICATION_FEATURES twin beside it.\n *\n * `systemAccessPolicy.create: ALLOWED` is what #1179's seam reads before materialising a\n * context-addressed singleton the caller never named, so an administrator can START setting a\n * tenant's entitlement overrides instead of being 404ed for the framework's own omission. The row\n * written is the scope foreign key and nothing else; this resource's schema fills the rest.\n *\n * NOTE, measured 2026-09-19: this does NOT make a READ materialise. That seam is reached for\n * UPDATE and DELETE only — extending it to READ was tried and reverted, because a probe of the\n * running backend showed the read route never enters it. A tenant whose row is still absent\n * therefore still 404s when the Entitlements pane reads it; making that row EXIST is a seeding\n * question, not an access-policy one.\n */\n systemAccessPolicy: {\n read: ResourceSystemAccessMode.ALLOWED,\n create: ResourceSystemAccessMode.ALLOWED,\n },\n\n coreOperations: [\n CoreResourceOperation.CREATE,\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition onParentDelete\n // cascade so the row is physically removed when its org is deleted. Without it the\n // cascade throws ErrorType.CONFIGURATION on any org that has a features row.\n CoreResourceOperation.DELETE\n ],\n\n customOperation: OrganizationFeatures_Operations,\n\n // assurance-control: WILDO.ENTITLEMENT.NO_SELF_GRANT — a tenant cannot widen its own entitlements.\n //\n // This ledger IS the organization's entitlement set, so the only thing standing between a tenant\n // administrator and an arbitrary feature grant is the role on each WRITE below. Every one of them —\n // CREATE, UPDATE, DELETE, ENABLE_FEATURE, DISABLE_FEATURE, RESET_FEATURES — is\n // `APP_ADMIN_SUPER_ADMIN`, a role no organization-scope entry can confer, while READ and SEARCH are\n // deliberately `ORG_MEMBER` so a tenant can see what it has without being able to change it.\n //\n // Field-level protection is NOT available here and would be the wrong instrument if it were: the\n // super-admin path has to write these same fields, so `excludeFromUpdate` would block the legitimate\n // grant along with the illegitimate one. The role gate is therefore the whole control, and adding a\n // tenant role to any write below removes it entirely rather than weakening it. Pinned by\n // `security-sensitive-operation-reachability.backend.test.ts`, which asserts the exact role array.\n operationsConfiguration: {\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n }\n ],\n },\n\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER], // Org members can view features\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: true,\n searchableFields: ['features'],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: ORGANIZATION_FEATURES_FILTER_FIELDS,\n sortFields: ORGANIZATION_FEATURES_SORT_FIELDS,\n maxPaginatedResultPerPageLimit: 50,\n }\n ],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN], // Only super admins can update organization features\n riskLevel: ResourceOperationRiskLevel.HIGH,\n requestDto: ScopeFeaturesWithOverridesSchema.partial(),\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY): powers the composition onParentDelete cascade,\n // not a public API surface — the ledger is reset, never DELETEd, over HTTP.\n // Role is APP_ADMIN_SUPER_ADMIN (matching this ledger's CREATE/UPDATE), NOT the\n // org-scope-admin (ORG_ADMIN) used by other org-scoped onParentDelete adopters\n // (progression/guidance/preferences): the features ledger is super-admin-managed —\n // org-admins have no authority over it — so its teardown tracks the super-admin tier.\n // Ratified 2026-07-11; the role is inert here anyway (REPOSITORY_ONLY → the cascade\n // calls repository.delete() with no role check). Do NOT \"align\" this to ORG_ADMIN.\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n\n [OrganizationFeatures_Operations.ENABLE_FEATURE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN], // Only super admins can enable features\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.UPDATE_MANY,\n requestDto: OrganizationFeaturesEnableFeatureRequestDtoSchema,\n // The collection-scoped route shape is UPDATE_MANY-like, but the\n // override-all implementation persists and returns the singleton\n // feature ledger. Keep the wire response owned here rather than\n // inheriting the per-row response an UPDATE_MANY answers.\n customResponseDto: ScopeFeaturesWithOverridesSchema,\n }\n ],\n },\n\n [OrganizationFeatures_Operations.DISABLE_FEATURE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN], // Only super admins can disable features\n riskLevel: ResourceOperationRiskLevel.HIGH,\n resourceOperationLike: CoreResourceOperation.UPDATE_MANY,\n requestDto: OrganizationFeaturesDisableFeatureRequestDtoSchema,\n customResponseDto: ScopeFeaturesWithOverridesSchema,\n }\n ],\n },\n\n [OrganizationFeatures_Operations.RESET_FEATURES]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN], // Only super admins can reset features\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n // IRREVERSIBLE: Clears every override on the organization. No backup of the list exists.\n // This is what admits it to the danger zone; risk alone no longer does.\n reversibility: ResourceOperationReversibility.IRREVERSIBLE,\n resourceOperationLike: CoreResourceOperation.UPDATE_MANY,\n requestDto: OrganizationFeaturesResetFeaturesRequestDtoSchema,\n customResponseDto: ScopeFeaturesWithOverridesSchema,\n }\n ],\n }\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"organization-features.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/organizations/organization-features.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Organization Features Shared Resource Configuration\n *\n * Resource configuration for organization feature management.\n * Controls which features are available to organizations.\n */\n\nimport { z } from 'zod';\nimport { CoreFeature } from './organization-features.shared.schemas';\nimport { OrganizationFeaturesSchema, ScopeFeaturesWithOverridesSchema } from '../features/scope-features.shared.schemas';\n\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceOperationReversibility, ResourcePrimaryScope, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { CoreUserNotificationTarget, CoreUserNotificationChannel } from '../notifications/notifications.shared.schemas';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\n\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\n\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\n\n// Custom operations enum for organization features\nexport enum OrganizationFeatures_Operations {\n ENABLE_FEATURE = 'enable_feature',\n DISABLE_FEATURE = 'disable_feature',\n RESET_FEATURES = 'reset_features', // Reset to default features\n}\n\nexport const OrganizationFeaturesEnableFeatureRequestDtoSchema = z.object({\n featureId: z.enum(CoreFeature).describe('The feature to switch on. It is added to this scope\\'s manual overrides and taken off its removed list, so it stays on through billing changes.'),\n reason: z.string().max(500).optional().describe('Why the feature is being switched on. Recorded on the audit trail with the change.')\n});\n\nexport const OrganizationFeaturesDisableFeatureRequestDtoSchema = z.object({\n featureId: z.enum(CoreFeature).describe('The feature to switch off. It is added to this scope\\'s removed list and taken off its added list, so it stays off through billing changes.'),\n reason: z.string().min(1).max(500).describe('Why the feature is being switched off. Recorded on the audit trail with the change.')\n});\n\nexport const OrganizationFeaturesResetFeaturesRequestDtoSchema = z.object({\n reason: z.string().min(1).max(500).describe('Why every manual override is being cleared. Recorded on the audit trail with the change.')\n});\n\nconst ORGANIZATION_FEATURES_SORT_FIELDS = ['features'];\n\nconst ORGANIZATION_FEATURES_FILTER_FIELDS = {\n features: z.enum(CoreFeature),\n};\n\ntype OrganizationFeaturesCoreOperations =\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.DELETE;\n\n/*\nOrganization Features Resource Configuration Factory\n*/\nexport const organizationFeaturesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n typeof OrganizationFeatures_Operations,\n OrganizationFeaturesCoreOperations,\n typeof OrganizationFeaturesSchema\n>({\n mainSchema: OrganizationFeaturesSchema,\n resourceIdentifier: CoreResourceType.ORGANIZATION_FEATURES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.ORGANIZATION_FEATURES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n /*\n * The framework may materialise this scope's row on a caller's behalf — the same opt-in, for the\n * same reason, as the APPLICATION_FEATURES twin beside it.\n *\n * `systemAccessPolicy.create: ALLOWED` is what #1179's seam reads before materialising a\n * context-addressed singleton the caller never named, so an administrator can START setting a\n * tenant's entitlement overrides instead of being 404ed for the framework's own omission. The row\n * written is the scope foreign key and nothing else; this resource's schema fills the rest.\n *\n * NOTE, measured 2026-09-19: this does NOT make a READ materialise. That seam is reached for\n * UPDATE and DELETE only — extending it to READ was tried and reverted, because a probe of the\n * running backend showed the read route never enters it. A tenant whose row is still absent\n * therefore still 404s when the Entitlements pane reads it; making that row EXIST is a seeding\n * question, not an access-policy one.\n */\n systemAccessPolicy: {\n read: ResourceSystemAccessMode.ALLOWED,\n create: ResourceSystemAccessMode.ALLOWED,\n },\n\n coreOperations: [\n CoreResourceOperation.CREATE,\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition onParentDelete\n // cascade so the row is physically removed when its org is deleted. Without it the\n // cascade throws ErrorType.CONFIGURATION on any org that has a features row.\n CoreResourceOperation.DELETE\n ],\n\n customOperation: OrganizationFeatures_Operations,\n\n // assurance-control: WILDO.ENTITLEMENT.NO_SELF_GRANT — a tenant cannot widen its own entitlements.\n //\n // This ledger IS the organization's entitlement set, so the only thing standing between a tenant\n // administrator and an arbitrary feature grant is the role on each WRITE below. Every one of them —\n // CREATE, UPDATE, DELETE, ENABLE_FEATURE, DISABLE_FEATURE, RESET_FEATURES — is\n // `APP_ADMIN_SUPER_ADMIN`, a role no organization-scope entry can confer, while READ and SEARCH are\n // deliberately `ORG_MEMBER` so a tenant can see what it has without being able to change it.\n //\n // Field-level protection is NOT available here and would be the wrong instrument if it were: the\n // super-admin path has to write these same fields, so `excludeFromUpdate` would block the legitimate\n // grant along with the illegitimate one. The role gate is therefore the whole control, and adding a\n // tenant role to any write below removes it entirely rather than weakening it. Pinned by\n // `security-sensitive-operation-reachability.backend.test.ts`, which asserts the exact role array.\n operationsConfiguration: {\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n }\n ],\n },\n\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER], // Org members can view features\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: true,\n searchableFields: ['features'],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: ORGANIZATION_FEATURES_FILTER_FIELDS,\n sortFields: ORGANIZATION_FEATURES_SORT_FIELDS,\n maxPaginatedResultPerPageLimit: 50,\n }\n ],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN], // Only super admins can update organization features\n riskLevel: ResourceOperationRiskLevel.HIGH,\n requestDto: ScopeFeaturesWithOverridesSchema.partial(),\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY): powers the composition onParentDelete cascade,\n // not a public API surface — the ledger is reset, never DELETEd, over HTTP.\n // Role is APP_ADMIN_SUPER_ADMIN (matching this ledger's CREATE/UPDATE), NOT the\n // org-scope-admin (ORG_ADMIN) used by other org-scoped onParentDelete adopters\n // (progression/guidance/preferences): the features ledger is super-admin-managed —\n // org-admins have no authority over it — so its teardown tracks the super-admin tier.\n // Ratified 2026-07-11; the role is inert here anyway (REPOSITORY_ONLY → the cascade\n // calls repository.delete() with no role check). Do NOT \"align\" this to ORG_ADMIN.\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n\n [OrganizationFeatures_Operations.ENABLE_FEATURE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN], // Only super admins can enable features\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.UPDATE_MANY,\n requestDto: OrganizationFeaturesEnableFeatureRequestDtoSchema,\n // The collection-scoped route shape is UPDATE_MANY-like, but the\n // override-all implementation persists and returns the singleton\n // feature ledger. Keep the wire response owned here rather than\n // inheriting the per-row response an UPDATE_MANY answers.\n customResponseDto: ScopeFeaturesWithOverridesSchema,\n }\n ],\n },\n\n [OrganizationFeatures_Operations.DISABLE_FEATURE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN], // Only super admins can disable features\n riskLevel: ResourceOperationRiskLevel.HIGH,\n resourceOperationLike: CoreResourceOperation.UPDATE_MANY,\n requestDto: OrganizationFeaturesDisableFeatureRequestDtoSchema,\n customResponseDto: ScopeFeaturesWithOverridesSchema,\n }\n ],\n },\n\n [OrganizationFeatures_Operations.RESET_FEATURES]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN], // Only super admins can reset features\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n // IRREVERSIBLE: Clears every override on the organization. No backup of the list exists.\n // This is what admits it to the danger zone; risk alone no longer does.\n reversibility: ResourceOperationReversibility.IRREVERSIBLE,\n resourceOperationLike: CoreResourceOperation.UPDATE_MANY,\n requestDto: OrganizationFeaturesResetFeaturesRequestDtoSchema,\n customResponseDto: ScopeFeaturesWithOverridesSchema,\n }\n ],\n }\n },\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organization-features.shared.schemas.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"organization-features.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/organizations/organization-features.shared.schemas.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AACH,oBAAY,WAAW;IACrB,eAAe,oBAAoB;IACnC,kBAAkB,uBAAuB;IACzC,cAAc,mBAAmB;IACjC,UAAU,eAAe;IACzB,qBAAqB,0BAA0B;IAC/C,sBAAsB,2BAA2B;IACjD;;;;;;OAMG;IACH,oBAAoB,yBAAyB;CAC9C;AAED,oBAAY,WAAW;IACrB,SAAS,cAAc;IACvB,KAAK,UAAc;IACnB,QAAQ,aAAc;IACtB,SAAS,cAAc;CACxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organization-features.shared.schemas.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"organization-features.shared.schemas.js","sourceRoot":"","sources":["../../../../src/organizations/organization-features.shared.schemas.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,WAeX;AAfD,WAAY,WAAW;IACrB,kDAAmC,CAAA;IACnC,wDAAyC,CAAA;IACzC,gDAAiC,CAAA;IACjC,wCAAyB,CAAA;IACzB,8DAA+C,CAAA;IAC/C,gEAAiD,CAAA;IACjD;;;;;;OAMG;IACH,4DAA6C,CAAA;AAC/C,CAAC,EAfW,WAAW,KAAX,WAAW,QAetB;AAED,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,sCAAuB,CAAA;IACvB,8BAAmB,CAAA;IACnB,oCAAsB,CAAA;IACtB,sCAAuB,CAAA;AACzB,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB","sourcesContent":["\n/**\n * Core Features - engine business features (not tied to external providers).\n * \n * Dropped from old CoreOrganizationFeature:\n * - PRIORITY_SUPPORT → modeled as a custom app feature (not engine-level)\n * - CUSTOM_INTEGRATIONS → modeled by provider declarations, not entitlement features\n * - ADVANCED_PERMISSIONS → handled by RBAC system, not feature gating\n */\nexport enum CoreFeature {\n CUSTOM_BRANDING = 'CUSTOM_BRANDING',\n ADVANCED_ANALYTICS = 'ADVANCED_ANALYTICS',\n SINGLE_SIGN_ON = 'SINGLE_SIGN_ON',\n AUDIT_LOGS = 'AUDIT_LOGS',\n SECURITY_EVENT_EXPORT = 'SECURITY_EVENT_EXPORT',\n DIRECTORY_PROVISIONING = 'DIRECTORY_PROVISIONING',\n /**\n * Gates outbound delivery of M2M (machine-to-machine) webhooks fired\n * by resource operations whose spec carries a `WEBHOOK_ORGANIZATION`\n * or `WEBHOOK_APPLICATION` notification channel. A single feature\n * gates both scope variants — the admin enables it once per org/app\n * and the dispatcher checks via `featureGate.has(scope, ...)`.\n */\n M2M_WEBHOOK_DELIVERY = 'M2M_WEBHOOK_DELIVERY',\n}\n\nexport enum SupportType {\n COMMUNITY = 'community',\n EMAIL = 'email',\n PRIORITY = 'priority',\n DEDICATED = 'dedicated'\n}\n"]}
|
package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organization-members.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"organization-members.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/organizations/organization-members.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAEL,wBAAwB,EACzB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAAoD,oBAAoB,EAA+B,MAAM,uCAAuC,CAAC;AAO5J,OAAO,EACL,wBAAwB,EAEzB,MAAM,6DAA6D,CAAC;AAMrE,OAAO,EAAkB,cAAc,EAAE,MAAM,iDAAiD,CAAC;AAmCjG,oBAAY,8BAA8B;IACxC,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,eAAe,mBAAmB;CACnC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,+CAA+C;;;CAK3B,CAAC;AA4DlC,KAAK,iCAAiC,GAClC,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,KAAK,GAE3B,qBAAqB,CAAC,WAAW,CAAC;AAKtC,eAAO,MAAM,8DAA8D,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;;;;;;mBAghB3H,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organization-members.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../src/organizations/organization-members.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Organization Members Shared Resource Configuration\n *\n * Resource configuration for organization member management.\n * Comprehensive member lifecycle and role management.\n */\n\nimport { z } from 'zod';\nimport {\n OrganizationMemberSchema,\n OrganizationMemberStatus,\n} from './organization-members.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourcePrimaryScope, ResourceRelationship, DefaultDeleteResponseSchema } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { CoreUserNotificationTarget, CoreUserNotificationChannel } from '../notifications/notifications.shared.schemas';\n\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport {\n CoreConsumableTokenTypes,\n ConsumableToken_ConsumptionMode,\n} from '../security/authentications/consumable-token.shared.schemas';\nimport type {\n TokenRevocationConfig,\n} from '../security/authentications/consumable-token.shared.schemas';\nimport { DurationUnit } from '@wildo-ai/zod-decorators';\n\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\nimport { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas';\n\n// Custom operations enum for organization members.\n// NOTE: cross-organization member transfer is intentionally NOT a framework\n// capability — moving a member between organizations is a tenant-boundary\n// crossing the framework does not sanction. Re-invite the identity in the\n// target organization instead.\n//\n// A membership row IS the invitation (there is no separate invitation resource):\n// - CREATE = invite (creates an `INVITED` row + mints the accept token).\n// - REVOKE = inviter/admin cancels a still-`INVITED` membership.\n// - RESEND = re-mint + re-send the accept token for an `INVITED` membership.\n// - SUSPEND/REACTIVATE = lifecycle of an ACTIVE/SUSPENDED member.\n// Invitee-side accept/reject is the tokenized `/auth/acceptInvitation` flow\n// (auth controller + `Auth_Invitation` screen), NOT a resource operation.\n//\n// ROLE CHANGES ARE `UPDATE`, NOT A DEDICATED VERB. `PROMOTE` / `DEMOTE` were declared here\n// as `ORG_ADMIN`-gated `riskLevel: HIGH` operations taking `{ newRole, reason }`, and were\n// removed on 2026-08-01: they were ROUTED but never implemented, so the request fell through\n// to the generic core UPDATE, which persists only fields the resource schema declares.\n// `newRole` is not one, so every call answered **HTTP 200 having changed nothing** — and the\n// dangerous direction is DEMOTE: an admin demotes a compromised account, is told 200 OK, and\n// the account keeps its privileges. Re-declaring an explicit role-change verb is legitimate,\n// but only WITH a custom implementation that writes `roles` and calls\n// `assertRequestedRolesWithinCallerCeiling` — a custom implementation is addressed by an EXACT\n// operation path, so it does NOT inherit the UPDATE variant's ceiling gate. Follow the\n// organization-units MOVE/ARCHIVE pattern (a `prefixCoreOperations` hook returning the field\n// patch the core UPDATE persists). See\n// the 2026-08-01 routed-but-unimplemented operation sweep (#1275).\n//\n// GRANT_OWNERSHIP is the ONE exception to \"role changes are UPDATE\", and it exists for a reason\n// UPDATE structurally cannot serve: it is the only operation on this resource a caller who is NOT a\n// member of the organization may perform. See its config entry below.\nexport enum OrganizationMembers_Operations {\n SUSPEND = 'suspend',\n REACTIVATE = 'reactivate',\n REVOKE = 'revoke',\n RESEND = 'resend',\n GRANT_OWNERSHIP = 'grantOwnership',\n}\n\n/**\n * One semantic definition for invalidating an organization invitation.\n *\n * REVOKE attaches it declaratively, so HTTP and trusted service callers enter\n * the same transactional revocation pipeline. Ordinary DELETE is\n * intentionally excluded: it removes a non-INVITED membership, which has no\n * invitation token to revoke.\n */\nexport const ORGANIZATION_MEMBER_INVITATION_TOKEN_REVOCATION = {\n tokenTypes: [\n CoreConsumableTokenTypes.ORGANIZATION_MEMBER_INVITATION,\n ],\n relatedIdField: '_id',\n} satisfies TokenRevocationConfig;\n\n/**\n * One predicate owns both invitation-token generation and invitation-email\n * dispatch. Keeping the two declarative side effects on the same named gate\n * prevents the polymorphic CREATE operation from drifting: an ACTIVE direct\n * add must produce neither an accept token nor an invitation email.\n */\nconst isPendingOrganizationMemberInvitation = ({\n currentObject,\n}: {\n currentObject: Record<string, unknown>;\n}): boolean =>\n currentObject.status === OrganizationMemberStatus.INVITED;\n\n/**\n * REACTIVATE's notifications say the member \"can now access organization resources again\", which is true only when\n * the membership came back ACTIVE. A service-provider membership whose relationship has ended, or whose person is no\n * longer assigned, lands INACTIVE instead (#1597), and neither the person nor the organization's users may be told\n * otherwise. Evaluated against the row as written.\n */\nconst isRestoredToActiveMembership = ({\n currentObject,\n}: {\n currentObject: Record<string, unknown>;\n}): boolean =>\n currentObject.status === OrganizationMemberStatus.ACTIVE;\n\n/**\n * The recipient of a membership's own status notice: the member whose membership was suspended or\n * reactivated (#1870).\n *\n * `USERS_CUSTOM` rather than `USER_SELF`, and the difference is the whole defect: `USER_SELF` is the\n * INITIATOR — the administrator who pressed the button — so \"your membership was suspended\" landed in\n * the administrator's inbox, and the scheduled reactivation sweep, which has no initiator, told nobody.\n * `ORGANIZATION_USERS` cannot reach the member either: it keeps only ACTIVE memberships, and a suspended\n * member is not one. The row the operation just wrote carries the member's `userId`, so that is the\n * recipient. Same shape as the `users` account-status notices (#1807).\n */\nconst selectMembershipStatusSubject = ({ currentObject }: { currentObject: { userId?: unknown } | null | undefined }): string[] =>\n currentObject?.userId ? [String(currentObject.userId)] : [];\n\n/**\n * Sortable member fields.\n *\n * `role` and `joinedAt` were listed here and neither is a field (#1806): the membership carries\n * `roles`, an ARRAY — which has no meaningful sort order on either adapter, so it is not offered —\n * and it records when it was created, not a separate join instant. Both entries were passed to the\n * repository verbatim and silently ignored. The factory now refuses a sort field that is not a field.\n */\nconst ORGANIZATION_MEMBERS_SORT_FIELDS = ['status', 'createdAt'];\n\nconst ORGANIZATION_MEMBERS_FILTER_FIELDS = {\n status: z.enum(OrganizationMemberStatus),\n // `roles` is an array, and a scalar filter on it matches array MEMBERSHIP on both adapters: MongoDB\n // does so natively and the PostgreSQL filter compiler emits a jsonb containment (`roles @> '\"x\"'`).\n // It was declared as `role`, a field no row has, so `?role=ORG_ADMIN` matched nothing (#1806).\n roles: z.string().min(1).describe('Only return members holding this role.'),\n};\n\ntype OrganizationMembersCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.LIST\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.DELETE\n | CoreResourceOperation.COUNT\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY.\n | CoreResourceOperation.UPDATE_MANY;\n\n/*\nOrganization Members Resource Configuration Factory\n*/\nexport const organizationMembersResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n typeof OrganizationMembers_Operations,\n OrganizationMembersCoreOperations,\n typeof OrganizationMemberSchema\n>({\n mainSchema: OrganizationMemberSchema,\n resourceIdentifier: CoreResourceType.ORGANIZATION_MEMBERS,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.ORGANIZATION_MEMBERS],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n // create: invitation-accept was the historical opt-in; now the org-admin INVITE, SSO/SCIM\n // JIT, and org-auto-create-on-registration all create members in-process with explicit\n // `userId` + `organizationId` FKs on a request-context-less EC (stripped by the\n // client-shaped CREATE DTO, re-attached by `createAsSystem`).\n // read/list: the invitee's own pending-invitation inbox reads INVITED rows cross-org\n // BEFORE the invitee is a scoped member — authorized by `userId`-ownership at the\n // entry point (`listMyPendingInvitations`/`loadOwnedPendingInvitation`), not org role.\n // update: invitation ACCEPTANCE flips INVITED → ACTIVE in-process; the invitee is not an\n // org admin, so the status flip goes through the trusted system path.\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED,\n create: ResourceSystemAccessMode.ALLOWED,\n read: ResourceSystemAccessMode.ALLOWED,\n list: ResourceSystemAccessMode.ALLOWED,\n update: ResourceSystemAccessMode.ALLOWED,\n },\n\n /**\n * Subject-export disclosure. The subject's OWN membership rows (org, roles, title) — not other members' data.\n */\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.OBSERVED },\n\n /**\n * Subject erasure RETAINS this row and scrubs the person's contact and professional details.\n *\n * The membership survives because it is the tenant's record of who belonged to it and under what\n * authority; what does not survive is `userEmail` and `userTitle`, the denormalized copies of the\n * person held here so a row can be read without resolving the user.\n *\n * `roles` is deliberately NOT scrubbed. It is this application's authorization vocabulary rather than\n * personal data — the field's own comment says so — and emptying it could leave a tenant with no\n * administrator, which the administrative-continuity floors would refuse, making an erasure fail closed\n * on a tenant. Keeping it means that interaction never arises.\n */\n retentionPolicy: {\n mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,\n },\n\n /**\n * Erasing one of these rows revokes NO session. A membership is a record ABOUT a person's place in a\n * tenant, not the person — their session ends through the `USERS` row, which is `SELF_PRINCIPAL`.\n */\n dataSubjectPolicy: { kind: ResourceDataSubjectKind.NO_PRINCIPAL },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.LIST,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.CREATE,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.DELETE,\n CoreResourceOperation.COUNT,\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY.\n CoreResourceOperation.UPDATE_MANY,\n ],\n\n customOperation: OrganizationMembers_Operations,\n\n operationsConfiguration: {\n\n /*\n\n * Route-less retention plumbing — INTERNAL_CALL registers no route, so no API surface is added, and it\n\n * must not be REPOSITORY_ONLY: the retention primitives resolve through `getServiceOperationPathDefault`,\n\n * which matches only INTERNAL_CALL / API_CALL. LIST is LOW (a read-shaped op may not claim the\n\n * HIGH/CRITICAL band, which carries an audit-emission obligation); UPDATE_MANY is CRITICAL — it is the\n\n * verb the impersonalize writer uses to stamp the retention markers.\n\n */\n\n [CoreResourceOperation.UPDATE_MANY]: {\n\n variants: [{\n\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n\n isDefault: true,\n\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n\n }],\n\n },\n\n [CoreResourceOperation.COUNT]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n // CREATE is POLYMORPHIC — two intents on one op:\n // • INVITE (BRANCH B): the org admin supplies `userEmail` (the strict identity\n // anchor); the CREATE prefix find-or-creates the `User` by it (`PENDING_INVITATION`\n // if new) and FORCES `status: INVITED`. A single-use accept token is minted AFTER the\n // row is created (relatedId = the membership `_id`, STABLE across `INVITED → ACTIVE`\n // so the emailed link never orphans); the pipeline injects it into the invite email and\n // the dispatcher builds the accept link (`emailLinkPath → /invitation?token=…`, consumed\n // by `/auth/acceptInvitation`). No `grantedRoles`: the accept handler reads the\n // membership's own `roles` when it flips the row to ACTIVE.\n // • DIRECT-ADD (BRANCH A): the caller supplies `userId` (founder org-owner grant,\n // SSO-JIT, SCIM) and the row persists `ACTIVE` — there is nothing to accept.\n // Token generation and notification dispatch share one named predicate.\n // The INVITE branch mints one accept token and sends one post-commit email;\n // the ACTIVE direct-add branch does neither.\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_ORG_ROLES.ORG_DELEGATED_INVITE_MEMBERS], // Org admins, or a firm's expert lent INVITE_MEMBERS (#1631)\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n // requestDto auto-derived from decorators (userEmail + roles +\n // organizationUnitsMembership + userTitle; userId/status/invitedByUserId/\n // invitedAt are server-injected via `.excludeFromCreate()`).\n tokenGeneration: {\n tokenType: CoreConsumableTokenTypes.ORGANIZATION_MEMBER_INVITATION,\n consumptionMode: ConsumableToken_ConsumptionMode.SINGLE_USE,\n expiresIn: { value: 7, unit: DurationUnit.DAYS },\n relatedIdField: '_id',\n emailLinkPath: '/invitation',\n // Mint the accept token for real invites only — never for an ACTIVE direct-add.\n condition: isPendingOrganizationMemberInvitation,\n },\n }\n ],\n // Deliver the invite email to the INVITEE (`userEmail`) via the\n // email-by-address path — the invitee may be a brand-new `PENDING_INVITATION`\n // user with no session. Carries the `acceptUrl` (`/invitation?token=…`) built\n // from the token minted above. `target: USER_SELF` is retained only so the\n // derived template ref stays `…create.user-self` and the accept link routes to\n // the main (non-admin) app.\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.EMAIL,\n recipientEmailField: 'userEmail',\n condition: isPendingOrganizationMemberInvitation,\n }\n ]\n },\n\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER], // Org members can read member info\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.LIST]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER], // Org members can list organization members\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: true,\n // `userEmail` is a denormalized, immutable own-field (mirror of the linked\n // user's email, captured at membership creation). First/last name are NOT\n // denormalized onto the member row — they live on `USER_PROFILES` and are\n // mutable there — so they are searched RELATIONALLY: the framework runs a\n // secondary match on `USER_PROFILES` (its own searchable fields) and folds\n // the matching `userId`s into an `$in` on this row's `userId`. The member\n // query stays org-scoped, so this is tenant-safe; names are never stale\n // because they are read live from the profile at search time. See\n // SearchableRelationDescriptor in resources-config.shared.schemas.ts.\n searchableFields: [\n 'userEmail',\n {\n localField: 'userId',\n relatedResource: CoreResourceType.USER_PROFILES,\n relatedJoinField: 'userId',\n fields: ['firstName', 'lastName'],\n },\n ],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: ORGANIZATION_MEMBERS_FILTER_FIELDS,\n sortFields: ORGANIZATION_MEMBERS_SORT_FIELDS,\n maxPaginatedResultPerPageLimit: 50,\n }\n ],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN], // Org admins can update member details\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n // requestDto auto-derived from decorators\n //\n // Ordinary UPDATE remains audited below the HIGH/CRITICAL floor: editing member details\n // is MEDIUM risk for the UI, but changing roles still requires privilege evidence.\n // The registered UPDATE implementation also emits ORGANIZATION_MEMBER_ROLE_CHANGED after\n // a durable role change, with previous, requested and resulting roles. That specialized\n // event complements the automatic operation event; it is not an unimplemented producer.\n //\n // GRANT_OWNERSHIP is a separate named role-change path. Its UPDATE-like core behavior does\n // not inherit UPDATE's custom hooks: registration resolves the exact operation identity.\n // Its CRITICAL risk triggers RESOURCE_OPERATION_PERFORMED automatically, with changed\n // role sets carried by the roles field's audit-evidence marker. Queries covering ownership\n // repair must include that operation family, not only the specialized role-change event.\n //\n // assurance-control: WILDO.ACCESS.PRIVILEGE_EVIDENCE — evidence of privilege grant/revocation.\n auditableEvent: { auditBelowRiskFloor: true },\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n }\n ]\n },\n\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_ORG_ROLES.ORG_DELEGATED_MANAGE_RELATIONSHIP_EXPERTS], // Org admins; a firm's expert lent MANAGE_RELATIONSHIP_EXPERTS, on its own relationship's experts only (#1631)\n riskLevel: ResourceOperationRiskLevel.HIGH,\n // Accepted/non-pending members use ordinary DELETE. A pending invite\n // is cancelled through REVOKE, which atomically revokes its accept\n // token. Keeping the vocabularies disjoint avoids making every\n // active-member removal token-coupled.\n enabledCondition: ({ currentObject }) =>\n currentObject.status !== OrganizationMemberStatus.INVITED,\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n }\n ]\n },\n\n /**\n * The higher-tier repair door for the organization-owner floor — the second half of the\n * industry pattern described in `.claude/rules/administrative-continuity-floors.md`.\n *\n * ## Why this cannot be UPDATE\n *\n * The floor refuses to let the last `ORG_OWNER` be removed, demoted or deactivated. That is the\n * correct tenant-tier answer, but on its own it converts every mistake that DID strand a tenant\n * — a direct database edit, a restore from a mid-erasure backup, an acknowledged erasure under\n * GDPR Art. 17, a seed that authored no owner — into a permanent lockout, because\n * `validateParentScopeAccess` denies a non-member on ORGANIZATIONS scope and there is no\n * `APP_ADMIN_SUPER_ADMIN` bypass. Both denials are pinned in\n * `cross-tenant-super-admin-reach.mongo.integration.test.ts`. So no tenant member can grant the\n * role (they would need the authority they just lost) and no platform administrator can reach\n * the row at all. GitHub solves this with an Enterprise owner one tier up; this is that tier.\n *\n * ## Why it is a distinct verb rather than a flag on UPDATE\n *\n * `admitsCrossTenantPlatformAdministration` relaxes the SCOPE check for the variant that carries\n * it. Putting it on generic UPDATE would open every field of every membership row in every\n * tenant to a cross-tenant caller. The whole safety argument is that the opened surface is\n * exactly one field with one direction, so it is authored as its own operation whose custom\n * implementation reads nothing from the payload but the justification — which it records, and\n * never persists onto the row.\n *\n * ## Deliberate narrowness\n *\n * - **Promotes an EXISTING member** (Microsoft Loop's rule). It cannot mint a membership, so it\n * never creates an identity inside a tenant nobody owns.\n * - **Additive only.** It adds the owner-conferring role; it cannot remove roles, so it can\n * never be used to demote and is not a second path through the floor.\n * - **`justification` is required**, not optional. This is a break-glass action against a tenant\n * the operator is not a member of; the audit row is worth nothing without the why. `AC-2(7)`\n * asks for privileged assignment to be monitored — the trail IS the control here, since by\n * construction no authorization check downstream can second-guess the caller. It lands on the\n * `ORGANIZATION_MEMBER_ROLE_CHANGED` row the grant emits post-commit (`eventData.justification`),\n * beside the before/after role sets. `RESOURCE_OPERATION_PERFORMED`, which this CRITICAL verb\n * also emits, carries no request payload and so cannot hold it. Until #593 it was validated here\n * and discarded at the service boundary.\n *\n * assurance-control: WILDO.ACCESS.ADMINISTRATIVE_CONTINUITY — restore administrability of a scope\n * that has no usable administrator.\n * assurance-control: WILDO.ACCESS.PRIVILEGE_EVIDENCE — evidence of privilege grant.\n */\n [OrganizationMembers_Operations.GRANT_OWNERSHIP]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n // Platform tier only. This is the role set the operation-roles gate checks INDEPENDENTLY\n // of the scope admission below: a caller holding this key at ORGANIZATIONS scope resolves\n // it against the organization role table, which does not contain it, and is denied there.\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n // THE cross-tenant admission. Without it the operation is unreachable by the only\n // principal it exists for, because a platform administrator is by definition not a member\n // of the stranded tenant.\n admitsCrossTenantPlatformAdministration: true,\n requestDto: z.object({\n justification: z.string().min(1).max(1000).describe('Why a platform administrator is making this member an owner of an organization they do not belong to. Required, and recorded on the audit trail with the role change.'),\n }),\n // No `auditableEvent` declaration: CRITICAL is inside `AUTOMATIC_AUDIT_RISK_FLOOR`, so the\n // event emits on the risk level alone and `auditBelowRiskFloor` would be inert here. The\n // before/after role sets ride along because `roles` carries `.isAuditEvidence()` — which is\n // what makes the trail answer the question that matters about this door: WHO was made an\n // owner of a tenant, by a caller who was not in it.\n },\n ],\n userNotifications: [\n {\n // The tenant learns that its ownership changed from outside. An operator repairing a\n // stranded tenant is legitimate; an operator quietly granting themselves an ally inside a\n // customer's tenant is not, and the difference is only visible to the tenant if it is told.\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n },\n ],\n },\n\n [OrganizationMembers_Operations.SUSPEND]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_ORG_ROLES.ORG_DELEGATED_MANAGE_RELATIONSHIP_EXPERTS], // Org admins; a firm's expert lent MANAGE_RELATIONSHIP_EXPERTS, on its own relationship's experts only (#1631)\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n requestDto: z.object({\n suspensionReason: z.string().min(1).max(500).describe('Why the member is suspended. Recorded on the audit trail, not on the membership.'),\n suspensionEndDate: z.date().optional().describe('When the suspension ends and the member is reactivated. Absent: suspended until someone reactivates them.'),\n }),\n // Implemented by the shared status-transition factory (ACTIVE → SUSPENDED, carrying\n // `suspensionEndDate` onto the row's `scheduledReactivationAt`). SUSPEND is legal only\n // from ACTIVE: an INVITED row has not accepted yet — cancel it with REVOKE, which also\n // revokes the accept token — and an INACTIVE one is already out.\n enabledCondition: ({ currentObject }) =>\n currentObject.status === OrganizationMemberStatus.ACTIVE,\n }\n ],\n userNotifications: [\n {\n // The suspended member. `alwaysDeliver`: a person who loses access to an organization has no\n // other way to learn why, whatever they chose for ordinary email notifications.\n target: CoreUserNotificationTarget.USERS_CUSTOM,\n channel: CoreUserNotificationChannel.EMAIL,\n userIdsSelector: selectMembershipStatusSubject,\n alwaysDeliver: true,\n },\n {\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n }\n ]\n },\n\n [OrganizationMembers_Operations.REACTIVATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n // Org admins only. NOT opened to MANAGE_RELATIONSHIP_EXPERTS (#1631): a suspension is the client's bar against\n // one person, which the firm cannot lift (#1597) — a firm may suspend or remove its own expert, never undo the\n // client's suspension of them.\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n requestDto: z.object({\n reason: z.string().max(500).optional()\n .describe('Why the member is being reactivated. Recorded with the audit event for the reactivation.')\n }),\n // Implemented by the shared status-transition factory (SUSPENDED → ACTIVE, clearing any\n // pending `scheduledReactivationAt`). Legal only from SUSPENDED: reactivating an INVITED\n // row would skip acceptance and grant a membership nobody agreed to. A service-provider\n // membership lands INACTIVE instead when its relationship has ended or its person is no\n // longer assigned (#1597, `resolveProviderMembershipReactivationStatus`).\n enabledCondition: ({ currentObject }) =>\n currentObject.status === OrganizationMemberStatus.SUSPENDED,\n // MEDIUM sits below `AUTOMATIC_AUDIT_RISK_FLOOR`, so without this the RESTORE half of the\n // pair would go untrailed while SUSPEND (CRITICAL) is recorded — a trail showing every\n // suspension and none of the lifts, which reads as a member still suspended a year after\n // they were reinstated. The risk level answers \"how alarming is the affordance\"; this\n // answers \"is it evidence an auditor needs\", and for the inverse of a CRITICAL verb it is.\n // assurance-control: WILDO.ACCESS.PRIVILEGE_EVIDENCE\n auditableEvent: { auditBelowRiskFloor: true },\n }\n ],\n userNotifications: [\n {\n // The reactivated member — reached on the scheduled sweep too, which runs with no initiator.\n target: CoreUserNotificationTarget.USERS_CUSTOM,\n channel: CoreUserNotificationChannel.EMAIL,\n userIdsSelector: selectMembershipStatusSubject,\n alwaysDeliver: true,\n condition: isRestoredToActiveMembership,\n },\n {\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n condition: isRestoredToActiveMembership,\n }\n ]\n },\n\n // REVOKE — inviter/admin cancels a still-`INVITED` membership. The exact\n // custom implementation DELETES the row and atomically revokes its accept\n // token. The paired PENDING_INVITATION user is retained here and reaped by\n // deferred hygiene only after it is old and still has no memberships:\n // point-operation cleanup cannot predicate-lock \"zero memberships\" against\n // a concurrent invitation insert under Mongo snapshot isolation. `reason`\n // is captured in the audit payload, not persisted on the deleted row.\n [OrganizationMembers_Operations.REVOKE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_ORG_ROLES.ORG_DELEGATED_INVITE_MEMBERS],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.DELETE,\n requestDto: z.object({\n reason: z.string().max(500).optional()\n .describe('Why the invitation is being revoked. Recorded with the audit event for the removal; it is not kept on the membership, which is deleted.')\n }),\n tokenRevocation:\n ORGANIZATION_MEMBER_INVITATION_TOKEN_REVOCATION,\n // REVOKE has an exact API custom registration; `resourceOperationLike`\n // selects DELETE persistence/DTO semantics but does not inherit the\n // core DELETE custom implementation. Its real return is the delete\n // envelope, declared explicitly so output validation matches runtime.\n customResponseDto: DefaultDeleteResponseSchema,\n // Only a still-pending invite can be revoked — an ACTIVE member is removed\n // via DELETE, not \"revoked\". Gates the roster action (paired with the preset's\n // `WHEN_AVAILABLE`, the button shows only on INVITED rows) AND fail-closes the\n // backend (`services-registry-handler` throws SERVICE_RESOURCE_OPERATION_DISABLED\n // → 403 if invoked on a non-INVITED row).\n enabledCondition: ({ currentObject }) => currentObject.status === OrganizationMemberStatus.INVITED,\n },\n ],\n // Two emails (distinct templates, disambiguated by `customNotificationRef`):\n // • the INVITEE (`recipientEmailField: 'userEmail'`) — \"your invitation was revoked\";\n // • the ADMIN/initiator (`USER_SELF`) — confirmation of the action.\n // Both USER_SELF+EMAIL, so each MUST carry a unique `customNotificationRef`.\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.EMAIL,\n recipientEmailField: 'userEmail',\n customNotificationRef: 'invitee',\n },\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.EMAIL,\n customNotificationRef: 'admin',\n }\n ]\n },\n\n // RESEND — re-mint the accept token (revoking any prior one for this membership)\n // and re-send the invite email with the fresh accept link. Only valid while the\n // membership is `INVITED`.\n [OrganizationMembers_Operations.RESEND]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_ORG_ROLES.ORG_DELEGATED_INVITE_MEMBERS],\n riskLevel: ResourceOperationRiskLevel.LOW,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n requestDto: z.object({}),\n tokenGeneration: {\n tokenType: CoreConsumableTokenTypes.ORGANIZATION_MEMBER_INVITATION,\n consumptionMode: ConsumableToken_ConsumptionMode.SINGLE_USE,\n expiresIn: { value: 7, unit: DurationUnit.DAYS },\n relatedIdField: '_id',\n revokeExistingForSameRelated: true,\n emailLinkPath: '/invitation',\n condition: isPendingOrganizationMemberInvitation,\n },\n // Resend is meaningful only while the invite is pending. Same dual enforcement\n // as REVOKE: hides the roster action on non-INVITED rows and 403s server-side.\n enabledCondition: ({ currentObject }) => currentObject.status === OrganizationMemberStatus.INVITED,\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.EMAIL,\n recipientEmailField: 'userEmail',\n condition: isPendingOrganizationMemberInvitation,\n }\n ]\n }\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"organization-members.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/organizations/organization-members.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Organization Members Shared Resource Configuration\n *\n * Resource configuration for organization member management.\n * Comprehensive member lifecycle and role management.\n */\n\nimport { z } from 'zod';\nimport {\n OrganizationMemberSchema,\n OrganizationMemberStatus,\n} from './organization-members.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourcePrimaryScope, ResourceRelationship, DefaultDeleteResponseSchema } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { CoreUserNotificationTarget, CoreUserNotificationChannel } from '../notifications/notifications.shared.schemas';\n\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport {\n CoreConsumableTokenTypes,\n ConsumableToken_ConsumptionMode,\n} from '../security/authentications/consumable-token.shared.schemas';\nimport type {\n TokenRevocationConfig,\n} from '../security/authentications/consumable-token.shared.schemas';\nimport { DurationUnit } from '@wildo-ai/zod-decorators';\n\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\nimport { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas';\n\n// Custom operations enum for organization members.\n// NOTE: cross-organization member transfer is intentionally NOT a framework\n// capability — moving a member between organizations is a tenant-boundary\n// crossing the framework does not sanction. Re-invite the identity in the\n// target organization instead.\n//\n// A membership row IS the invitation (there is no separate invitation resource):\n// - CREATE = invite (creates an `INVITED` row + mints the accept token).\n// - REVOKE = inviter/admin cancels a still-`INVITED` membership.\n// - RESEND = re-mint + re-send the accept token for an `INVITED` membership.\n// - SUSPEND/REACTIVATE = lifecycle of an ACTIVE/SUSPENDED member.\n// Invitee-side accept/reject is the tokenized `/auth/acceptInvitation` flow\n// (auth controller + `Auth_Invitation` screen), NOT a resource operation.\n//\n// ROLE CHANGES ARE `UPDATE`, NOT A DEDICATED VERB. `PROMOTE` / `DEMOTE` were declared here\n// as `ORG_ADMIN`-gated `riskLevel: HIGH` operations taking `{ newRole, reason }`, and were\n// removed on 2026-08-01: they were ROUTED but never implemented, so the request fell through\n// to the generic core UPDATE, which persists only fields the resource schema declares.\n// `newRole` is not one, so every call answered **HTTP 200 having changed nothing** — and the\n// dangerous direction is DEMOTE: an admin demotes a compromised account, is told 200 OK, and\n// the account keeps its privileges. Re-declaring an explicit role-change verb is legitimate,\n// but only WITH a custom implementation that writes `roles` and calls\n// `assertRequestedRolesWithinCallerCeiling` — a custom implementation is addressed by an EXACT\n// operation path, so it does NOT inherit the UPDATE variant's ceiling gate. Follow the\n// organization-units MOVE/ARCHIVE pattern (a `prefixCoreOperations` hook returning the field\n// patch the core UPDATE persists). See\n// the 2026-08-01 routed-but-unimplemented operation sweep (#1275).\n//\n// GRANT_OWNERSHIP is the ONE exception to \"role changes are UPDATE\", and it exists for a reason\n// UPDATE structurally cannot serve: it is the only operation on this resource a caller who is NOT a\n// member of the organization may perform. See its config entry below.\nexport enum OrganizationMembers_Operations {\n SUSPEND = 'suspend',\n REACTIVATE = 'reactivate',\n REVOKE = 'revoke',\n RESEND = 'resend',\n GRANT_OWNERSHIP = 'grantOwnership',\n}\n\n/**\n * One semantic definition for invalidating an organization invitation.\n *\n * REVOKE attaches it declaratively, so HTTP and trusted service callers enter\n * the same transactional revocation pipeline. Ordinary DELETE is\n * intentionally excluded: it removes a non-INVITED membership, which has no\n * invitation token to revoke.\n */\nexport const ORGANIZATION_MEMBER_INVITATION_TOKEN_REVOCATION = {\n tokenTypes: [\n CoreConsumableTokenTypes.ORGANIZATION_MEMBER_INVITATION,\n ],\n relatedIdField: '_id',\n} satisfies TokenRevocationConfig;\n\n/**\n * One predicate owns both invitation-token generation and invitation-email\n * dispatch. Keeping the two declarative side effects on the same named gate\n * prevents the polymorphic CREATE operation from drifting: an ACTIVE direct\n * add must produce neither an accept token nor an invitation email.\n */\nconst isPendingOrganizationMemberInvitation = ({\n currentObject,\n}: {\n currentObject: Record<string, unknown>;\n}): boolean =>\n currentObject.status === OrganizationMemberStatus.INVITED;\n\n/**\n * REACTIVATE's notifications say the member \"can now access organization resources again\", which is true only when\n * the membership came back ACTIVE. A service-provider membership whose relationship has ended, or whose person is no\n * longer assigned, lands INACTIVE instead (#1597), and neither the person nor the organization's users may be told\n * otherwise. Evaluated against the row as written.\n */\nconst isRestoredToActiveMembership = ({\n currentObject,\n}: {\n currentObject: Record<string, unknown>;\n}): boolean =>\n currentObject.status === OrganizationMemberStatus.ACTIVE;\n\n/**\n * The recipient of a membership's own status notice: the member whose membership was suspended or\n * reactivated (#1870).\n *\n * `USERS_CUSTOM` rather than `USER_SELF`, and the difference is the whole defect: `USER_SELF` is the\n * INITIATOR — the administrator who pressed the button — so \"your membership was suspended\" landed in\n * the administrator's inbox, and the scheduled reactivation sweep, which has no initiator, told nobody.\n * `ORGANIZATION_USERS` cannot reach the member either: it keeps only ACTIVE memberships, and a suspended\n * member is not one. The row the operation just wrote carries the member's `userId`, so that is the\n * recipient. Same shape as the `users` account-status notices (#1807).\n */\nconst selectMembershipStatusSubject = ({ currentObject }: { currentObject: { userId?: unknown } | null | undefined }): string[] =>\n currentObject?.userId ? [String(currentObject.userId)] : [];\n\n/**\n * Sortable member fields.\n *\n * `role` and `joinedAt` were listed here and neither is a field (#1806): the membership carries\n * `roles`, an ARRAY — which has no meaningful sort order on either adapter, so it is not offered —\n * and it records when it was created, not a separate join instant. Both entries were passed to the\n * repository verbatim and silently ignored. The factory now refuses a sort field that is not a field.\n */\nconst ORGANIZATION_MEMBERS_SORT_FIELDS = ['status', 'createdAt'];\n\nconst ORGANIZATION_MEMBERS_FILTER_FIELDS = {\n status: z.enum(OrganizationMemberStatus),\n // `roles` is an array, and a scalar filter on it matches array MEMBERSHIP on both adapters: MongoDB\n // does so natively and the PostgreSQL filter compiler emits a jsonb containment (`roles @> '\"x\"'`).\n // It was declared as `role`, a field no row has, so `?role=ORG_ADMIN` matched nothing (#1806).\n roles: z.string().min(1).describe('Only return members holding this role.'),\n};\n\ntype OrganizationMembersCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.LIST\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.DELETE\n | CoreResourceOperation.COUNT\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY.\n | CoreResourceOperation.UPDATE_MANY;\n\n/*\nOrganization Members Resource Configuration Factory\n*/\nexport const organizationMembersResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n typeof OrganizationMembers_Operations,\n OrganizationMembersCoreOperations,\n typeof OrganizationMemberSchema\n>({\n mainSchema: OrganizationMemberSchema,\n resourceIdentifier: CoreResourceType.ORGANIZATION_MEMBERS,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.ORGANIZATION_MEMBERS],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n // create: invitation-accept was the historical opt-in; now the org-admin INVITE, SSO/SCIM\n // JIT, and org-auto-create-on-registration all create members in-process with explicit\n // `userId` + `organizationId` FKs on a request-context-less EC (stripped by the\n // client-shaped CREATE DTO, re-attached by `createAsSystem`).\n // read/list: the invitee's own pending-invitation inbox reads INVITED rows cross-org\n // BEFORE the invitee is a scoped member — authorized by `userId`-ownership at the\n // entry point (`listMyPendingInvitations`/`loadOwnedPendingInvitation`), not org role.\n // update: invitation ACCEPTANCE flips INVITED → ACTIVE in-process; the invitee is not an\n // org admin, so the status flip goes through the trusted system path.\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED,\n create: ResourceSystemAccessMode.ALLOWED,\n read: ResourceSystemAccessMode.ALLOWED,\n list: ResourceSystemAccessMode.ALLOWED,\n update: ResourceSystemAccessMode.ALLOWED,\n },\n\n /**\n * Subject-export disclosure. The subject's OWN membership rows (org, roles, title) — not other members' data.\n */\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.OBSERVED },\n\n /**\n * Subject erasure RETAINS this row and scrubs the person's contact and professional details.\n *\n * The membership survives because it is the tenant's record of who belonged to it and under what\n * authority; what does not survive is `userEmail` and `userTitle`, the denormalized copies of the\n * person held here so a row can be read without resolving the user.\n *\n * `roles` is deliberately NOT scrubbed. It is this application's authorization vocabulary rather than\n * personal data — the field's own comment says so — and emptying it could leave a tenant with no\n * administrator, which the administrative-continuity floors would refuse, making an erasure fail closed\n * on a tenant. Keeping it means that interaction never arises.\n */\n retentionPolicy: {\n mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,\n },\n\n /**\n * Erasing one of these rows revokes NO session. A membership is a record ABOUT a person's place in a\n * tenant, not the person — their session ends through the `USERS` row, which is `SELF_PRINCIPAL`.\n */\n dataSubjectPolicy: { kind: ResourceDataSubjectKind.NO_PRINCIPAL },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.LIST,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.CREATE,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.DELETE,\n CoreResourceOperation.COUNT,\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY.\n CoreResourceOperation.UPDATE_MANY,\n ],\n\n customOperation: OrganizationMembers_Operations,\n\n operationsConfiguration: {\n\n /*\n\n * Route-less retention plumbing — INTERNAL_CALL registers no route, so no API surface is added, and it\n\n * must not be REPOSITORY_ONLY: the retention primitives resolve through `getServiceOperationPathDefault`,\n\n * which matches only INTERNAL_CALL / API_CALL. LIST is LOW (a read-shaped op may not claim the\n\n * HIGH/CRITICAL band, which carries an audit-emission obligation); UPDATE_MANY is CRITICAL — it is the\n\n * verb the impersonalize writer uses to stamp the retention markers.\n\n */\n\n [CoreResourceOperation.UPDATE_MANY]: {\n\n variants: [{\n\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n\n isDefault: true,\n\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n\n }],\n\n },\n\n [CoreResourceOperation.COUNT]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n // CREATE is POLYMORPHIC — two intents on one op:\n // • INVITE (BRANCH B): the org admin supplies `userEmail` (the strict identity\n // anchor); the CREATE prefix find-or-creates the `User` by it (`PENDING_INVITATION`\n // if new) and FORCES `status: INVITED`. A single-use accept token is minted AFTER the\n // row is created (relatedId = the membership `_id`, STABLE across `INVITED → ACTIVE`\n // so the emailed link never orphans); the pipeline injects it into the invite email and\n // the dispatcher builds the accept link (`emailLinkPath → /invitation?token=…`, consumed\n // by `/auth/acceptInvitation`). No `grantedRoles`: the accept handler reads the\n // membership's own `roles` when it flips the row to ACTIVE.\n // • DIRECT-ADD (BRANCH A): the caller supplies `userId` (founder org-owner grant,\n // SSO-JIT, SCIM) and the row persists `ACTIVE` — there is nothing to accept.\n // Token generation and notification dispatch share one named predicate.\n // The INVITE branch mints one accept token and sends one post-commit email;\n // the ACTIVE direct-add branch does neither.\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_ORG_ROLES.ORG_DELEGATED_INVITE_MEMBERS], // Org admins, or a firm's expert lent INVITE_MEMBERS (#1631)\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n // requestDto auto-derived from decorators (userEmail + roles +\n // organizationUnitsMembership + userTitle; userId/status/invitedByUserId/\n // invitedAt are server-injected via `.excludeFromCreate()`).\n tokenGeneration: {\n tokenType: CoreConsumableTokenTypes.ORGANIZATION_MEMBER_INVITATION,\n consumptionMode: ConsumableToken_ConsumptionMode.SINGLE_USE,\n expiresIn: { value: 7, unit: DurationUnit.DAYS },\n relatedIdField: '_id',\n emailLinkPath: '/invitation',\n // Mint the accept token for real invites only — never for an ACTIVE direct-add.\n condition: isPendingOrganizationMemberInvitation,\n },\n }\n ],\n // Deliver the invite email to the INVITEE (`userEmail`) via the\n // email-by-address path — the invitee may be a brand-new `PENDING_INVITATION`\n // user with no session. Carries the `acceptUrl` (`/invitation?token=…`) built\n // from the token minted above. `target: USER_SELF` is retained only so the\n // derived template ref stays `…create.user-self` and the accept link routes to\n // the main (non-admin) app.\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.EMAIL,\n recipientEmailField: 'userEmail',\n condition: isPendingOrganizationMemberInvitation,\n }\n ]\n },\n\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER], // Org members can read member info\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.LIST]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER], // Org members can list organization members\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: true,\n // `userEmail` is a denormalized, immutable own-field (mirror of the linked\n // user's email, captured at membership creation). First/last name are NOT\n // denormalized onto the member row — they live on `USER_PROFILES` and are\n // mutable there — so they are searched RELATIONALLY: the framework runs a\n // secondary match on `USER_PROFILES` (its own searchable fields) and folds\n // the matching `userId`s into an `$in` on this row's `userId`. The member\n // query stays org-scoped, so this is tenant-safe; names are never stale\n // because they are read live from the profile at search time. See\n // SearchableRelationDescriptor in resources-config.shared.schemas.ts.\n searchableFields: [\n 'userEmail',\n {\n localField: 'userId',\n relatedResource: CoreResourceType.USER_PROFILES,\n relatedJoinField: 'userId',\n fields: ['firstName', 'lastName'],\n },\n ],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: ORGANIZATION_MEMBERS_FILTER_FIELDS,\n sortFields: ORGANIZATION_MEMBERS_SORT_FIELDS,\n maxPaginatedResultPerPageLimit: 50,\n }\n ],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN], // Org admins can update member details\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n // requestDto auto-derived from decorators\n //\n // Ordinary UPDATE remains audited below the HIGH/CRITICAL floor: editing member details\n // is MEDIUM risk for the UI, but changing roles still requires privilege evidence.\n // The registered UPDATE implementation also emits ORGANIZATION_MEMBER_ROLE_CHANGED after\n // a durable role change, with previous, requested and resulting roles. That specialized\n // event complements the automatic operation event; it is not an unimplemented producer.\n //\n // GRANT_OWNERSHIP is a separate named role-change path. Its UPDATE-like core behavior does\n // not inherit UPDATE's custom hooks: registration resolves the exact operation identity.\n // Its CRITICAL risk triggers RESOURCE_OPERATION_PERFORMED automatically, with changed\n // role sets carried by the roles field's audit-evidence marker. Queries covering ownership\n // repair must include that operation family, not only the specialized role-change event.\n //\n // assurance-control: WILDO.ACCESS.PRIVILEGE_EVIDENCE — evidence of privilege grant/revocation.\n auditableEvent: { auditBelowRiskFloor: true },\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n }\n ]\n },\n\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_ORG_ROLES.ORG_DELEGATED_MANAGE_RELATIONSHIP_EXPERTS], // Org admins; a firm's expert lent MANAGE_RELATIONSHIP_EXPERTS, on its own relationship's experts only (#1631)\n riskLevel: ResourceOperationRiskLevel.HIGH,\n // Accepted/non-pending members use ordinary DELETE. A pending invite\n // is cancelled through REVOKE, which atomically revokes its accept\n // token. Keeping the vocabularies disjoint avoids making every\n // active-member removal token-coupled.\n enabledCondition: ({ currentObject }) =>\n currentObject.status !== OrganizationMemberStatus.INVITED,\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n }\n ]\n },\n\n /**\n * The higher-tier repair door for the organization-owner floor — the second half of the\n * industry pattern described in `.claude/rules/administrative-continuity-floors.md`.\n *\n * ## Why this cannot be UPDATE\n *\n * The floor refuses to let the last `ORG_OWNER` be removed, demoted or deactivated. That is the\n * correct tenant-tier answer, but on its own it converts every mistake that DID strand a tenant\n * — a direct database edit, a restore from a mid-erasure backup, an acknowledged erasure under\n * GDPR Art. 17, a seed that authored no owner — into a permanent lockout, because\n * `validateParentScopeAccess` denies a non-member on ORGANIZATIONS scope and there is no\n * `APP_ADMIN_SUPER_ADMIN` bypass. Both denials are pinned in\n * `cross-tenant-super-admin-reach.mongo.integration.test.ts`. So no tenant member can grant the\n * role (they would need the authority they just lost) and no platform administrator can reach\n * the row at all. GitHub solves this with an Enterprise owner one tier up; this is that tier.\n *\n * ## Why it is a distinct verb rather than a flag on UPDATE\n *\n * `admitsCrossTenantPlatformAdministration` relaxes the SCOPE check for the variant that carries\n * it. Putting it on generic UPDATE would open every field of every membership row in every\n * tenant to a cross-tenant caller. The whole safety argument is that the opened surface is\n * exactly one field with one direction, so it is authored as its own operation whose custom\n * implementation reads nothing from the payload but the justification — which it records, and\n * never persists onto the row.\n *\n * ## Deliberate narrowness\n *\n * - **Promotes an EXISTING member** (Microsoft Loop's rule). It cannot mint a membership, so it\n * never creates an identity inside a tenant nobody owns.\n * - **Additive only.** It adds the owner-conferring role; it cannot remove roles, so it can\n * never be used to demote and is not a second path through the floor.\n * - **`justification` is required**, not optional. This is a break-glass action against a tenant\n * the operator is not a member of; the audit row is worth nothing without the why. `AC-2(7)`\n * asks for privileged assignment to be monitored — the trail IS the control here, since by\n * construction no authorization check downstream can second-guess the caller. It lands on the\n * `ORGANIZATION_MEMBER_ROLE_CHANGED` row the grant emits post-commit (`eventData.justification`),\n * beside the before/after role sets. `RESOURCE_OPERATION_PERFORMED`, which this CRITICAL verb\n * also emits, carries no request payload and so cannot hold it. Until #593 it was validated here\n * and discarded at the service boundary.\n *\n * assurance-control: WILDO.ACCESS.ADMINISTRATIVE_CONTINUITY — restore administrability of a scope\n * that has no usable administrator.\n * assurance-control: WILDO.ACCESS.PRIVILEGE_EVIDENCE — evidence of privilege grant.\n */\n [OrganizationMembers_Operations.GRANT_OWNERSHIP]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n // Platform tier only. This is the role set the operation-roles gate checks INDEPENDENTLY\n // of the scope admission below: a caller holding this key at ORGANIZATIONS scope resolves\n // it against the organization role table, which does not contain it, and is denied there.\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n // THE cross-tenant admission. Without it the operation is unreachable by the only\n // principal it exists for, because a platform administrator is by definition not a member\n // of the stranded tenant.\n admitsCrossTenantPlatformAdministration: true,\n requestDto: z.object({\n justification: z.string().min(1).max(1000).describe('Why a platform administrator is making this member an owner of an organization they do not belong to. Required, and recorded on the audit trail with the role change.'),\n }),\n // No `auditableEvent` declaration: CRITICAL is inside `AUTOMATIC_AUDIT_RISK_FLOOR`, so the\n // event emits on the risk level alone and `auditBelowRiskFloor` would be inert here. The\n // before/after role sets ride along because `roles` carries `.isAuditEvidence()` — which is\n // what makes the trail answer the question that matters about this door: WHO was made an\n // owner of a tenant, by a caller who was not in it.\n },\n ],\n userNotifications: [\n {\n // The tenant learns that its ownership changed from outside. An operator repairing a\n // stranded tenant is legitimate; an operator quietly granting themselves an ally inside a\n // customer's tenant is not, and the difference is only visible to the tenant if it is told.\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n },\n ],\n },\n\n [OrganizationMembers_Operations.SUSPEND]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_ORG_ROLES.ORG_DELEGATED_MANAGE_RELATIONSHIP_EXPERTS], // Org admins; a firm's expert lent MANAGE_RELATIONSHIP_EXPERTS, on its own relationship's experts only (#1631)\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n requestDto: z.object({\n suspensionReason: z.string().min(1).max(500).describe('Why the member is suspended. Recorded on the audit trail, not on the membership.'),\n suspensionEndDate: z.date().optional().describe('When the suspension ends and the member is reactivated. Absent: suspended until someone reactivates them.'),\n }),\n // Implemented by the shared status-transition factory (ACTIVE → SUSPENDED, carrying\n // `suspensionEndDate` onto the row's `scheduledReactivationAt`). SUSPEND is legal only\n // from ACTIVE: an INVITED row has not accepted yet — cancel it with REVOKE, which also\n // revokes the accept token — and an INACTIVE one is already out.\n enabledCondition: ({ currentObject }) =>\n currentObject.status === OrganizationMemberStatus.ACTIVE,\n }\n ],\n userNotifications: [\n {\n // The suspended member. `alwaysDeliver`: a person who loses access to an organization has no\n // other way to learn why, whatever they chose for ordinary email notifications.\n target: CoreUserNotificationTarget.USERS_CUSTOM,\n channel: CoreUserNotificationChannel.EMAIL,\n userIdsSelector: selectMembershipStatusSubject,\n alwaysDeliver: true,\n },\n {\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n }\n ]\n },\n\n [OrganizationMembers_Operations.REACTIVATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n // Org admins only. NOT opened to MANAGE_RELATIONSHIP_EXPERTS (#1631): a suspension is the client's bar against\n // one person, which the firm cannot lift (#1597) — a firm may suspend or remove its own expert, never undo the\n // client's suspension of them.\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n requestDto: z.object({\n reason: z.string().max(500).optional()\n .describe('Why the member is being reactivated. Recorded with the audit event for the reactivation.')\n }),\n // Implemented by the shared status-transition factory (SUSPENDED → ACTIVE, clearing any\n // pending `scheduledReactivationAt`). Legal only from SUSPENDED: reactivating an INVITED\n // row would skip acceptance and grant a membership nobody agreed to. A service-provider\n // membership lands INACTIVE instead when its relationship has ended or its person is no\n // longer assigned (#1597, `resolveProviderMembershipReactivationStatus`).\n enabledCondition: ({ currentObject }) =>\n currentObject.status === OrganizationMemberStatus.SUSPENDED,\n // MEDIUM sits below `AUTOMATIC_AUDIT_RISK_FLOOR`, so without this the RESTORE half of the\n // pair would go untrailed while SUSPEND (CRITICAL) is recorded — a trail showing every\n // suspension and none of the lifts, which reads as a member still suspended a year after\n // they were reinstated. The risk level answers \"how alarming is the affordance\"; this\n // answers \"is it evidence an auditor needs\", and for the inverse of a CRITICAL verb it is.\n // assurance-control: WILDO.ACCESS.PRIVILEGE_EVIDENCE\n auditableEvent: { auditBelowRiskFloor: true },\n }\n ],\n userNotifications: [\n {\n // The reactivated member — reached on the scheduled sweep too, which runs with no initiator.\n target: CoreUserNotificationTarget.USERS_CUSTOM,\n channel: CoreUserNotificationChannel.EMAIL,\n userIdsSelector: selectMembershipStatusSubject,\n alwaysDeliver: true,\n condition: isRestoredToActiveMembership,\n },\n {\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n condition: isRestoredToActiveMembership,\n }\n ]\n },\n\n // REVOKE — inviter/admin cancels a still-`INVITED` membership. The exact\n // custom implementation DELETES the row and atomically revokes its accept\n // token. The paired PENDING_INVITATION user is retained here and reaped by\n // deferred hygiene only after it is old and still has no memberships:\n // point-operation cleanup cannot predicate-lock \"zero memberships\" against\n // a concurrent invitation insert under Mongo snapshot isolation. `reason`\n // is captured in the audit payload, not persisted on the deleted row.\n [OrganizationMembers_Operations.REVOKE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_ORG_ROLES.ORG_DELEGATED_INVITE_MEMBERS],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.DELETE,\n requestDto: z.object({\n reason: z.string().max(500).optional()\n .describe('Why the invitation is being revoked. Recorded with the audit event for the removal; it is not kept on the membership, which is deleted.')\n }),\n tokenRevocation:\n ORGANIZATION_MEMBER_INVITATION_TOKEN_REVOCATION,\n // REVOKE has an exact API custom registration; `resourceOperationLike`\n // selects DELETE persistence/DTO semantics but does not inherit the\n // core DELETE custom implementation. Its real return is the delete\n // envelope, declared explicitly so output validation matches runtime.\n customResponseDto: DefaultDeleteResponseSchema,\n // Only a still-pending invite can be revoked — an ACTIVE member is removed\n // via DELETE, not \"revoked\". Gates the roster action (paired with the preset's\n // `WHEN_AVAILABLE`, the button shows only on INVITED rows) AND fail-closes the\n // backend (`services-registry-handler` throws SERVICE_RESOURCE_OPERATION_DISABLED\n // → 403 if invoked on a non-INVITED row).\n enabledCondition: ({ currentObject }) => currentObject.status === OrganizationMemberStatus.INVITED,\n },\n ],\n // Two emails (distinct templates, disambiguated by `customNotificationRef`):\n // • the INVITEE (`recipientEmailField: 'userEmail'`) — \"your invitation was revoked\";\n // • the ADMIN/initiator (`USER_SELF`) — confirmation of the action.\n // Both USER_SELF+EMAIL, so each MUST carry a unique `customNotificationRef`.\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.EMAIL,\n recipientEmailField: 'userEmail',\n customNotificationRef: 'invitee',\n },\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.EMAIL,\n customNotificationRef: 'admin',\n }\n ]\n },\n\n // RESEND — re-mint the accept token (revoking any prior one for this membership)\n // and re-send the invite email with the fresh accept link. Only valid while the\n // membership is `INVITED`.\n [OrganizationMembers_Operations.RESEND]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_ORG_ROLES.ORG_DELEGATED_INVITE_MEMBERS],\n riskLevel: ResourceOperationRiskLevel.LOW,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n requestDto: z.object({}),\n tokenGeneration: {\n tokenType: CoreConsumableTokenTypes.ORGANIZATION_MEMBER_INVITATION,\n consumptionMode: ConsumableToken_ConsumptionMode.SINGLE_USE,\n expiresIn: { value: 7, unit: DurationUnit.DAYS },\n relatedIdField: '_id',\n revokeExistingForSameRelated: true,\n emailLinkPath: '/invitation',\n condition: isPendingOrganizationMemberInvitation,\n },\n // Resend is meaningful only while the invite is pending. Same dual enforcement\n // as REVOKE: hides the roster action on non-INVITED rows and 403s server-side.\n enabledCondition: ({ currentObject }) => currentObject.status === OrganizationMemberStatus.INVITED,\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.EMAIL,\n recipientEmailField: 'userEmail',\n condition: isPendingOrganizationMemberInvitation,\n }\n ]\n }\n },\n});\n"]}
|