@wildo-ai/saas-models 1.1.0 → 1.1.2
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/applications/applications-context.schemas.d.ts +2 -0
- package/dist/esm/applications/applications-context.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts +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 +36 -0
- 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 +8 -1
- package/dist/esm/billing/billing-account.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-types.shared.schemas.d.ts +2 -2
- package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts +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 +39 -0
- package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/credit-pool.shared.schemas.d.ts +6 -6
- package/dist/esm/billing/credit-pool.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/credit-pool.shared.schemas.js +8 -4
- package/dist/esm/billing/credit-pool.shared.schemas.js.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts +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 +35 -0
- 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 +8 -3
- package/dist/esm/billing/invoice-ref.shared.schemas.js.map +1 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts +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 +39 -0
- package/dist/esm/billing/subscription.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/subscription.shared.schemas.d.ts +4 -4
- package/dist/esm/billing/subscription.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/subscription.shared.schemas.js +6 -2
- package/dist/esm/billing/subscription.shared.schemas.js.map +1 -1
- package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts +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 +39 -0
- package/dist/esm/billing/usage-record.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/usage-record.shared.schemas.d.ts +4 -4
- package/dist/esm/billing/usage-record.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/usage-record.shared.schemas.js +7 -3
- package/dist/esm/billing/usage-record.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 +35 -2
- package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts +61 -0
- 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 +58 -0
- 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 +14 -0
- package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts +49 -0
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js +124 -1
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts +11 -3
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js +11 -3
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts +93 -0
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts.map +1 -0
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js +116 -0
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js.map +1 -0
- package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts +67 -12
- 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 +95 -8
- package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts +21 -1
- package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/redaction.shared.schemas.js +20 -0
- package/dist/esm/compliance/privacy/redaction.shared.schemas.js.map +1 -1
- package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts +2 -0
- package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/app-configuration-shared.shared.schemas.js +29 -0
- package/dist/esm/config/app-configuration-shared.shared.schemas.js.map +1 -1
- package/dist/esm/config/frontend/navigation.shared.schemas.d.ts +33 -0
- package/dist/esm/config/frontend/navigation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/frontend/navigation.shared.schemas.js +32 -0
- package/dist/esm/config/frontend/navigation.shared.schemas.js.map +1 -1
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts +12 -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 +12 -1
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js.map +1 -1
- package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts +13 -0
- 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-providers/engine-capabilities.shared.schemas.d.ts +6 -6
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.js +26 -6
- 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 +0 -2
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js.map +1 -1
- package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts +1 -0
- package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts +4 -3
- package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-capability.shared.schemas.js +4 -3
- package/dist/esm/external-providers/provider-capability.shared.schemas.js.map +1 -1
- package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts +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 +48 -0
- package/dist/esm/features/user-features.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/files/file-upload-grant.shared.schemas.d.ts +144 -0
- package/dist/esm/files/file-upload-grant.shared.schemas.d.ts.map +1 -0
- package/dist/esm/files/file-upload-grant.shared.schemas.js +136 -0
- package/dist/esm/files/file-upload-grant.shared.schemas.js.map +1 -0
- package/dist/esm/files/files.shared.schemas.d.ts +45 -4
- package/dist/esm/files/files.shared.schemas.d.ts.map +1 -1
- package/dist/esm/files/files.shared.schemas.js +48 -4
- package/dist/esm/files/files.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts +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 +33 -0
- 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 +6 -2
- 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 +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 +53 -0
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts +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 +43 -0
- 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 +8 -3
- 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 +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 +41 -0
- 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 +0 -7
- 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 +23 -13
- package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts +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 +51 -0
- 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 +8 -2
- package/dist/esm/guidance/guidance-state.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts +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 +51 -0
- 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 +28 -3
- package/dist/esm/guidance/lifecycle-state.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts +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 +51 -0
- 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 +18 -4
- package/dist/esm/guidance/progression-state.shared.schemas.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts +37 -3
- 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 +29 -3
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js.map +1 -1
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts +70 -0
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts.map +1 -0
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js +71 -0
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js.map +1 -0
- package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts +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 +36 -0
- package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts +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 +44 -0
- 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 +15 -4
- package/dist/esm/organizations/organization-members.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 +18 -10
- package/dist/esm/organizations/organizations.shared.resources-config.schemas.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 +17 -0
- package/dist/esm/queue/jobs.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/requests/websocket.shared.schemas.d.ts +59 -0
- package/dist/esm/requests/websocket.shared.schemas.d.ts.map +1 -1
- package/dist/esm/requests/websocket.shared.schemas.js +103 -0
- package/dist/esm/requests/websocket.shared.schemas.js.map +1 -1
- package/dist/esm/resources/collection-query-parameters.shared.d.ts +22 -0
- package/dist/esm/resources/collection-query-parameters.shared.d.ts.map +1 -0
- package/dist/esm/resources/collection-query-parameters.shared.js +22 -0
- package/dist/esm/resources/collection-query-parameters.shared.js.map +1 -0
- package/dist/esm/resources/resources-config.shared.factory.d.ts.map +1 -1
- package/dist/esm/resources/resources-config.shared.factory.js +86 -13
- package/dist/esm/resources/resources-config.shared.factory.js.map +1 -1
- package/dist/esm/resources/resources-config.shared.schemas.d.ts +162 -41
- package/dist/esm/resources/resources-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/resources-config.shared.schemas.js +109 -20
- package/dist/esm/resources/resources-config.shared.schemas.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 +21 -6
- package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.schemas.d.ts +57 -0
- package/dist/esm/security/authentications/authentication.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.schemas.js +64 -0
- package/dist/esm/security/authentications/authentication.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts +17 -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 +16 -0
- package/dist/esm/security/authentications/consumable-token.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts +28 -0
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts.map +1 -0
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js +28 -0
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js.map +1 -0
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts +21 -0
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts.map +1 -0
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js +21 -0
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js.map +1 -0
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts +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 +43 -0
- 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 +0 -8
- 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 +13 -4
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.d.ts +16 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.js +16 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.utils.d.ts +54 -0
- package/dist/esm/security/authorizations/roles.shared.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.utils.js +59 -0
- package/dist/esm/security/authorizations/roles.shared.utils.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts +61 -0
- 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 +13 -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 +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 +35 -0
- 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 +7 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts +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 +34 -0
- 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 +7 -4
- package/dist/esm/users/inbound-contacts.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts +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 +37 -0
- 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 +17 -2
- 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 +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 +36 -0
- 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 +15 -5
- package/dist/esm/users/user-identity-links.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts +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 +53 -0
- 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 +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 +62 -0
- 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 +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 +53 -0
- 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 +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 +62 -0
- package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/users.shared.schemas.d.ts +19 -0
- package/dist/esm/users/users.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/users.shared.schemas.js +41 -16
- package/dist/esm/users/users.shared.schemas.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -6
- package/dist/esm/.builder.pid +0 -9
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Handles notifications, privacy, UI, regional, and language preferences.
|
|
6
6
|
*/
|
|
7
7
|
import { UserPreferencesSchema } from './users.shared.schemas.js';
|
|
8
|
+
import { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas.js';
|
|
8
9
|
import { CoreResourceOperation } from '../resources/resources.shared.core.definitions.js';
|
|
9
10
|
import { ResourceOperationRiskLevel } from '../resources/resources.shared.schemas.js';
|
|
10
11
|
import { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions.js';
|
|
@@ -37,13 +38,65 @@ export const userPreferencesResourceConfiguration_InitializationFactory = (resou
|
|
|
37
38
|
* Subject-export disclosure. Admin door onto the same preference rows.
|
|
38
39
|
*/
|
|
39
40
|
portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },
|
|
41
|
+
/**
|
|
42
|
+
* Subject erasure RETAINS the preferences row and RESETS what it holds.
|
|
43
|
+
*
|
|
44
|
+
* `RETAIN_AND_IMPERSONALIZE`: notification routing, privacy choices, regional settings (which carry
|
|
45
|
+
* LOCATION — a timezone and a locale narrow where a person is) and language preferences are all a
|
|
46
|
+
* record of one person's choices. All four take `RESET`, returning the application's own defaults.
|
|
47
|
+
*
|
|
48
|
+
* RESET rather than REMOVE, and the distinction is why this resource could not be declared at all
|
|
49
|
+
* until 2026-09-01: every one of these fields is non-nullable with a schema default, so a null fails
|
|
50
|
+
* the strict re-parse and `maskValue` (typed `string`) cannot express an object. Neither mode was
|
|
51
|
+
* authorable — `RETAIN_AND_IMPERSONALIZE` is refused when nothing would be scrubbed, and
|
|
52
|
+
* `RETAIN_ONLY` would have asserted this resource holds no personal data, which is false.
|
|
53
|
+
*
|
|
54
|
+
* ⚠️ `USER_SELF_PREFERENCES` declares the SAME policy on purpose — a second config over the SAME
|
|
55
|
+
* collection and the SAME schema, so both must inject the same marker and emit the same partial
|
|
56
|
+
* index. Change the two together, as `USERS` / `USER_SELF` documents.
|
|
57
|
+
*/
|
|
58
|
+
retentionPolicy: {
|
|
59
|
+
mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,
|
|
60
|
+
},
|
|
61
|
+
/** The subject is the person whose preferences these are, reached through `userId`. */
|
|
62
|
+
dataSubjectPolicy: { kind: ResourceDataSubjectKind.SELF_PRINCIPAL },
|
|
40
63
|
coreOperations: [
|
|
41
64
|
CoreResourceOperation.READ,
|
|
42
65
|
CoreResourceOperation.UPDATE,
|
|
43
66
|
CoreResourceOperation.CREATE,
|
|
44
67
|
CoreResourceOperation.DELETE,
|
|
68
|
+
// Route-less; required by `retentionPolicy` (the in-place scrub + audited see-through read).
|
|
69
|
+
CoreResourceOperation.LIST,
|
|
70
|
+
CoreResourceOperation.UPDATE_MANY,
|
|
45
71
|
],
|
|
46
72
|
operationsConfiguration: {
|
|
73
|
+
/*
|
|
74
|
+
* Route-less retention plumbing. INTERNAL_CALL registers NO route, and must not be
|
|
75
|
+
* REPOSITORY_ONLY: the retention primitives resolve through `getServiceOperationPathDefault`,
|
|
76
|
+
* which excludes it, so that spelling passes the boot guard and fails when an erasure runs.
|
|
77
|
+
* LIST is LOW — a read-shaped operation may not claim the HIGH/CRITICAL band, which carries an
|
|
78
|
+
* audit-emission obligation checked over the real engine catalogue.
|
|
79
|
+
*/
|
|
80
|
+
[CoreResourceOperation.LIST]: {
|
|
81
|
+
variants: [
|
|
82
|
+
{
|
|
83
|
+
variantType: ResourceOperationVariantType.INTERNAL_CALL,
|
|
84
|
+
isDefault: true,
|
|
85
|
+
roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
86
|
+
riskLevel: ResourceOperationRiskLevel.LOW,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
[CoreResourceOperation.UPDATE_MANY]: {
|
|
91
|
+
variants: [
|
|
92
|
+
{
|
|
93
|
+
variantType: ResourceOperationVariantType.INTERNAL_CALL,
|
|
94
|
+
isDefault: true,
|
|
95
|
+
roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
96
|
+
riskLevel: ResourceOperationRiskLevel.CRITICAL,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
47
100
|
[CoreResourceOperation.READ]: {
|
|
48
101
|
variants: [
|
|
49
102
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-preferences.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/users/user-preferences.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Preferences Shared Resource Configuration\n *\n * Resource configuration for user preferences management operations.\n * Handles notifications, privacy, UI, regional, and language preferences.\n */\n\nimport { UserPreferencesSchema } from './users.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } 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';\n\nimport { CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\ntype UserPreferencesCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE;\n\n/*\nUser Preferences Resource Configuration Factory\n*/\nexport const userPreferencesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n undefined,\n UserPreferencesCoreOperations,\n typeof UserPreferencesSchema\n>({\n mainSchema: UserPreferencesSchema,\n resourceIdentifier: CoreResourceType.USER_PREFERENCES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_PREFERENCES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n // Eager composition seeding: the USERS → USER_PREFERENCES relationship declares\n // `onParentCreate.enabled`, so a default preferences row is written via\n // `createAsSystem` on user creation. Registration (and OAuth/SCIM/SAML/enterprise)\n // create USERS; USER_SELF_PREFERENCES is a read-only view over the SAME collection\n // (`getCollectionNameForResource` maps USER_SELF_PREFERENCES → USER_PREFERENCES),\n // so the self-read finds this seeded row. Guard-1 is fail-closed by omission, so\n // the system seed requires this explicit CREATE opt-in.\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED, create: ResourceSystemAccessMode.ALLOWED },\n\n /**\n * Subject-export disclosure. Admin door onto the same preference rows.\n */\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n CoreResourceOperation.DELETE,\n ],\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_VIEWER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n // USER_PREFERENCES is the cross-subject administrative door onto the same rows exposed\n // to a subject by USER_SELF_PREFERENCES. This opt-in is what makes the addressed\n // `{userId}` an administrator-selected subject rather than forcing it to equal the\n // caller. The APP_ADMIN_VIEWER role remains the independent authorization gate.\n admitsCrossSubjectUserAdministration: true,\n }\n ]\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n // Preferences are seeded by the USERS -> USER_PREFERENCES composition. CREATE remains\n // enabled only so the trusted lifecycle hook can call createAsSystem; it is not a public\n // recovery endpoint and does not belong in either API-reference section.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n admitsCrossSubjectUserAdministration: true,\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n // The USERS composition cascade needs DELETE to exist, but no actor should delete an\n // eagerly seeded preferences row through HTTP. The self API has selective reset; the\n // administration API has UPDATE. Account deletion invokes this internal lifecycle edge.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n }\n ],\n }\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"user-preferences.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/users/user-preferences.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Preferences Shared Resource Configuration\n *\n * Resource configuration for user preferences management operations.\n * Handles notifications, privacy, UI, regional, and language preferences.\n */\n\nimport { UserPreferencesSchema } from './users.shared.schemas';\nimport { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } 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';\n\nimport { CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\ntype UserPreferencesCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.LIST\n | CoreResourceOperation.UPDATE_MANY\n | CoreResourceOperation.DELETE;\n\n/*\nUser Preferences Resource Configuration Factory\n*/\nexport const userPreferencesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n undefined,\n UserPreferencesCoreOperations,\n typeof UserPreferencesSchema\n>({\n mainSchema: UserPreferencesSchema,\n resourceIdentifier: CoreResourceType.USER_PREFERENCES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_PREFERENCES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n // Eager composition seeding: the USERS → USER_PREFERENCES relationship declares\n // `onParentCreate.enabled`, so a default preferences row is written via\n // `createAsSystem` on user creation. Registration (and OAuth/SCIM/SAML/enterprise)\n // create USERS; USER_SELF_PREFERENCES is a read-only view over the SAME collection\n // (`getCollectionNameForResource` maps USER_SELF_PREFERENCES → USER_PREFERENCES),\n // so the self-read finds this seeded row. Guard-1 is fail-closed by omission, so\n // the system seed requires this explicit CREATE opt-in.\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED, create: ResourceSystemAccessMode.ALLOWED },\n\n /**\n * Subject-export disclosure. Admin door onto the same preference rows.\n */\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },\n\n\n /**\n * Subject erasure RETAINS the preferences row and RESETS what it holds.\n *\n * `RETAIN_AND_IMPERSONALIZE`: notification routing, privacy choices, regional settings (which carry\n * LOCATION — a timezone and a locale narrow where a person is) and language preferences are all a\n * record of one person's choices. All four take `RESET`, returning the application's own defaults.\n *\n * RESET rather than REMOVE, and the distinction is why this resource could not be declared at all\n * until 2026-09-01: every one of these fields is non-nullable with a schema default, so a null fails\n * the strict re-parse and `maskValue` (typed `string`) cannot express an object. Neither mode was\n * authorable — `RETAIN_AND_IMPERSONALIZE` is refused when nothing would be scrubbed, and\n * `RETAIN_ONLY` would have asserted this resource holds no personal data, which is false.\n *\n * ⚠️ `USER_SELF_PREFERENCES` declares the SAME policy on purpose — a second config over the SAME\n * collection and the SAME schema, so both must inject the same marker and emit the same partial\n * index. Change the two together, as `USERS` / `USER_SELF` documents.\n */\n retentionPolicy: {\n mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,\n },\n\n /** The subject is the person whose preferences these are, reached through `userId`. */\n dataSubjectPolicy: { kind: ResourceDataSubjectKind.SELF_PRINCIPAL },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n CoreResourceOperation.DELETE,\n // Route-less; required by `retentionPolicy` (the in-place scrub + audited see-through read).\n CoreResourceOperation.LIST,\n CoreResourceOperation.UPDATE_MANY,\n ],\n\n operationsConfiguration: {\n /*\n * Route-less retention plumbing. INTERNAL_CALL registers NO route, and must not be\n * REPOSITORY_ONLY: the retention primitives resolve through `getServiceOperationPathDefault`,\n * which excludes it, so that spelling passes the boot guard and fails when an erasure runs.\n * LIST is LOW — a read-shaped operation may not claim the HIGH/CRITICAL band, which carries an\n * audit-emission obligation checked over the real engine catalogue.\n */\n [CoreResourceOperation.LIST]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n ],\n },\n [CoreResourceOperation.UPDATE_MANY]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n },\n ],\n },\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_VIEWER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n // USER_PREFERENCES is the cross-subject administrative door onto the same rows exposed\n // to a subject by USER_SELF_PREFERENCES. This opt-in is what makes the addressed\n // `{userId}` an administrator-selected subject rather than forcing it to equal the\n // caller. The APP_ADMIN_VIEWER role remains the independent authorization gate.\n admitsCrossSubjectUserAdministration: true,\n }\n ]\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n // Preferences are seeded by the USERS -> USER_PREFERENCES composition. CREATE remains\n // enabled only so the trusted lifecycle hook can call createAsSystem; it is not a public\n // recovery endpoint and does not belong in either API-reference section.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n admitsCrossSubjectUserAdministration: true,\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n // The USERS composition cascade needs DELETE to exist, but no actor should delete an\n // eagerly seeded preferences row through HTTP. The self API has selective reset; the\n // administration API has UPDATE. Account deletion invokes this internal lifecycle edge.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n }\n ],\n }\n },\n});\n"]}
|
|
@@ -12,7 +12,7 @@ export declare enum UserProfiles_Operations {
|
|
|
12
12
|
REMOVE_AVATAR = "remove_avatar",// Remove user avatar
|
|
13
13
|
UPDATE_CONTACT_INFO = "update_contact_info"
|
|
14
14
|
}
|
|
15
|
-
type UserProfilesCoreOperations = CoreResourceOperation.READ | CoreResourceOperation.SEARCH | CoreResourceOperation.UPDATE | CoreResourceOperation.CREATE | CoreResourceOperation.DELETE;
|
|
15
|
+
type UserProfilesCoreOperations = CoreResourceOperation.READ | CoreResourceOperation.SEARCH | CoreResourceOperation.UPDATE | CoreResourceOperation.CREATE | CoreResourceOperation.DELETE | CoreResourceOperation.LIST | CoreResourceOperation.UPDATE_MANY;
|
|
16
16
|
export declare const userProfilesResourceConfiguration_InitializationFactory: (resourcesRelationships: ResourceRelationship[]) => import("..").ResourceConfiguration<typeof UserProfiles_Operations, UserProfilesCoreOperations, z.ZodObject<{
|
|
17
17
|
_id: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<z.ZodString>>;
|
|
18
18
|
userId: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<z.ZodString>>>>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-profiles.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/users/user-profiles.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAA8B,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"user-profiles.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/users/user-profiles.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAA8B,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAyBzG,oBAAY,uBAAuB;IACjC,aAAa,kBAAkB,CAAE,qBAAqB;IACtD,aAAa,kBAAkB,CAAE,qBAAqB;IACtD,mBAAmB,wBAAwB;CAC5C;AAED,KAAK,0BAA0B,GAC3B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,WAAW,CAAC;AAKtC,eAAO,MAAM,uDAAuD,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;kBAkUpH,CAAC"}
|
|
@@ -14,6 +14,7 @@ import { CoreUserNotificationTarget, CoreUserNotificationChannel } from '../noti
|
|
|
14
14
|
import { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory.js';
|
|
15
15
|
import { ResourceSystemAccessMode, acknowledgeUnimplementedEngineOperation } from '../resources/resources-config.shared.schemas.js';
|
|
16
16
|
import { CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas.js';
|
|
17
|
+
import { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas.js';
|
|
17
18
|
import { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas.js';
|
|
18
19
|
// Custom operations enum for user profile management.
|
|
19
20
|
//
|
|
@@ -62,15 +63,76 @@ export const userProfilesResourceConfiguration_InitializationFactory = (resource
|
|
|
62
63
|
* Subject-export disclosure. Admin door onto the same profile rows.
|
|
63
64
|
*/
|
|
64
65
|
portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },
|
|
66
|
+
/**
|
|
67
|
+
* Subject erasure scrubs-and-RETAINS the profile row rather than deleting it.
|
|
68
|
+
*
|
|
69
|
+
* `RETAIN_AND_IMPERSONALIZE` because this row holds personal data of its OWN — names, avatar, bio,
|
|
70
|
+
* phone, title — which the treatments on the shared `UserProfileSchema` mask or remove. The two
|
|
71
|
+
* required name fields MASK to `ERASED_USER_NAME` rather than REMOVE: they are `min(1)`, so nulling
|
|
72
|
+
* them would leave a row the schema rejects on the next read.
|
|
73
|
+
*
|
|
74
|
+
* RETAIN rather than delete, to match the identity row. `USERS` is retained so the financial records
|
|
75
|
+
* whose foreign keys point at it stay resolvable; a profile deleted out from under a retained user
|
|
76
|
+
* would leave that user's 1:1 composition dangling. Retaining and scrubbing keeps the collection's
|
|
77
|
+
* contract coherent and removes the personal data, which is what the obligation actually asks.
|
|
78
|
+
*
|
|
79
|
+
* ⚠️ `USER_SELF_PROFILES` declares the SAME policy on purpose — a second config over the SAME
|
|
80
|
+
* collection and the SAME `UserProfileSchema`. Both must inject the same marker and emit the same
|
|
81
|
+
* partial index, exactly as `USERS` / `USER_SELF` do. Change the two together.
|
|
82
|
+
*/
|
|
83
|
+
retentionPolicy: {
|
|
84
|
+
mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* The subject IS the person this profile describes, reached through its `userId` composition parent.
|
|
88
|
+
*/
|
|
89
|
+
dataSubjectPolicy: { kind: ResourceDataSubjectKind.SELF_PRINCIPAL },
|
|
65
90
|
coreOperations: [
|
|
66
91
|
CoreResourceOperation.READ,
|
|
67
92
|
CoreResourceOperation.SEARCH,
|
|
68
93
|
CoreResourceOperation.UPDATE,
|
|
69
94
|
CoreResourceOperation.CREATE,
|
|
70
95
|
CoreResourceOperation.DELETE,
|
|
96
|
+
// LIST + UPDATE_MANY exist for the retention capability ONLY, as INTERNAL_CALL variants that
|
|
97
|
+
// register no route. `retentionPolicy` requires UPDATE_MANY (the in-place scrub via
|
|
98
|
+
// `updateManyAsSystem`) plus READ + LIST (the audited see-through read of retained rows).
|
|
99
|
+
CoreResourceOperation.LIST,
|
|
100
|
+
CoreResourceOperation.UPDATE_MANY,
|
|
71
101
|
],
|
|
72
102
|
customOperation: UserProfiles_Operations,
|
|
73
103
|
operationsConfiguration: {
|
|
104
|
+
/*
|
|
105
|
+
* Route-less retention plumbing. Both are INTERNAL_CALL, *not* REPOSITORY_ONLY: the retention
|
|
106
|
+
* primitives resolve through `getServiceOperationPathDefault`, which matches INTERNAL_CALL /
|
|
107
|
+
* API_CALL / API_CALL_WITH_CALLBACK and deliberately excludes REPOSITORY_ONLY — so a
|
|
108
|
+
* REPOSITORY_ONLY variant satisfies the factory's boot-time "operation exists" guard and then
|
|
109
|
+
* FAILS TO RESOLVE when an erasure actually runs. `roles` is inert on a non-URL-bearing variant;
|
|
110
|
+
* the real gate is the derived `systemAccessPolicy` grant the trusted writer fails closed on.
|
|
111
|
+
*/
|
|
112
|
+
[CoreResourceOperation.LIST]: {
|
|
113
|
+
variants: [
|
|
114
|
+
{
|
|
115
|
+
// LOW, matching `USER_SELF`'s retention LIST. A read-shaped operation may not be declared
|
|
116
|
+
// HIGH/CRITICAL — the audit contract pairs that band with an emission obligation, and it is
|
|
117
|
+
// checked over the real engine catalogue. Declaring HIGH here failed both halves of that
|
|
118
|
+
// check at once: an unemitted HIGH, and a read at a write's risk band.
|
|
119
|
+
variantType: ResourceOperationVariantType.INTERNAL_CALL,
|
|
120
|
+
isDefault: true,
|
|
121
|
+
roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
122
|
+
riskLevel: ResourceOperationRiskLevel.LOW,
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
[CoreResourceOperation.UPDATE_MANY]: {
|
|
127
|
+
variants: [
|
|
128
|
+
{
|
|
129
|
+
variantType: ResourceOperationVariantType.INTERNAL_CALL,
|
|
130
|
+
isDefault: true,
|
|
131
|
+
roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
132
|
+
riskLevel: ResourceOperationRiskLevel.CRITICAL,
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
},
|
|
74
136
|
[CoreResourceOperation.READ]: {
|
|
75
137
|
variants: [
|
|
76
138
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-profiles.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/users/user-profiles.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Profiles Shared Resource Configuration\n *\n * Resource configuration for user profile management operations.\n * Handles profile information like name, avatar, bio, contact details.\n */\n\nimport { z } from 'zod';\nimport { UserProfileSchema } from './users.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } 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, acknowledgeUnimplementedEngineOperation } from '../resources/resources-config.shared.schemas';\n\nimport { CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\n// Custom operations enum for user profile management.\n//\n// There is deliberately no `verify_phone` here. Proving possession of a phone number is a\n// challenge/response against an issued code, and the framework already implements exactly that in\n// `AuthPhoneVerificationBackendService`: `CoreConsumableTokenTypes.PHONE_VERIFICATION` tokens\n// (single-use, 10-minute expiry, revoke-then-issue), a constant-time `timingSafeEqual` comparison,\n// an audit event on BOTH the success and the failure path, and the verified state persisted via\n// `setVerifiedPhone`. `AuthMethod.SMS_OTP` covers the same proof as a first-or-second auth factor\n// with its own rate limits and audit events. `USER_SELF_PROFILES` — the resource where a subject\n// edits their OWN profile — dropped its equivalent op for the same reason. A `verify_phone` on\n// THIS resource would be worse still: `USER_PROFILES` is the admin/directory surface, and an SMS\n// code proves possession by the phone's OWNER, not by the admin submitting it. Route phone-factor\n// work to the auth service, not to a second challenge store hanging off the profile row.\nexport enum UserProfiles_Operations {\n UPDATE_AVATAR = 'update_avatar', // Update user avatar\n REMOVE_AVATAR = 'remove_avatar', // Remove user avatar\n UPDATE_CONTACT_INFO = 'update_contact_info', // Update contact information\n}\n\ntype UserProfilesCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE;\n\n/*\nUser Profiles Resource Configuration Factory\n*/\nexport const userProfilesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n typeof UserProfiles_Operations,\n UserProfilesCoreOperations,\n typeof UserProfileSchema\n>({\n mainSchema: UserProfileSchema,\n resourceIdentifier: CoreResourceType.USER_PROFILES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_PROFILES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n // Registration / invitation / SSO-JIT flows create a profile in-process with an\n // explicit `userId` FK on a request-context-less EC, which the client-shaped\n // CREATE DTO strips by name. Opt CREATE into the trusted `createAsSystem` path\n // so `userId` is re-attached after the strict parse.\n //\n // UPDATE is opted into the same trust class: enterprise SSO + SCIM directory sync\n // update profile attributes (EnterpriseUserProvisioningService.updateOrgUser) on a\n // synthesised super-admin EC. Routing them through `updateAsSystem` keeps every\n // trusted profile mutation on one fail-closed, policy-gated path and records the\n // ACL-bypassing write in the SYSTEM_CONTEXT_WRITE audit trail (parity with reads).\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED,\n create: ResourceSystemAccessMode.ALLOWED,\n update: ResourceSystemAccessMode.ALLOWED,\n },\n\n /**\n * Subject-export disclosure. Admin door onto the same profile rows.\n */\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: UserProfiles_Operations,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Users can read their own and others' profiles\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: false,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_VIEWER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n // The default variant remains self-only. This explicit admission lets\n // the separately role-gated administration variant address another\n // user's profile without weakening the APP_USER route.\n admitsCrossSubjectUserAdministration: true,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: true,\n searchableFields: ['firstName', 'lastName', 'displayName'],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: ['firstName', 'lastName'],\n maxPaginatedResultPerPageLimit: 50,\n },\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: false,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_VIEWER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n admitsCrossSubjectUserAdministration: true,\n isSearchable: true,\n searchableFields: ['firstName', 'lastName', 'displayName', 'phoneNumber'],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: ['firstName', 'lastName'],\n maxPaginatedResultPerPageLimit: 200,\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Users can create their own profile\n riskLevel: ResourceOperationRiskLevel.LOW,\n // requestDto auto-derived from decorators\n },\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: false,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n admitsCrossSubjectUserAdministration: true,\n // requestDto auto-derived from decorators\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Users can update their own profile\n riskLevel: ResourceOperationRiskLevel.LOW,\n // requestDto auto-derived from decorators\n },\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: false,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n admitsCrossSubjectUserAdministration: true,\n // requestDto auto-derived from decorators\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Users can delete their own profile\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n },\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: false,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n admitsCrossSubjectUserAdministration: true,\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [UserProfiles_Operations.UPDATE_AVATAR]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n // The profile schema owns the upload-only file reference contract.\n // Reusing it prevents this convenience route from accepting an\n // external URL that persistence cannot store as an avatar.\n requestDto: z.object({\n avatar: UserProfileSchema.shape.avatar.unwrap(),\n }),\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [UserProfiles_Operations.REMOVE_AVATAR]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n // A verb whose entire job is to clear ONE field must not accept the whole profile.\n // Omitting `requestDto` auto-derived the FULL profile update DTO\n // (`{firstName, lastName, displayName, avatar, bio, phoneNumber, title}`), so\n // \"remove_avatar\" was an unconstrained profile rewrite that never had to touch the\n // avatar at all.\n requestDto: z.object({}),\n // Narrowing exposes that the clearing itself was never implemented — the overbroad\n // contract was the only thing making this operation appear to write. Clearing an\n // avatar is NOT a plain `{avatar: null}` patch: the field is `z_file(...).optional()`\n // (not `.nullish()`), so a null would fail the response projection, and dropping the\n // reference without releasing the stored object orphans the uploaded file. Both\n // belong to the file-management pipeline, so this is acknowledged (and now refuses)\n // rather than half-implemented here.\n unimplementedAcknowledgement: acknowledgeUnimplementedEngineOperation(\n 'Clearing an avatar needs the file pipeline, not a field patch: `avatar` is `z_file(...).optional()`, so writing `null` fails the response projection (the field would first have to become `.nullish()` — a schema reshape with its own blast radius), and releasing the stored object requires the file-deletion path or the upload is orphaned. Implement alongside file management; until then this refuses instead of silently rewriting the rest of the profile.',\n ),\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [UserProfiles_Operations.UPDATE_CONTACT_INFO]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n // A named \"update contact info\" call must perform a change; an empty\n // body was previously accepted as a successful no-op. The same\n // canonical phone schema now governs both the main update and this\n // focused route.\n requestDto: z.object({\n phoneNumber: UserProfileSchema.shape.phoneNumber.unwrap(),\n }),\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"user-profiles.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/users/user-profiles.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Profiles Shared Resource Configuration\n *\n * Resource configuration for user profile management operations.\n * Handles profile information like name, avatar, bio, contact details.\n */\n\nimport { z } from 'zod';\nimport { UserProfileSchema } from './users.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } 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, acknowledgeUnimplementedEngineOperation } from '../resources/resources-config.shared.schemas';\n\nimport { CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\n// Custom operations enum for user profile management.\n//\n// There is deliberately no `verify_phone` here. Proving possession of a phone number is a\n// challenge/response against an issued code, and the framework already implements exactly that in\n// `AuthPhoneVerificationBackendService`: `CoreConsumableTokenTypes.PHONE_VERIFICATION` tokens\n// (single-use, 10-minute expiry, revoke-then-issue), a constant-time `timingSafeEqual` comparison,\n// an audit event on BOTH the success and the failure path, and the verified state persisted via\n// `setVerifiedPhone`. `AuthMethod.SMS_OTP` covers the same proof as a first-or-second auth factor\n// with its own rate limits and audit events. `USER_SELF_PROFILES` — the resource where a subject\n// edits their OWN profile — dropped its equivalent op for the same reason. A `verify_phone` on\n// THIS resource would be worse still: `USER_PROFILES` is the admin/directory surface, and an SMS\n// code proves possession by the phone's OWNER, not by the admin submitting it. Route phone-factor\n// work to the auth service, not to a second challenge store hanging off the profile row.\nexport enum UserProfiles_Operations {\n UPDATE_AVATAR = 'update_avatar', // Update user avatar\n REMOVE_AVATAR = 'remove_avatar', // Remove user avatar\n UPDATE_CONTACT_INFO = 'update_contact_info', // Update contact information\n}\n\ntype UserProfilesCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE\n | CoreResourceOperation.LIST\n | CoreResourceOperation.UPDATE_MANY;\n\n/*\nUser Profiles Resource Configuration Factory\n*/\nexport const userProfilesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n typeof UserProfiles_Operations,\n UserProfilesCoreOperations,\n typeof UserProfileSchema\n>({\n mainSchema: UserProfileSchema,\n resourceIdentifier: CoreResourceType.USER_PROFILES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_PROFILES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n // Registration / invitation / SSO-JIT flows create a profile in-process with an\n // explicit `userId` FK on a request-context-less EC, which the client-shaped\n // CREATE DTO strips by name. Opt CREATE into the trusted `createAsSystem` path\n // so `userId` is re-attached after the strict parse.\n //\n // UPDATE is opted into the same trust class: enterprise SSO + SCIM directory sync\n // update profile attributes (EnterpriseUserProvisioningService.updateOrgUser) on a\n // synthesised super-admin EC. Routing them through `updateAsSystem` keeps every\n // trusted profile mutation on one fail-closed, policy-gated path and records the\n // ACL-bypassing write in the SYSTEM_CONTEXT_WRITE audit trail (parity with reads).\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED,\n create: ResourceSystemAccessMode.ALLOWED,\n update: ResourceSystemAccessMode.ALLOWED,\n },\n\n /**\n * Subject-export disclosure. Admin door onto the same profile rows.\n */\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },\n\n /**\n * Subject erasure scrubs-and-RETAINS the profile row rather than deleting it.\n *\n * `RETAIN_AND_IMPERSONALIZE` because this row holds personal data of its OWN — names, avatar, bio,\n * phone, title — which the treatments on the shared `UserProfileSchema` mask or remove. The two\n * required name fields MASK to `ERASED_USER_NAME` rather than REMOVE: they are `min(1)`, so nulling\n * them would leave a row the schema rejects on the next read.\n *\n * RETAIN rather than delete, to match the identity row. `USERS` is retained so the financial records\n * whose foreign keys point at it stay resolvable; a profile deleted out from under a retained user\n * would leave that user's 1:1 composition dangling. Retaining and scrubbing keeps the collection's\n * contract coherent and removes the personal data, which is what the obligation actually asks.\n *\n * ⚠️ `USER_SELF_PROFILES` declares the SAME policy on purpose — a second config over the SAME\n * collection and the SAME `UserProfileSchema`. Both must inject the same marker and emit the same\n * partial index, exactly as `USERS` / `USER_SELF` do. Change the two together.\n */\n retentionPolicy: {\n mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,\n },\n\n /**\n * The subject IS the person this profile describes, reached through its `userId` composition parent.\n */\n dataSubjectPolicy: { kind: ResourceDataSubjectKind.SELF_PRINCIPAL },\n\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n CoreResourceOperation.DELETE,\n // LIST + UPDATE_MANY exist for the retention capability ONLY, as INTERNAL_CALL variants that\n // register no route. `retentionPolicy` requires UPDATE_MANY (the in-place scrub via\n // `updateManyAsSystem`) plus READ + LIST (the audited see-through read of retained rows).\n CoreResourceOperation.LIST,\n CoreResourceOperation.UPDATE_MANY,\n ],\n\n customOperation: UserProfiles_Operations,\n\n operationsConfiguration: {\n /*\n * Route-less retention plumbing. Both are INTERNAL_CALL, *not* REPOSITORY_ONLY: the retention\n * primitives resolve through `getServiceOperationPathDefault`, which matches INTERNAL_CALL /\n * API_CALL / API_CALL_WITH_CALLBACK and deliberately excludes REPOSITORY_ONLY — so a\n * REPOSITORY_ONLY variant satisfies the factory's boot-time \"operation exists\" guard and then\n * FAILS TO RESOLVE when an erasure actually runs. `roles` is inert on a non-URL-bearing variant;\n * the real gate is the derived `systemAccessPolicy` grant the trusted writer fails closed on.\n */\n [CoreResourceOperation.LIST]: {\n variants: [\n {\n // LOW, matching `USER_SELF`'s retention LIST. A read-shaped operation may not be declared\n // HIGH/CRITICAL — the audit contract pairs that band with an emission obligation, and it is\n // checked over the real engine catalogue. Declaring HIGH here failed both halves of that\n // check at once: an unemitted HIGH, and a read at a write's risk band.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n ],\n },\n [CoreResourceOperation.UPDATE_MANY]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n },\n ],\n },\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Users can read their own and others' profiles\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: false,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_VIEWER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n // The default variant remains self-only. This explicit admission lets\n // the separately role-gated administration variant address another\n // user's profile without weakening the APP_USER route.\n admitsCrossSubjectUserAdministration: true,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: true,\n searchableFields: ['firstName', 'lastName', 'displayName'],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: ['firstName', 'lastName'],\n maxPaginatedResultPerPageLimit: 50,\n },\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: false,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_VIEWER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n admitsCrossSubjectUserAdministration: true,\n isSearchable: true,\n searchableFields: ['firstName', 'lastName', 'displayName', 'phoneNumber'],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: ['firstName', 'lastName'],\n maxPaginatedResultPerPageLimit: 200,\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Users can create their own profile\n riskLevel: ResourceOperationRiskLevel.LOW,\n // requestDto auto-derived from decorators\n },\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: false,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n admitsCrossSubjectUserAdministration: true,\n // requestDto auto-derived from decorators\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Users can update their own profile\n riskLevel: ResourceOperationRiskLevel.LOW,\n // requestDto auto-derived from decorators\n },\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: false,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n admitsCrossSubjectUserAdministration: true,\n // requestDto auto-derived from decorators\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Users can delete their own profile\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n },\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: false,\n variantKey: \"admin\",\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n admitsCrossSubjectUserAdministration: true,\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [UserProfiles_Operations.UPDATE_AVATAR]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n // The profile schema owns the upload-only file reference contract.\n // Reusing it prevents this convenience route from accepting an\n // external URL that persistence cannot store as an avatar.\n requestDto: z.object({\n avatar: UserProfileSchema.shape.avatar.unwrap(),\n }),\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [UserProfiles_Operations.REMOVE_AVATAR]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n // A verb whose entire job is to clear ONE field must not accept the whole profile.\n // Omitting `requestDto` auto-derived the FULL profile update DTO\n // (`{firstName, lastName, displayName, avatar, bio, phoneNumber, title}`), so\n // \"remove_avatar\" was an unconstrained profile rewrite that never had to touch the\n // avatar at all.\n requestDto: z.object({}),\n // Narrowing exposes that the clearing itself was never implemented — the overbroad\n // contract was the only thing making this operation appear to write. Clearing an\n // avatar is NOT a plain `{avatar: null}` patch: the field is `z_file(...).optional()`\n // (not `.nullish()`), so a null would fail the response projection, and dropping the\n // reference without releasing the stored object orphans the uploaded file. Both\n // belong to the file-management pipeline, so this is acknowledged (and now refuses)\n // rather than half-implemented here.\n unimplementedAcknowledgement: acknowledgeUnimplementedEngineOperation(\n 'Clearing an avatar needs the file pipeline, not a field patch: `avatar` is `z_file(...).optional()`, so writing `null` fails the response projection (the field would first have to become `.nullish()` — a schema reshape with its own blast radius), and releasing the stored object requires the file-deletion path or the upload is orphaned. Implement alongside file management; until then this refuses instead of silently rewriting the rest of the profile.',\n ),\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [UserProfiles_Operations.UPDATE_CONTACT_INFO]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n // A named \"update contact info\" call must perform a change; an empty\n // body was previously accepted as a successful no-op. The same\n // canonical phone schema now governs both the main update and this\n // focused route.\n requestDto: z.object({\n phoneNumber: UserProfileSchema.shape.phoneNumber.unwrap(),\n }),\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n },\n});\n"]}
|
|
@@ -10,7 +10,7 @@ import { ResourceRelationship } from '../resources/resources.shared.schemas';
|
|
|
10
10
|
export declare enum UserSelfPreferences_Operations {
|
|
11
11
|
RESET_TO_DEFAULTS = "reset_to_defaults"
|
|
12
12
|
}
|
|
13
|
-
type UserSelfPreferencesCoreOperations = CoreResourceOperation.READ | CoreResourceOperation.UPDATE;
|
|
13
|
+
type UserSelfPreferencesCoreOperations = CoreResourceOperation.READ | CoreResourceOperation.LIST | CoreResourceOperation.UPDATE_MANY | CoreResourceOperation.UPDATE;
|
|
14
14
|
export declare const userSelfPreferencesResourceConfiguration_InitializationFactory: (resourcesRelationships: ResourceRelationship[]) => import("..").ResourceConfiguration<typeof UserSelfPreferences_Operations, UserSelfPreferencesCoreOperations, import("zod").ZodObject<{
|
|
15
15
|
_id: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("zod").ZodString>>;
|
|
16
16
|
userId: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("zod").ZodString>>>>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-self-preferences.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/users/user-self-preferences.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"user-self-preferences.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/users/user-self-preferences.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAA8B,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAgBzG,oBAAY,8BAA8B;IACxC,iBAAiB,sBAAsB;CACxC;AAED,KAAK,iCAAiC,GAClC,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,WAAW,GACjC,qBAAqB,CAAC,MAAM,CAAC;AAKjC,eAAO,MAAM,8DAA8D,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAoK3H,CAAC"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* Separated from USER_PREFERENCES for strict access control.
|
|
7
7
|
*/
|
|
8
8
|
import { UserPreferencesSchema, } from './users.shared.schemas.js';
|
|
9
|
+
import { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas.js';
|
|
9
10
|
import { buildUserPreferencesResetPatch, UserPreferencesResetRequestSchema } from './user-preferences-reset.shared.utils.js';
|
|
10
11
|
import { CoreResourceOperation } from '../resources/resources.shared.core.definitions.js';
|
|
11
12
|
import { ResourceOperationRiskLevel } from '../resources/resources.shared.schemas.js';
|
|
@@ -42,12 +43,64 @@ export const userSelfPreferencesResourceConfiguration_InitializationFactory = (r
|
|
|
42
43
|
* Subject-export disclosure. Settings the user chose.
|
|
43
44
|
*/
|
|
44
45
|
portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },
|
|
46
|
+
/**
|
|
47
|
+
* Subject erasure RETAINS the preferences row and RESETS what it holds.
|
|
48
|
+
*
|
|
49
|
+
* `RETAIN_AND_IMPERSONALIZE`: notification routing, privacy choices, regional settings (which carry
|
|
50
|
+
* LOCATION — a timezone and a locale narrow where a person is) and language preferences are all a
|
|
51
|
+
* record of one person's choices. All four take `RESET`, returning the application's own defaults.
|
|
52
|
+
*
|
|
53
|
+
* RESET rather than REMOVE, and the distinction is why this resource could not be declared at all
|
|
54
|
+
* until 2026-09-01: every one of these fields is non-nullable with a schema default, so a null fails
|
|
55
|
+
* the strict re-parse and `maskValue` (typed `string`) cannot express an object. Neither mode was
|
|
56
|
+
* authorable — `RETAIN_AND_IMPERSONALIZE` is refused when nothing would be scrubbed, and
|
|
57
|
+
* `RETAIN_ONLY` would have asserted this resource holds no personal data, which is false.
|
|
58
|
+
*
|
|
59
|
+
* ⚠️ `USER_SELF_PREFERENCES` declares the SAME policy on purpose — a second config over the SAME
|
|
60
|
+
* collection and the SAME schema, so both must inject the same marker and emit the same partial
|
|
61
|
+
* index. Change the two together, as `USERS` / `USER_SELF` documents.
|
|
62
|
+
*/
|
|
63
|
+
retentionPolicy: {
|
|
64
|
+
mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,
|
|
65
|
+
},
|
|
66
|
+
/** The subject is the person whose preferences these are, reached through `userId`. */
|
|
67
|
+
dataSubjectPolicy: { kind: ResourceDataSubjectKind.SELF_PRINCIPAL },
|
|
45
68
|
coreOperations: [
|
|
46
69
|
CoreResourceOperation.READ,
|
|
47
70
|
CoreResourceOperation.UPDATE,
|
|
71
|
+
// Route-less; required by `retentionPolicy` (the in-place scrub + audited see-through read).
|
|
72
|
+
CoreResourceOperation.LIST,
|
|
73
|
+
CoreResourceOperation.UPDATE_MANY,
|
|
48
74
|
],
|
|
49
75
|
customOperation: UserSelfPreferences_Operations,
|
|
50
76
|
operationsConfiguration: {
|
|
77
|
+
/*
|
|
78
|
+
* Route-less retention plumbing. INTERNAL_CALL registers NO route, and must not be
|
|
79
|
+
* REPOSITORY_ONLY: the retention primitives resolve through `getServiceOperationPathDefault`,
|
|
80
|
+
* which excludes it, so that spelling passes the boot guard and fails when an erasure runs.
|
|
81
|
+
* LIST is LOW — a read-shaped operation may not claim the HIGH/CRITICAL band, which carries an
|
|
82
|
+
* audit-emission obligation checked over the real engine catalogue.
|
|
83
|
+
*/
|
|
84
|
+
[CoreResourceOperation.LIST]: {
|
|
85
|
+
variants: [
|
|
86
|
+
{
|
|
87
|
+
variantType: ResourceOperationVariantType.INTERNAL_CALL,
|
|
88
|
+
isDefault: true,
|
|
89
|
+
roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
90
|
+
riskLevel: ResourceOperationRiskLevel.LOW,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
[CoreResourceOperation.UPDATE_MANY]: {
|
|
95
|
+
variants: [
|
|
96
|
+
{
|
|
97
|
+
variantType: ResourceOperationVariantType.INTERNAL_CALL,
|
|
98
|
+
isDefault: true,
|
|
99
|
+
roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
100
|
+
riskLevel: ResourceOperationRiskLevel.CRITICAL,
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
},
|
|
51
104
|
[CoreResourceOperation.READ]: {
|
|
52
105
|
variants: [
|
|
53
106
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-self-preferences.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/users/user-self-preferences.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Self Preferences Shared Resource Configuration\n *\n * Resource configuration for user self preferences management operations.\n * Handles preferences that users can manage for themselves only.\n * Separated from USER_PREFERENCES for strict access control.\n */\n\nimport {\n UserPreferencesSchema,\n} from './users.shared.schemas';\nimport { buildUserPreferencesResetPatch, UserPreferencesResetRequestSchema } from './user-preferences-reset.shared.utils';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } 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';\n\nimport { CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\n// Custom operations enum for user self preferences management.\n// Granular per-section update ops (notifications / privacy / ui-theme / regional /\n// language / dark-mode toggle) were removed: editing happens through the generic\n// UPDATE form, and theme/dark-mode live in the Appearance panel — not as resource\n// operations. Only the genuinely-distinct action remains.\nexport enum UserSelfPreferences_Operations {\n RESET_TO_DEFAULTS = 'reset_to_defaults', // Reset all preferences to defaults\n}\n\ntype UserSelfPreferencesCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.UPDATE;\n\n/*\nUser Self Preferences Resource Configuration Factory\n*/\nexport const userSelfPreferencesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n typeof UserSelfPreferences_Operations,\n UserSelfPreferencesCoreOperations,\n typeof UserPreferencesSchema\n>({\n mainSchema: UserPreferencesSchema,\n resourceIdentifier: CoreResourceType.USER_SELF_PREFERENCES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_SELF_PREFERENCES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true, // Self-scoped resource - same user context\n\n /**\n * Subject-export disclosure. Settings the user chose.\n */\n systemAccessPolicy: { exportSubject: ResourceSystemAccessMode.ALLOWED },\n\n /**\n * Subject-export disclosure. Settings the user chose.\n */\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.UPDATE,\n ],\n\n customOperation: UserSelfPreferences_Operations,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Only self can read their own preferences\n riskLevel: ResourceOperationRiskLevel.LOW,\n // MCP: exposed to a USER-DELEGATED agent caller only. A machine principal carries no\n // `userId`, so this USER_SELF operation is not in its reachable scope set and is never\n // advertised to it. The record resolves to the CALLER's own preferences (the execution\n // context is scoped by the authenticated `userId`), so an agent can read the preferences\n // of the user who consented — never another user's.\n mcp: {\n exposed: true,\n description: 'Read the preferences of the user you are acting for (locale, timezone, theme, notification settings). Returns only that user\\'s own preferences.',\n },\n }\n ]\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Only self can update their own preferences\n riskLevel: ResourceOperationRiskLevel.LOW,\n // requestDto auto-derived from decorators\n // MCP: same USER-DELEGATED-only exposure as READ above. The write targets the CALLER's own\n // preferences record; a machine principal never sees this tool.\n mcp: {\n exposed: true,\n description: 'Update the preferences of the user you are acting for (e.g. locale, timezone, theme, notification settings). Only supply the fields being changed; affects only that user\\'s own preferences.',\n },\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [UserSelfPreferences_Operations.RESET_TO_DEFAULTS]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n // CRITICAL: a full/selective reset wipes the user's preferences — it must\n // require an explicit double-validation confirmation (see the framework\n // topics plan: settings-hub-framework-topics.md).\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n // The caller names WHICH blocks to reset, from the closed `UserPreferenceGroup`\n // vocabulary whose values ARE the persisted field names. It previously declared six\n // booleans (`resetNotifications`, `resetAll`, …) which name no schema path, so the\n // whole request was stripped — by the controller DTO parse, the repository re-parse,\n // and Mongoose strict — and the route answered 200 having reset nothing.\n requestDto: UserPreferencesResetRequestSchema,\n basicPrefixOperation: ({ inputDto, currentObject }) =>\n buildUserPreferencesResetPatch(\n // `inputDto` is typed as the resource main schema while the runtime value is this\n // operation's request DTO, so re-parse rather than cast — the same idiom the\n // Wonder Todos `set_as_recurring` prefix uses. Doubles as a fail-closed guard on\n // any non-HTTP path that reached dispatch without the controller's parse.\n UserPreferencesResetRequestSchema.parse(inputDto),\n currentObject,\n ),\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n }\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"user-self-preferences.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/users/user-self-preferences.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Self Preferences Shared Resource Configuration\n *\n * Resource configuration for user self preferences management operations.\n * Handles preferences that users can manage for themselves only.\n * Separated from USER_PREFERENCES for strict access control.\n */\n\nimport {\n UserPreferencesSchema,\n} from './users.shared.schemas';\nimport { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas';\nimport { buildUserPreferencesResetPatch, UserPreferencesResetRequestSchema } from './user-preferences-reset.shared.utils';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } 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';\n\nimport { CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\n// Custom operations enum for user self preferences management.\n// Granular per-section update ops (notifications / privacy / ui-theme / regional /\n// language / dark-mode toggle) were removed: editing happens through the generic\n// UPDATE form, and theme/dark-mode live in the Appearance panel — not as resource\n// operations. Only the genuinely-distinct action remains.\nexport enum UserSelfPreferences_Operations {\n RESET_TO_DEFAULTS = 'reset_to_defaults', // Reset all preferences to defaults\n}\n\ntype UserSelfPreferencesCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.LIST\n | CoreResourceOperation.UPDATE_MANY\n | CoreResourceOperation.UPDATE;\n\n/*\nUser Self Preferences Resource Configuration Factory\n*/\nexport const userSelfPreferencesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n typeof UserSelfPreferences_Operations,\n UserSelfPreferencesCoreOperations,\n typeof UserPreferencesSchema\n>({\n mainSchema: UserPreferencesSchema,\n resourceIdentifier: CoreResourceType.USER_SELF_PREFERENCES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_SELF_PREFERENCES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true, // Self-scoped resource - same user context\n\n /**\n * Subject-export disclosure. Settings the user chose.\n */\n systemAccessPolicy: { exportSubject: ResourceSystemAccessMode.ALLOWED },\n\n /**\n * Subject-export disclosure. Settings the user chose.\n */\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },\n\n\n /**\n * Subject erasure RETAINS the preferences row and RESETS what it holds.\n *\n * `RETAIN_AND_IMPERSONALIZE`: notification routing, privacy choices, regional settings (which carry\n * LOCATION — a timezone and a locale narrow where a person is) and language preferences are all a\n * record of one person's choices. All four take `RESET`, returning the application's own defaults.\n *\n * RESET rather than REMOVE, and the distinction is why this resource could not be declared at all\n * until 2026-09-01: every one of these fields is non-nullable with a schema default, so a null fails\n * the strict re-parse and `maskValue` (typed `string`) cannot express an object. Neither mode was\n * authorable — `RETAIN_AND_IMPERSONALIZE` is refused when nothing would be scrubbed, and\n * `RETAIN_ONLY` would have asserted this resource holds no personal data, which is false.\n *\n * ⚠️ `USER_SELF_PREFERENCES` declares the SAME policy on purpose — a second config over the SAME\n * collection and the SAME schema, so both must inject the same marker and emit the same partial\n * index. Change the two together, as `USERS` / `USER_SELF` documents.\n */\n retentionPolicy: {\n mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,\n },\n\n /** The subject is the person whose preferences these are, reached through `userId`. */\n dataSubjectPolicy: { kind: ResourceDataSubjectKind.SELF_PRINCIPAL },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.UPDATE,\n // Route-less; required by `retentionPolicy` (the in-place scrub + audited see-through read).\n CoreResourceOperation.LIST,\n CoreResourceOperation.UPDATE_MANY,\n ],\n\n customOperation: UserSelfPreferences_Operations,\n\n operationsConfiguration: {\n /*\n * Route-less retention plumbing. INTERNAL_CALL registers NO route, and must not be\n * REPOSITORY_ONLY: the retention primitives resolve through `getServiceOperationPathDefault`,\n * which excludes it, so that spelling passes the boot guard and fails when an erasure runs.\n * LIST is LOW — a read-shaped operation may not claim the HIGH/CRITICAL band, which carries an\n * audit-emission obligation checked over the real engine catalogue.\n */\n [CoreResourceOperation.LIST]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n ],\n },\n [CoreResourceOperation.UPDATE_MANY]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n },\n ],\n },\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Only self can read their own preferences\n riskLevel: ResourceOperationRiskLevel.LOW,\n // MCP: exposed to a USER-DELEGATED agent caller only. A machine principal carries no\n // `userId`, so this USER_SELF operation is not in its reachable scope set and is never\n // advertised to it. The record resolves to the CALLER's own preferences (the execution\n // context is scoped by the authenticated `userId`), so an agent can read the preferences\n // of the user who consented — never another user's.\n mcp: {\n exposed: true,\n description: 'Read the preferences of the user you are acting for (locale, timezone, theme, notification settings). Returns only that user\\'s own preferences.',\n },\n }\n ]\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Only self can update their own preferences\n riskLevel: ResourceOperationRiskLevel.LOW,\n // requestDto auto-derived from decorators\n // MCP: same USER-DELEGATED-only exposure as READ above. The write targets the CALLER's own\n // preferences record; a machine principal never sees this tool.\n mcp: {\n exposed: true,\n description: 'Update the preferences of the user you are acting for (e.g. locale, timezone, theme, notification settings). Only supply the fields being changed; affects only that user\\'s own preferences.',\n },\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [UserSelfPreferences_Operations.RESET_TO_DEFAULTS]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n // CRITICAL: a full/selective reset wipes the user's preferences — it must\n // require an explicit double-validation confirmation (see the framework\n // topics plan: settings-hub-framework-topics.md).\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n // The caller names WHICH blocks to reset, from the closed `UserPreferenceGroup`\n // vocabulary whose values ARE the persisted field names. It previously declared six\n // booleans (`resetNotifications`, `resetAll`, …) which name no schema path, so the\n // whole request was stripped — by the controller DTO parse, the repository re-parse,\n // and Mongoose strict — and the route answered 200 having reset nothing.\n requestDto: UserPreferencesResetRequestSchema,\n basicPrefixOperation: ({ inputDto, currentObject }) =>\n buildUserPreferencesResetPatch(\n // `inputDto` is typed as the resource main schema while the runtime value is this\n // operation's request DTO, so re-parse rather than cast — the same idiom the\n // Wonder Todos `set_as_recurring` prefix uses. Doubles as a fail-closed guard on\n // any non-HTTP path that reached dispatch without the controller's parse.\n UserPreferencesResetRequestSchema.parse(inputDto),\n currentObject,\n ),\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n }\n },\n});\n"]}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { CoreResourceOperation } from '../resources/resources.shared.core.definitions';
|
|
9
9
|
import { ResourceRelationship } from '../resources/resources.shared.schemas';
|
|
10
|
-
type UserSelfProfilesCoreOperations = CoreResourceOperation.READ | CoreResourceOperation.UPDATE | CoreResourceOperation.CREATE;
|
|
10
|
+
type UserSelfProfilesCoreOperations = CoreResourceOperation.READ | CoreResourceOperation.UPDATE | CoreResourceOperation.CREATE | CoreResourceOperation.LIST | CoreResourceOperation.UPDATE_MANY;
|
|
11
11
|
export declare const userSelfProfilesResourceConfiguration_InitializationFactory: (resourcesRelationships: ResourceRelationship[]) => import("..").ResourceConfiguration<Record<string, never>, UserSelfProfilesCoreOperations, import("zod").ZodObject<{
|
|
12
12
|
_id: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("zod").ZodString>>;
|
|
13
13
|
userId: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("zod").ZodString>>>>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-self-profiles.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/users/user-self-profiles.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAA8B,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"user-self-profiles.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/users/user-self-profiles.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAA8B,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAgBzG,KAAK,8BAA8B,GAC/B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,WAAW,CAAC;AAKtC,eAAO,MAAM,2DAA2D,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;iCA6IxH,CAAC"}
|
|
@@ -14,6 +14,7 @@ import { CoreUserNotificationTarget, CoreUserNotificationChannel } from '../noti
|
|
|
14
14
|
import { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory.js';
|
|
15
15
|
import { CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas.js';
|
|
16
16
|
import { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas.js';
|
|
17
|
+
import { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas.js';
|
|
17
18
|
import { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas.js';
|
|
18
19
|
/*
|
|
19
20
|
User Self Profiles Resource Configuration Factory
|
|
@@ -32,13 +33,74 @@ export const userSelfProfilesResourceConfiguration_InitializationFactory = (reso
|
|
|
32
33
|
* Subject-export disclosure. Name, bio, avatar — supplied by the user.
|
|
33
34
|
*/
|
|
34
35
|
portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },
|
|
36
|
+
/**
|
|
37
|
+
* Subject erasure scrubs-and-RETAINS the profile row rather than deleting it.
|
|
38
|
+
*
|
|
39
|
+
* `RETAIN_AND_IMPERSONALIZE` because this row holds personal data of its OWN — names, avatar, bio,
|
|
40
|
+
* phone, title — which the treatments on the shared `UserProfileSchema` mask or remove. The two
|
|
41
|
+
* required name fields MASK to `ERASED_USER_NAME` rather than REMOVE: they are `min(1)`, so nulling
|
|
42
|
+
* them would leave a row the schema rejects on the next read.
|
|
43
|
+
*
|
|
44
|
+
* RETAIN rather than delete, to match the identity row. `USERS` is retained so the financial records
|
|
45
|
+
* whose foreign keys point at it stay resolvable; a profile deleted out from under a retained user
|
|
46
|
+
* would leave that user's 1:1 composition dangling. Retaining and scrubbing keeps the collection's
|
|
47
|
+
* contract coherent and removes the personal data, which is what the obligation actually asks.
|
|
48
|
+
*
|
|
49
|
+
* ⚠️ `USER_SELF_PROFILES` declares the SAME policy on purpose — a second config over the SAME
|
|
50
|
+
* collection and the SAME `UserProfileSchema`. Both must inject the same marker and emit the same
|
|
51
|
+
* partial index, exactly as `USERS` / `USER_SELF` do. Change the two together.
|
|
52
|
+
*/
|
|
53
|
+
retentionPolicy: {
|
|
54
|
+
mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* The subject IS the person this profile describes, reached through its `userId` composition parent.
|
|
58
|
+
*/
|
|
59
|
+
dataSubjectPolicy: { kind: ResourceDataSubjectKind.SELF_PRINCIPAL },
|
|
35
60
|
coreOperations: [
|
|
36
61
|
CoreResourceOperation.READ,
|
|
37
62
|
CoreResourceOperation.UPDATE,
|
|
38
63
|
CoreResourceOperation.CREATE,
|
|
64
|
+
// LIST + UPDATE_MANY exist for the retention capability ONLY, as INTERNAL_CALL variants that
|
|
65
|
+
// register no route. `retentionPolicy` requires UPDATE_MANY (the in-place scrub via
|
|
66
|
+
// `updateManyAsSystem`) plus READ + LIST (the audited see-through read of retained rows).
|
|
67
|
+
CoreResourceOperation.LIST,
|
|
68
|
+
CoreResourceOperation.UPDATE_MANY,
|
|
39
69
|
],
|
|
40
70
|
customOperation: {},
|
|
41
71
|
operationsConfiguration: {
|
|
72
|
+
/*
|
|
73
|
+
* Route-less retention plumbing. Both are INTERNAL_CALL, *not* REPOSITORY_ONLY: the retention
|
|
74
|
+
* primitives resolve through `getServiceOperationPathDefault`, which matches INTERNAL_CALL /
|
|
75
|
+
* API_CALL / API_CALL_WITH_CALLBACK and deliberately excludes REPOSITORY_ONLY — so a
|
|
76
|
+
* REPOSITORY_ONLY variant satisfies the factory's boot-time "operation exists" guard and then
|
|
77
|
+
* FAILS TO RESOLVE when an erasure actually runs. `roles` is inert on a non-URL-bearing variant;
|
|
78
|
+
* the real gate is the derived `systemAccessPolicy` grant the trusted writer fails closed on.
|
|
79
|
+
*/
|
|
80
|
+
[CoreResourceOperation.LIST]: {
|
|
81
|
+
variants: [
|
|
82
|
+
{
|
|
83
|
+
// LOW, matching `USER_SELF`'s retention LIST. A read-shaped operation may not be declared
|
|
84
|
+
// HIGH/CRITICAL — the audit contract pairs that band with an emission obligation, and it is
|
|
85
|
+
// checked over the real engine catalogue. Declaring HIGH here failed both halves of that
|
|
86
|
+
// check at once: an unemitted HIGH, and a read at a write's risk band.
|
|
87
|
+
variantType: ResourceOperationVariantType.INTERNAL_CALL,
|
|
88
|
+
isDefault: true,
|
|
89
|
+
roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
90
|
+
riskLevel: ResourceOperationRiskLevel.LOW,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
[CoreResourceOperation.UPDATE_MANY]: {
|
|
95
|
+
variants: [
|
|
96
|
+
{
|
|
97
|
+
variantType: ResourceOperationVariantType.INTERNAL_CALL,
|
|
98
|
+
isDefault: true,
|
|
99
|
+
roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
100
|
+
riskLevel: ResourceOperationRiskLevel.CRITICAL,
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
},
|
|
42
104
|
[CoreResourceOperation.READ]: {
|
|
43
105
|
variants: [
|
|
44
106
|
{
|