@wildo-ai/saas-backend-lib 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/base-classes/services/controllers/controller-resource.backend.service.d.ts +14 -3
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js +115 -22
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts +3 -1
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js +8 -3
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts +11 -0
- package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js +11 -2
- package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts +1 -0
- package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js +6 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js +16 -0
- package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts +20 -6
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js +88 -32
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts +3 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js +32 -7
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts +8 -5
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts +31 -0
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js +127 -5
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts +71 -1
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js +62 -2
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts +21 -0
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js +126 -4
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts +3 -26
- package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js +3 -68
- package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js.map +1 -1
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +4 -2
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js +6 -6
- package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts +38 -0
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js +40 -0
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts +20 -0
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js +28 -0
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts +12 -0
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js +118 -0
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js +8 -5
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js +14 -0
- package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js.map +1 -1
- package/dist/esm/config/custom/application-config-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/config/custom/application-config-controller.backend.service.js +7 -1
- package/dist/esm/config/custom/application-config-controller.backend.service.js.map +1 -1
- package/dist/esm/config/models/app-config.backend.schemas.d.ts +4 -0
- package/dist/esm/config/models/app-config.backend.schemas.d.ts.map +1 -1
- package/dist/esm/config/services/app-configuration.backend.utils.d.ts +10 -1
- package/dist/esm/config/services/app-configuration.backend.utils.d.ts.map +1 -1
- package/dist/esm/config/services/app-configuration.backend.utils.js +13 -2
- package/dist/esm/config/services/app-configuration.backend.utils.js.map +1 -1
- package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.d.ts +2 -2
- package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js +2 -2
- package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js.map +1 -1
- package/dist/esm/databases/models/filter.backend.schemas.js +2 -2
- package/dist/esm/databases/models/filter.backend.schemas.js.map +1 -1
- package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js +20 -1
- package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js.map +1 -1
- package/dist/esm/databases/services/redis.service.d.ts +27 -0
- package/dist/esm/databases/services/redis.service.d.ts.map +1 -1
- package/dist/esm/databases/services/redis.service.js +29 -0
- package/dist/esm/databases/services/redis.service.js.map +1 -1
- package/dist/esm/errors/services/error-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/errors/services/error-handler.backend.service.js +5 -0
- package/dist/esm/errors/services/error-handler.backend.service.js.map +1 -1
- package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts +41 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts.map +1 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js +40 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js.map +1 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts +64 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts.map +1 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js +193 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js.map +1 -0
- package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts +13 -2
- package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-run.backend.service.js +8 -2
- package/dist/esm/external-data/external-data-pipeline-run.backend.service.js.map +1 -1
- package/dist/esm/external-data/external-data-transform.backend.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-transform.backend.js +7 -1
- package/dist/esm/external-data/external-data-transform.backend.js.map +1 -1
- package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts +2 -0
- package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts.map +1 -1
- package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js +13 -0
- package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js.map +1 -1
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +14 -0
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +6 -0
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
- package/dist/esm/files/controllers/file.controller.d.ts +24 -1
- package/dist/esm/files/controllers/file.controller.d.ts.map +1 -1
- package/dist/esm/files/controllers/file.controller.js +66 -2
- package/dist/esm/files/controllers/file.controller.js.map +1 -1
- package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts +17 -0
- package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts.map +1 -0
- package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js +1 -0
- package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js.map +1 -0
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts +5 -1
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js +42 -3
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js.map +1 -1
- package/dist/esm/files/services/file-operation-handler.backend.service.d.ts +18 -0
- package/dist/esm/files/services/file-operation-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-operation-handler.backend.service.js +36 -28
- package/dist/esm/files/services/file-operation-handler.backend.service.js.map +1 -1
- package/dist/esm/files/services/file-upload-grant.backend.service.d.ts +163 -0
- package/dist/esm/files/services/file-upload-grant.backend.service.d.ts.map +1 -0
- package/dist/esm/files/services/file-upload-grant.backend.service.js +442 -0
- package/dist/esm/files/services/file-upload-grant.backend.service.js.map +1 -0
- package/dist/esm/files/services/files.backend.service.d.ts +19 -0
- package/dist/esm/files/services/files.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/files.backend.service.js +78 -15
- package/dist/esm/files/services/files.backend.service.js.map +1 -1
- package/dist/esm/files/utils/file-uploader.utils.d.ts.map +1 -1
- package/dist/esm/files/utils/file-uploader.utils.js +12 -0
- package/dist/esm/files/utils/file-uploader.utils.js.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js +5 -5
- package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts +79 -0
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/agents.backend.service.js +319 -42
- package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts +151 -41
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +300 -139
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
- package/dist/esm/index.d.ts +4 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +14 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/inject/models/container.d.ts.map +1 -1
- package/dist/esm/inject/models/container.js +4 -0
- package/dist/esm/inject/models/container.js.map +1 -1
- package/dist/esm/inject/models/service-types.d.ts +3 -0
- package/dist/esm/inject/models/service-types.d.ts.map +1 -1
- package/dist/esm/inject/models/service-types.js +2 -0
- package/dist/esm/inject/models/service-types.js.map +1 -1
- package/dist/esm/mcp/controllers/mcp.controller.d.ts.map +1 -1
- package/dist/esm/mcp/controllers/mcp.controller.js +12 -4
- package/dist/esm/mcp/controllers/mcp.controller.js.map +1 -1
- package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts +34 -0
- package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts.map +1 -1
- package/dist/esm/mcp/models/mcp-tool.backend.schemas.js +42 -0
- package/dist/esm/mcp/models/mcp-tool.backend.schemas.js.map +1 -1
- package/dist/esm/mcp/services/mcp-server.backend.service.d.ts +29 -1
- package/dist/esm/mcp/services/mcp-server.backend.service.d.ts.map +1 -1
- package/dist/esm/mcp/services/mcp-server.backend.service.js +131 -3
- package/dist/esm/mcp/services/mcp-server.backend.service.js.map +1 -1
- package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts +64 -2
- package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts.map +1 -1
- package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js +130 -6
- package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js.map +1 -1
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts +9 -0
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js +11 -36
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js +9 -7
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts +5 -5
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js +14 -13
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts +2 -1
- package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js +2 -2
- package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js +9 -7
- package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.d.ts.map +1 -1
- package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js +4 -1
- package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js.map +1 -1
- package/dist/esm/requests/service/websocket.service.d.ts.map +1 -1
- package/dist/esm/requests/service/websocket.service.js +56 -7
- package/dist/esm/requests/service/websocket.service.js.map +1 -1
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.d.ts.map +1 -1
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.js +2 -0
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.js.map +1 -1
- package/dist/esm/resources/services/resource-id.backend.service.js +3 -3
- package/dist/esm/resources/services/resource-id.backend.service.js.map +1 -1
- package/dist/esm/resources/services/resources-registry.backend.service.js +1 -1
- package/dist/esm/resources/services/resources-registry.backend.service.js.map +1 -1
- package/dist/esm/runtime/services/execution-context-creator.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/services/execution-context-creator.backend.service.js +13 -7
- package/dist/esm/runtime/services/execution-context-creator.backend.service.js.map +1 -1
- package/dist/esm/runtime/services/start-application.backend.service.d.ts +28 -0
- package/dist/esm/runtime/services/start-application.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/services/start-application.backend.service.js +82 -0
- package/dist/esm/runtime/services/start-application.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts +3 -23
- package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/jwt.backend.schemas.js +20 -45
- package/dist/esm/security/authentications/models/jwt.backend.schemas.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts +9 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js +9 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js +5 -3
- package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts +25 -1
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js +55 -4
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js.map +1 -1
- package/dist/esm/security/authorizations/initiator-organization-confinement.backend.d.ts.map +1 -1
- package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js +24 -1
- package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js.map +1 -1
- package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts +117 -0
- package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts.map +1 -0
- package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js +104 -0
- package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js.map +1 -0
- package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts +101 -6
- package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authorizations/services/authorizations.backend.service.js +210 -30
- package/dist/esm/security/authorizations/services/authorizations.backend.service.js.map +1 -1
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts +18 -1
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js +110 -74
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js.map +1 -1
- package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts +22 -0
- package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts.map +1 -0
- package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js +22 -0
- package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js.map +1 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts +17 -3
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js +12 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts +20 -0
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js +58 -5
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js.map +1 -1
- package/dist/esm/security/jwt/services/jwt.backend.service.d.ts.map +1 -1
- package/dist/esm/security/jwt/services/jwt.backend.service.js +1 -18
- package/dist/esm/security/jwt/services/jwt.backend.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +15 -9
- package/dist/esm/.builder.pid +0 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-api-resource-repository.backend.service.js","sourceRoot":"","sources":["../../../../../../../src/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The HTTP-API resource repository — the third `BackendResourceRepository` implementation\n * (ETL plan Step 3): rows live in a system reached over an authenticated HTTP API and are\n * queried ON DEMAND per the resource's committed `httpApiBinding`.\n *\n * READ-ONLY in slice 1 (decision D3): `read`/`list`/`count`/`search` and the internal-scan\n * variants execute; EVERY other contract member throws `CONFIGURATION` naming the reason\n * (decision D2 — the full contract is implemented, nothing is omitted, nothing returns a\n * fabricated empty result).\n *\n * Query admission is the frozen T-set (paper B) via `translateHttpApiReadInputs` — this class is\n * the boundary that enforces it, because `_doList`/`_doCount` have no repository-side\n * sanitization anywhere else. Row identity is the synthesized id (paper A) via the codec\n * authority; an undecodable id is a LOUD VALIDATION refusal, never a silent not-found (the\n * Mongo CastError→404 behavior is deliberately NOT mimicked). A remote 404 for a well-formed id\n * IS `null` — that is a genuine \"no row\".\n */\n\nimport {\n CoreResourceOperation,\n ErrorType,\n HttpApiResourceIdError,\n PRIMARY_SCOPE_TO_FIELD_IDENTIFIER,\n ResourceOperationVariantType,\n ResourcesConfig_OperationPathUtils,\n ResourceOperationsUtils,\n resolveHttpApiKeyComponents,\n type ResourceType,\n type Resources_PaginatedResult,\n type Resources_PaginationRequest,\n} from '@wildo-ai/saas-models';\nimport {\n HttpApiErasureStance,\n HttpApiTenancyStance,\n HttpApiTransportDialect,\n type HttpApiErasureOperationSpec,\n type HttpApiResourceBinding,\n} from '@wildo-ai/saas-models/external-data';\n\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport type { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport type { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport { ErrorCustomMessageReference } from '@wildo-ai/saas-models';\nimport type { RepositoryOptions } from '~wildo-backend-lib/base-classes/models/repositories.backend.schemas';\n\nimport {\n HttpApiTransportError,\n HttpApiTransportFailureKind,\n type HttpApiFetchLike,\n type HttpApiTransportRequest,\n} from './http-api-transport.backend';\nimport { HttpApiReadClient, defaultHttpApiFetch } from './http-api-read-client.backend';\nimport {\n HttpApiTranslationRefusal,\n translateHttpApiReadInputs,\n} from './http-api-filter-translation.backend';\nimport type { HttpApiTranslatedQuery } from './http-api-query.backend';\nimport {\n compileODataCollectionRead,\n compileODataCountRead,\n compileODataKeyAddressedRead,\n type ODataCompiledRequest,\n} from './odata-query-compiler.backend';\nimport {\n RestJsonTranslationRefusal,\n compileRestJsonCollectionRead,\n compileRestJsonDeclaredErasure,\n compileRestJsonKeyAddressedRead,\n type RestJsonCompiledRequest,\n} from './rest-json-query-compiler.backend';\nimport {\n HttpApiRemoteContractError,\n projectHttpApiRemoteRow,\n resolveHttpApiResultPath,\n} from './http-api-row-projection.backend';\nimport {\n compileOdooCanonicalDelete,\n compileOdooCollectionRead,\n compileOdooCountRead,\n compileOdooKeyAddressedRead,\n type OdooCompiledCall,\n} from './odoo-jsonrpc-compiler.backend';\nimport {\n HttpApiProviderAccessError,\n type HttpApiProviderAccessResolver,\n} from './http-api-provider-access.backend';\n\ntype AnyOperation = { operationIdentifier: string; isOperationDefault?: boolean } & Record<string, unknown>;\n\ntype ListCallOptions = RepositoryOptions & {\n listOptions?: Partial<Resources_PaginationRequest> & { sort?: Record<string, 1 | -1> };\n};\n\n/**\n * The audit seam, structural + lazily resolved (the authorizations-service precedent): the\n * adapter never holds the service, only a thunk the registry handler builds off the container.\n * Absent binding (unit harnesses, partial containers) means no emission — and emission failure\n * must never fail the read it observes.\n */\nexport type HttpApiAuditLogsResolver = () => {\n logHttpApiReadThroughAccess?: (\n data: Record<string, unknown>,\n requestExecutionContext?: ExecutionContext<any>,\n ) => Promise<void>;\n} | undefined;\n\n/**\n * A stance-6b external erasure that stopped mid-way — `deletedCount` is what ALREADY applied\n * remotely before the failure, which is the number that decides PARTIAL (some rows gone, some\n * live) versus FAILED (nothing applied). Deletions are idempotent by key, so the remediation is a\n * re-run of the subject erasure: discovery finds only the surviving rows.\n */\nexport class HttpApiExternalErasureError extends Error {\n constructor(\n message: string,\n public readonly deletedCount: number,\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = 'HttpApiExternalErasureError';\n }\n}\n\nconst READ_FAMILY: ReadonlySet<CoreResourceOperation> = new Set([\n CoreResourceOperation.READ,\n CoreResourceOperation.LIST,\n CoreResourceOperation.COUNT,\n CoreResourceOperation.SEARCH,\n]);\n\nexport class HttpApiResourceRepositoryBackendService {\n private readonly resourceConfiguration: any;\n private readonly binding: HttpApiResourceBinding;\n private readonly operationsMap = new Map<string, AnyOperation>();\n private readonly readClient: HttpApiReadClient;\n private readonly logDebug: (message: string, data?: unknown) => void;\n\n constructor(\n resourceType: ResourceType,\n private readonly logger: LoggerService,\n private readonly errorBuilder: ErrorBuilderBackendService,\n private readonly resourceRegistry: ResourcesRegistryBackendService,\n private readonly providerAccessResolver: HttpApiProviderAccessResolver,\n private readonly fetchImpl: HttpApiFetchLike = defaultHttpApiFetch,\n private readonly auditLogsResolver?: HttpApiAuditLogsResolver,\n ) {\n this.resourceConfiguration = this.resourceRegistry.getResourceConfiguration(resourceType);\n const binding = (this.resourceConfiguration as { httpApiBinding?: HttpApiResourceBinding }).httpApiBinding;\n if (!binding) {\n // The factory enforces presence at authoring; this is the fail-closed backstop for a\n // hand-built configuration reaching construction without one.\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: { reason: 'http_api_resource_without_binding', resourceType },\n });\n }\n this.binding = binding;\n // PR-29: ALL wire mechanics live in the ONE shared client (also consumed by the pipeline\n // extraction source) — this class owns translation/projection/scope/audit/erasure, never framing.\n this.readClient = new HttpApiReadClient(binding, providerAccessResolver, fetchImpl);\n this.logDebug = this.logger.debugByType(`HttpApiRepositoryResource_${resourceType}`);\n this.logger.setDebugTypeLogging(`HttpApiRepositoryResource_${resourceType}`, false);\n\n for (const operation of (this.resourceConfiguration.operations ?? []) as AnyOperation[]) {\n try {\n const path = ResourcesConfig_OperationPathUtils.extractOperationRepositoryPath(operation as never);\n this.operationsMap.set(ResourcesConfig_OperationPathUtils.createOperationRepositoryPathKey(path), operation);\n } catch {\n // An operation with no repository-resolvable identity (no core op, no\n // resourceOperationLike) is simply not addressable through this transport. NOTE this is\n // MORE tolerant than the Mongo sibling's map construction (which propagates); tolerated\n // here because a custom operation with no repository routing is legal on a read-only\n // resource and every read-family core op resolves.\n }\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Dispatch (mirrors the sibling adapters: path → key → operationsMap → doOperation)\n // ─────────────────────────────────────────────────────────────────────────────\n\n public async doByPath<T = any, U = any>(\n operationRepositoryPath: Parameters<typeof ResourcesConfig_OperationPathUtils.createOperationRepositoryPathKey>[0],\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: any,\n data?: U,\n options?: RepositoryOptions,\n ): Promise<T> {\n const key = ResourcesConfig_OperationPathUtils.createOperationRepositoryPathKey(operationRepositoryPath);\n return this.doByKey(key, executionContext, id_or_ids_or_filter, data, options);\n }\n\n public async doByKey<T = any, U = any>(\n operationRepositoryPathKey: string,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: any,\n data?: U,\n options?: RepositoryOptions,\n ): Promise<T> {\n ResourcesConfig_OperationPathUtils.validateOperationRepositoryPathKey(operationRepositoryPathKey);\n const operation = this.operationsMap.get(operationRepositoryPathKey);\n if (!operation) {\n throw this.errorBuilder.buildError(ErrorType.NOT_FOUND, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: {\n reason: 'operation_not_found_on_http_api_repository',\n operationRepositoryPathKey,\n resourceType: this.resourceConfiguration.resourceIdentifier,\n },\n });\n }\n return this.doOperation(operation, executionContext, id_or_ids_or_filter, data, options);\n }\n\n public async doByExecutionContext<T = any>(\n executionContext: ExecutionContext<any>,\n data?: any,\n options?: RepositoryOptions,\n ): Promise<T> {\n const operation = executionContext.operation as unknown as AnyOperation;\n const idFromContext = executionContext.getContextResourceId(\n this.resourceConfiguration.resourceFieldIdentifier,\n );\n return this.doOperation(operation, executionContext, idFromContext, data, options);\n }\n\n private async doOperation(\n operation: AnyOperation,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: any,\n data?: any,\n options?: RepositoryOptions,\n ): Promise<any> {\n const operationIdentifier = ResourceOperationsUtils.getCoreResourceOperationFromOperation(operation as never);\n if (!operationIdentifier || !READ_FAMILY.has(operationIdentifier)) {\n throw this.readOnlyRefusal(String(operationIdentifier ?? operation.operationIdentifier), executionContext);\n }\n switch (operationIdentifier) {\n case CoreResourceOperation.READ:\n if (Array.isArray(id_or_ids_or_filter)) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n context: { reason: 'read_received_id_array', resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n return this._doRead(operation, executionContext, id_or_ids_or_filter, options);\n case CoreResourceOperation.LIST: {\n const idsToList = typeof id_or_ids_or_filter === 'string' ? [id_or_ids_or_filter] : id_or_ids_or_filter;\n return this._doList(operation, executionContext, idsToList, options as ListCallOptions);\n }\n case CoreResourceOperation.COUNT:\n return this._doCount(operation, executionContext, (data?.filter as Record<string, unknown>) ?? {}, options);\n case CoreResourceOperation.SEARCH:\n return this._doSearch(operation, executionContext, data?.query || '', (data?.filter as Record<string, unknown>) ?? {}, {\n ...options,\n searchOptions: (options as { searchOptions?: Record<string, unknown> } | undefined)?.searchOptions ?? {},\n });\n default:\n throw this.readOnlyRefusal(String(operationIdentifier), executionContext);\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Public read-family members (operation resolution mirrors the siblings)\n // ─────────────────────────────────────────────────────────────────────────────\n\n public async read<T = undefined>(\n executionContext: ExecutionContext<any>,\n id_or_filter: any,\n options?: RepositoryOptions,\n ): Promise<any> {\n const operation = this.findDefaultOperation(CoreResourceOperation.READ)\n ?? this.syntheticOperation(CoreResourceOperation.READ);\n return this._doRead(operation, executionContext, id_or_filter, options);\n }\n\n public async readForInternalScan<T = undefined>(\n executionContext: ExecutionContext<any>,\n id_or_filter: any,\n options?: RepositoryOptions,\n ): Promise<any> {\n return this._doRead(this.syntheticOperation(CoreResourceOperation.READ), executionContext, id_or_filter, options);\n }\n\n public async list<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: any,\n options?: ListCallOptions,\n ): Promise<any> {\n const operation = this.findDefaultOperation(CoreResourceOperation.LIST);\n if (!operation) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n context: {\n reason: 'no default LIST operation declared on this resource',\n resourceType: this.resourceConfiguration.resourceIdentifier,\n },\n });\n }\n return this._doList(operation, executionContext, ids_or_filter, options);\n }\n\n public async listForInternalScan<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: any,\n options?: ListCallOptions,\n ): Promise<any> {\n const operation = this.findDefaultOperation(CoreResourceOperation.LIST)\n ?? this.syntheticOperation(CoreResourceOperation.LIST);\n return this._doList(operation, executionContext, ids_or_filter, options);\n }\n\n public async search<T = any>(\n executionContext: ExecutionContext<any>,\n searchQuery: string,\n filter?: any,\n searchOptions?: any,\n options?: RepositoryOptions,\n ): Promise<Resources_PaginatedResult<T>> {\n const operation = this.findDefaultOperation(CoreResourceOperation.SEARCH);\n if (!operation) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n context: { reason: 'no default SEARCH operation declared', resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n return this._doSearch(operation, executionContext, searchQuery, filter ?? {}, { ...options, searchOptions: searchOptions ?? {} });\n }\n\n public async count(\n executionContext: ExecutionContext<any>,\n filter?: any,\n options?: RepositoryOptions,\n ): Promise<{ count: number }> {\n const operation = this.findDefaultOperation(CoreResourceOperation.COUNT)\n ?? this.syntheticOperation(CoreResourceOperation.COUNT);\n return this._doCount(operation, executionContext, filter ?? {}, options);\n }\n\n public supportsOperation(operationIdentifier: string): boolean {\n // Sibling-parity: capability means a DEFAULT variant exists (both platform adapters require\n // `isOperationDefault === true`), not merely that any variant mentions the identifier.\n return (this.resourceConfiguration.operations as AnyOperation[]).some(\n (operation) => operation.operationIdentifier === operationIdentifier && operation.isOperationDefault === true,\n );\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Read-family execution\n // ─────────────────────────────────────────────────────────────────────────────\n\n private async _doRead(\n operation: AnyOperation,\n executionContext: ExecutionContext<any>,\n id_or_filter: any,\n options?: RepositoryOptions,\n ): Promise<Record<string, unknown> | null> {\n return this.guarded(executionContext, async () => {\n if (typeof id_or_filter === 'string') {\n return this.readByKeyWithScopeCheck(executionContext, id_or_filter, options);\n }\n\n // A filter of exactly `{ _id: <string> }` IS a key-addressed read — the write-integrity FK\n // probe's shape (`{ _id: fkValue }`, with `excludeContextualFilter: true`) — and must work\n // on BOTH dialects, so it routes through the key path rather than the collection query.\n const rawFilter = (id_or_filter as { filter?: Record<string, unknown> })?.filter\n ?? (id_or_filter as Record<string, unknown>) ?? {};\n const filterKeys = Object.keys(rawFilter);\n if (filterKeys.length === 1 && filterKeys[0] === '_id' && typeof rawFilter._id === 'string') {\n return this.readByKeyWithScopeCheck(executionContext, rawFilter._id, options);\n }\n\n // Filter-shaped READ (child fetches, business-key-less lookups): translate + take the\n // first row of a limit-1 collection query.\n const query = this.translate(executionContext, rawFilter, options, { limit: 1, offset: 0 });\n if (query.matchNothing) return null;\n const rows = await this.executeCollectionRead(executionContext, query, operation);\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.READ, { rowCount: rows.length }); // site 2/5\n return rows.length > 0 ? projectHttpApiRemoteRow(this.binding, rows[0]) : null;\n });\n }\n\n /**\n * Key-addressed single-row read WITH the tenant-scope check (paper B T1 / requirement R4).\n *\n * A key-addressed read has no `$filter`, so on a SCOPE_FILTER_PUSHDOWN binding the scope\n * predicate is enforced POST-FETCH against the raw remote row: a row whose declared remote\n * scope field does not carry the caller's scope value answers `null` — exactly what the Mongo\n * sibling's conjoined contextual filter yields for an out-of-scope id. Skipped only by the\n * engine's own bypass (`excludeContextualFilter: true` — internal probes) and on\n * SINGLE_TENANT bindings, where scope is N/A by declared stance.\n */\n private async readByKeyWithScopeCheck(\n executionContext: ExecutionContext<any>,\n resourceId: string,\n options?: RepositoryOptions,\n ): Promise<Record<string, unknown> | null> {\n // Assert decodability BEFORE the remote call: an id this binding could not have synthesized\n // is a VALIDATION refusal, never a silent 404.\n resolveHttpApiKeyComponents(this.binding, resourceId);\n\n // Resolve the tenant scope BEFORE spending the remote call, so a scope-less pushdown context\n // refuses without touching the target — same ordering as the translation boundary.\n let requiredScope: { remoteField: string; value: string } | undefined;\n if (\n options?.excludeContextualFilter !== true\n && this.binding.tenancy.stance === HttpApiTenancyStance.SCOPE_FILTER_PUSHDOWN\n ) {\n const remoteScopeField = this.binding.tenancy.remoteScopeField;\n const primaryScopeFieldIdentifier = this.resourceConfiguration.resourcePrimaryScope\n ? PRIMARY_SCOPE_TO_FIELD_IDENTIFIER[this.resourceConfiguration.resourcePrimaryScope as keyof typeof PRIMARY_SCOPE_TO_FIELD_IDENTIFIER]\n : undefined;\n const scopeValue = primaryScopeFieldIdentifier\n ? executionContext.getContextResourceId(primaryScopeFieldIdentifier as never)\n : undefined;\n if (typeof scopeValue !== 'string' || scopeValue.length === 0) {\n // Same fail-closed refusal as the translation boundary: no scope, no remote row.\n throw new HttpApiTranslationRefusal(\n `Resource '${this.resourceConfiguration.resourceIdentifier}' declares SCOPE_FILTER_PUSHDOWN tenancy but the execution context carries no `\n + `'${String(primaryScopeFieldIdentifier)}' scope value — refusing an unscoped key-addressed read.`,\n );\n }\n requiredScope = { remoteField: remoteScopeField, value: scopeValue };\n }\n\n const body = await this.executeKeyAddressedRead(executionContext, resourceId);\n // Site 1/5: a remote round-trip happened whether or not a row came back (or survives the\n // scope check below) — the trail records EXTERNAL access, not what was served.\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.READ, {\n resourceId, rowCount: body === null ? 0 : 1,\n });\n if (body === null) return null;\n const rawRow = body as Record<string, unknown>;\n\n if (\n requiredScope !== undefined\n && String(rawRow[requiredScope.remoteField]) !== requiredScope.value\n ) {\n // Out-of-scope row: indistinguishable from \"no row\" for this caller, by design — exactly\n // what the Mongo sibling's conjoined contextual filter yields for an out-of-scope id.\n return null;\n }\n\n return projectHttpApiRemoteRow(this.binding, rawRow);\n }\n\n private async _doList(\n operation: AnyOperation,\n executionContext: ExecutionContext<any>,\n ids_or_filter: any,\n options?: ListCallOptions,\n ): Promise<any> {\n return this.guarded(executionContext, async () => {\n const paginated = options?.paginated ?? false;\n const listOptions = options?.listOptions;\n const hasPagination = listOptions?.page !== undefined || listOptions?.limit !== undefined;\n\n // Sibling-parity page math (measured: default page size 20, ceiling from the operation).\n const maxLimit = (operation as { maxPaginatedResultPerPageLimit?: number }).maxPaginatedResultPerPageLimit || 100;\n const page = hasPagination ? Math.max(1, listOptions?.page || 1) : 1;\n const limit = Math.min(maxLimit, Math.max(1, listOptions?.limit || 20));\n const bounded = paginated || hasPagination;\n\n const filter = Array.isArray(ids_or_filter)\n ? { _id: { $in: ids_or_filter } }\n : (ids_or_filter as Record<string, unknown>) ?? {};\n\n const query = this.translate(executionContext, filter, options, {\n // An unpaginated internal list against a REMOTE system is still bounded by the\n // binding's page ceiling — \"the whole entity set\" is never a single call (paper B, T5).\n limit: bounded ? limit : maxLimit,\n offset: bounded ? (page - 1) * limit : 0,\n }, listOptions?.sort, (operation as { sortFields?: readonly string[] }).sortFields);\n if (!bounded) {\n // The sibling's unpaginated list returns the FULL set; this adapter caps at the ceiling.\n // Named once so a truncated internal scan never reads as \"covered everything\".\n this.logDebug(\n `Unpaginated internal LIST on '${this.resourceConfiguration.resourceIdentifier}' is capped at ${maxLimit} remote rows (paper B, T5).`,\n );\n }\n\n if (query.matchNothing) {\n return paginated\n ? { data: [], pagination: { page, limit, total: 0, totalPages: 0 } }\n : [];\n }\n\n if (!paginated) {\n const rows = await this.executeCollectionRead(executionContext, query, operation);\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.LIST, { rowCount: rows.length }); // site 3/5\n return rows.map((row) => projectHttpApiRemoteRow(this.binding, row));\n }\n\n const { rows, total } = await this.executeCollectionReadWithTotal(executionContext, query, operation);\n // Site 3/5 (paginated shape): the list and the count that totals its envelope are ONE access.\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.LIST, { rowCount: rows.length });\n return {\n data: rows.map((row) => projectHttpApiRemoteRow(this.binding, row)),\n pagination: { page, limit, total, totalPages: limit > 0 ? Math.ceil(total / limit) : 1 },\n };\n });\n }\n\n private async _doCount(\n operation: AnyOperation,\n executionContext: ExecutionContext<any>,\n filter: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<{ count: number }> {\n return this.guarded(executionContext, async () => {\n const query = this.translate(executionContext, filter, options);\n if (query.matchNothing) return { count: 0 };\n const count = await this.executeCountRead(executionContext, query, operation);\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.COUNT, { rowCount: count }); // site 4/5\n return { count };\n });\n }\n\n private async _doSearch(\n operation: AnyOperation,\n executionContext: ExecutionContext<any>,\n searchQuery: string,\n filter: Record<string, unknown>,\n options: RepositoryOptions & { searchOptions: Record<string, unknown> },\n ): Promise<Resources_PaginatedResult<any>> {\n return this.guarded(executionContext, async () => {\n const searchOptions = options.searchOptions as { page?: number; limit?: number; sort?: Record<string, 1 | -1> };\n const maxLimit = (operation as { maxPaginatedResultPerPageLimit?: number }).maxPaginatedResultPerPageLimit || 50;\n const page = Math.max(1, searchOptions.page || 1);\n const limit = Math.min(maxLimit, Math.max(1, searchOptions.limit || 20));\n\n const query = this.translate(\n executionContext, filter, options,\n { limit, offset: (page - 1) * limit },\n searchOptions.sort,\n (operation as { sortFields?: readonly string[] }).sortFields,\n );\n\n if (searchQuery.trim().length > 0) {\n const searchableFields = ((operation as { searchableFields?: unknown[] }).searchableFields ?? [])\n .filter((entry): entry is string => typeof entry === 'string');\n if (searchableFields.length === 0) {\n throw new HttpApiTranslationRefusal(\n 'SEARCH on an HTTP_API resource requires declared own-field searchableFields (the Mongo $text fallback and relational descriptors have no remote translation — paper B).',\n );\n }\n const rawOptions = (operation as { searchableOptions?: { caseSensitive?: boolean; fullMatchOnly?: boolean } }).searchableOptions;\n query.search = {\n localFields: searchableFields,\n query: searchQuery,\n caseSensitive: rawOptions?.caseSensitive === true,\n fullMatchOnly: rawOptions?.fullMatchOnly === true,\n };\n }\n\n if (query.matchNothing) {\n return { data: [], pagination: { page, limit, total: 0, totalPages: 0 } };\n }\n const { rows, total } = await this.executeCollectionReadWithTotal(executionContext, query, operation, CoreResourceOperation.SEARCH);\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.SEARCH, { rowCount: rows.length }); // site 5/5\n return {\n data: rows.map((row) => projectHttpApiRemoteRow(this.binding, row)),\n pagination: { page, limit, total, totalPages: limit > 0 ? Math.ceil(total / limit) : 1 },\n };\n });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Remote execution per dialect\n // ─────────────────────────────────────────────────────────────────────────────\n\n private translate(\n executionContext: ExecutionContext<any>,\n filter: Record<string, unknown>,\n options: RepositoryOptions | undefined,\n pagination?: { limit: number; offset: number },\n sort?: Record<string, 1 | -1>,\n declaredSortFields?: readonly string[],\n ): HttpApiTranslatedQuery {\n return translateHttpApiReadInputs({\n executionContext,\n binding: this.binding,\n resourceConfiguration: this.resourceConfiguration,\n filter,\n excludeContextualFilter: options?.excludeContextualFilter,\n sort,\n declaredSortFields,\n pagination,\n });\n }\n\n private restOperationSpec(member: 'read' | 'list' | 'count' | 'search'): any {\n if (this.binding.dialect !== HttpApiTransportDialect.REST_JSON) return undefined;\n const spec = this.binding.operations[member];\n if (!spec) {\n throw new RestJsonTranslationRefusal(\n `This REST_JSON binding declares no '${member}' operation — the member is refused for this binding, never emulated.`,\n );\n }\n return spec;\n }\n\n private async executeKeyAddressedRead(\n executionContext: ExecutionContext<any>,\n resourceId: string,\n ): Promise<unknown | null> {\n let body: unknown;\n if (this.binding.dialect === HttpApiTransportDialect.ODATA) {\n const compiled = compileODataKeyAddressedRead(this.binding, resourceId);\n const response = await this.readClient.odataGetOrNull(executionContext, compiled);\n if (response === null) return null;\n body = response;\n } else if (this.binding.dialect === HttpApiTransportDialect.ODOO_JSONRPC) {\n // `read([[id]])` answers an ARRAY; empty = the documented \"no such row\".\n const rows = this.expectRowArray(\n await this.readClient.odooExecuteKw(executionContext, compileOdooKeyAddressedRead(this.binding, resourceId)),\n \"the Odoo 'read' result array\",\n );\n return rows.length > 0 ? rows[0] : null;\n } else {\n const spec = this.restOperationSpec('read');\n const compiled = compileRestJsonKeyAddressedRead(this.binding, spec, resourceId);\n const response = await this.readClient.restJsonReadOrNull(executionContext, compiled);\n if (response === null) return null;\n body = response;\n }\n return body;\n }\n\n private async executeCollectionRead(\n executionContext: ExecutionContext<any>,\n query: HttpApiTranslatedQuery,\n _operation: AnyOperation,\n member: 'list' | 'search' = 'list',\n ): Promise<Array<Record<string, unknown>>> {\n if (this.binding.dialect === HttpApiTransportDialect.ODATA) {\n const compiled = compileODataCollectionRead(this.binding, query);\n const body = await this.readClient.odataGet(executionContext, compiled);\n return this.expectRowArray((body as { value?: unknown })?.value, \"the OData 'value' array\");\n }\n if (this.binding.dialect === HttpApiTransportDialect.ODOO_JSONRPC) {\n return this.expectRowArray(\n await this.readClient.odooExecuteKw(executionContext, compileOdooCollectionRead(this.binding, query)),\n \"the Odoo 'search_read' result array\",\n );\n }\n const spec = this.restOperationSpec(member === 'search' ? 'search' : 'list');\n const compiled = compileRestJsonCollectionRead(this.binding, spec, query);\n const body = await this.readClient.restJson(executionContext, compiled);\n return this.expectRowArray(resolveHttpApiResultPath(body, compiled.resultPath), `the declared resultPath '${compiled.resultPath ?? '(body)'}'`);\n }\n\n private async executeCollectionReadWithTotal(\n executionContext: ExecutionContext<any>,\n query: HttpApiTranslatedQuery,\n operation: AnyOperation,\n searchMember?: CoreResourceOperation.SEARCH,\n ): Promise<{ rows: Array<Record<string, unknown>>; total: number }> {\n if (this.binding.dialect === HttpApiTransportDialect.ODATA) {\n const compiled = compileODataCollectionRead(this.binding, query, { count: true });\n const body = await this.readClient.odataGet(executionContext, compiled) as Record<string, unknown>;\n const rows = this.expectRowArray(body?.value, \"the OData 'value' array\");\n const total = body?.['@odata.count'];\n if (typeof total !== 'number') {\n throw new HttpApiTranslationRefusal(\n \"A paginated envelope needs a total, but the target answered no '@odata.count' — the target does not honor $count=true; only non-paginated reads are available against it.\",\n );\n }\n return { rows, total };\n }\n // Resolve the count declaration FIRST (REST_JSON only — Odoo's search_count is generic):\n // a paginated envelope needs a total, and an undeclared count operation must refuse before\n // any remote list call is spent.\n if (this.binding.dialect === HttpApiTransportDialect.REST_JSON) {\n this.restOperationSpec('count');\n }\n const rows = await this.executeCollectionRead(executionContext, query, operation, searchMember ? 'search' : 'list');\n const total = await this.executeCountRead(executionContext, { ...query, pagination: undefined, sort: [] }, operation);\n return { rows, total };\n }\n\n private async executeCountRead(\n executionContext: ExecutionContext<any>,\n query: HttpApiTranslatedQuery,\n _operation: AnyOperation,\n ): Promise<number> {\n if (this.binding.dialect === HttpApiTransportDialect.ODATA) {\n const compiled = compileODataCountRead(this.binding, query);\n const body = await this.readClient.odataGet(executionContext, compiled);\n const count = typeof body === 'number' ? body : Number(body);\n if (!Number.isFinite(count)) {\n throw new HttpApiTranslationRefusal(`The OData /$count endpoint answered a non-numeric body (${typeof body}).`);\n }\n return count;\n }\n if (this.binding.dialect === HttpApiTransportDialect.ODOO_JSONRPC) {\n const result = await this.readClient.odooExecuteKw(executionContext, compileOdooCountRead(this.binding, query));\n if (typeof result !== 'number' || !Number.isFinite(result)) {\n throw new HttpApiRemoteContractError(`Odoo 'search_count' answered a non-numeric result (${typeof result}).`);\n }\n return result;\n }\n const spec = this.restOperationSpec('count');\n const compiled = compileRestJsonCollectionRead(this.binding, spec, { ...query, pagination: undefined });\n const body = await this.readClient.restJson(executionContext, compiled);\n const payload = resolveHttpApiResultPath(body, compiled.resultPath);\n const count = typeof payload === 'number' ? payload : Number(payload);\n if (!Number.isFinite(count)) {\n throw new HttpApiTranslationRefusal(\n `The declared count operation answered a non-numeric payload at '${compiled.resultPath ?? '(body)'}'.`,\n );\n }\n return count;\n }\n\n // ── Wire mechanics: see HttpApiReadClient (PR-29 — one implementation, two consumers) ──\n\n // ── Read-through audit trail (ETL D8/R6) ─────────────────────────────────────\n\n /**\n * Record one read-through access — the row that keeps attribution alive through the shared\n * service principal (R12). Fire-and-forget and feature-detected per the house pattern\n * (`recordCrossTenantAdministrativeAccess`): a partial audit binding or a store failure must\n * never fail the read it observes. Emitted ONLY after a remote round-trip actually happened —\n * match-nothing short-circuits touch no external system and record nothing.\n *\n * Emission lives at the ADAPTER, deliberately inverting the services-tier precedent\n * (`recordPlatformDirectoryAccess`'s \"the repository exists once per adapter\" argument):\n * HTTP_API has exactly ONE adapter, and it is the only tier that witnesses EVERY remote access\n * — repository-direct probes (write-integrity's `readForInternalScan`) never pass the\n * services tier at all. Call sites, enumerated: `readByKeyWithScopeCheck`, `_doRead`'s\n * filter branch, `_doList` (both shapes), `_doCount`, `_doSearch`.\n *\n * assurance-control: WILDO.AUDIT.ATTRIBUTION — external read-through access recorded with the\n * real initiating user carried through the shared service principal.\n */\n private recordReadThroughAccess(\n executionContext: ExecutionContext<any>,\n operationIdentifier: CoreResourceOperation,\n extras: { resourceId?: string; rowCount?: number } = {},\n ): void {\n try {\n const auditLogsService = this.auditLogsResolver?.();\n if (typeof auditLogsService?.logHttpApiReadThroughAccess !== 'function') return;\n const initiatorIds = (executionContext as { initiatorIds?: { userId?: string; organizationId?: string } }).initiatorIds;\n void auditLogsService.logHttpApiReadThroughAccess({\n resourceType: String(this.resourceConfiguration.resourceIdentifier),\n operationIdentifier: String(operationIdentifier),\n providerRef: this.binding.providerRef,\n remoteEntityRef: this.binding.entityRef,\n dialect: this.binding.dialect,\n initiatorUserId: initiatorIds?.userId,\n executionType: (executionContext as { executionType?: string }).executionType,\n organizationId: initiatorIds?.organizationId\n ?? executionContext.getContextResourceId?.('organizationId' as never),\n ...extras,\n }, executionContext)?.catch?.(() => undefined);\n } catch {\n // Observation only — never the reason a read fails.\n }\n }\n\n // ── D6 stance 6b: the declared external-erasure door ─────────────────────────\n\n /**\n * The ONE write slice 1 sanctions (the stance JSDoc's \"a single declared write\"): delete every\n * remote row linked to ONE erased subject through the binding's DECLARED erasure operation.\n * Callable only by the subject-erasure external effect — every generic write member of this\n * repository stays refused (D3), and the boot-time B1 sweep keeps lifecycle cascades away from\n * HTTP_API children, so this door cannot be reached by an ordinary teardown.\n *\n * ## Identity-less by design\n *\n * The internal context below is inert on this path, verified per consumer: translation runs\n * `excludeContextualFilter` (an erasure must reach the subject's rows in EVERY tenant — the FK\n * equality is the confinement), and `resolveAccess` ignores the context for SERVICE_PRINCIPAL.\n * Attribution lives in the `HTTP_API_EXTERNAL_ERASURE` audit row the calling effect emits;\n * discovery reads here deliberately do NOT emit read-through events (the read exists only to\n * address the deletion the event already records — double-recording would be noise with no\n * initiator).\n *\n * ## Discovery deletes as it goes\n *\n * Each iteration re-queries PAGE ONE (offset 0): deleting shifts pagination windows, so paging\n * forward would skip every second page. A page whose leading row survives two consecutive\n * iterations means the target is not actually deleting — refused loudly rather than looping.\n *\n * ## Failure semantics\n *\n * Throws {@link HttpApiExternalErasureError} carrying what already applied. A retried transport\n * call that landed remotely before its response was lost can surface as an Odoo `unlink` error\n * on missing ids — reported as PARTIAL by the effect, and self-healing on the next erasure run\n * (discovery finds only survivors; a remote 404 on a key-addressed DELETE counts as already\n * gone for the same reason).\n */\n public async executeDeclaredSubjectLinkErasure(\n localFkField: string,\n subjectId: string,\n ): Promise<{ deletedCount: number }> {\n if (this.binding.erasure.stance !== HttpApiErasureStance.EXTERNAL_ERASURE_OPERATION) {\n throw new HttpApiTranslationRefusal(\n `Resource '${String(this.resourceConfiguration.resourceIdentifier)}' declares erasure stance '${this.binding.erasure.stance}' — the external-erasure door is only defined for EXTERNAL_ERASURE_OPERATION (D6 stance 6b).`,\n );\n }\n\n const executionContext = this.systemErasureExecutionContext();\n let deletedCount = 0;\n let previousLeadingId: string | undefined;\n\n for (let iteration = 0; iteration < HttpApiResourceRepositoryBackendService.ERASURE_MAX_DISCOVERY_ITERATIONS; iteration++) {\n let rowIds: string[];\n try {\n const query = this.translate(\n executionContext,\n { [localFkField]: subjectId },\n { excludeContextualFilter: true },\n { limit: HttpApiResourceRepositoryBackendService.ERASURE_DISCOVERY_PAGE, offset: 0 },\n );\n const rows = await this.executeCollectionRead(\n executionContext,\n query,\n this.syntheticOperation(CoreResourceOperation.LIST),\n );\n rowIds = rows.map((row) => String(projectHttpApiRemoteRow(this.binding, row)._id));\n } catch (error) {\n throw new HttpApiExternalErasureError(\n `External-erasure discovery failed for '${String(this.resourceConfiguration.resourceIdentifier)}' (link field '${localFkField}'): ${error instanceof Error ? error.message : String(error)}`,\n deletedCount,\n error,\n );\n }\n\n if (rowIds.length === 0) {\n return { deletedCount };\n }\n if (rowIds[0] === previousLeadingId) {\n throw new HttpApiExternalErasureError(\n `The target acknowledged the delete of row '${rowIds[0]}' but discovery still returns it — the declared erasure operation is not actually deleting; refusing to loop.`,\n deletedCount,\n );\n }\n previousLeadingId = rowIds[0];\n\n try {\n await this.deleteRemoteRowsByIds(executionContext, rowIds);\n } catch (error) {\n // A mid-page per-row failure carries what THAT page already applied — losing it would\n // report a PARTIAL as a clean FAILED and invite a retry the registry believes is safe.\n const appliedInFailedPage = error instanceof HttpApiExternalErasureError ? error.deletedCount : 0;\n throw new HttpApiExternalErasureError(\n `The declared erasure operation failed for '${String(this.resourceConfiguration.resourceIdentifier)}' after ${deletedCount + appliedInFailedPage} deletion(s): ${error instanceof Error ? error.message : String(error)}`,\n deletedCount + appliedInFailedPage,\n error,\n );\n }\n deletedCount += rowIds.length;\n }\n\n throw new HttpApiExternalErasureError(\n `External erasure exceeded ${HttpApiResourceRepositoryBackendService.ERASURE_MAX_DISCOVERY_ITERATIONS} discovery pages for one subject — refusing an unbounded remote loop.`,\n deletedCount,\n );\n }\n\n /**\n * Best-effort remote count of rows linked to one subject — the stance-6c acknowledgement's\n * evidence (`remainingRowCount` on the CRITICAL audit row). Throws on any refusal or transport\n * failure; the caller records ABSENCE rather than a fabricated zero.\n */\n public async countRowsLinkedToSubject(localFkField: string, subjectId: string): Promise<number> {\n const executionContext = this.systemErasureExecutionContext();\n const query = this.translate(\n executionContext,\n { [localFkField]: subjectId },\n { excludeContextualFilter: true },\n );\n return this.executeCountRead(executionContext, query, this.syntheticOperation(CoreResourceOperation.COUNT));\n }\n\n private static readonly ERASURE_DISCOVERY_PAGE = 50;\n private static readonly ERASURE_MAX_DISCOVERY_ITERATIONS = 200;\n\n /**\n * The minimal internal context the erasure path runs under. Structurally an ExecutionContext,\n * deliberately identity-less (a system erasure carries no request identity — the same doctrine\n * as the file-teardown gates); every consumer on this path is verified inert against it, per\n * the door's JSDoc.\n */\n private systemErasureExecutionContext(): ExecutionContext<any> {\n return {\n getContextResourceId: () => undefined,\n getContextResourceIds: () => new Map(),\n operation: undefined,\n } as unknown as ExecutionContext<any>;\n }\n\n /** Delete one discovered page of rows through the DECLARED erasure operation, per dialect. */\n private async deleteRemoteRowsByIds(\n executionContext: ExecutionContext<any>,\n rowIds: readonly string[],\n ): Promise<void> {\n if (this.binding.dialect === HttpApiTransportDialect.ODOO_JSONRPC) {\n // Odoo's canonical delete is ONE batched `unlink [[ids]]` per page.\n const integerIds = rowIds.map((rowId) => Number(resolveHttpApiKeyComponents(this.binding, rowId)[0]));\n await this.readClient.odooExecuteKw(executionContext, compileOdooCanonicalDelete(integerIds));\n return;\n }\n\n if (this.binding.dialect === HttpApiTransportDialect.ODATA) {\n // OData's canonical delete: `DELETE /EntitySet(key)` per row; 404 = already gone. A per-row\n // failure surfaces WITH the count that already applied in this page (PARTIAL accuracy).\n let appliedInPage = 0;\n for (const rowId of rowIds) {\n const compiled = compileODataKeyAddressedRead(this.binding, rowId);\n try {\n await this.readClient.odataDeleteByPath(executionContext, compiled.path);\n } catch (error) {\n throw new HttpApiExternalErasureError(\n `Canonical DELETE failed for row '${rowId}': ${error instanceof Error ? error.message : String(error)}`,\n appliedInPage,\n error,\n );\n }\n appliedInPage += 1;\n }\n return;\n }\n\n // REST_JSON: the EXPLICIT declared operation (dialect coherence guarantees the form).\n const declaredOperation = this.binding.erasure.stance === HttpApiErasureStance.EXTERNAL_ERASURE_OPERATION\n ? this.binding.erasure.operation\n : undefined;\n if (!declaredOperation || 'useCanonicalDelete' in declaredOperation) {\n throw new HttpApiTranslationRefusal(\n 'A REST_JSON external erasure needs the EXPLICIT declared operation spec — the boot-time dialect coherence should have refused this binding.',\n );\n }\n const spec: HttpApiErasureOperationSpec = declaredOperation;\n let appliedInPage = 0;\n for (const rowId of rowIds) {\n const compiled = compileRestJsonDeclaredErasure(this.binding, spec, rowId);\n try {\n await this.readClient.restDeclaredErasureCall(executionContext, compiled);\n } catch (error) {\n throw new HttpApiExternalErasureError(\n `Declared erasure operation failed for row '${rowId}': ${error instanceof Error ? error.message : String(error)}`,\n appliedInPage,\n error,\n );\n }\n appliedInPage += 1;\n }\n }\n\n private expectRowArray(candidate: unknown, where: string): Array<Record<string, unknown>> {\n if (!Array.isArray(candidate)) {\n // A remote-CONTRACT breach, not a translation refusal: the query was legal, the answer is not.\n throw new HttpApiRemoteContractError(`The remote response carries no row array at ${where}.`);\n }\n return candidate as Array<Record<string, unknown>>;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Error projection + refusals\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Map the module-level error vocabulary into the engine's error projection, once. */\n private async guarded<T>(executionContext: ExecutionContext<any>, work: () => Promise<T>): Promise<T> {\n try {\n return await work();\n } catch (error) {\n if (error instanceof HttpApiTranslationRefusal || error instanceof RestJsonTranslationRefusal || error instanceof HttpApiRemoteContractError) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: { reason: 'http_api_untranslatable_shape', message: error.message, resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n if (error instanceof HttpApiProviderAccessError) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: { reason: 'http_api_provider_access_unresolvable', message: error.message, resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n if (error instanceof HttpApiTransportError) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: { reason: 'http_api_remote_call_failed', message: error.message, ...error.detail, resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n // Codec errors (undecodable / non-canonical / missing key components) are the shared\n // authority's TYPED refusal: LOUD VALIDATION by design, classified by instance.\n if (error instanceof HttpApiResourceIdError) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.RESOURCE_ID_VALIDATION_FAILED,\n context: { reason: 'http_api_id_refused', message: error.message, resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n throw error;\n }\n }\n\n private readOnlyRefusal(member: string, executionContext?: ExecutionContext<any>): ReturnType<ErrorBuilderBackendService['buildError']> {\n return this.errorBuilder.buildError(ErrorType.CONFIGURATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: {\n reason: 'http_api_repository_member_unsupported',\n member,\n message: `'${member}' is not available on an HTTP_API-backed resource in slice 1 (read-only — ETL decision D3/D10). `\n + 'Reads: read/list/count/search and the internal-scan variants.',\n resourceType: this.resourceConfiguration.resourceIdentifier,\n },\n });\n }\n\n private findDefaultOperation(operationIdentifier: CoreResourceOperation): AnyOperation | undefined {\n return (this.resourceConfiguration.operations as AnyOperation[]).find(\n (operation) => operation.operationIdentifier === operationIdentifier && operation.isOperationDefault === true,\n );\n }\n\n private syntheticOperation(operationIdentifier: CoreResourceOperation): AnyOperation {\n return {\n operationIdentifier,\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isOperationDefault: true,\n } as unknown as AnyOperation;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // The refused remainder of the contract (D2: implemented, never omitted; D3: read-only)\n // ─────────────────────────────────────────────────────────────────────────────\n\n public async create(): Promise<never> { throw this.readOnlyRefusal('create'); }\n public async createMany(): Promise<never> { throw this.readOnlyRefusal('createMany'); }\n public async update(): Promise<never> { throw this.readOnlyRefusal('update'); }\n public async updateMany(): Promise<never> { throw this.readOnlyRefusal('updateMany'); }\n public async delete(): Promise<never> { throw this.readOnlyRefusal('delete'); }\n public async deleteMany(): Promise<never> { throw this.readOnlyRefusal('deleteMany'); }\n public async atomicIncrementField(): Promise<never> { throw this.readOnlyRefusal('atomicIncrementField'); }\n public async atomicConditionalSet(): Promise<never> { throw this.readOnlyRefusal('atomicConditionalSet'); }\n public async atomicGuardedMutation(): Promise<never> { throw this.readOnlyRefusal('atomicGuardedMutation'); }\n public async updateManyByRawFilter(): Promise<never> { throw this.readOnlyRefusal('updateManyByRawFilter'); }\n public async insertRawDocument(): Promise<never> { throw this.readOnlyRefusal('insertRawDocument'); }\n public async findManyByRawFilter(): Promise<never> { throw this.readOnlyRefusal('findManyByRawFilter (raw filters are refused — T-set only, paper B R1)'); }\n public async countByRawFilter(): Promise<never> { throw this.readOnlyRefusal('countByRawFilter (raw filters are refused — T-set only, paper B R1)'); }\n public async readUnscopedByKey(): Promise<never> { throw this.readOnlyRefusal('readUnscopedByKey (raw filters are refused — T-set only, paper B R1)'); }\n public async findScopeRelatedTargetIds(): Promise<never> { throw this.readOnlyRefusal('findScopeRelatedTargetIds (an HTTP_API resource cannot serve as a scope junction in slice 1)'); }\n public async aggregateField(): Promise<never> { throw this.readOnlyRefusal('aggregateField (remote aggregation is refused — ETL decision D10)'); }\n public async findByBusinessKey(): Promise<never> { throw this.readOnlyRefusal('findByBusinessKey (data-seeding never targets an HTTP_API resource)'); }\n public async findManyByBusinessKeys(): Promise<never> { throw this.readOnlyRefusal('findManyByBusinessKeys (data-seeding never targets an HTTP_API resource)'); }\n public async upsertByBusinessKey(): Promise<never> { throw this.readOnlyRefusal('upsertByBusinessKey'); }\n public async upsertByFilter(): Promise<never> { throw this.readOnlyRefusal('upsertByFilter'); }\n public async updateSeedMetadata(): Promise<never> { throw this.readOnlyRefusal('updateSeedMetadata'); }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"http-api-resource-repository.backend.service.js","sourceRoot":"","sources":["../../../../../../../src/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The HTTP-API resource repository — the third `BackendResourceRepository` implementation\n * (ETL plan Step 3): rows live in a system reached over an authenticated HTTP API and are\n * queried ON DEMAND per the resource's committed `httpApiBinding`.\n *\n * READ-ONLY in slice 1 (decision D3): `read`/`list`/`count`/`search` and the internal-scan\n * variants execute; EVERY other contract member throws `CONFIGURATION` naming the reason\n * (decision D2 — the full contract is implemented, nothing is omitted, nothing returns a\n * fabricated empty result).\n *\n * Query admission is the frozen T-set (paper B) via `translateHttpApiReadInputs` — this class is\n * the boundary that enforces it, because `_doList`/`_doCount` have no repository-side\n * sanitization anywhere else. Row identity is the synthesized id (paper A) via the codec\n * authority; an undecodable id is a LOUD VALIDATION refusal, never a silent not-found (the\n * Mongo CastError→404 behavior is deliberately NOT mimicked). A remote 404 for a well-formed id\n * IS `null` — that is a genuine \"no row\".\n */\n\nimport {\n CoreResourceOperation,\n ErrorType,\n HttpApiResourceIdError,\n PRIMARY_SCOPE_TO_FIELD_IDENTIFIER,\n ResourceOperationVariantType,\n ResourcesConfig_OperationPathUtils,\n ResourceOperationsUtils,\n resolveHttpApiKeyComponents,\n type ResourceType,\n type Resources_PaginatedResult,\n type Resources_PaginationRequest,\n} from '@wildo-ai/saas-models';\nimport {\n HttpApiErasureStance,\n HttpApiTenancyStance,\n HttpApiTransportDialect,\n type HttpApiErasureOperationSpec,\n type HttpApiResourceBinding,\n} from '@wildo-ai/saas-models/external-data';\n\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport type { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport type { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport { ErrorCustomMessageReference } from '@wildo-ai/saas-models';\nimport type { RepositoryOptions } from '~wildo-backend-lib/base-classes/models/repositories.backend.schemas';\n\nimport {\n HttpApiTransportError,\n HttpApiTransportFailureKind,\n type HttpApiFetchLike,\n type HttpApiTransportRequest,\n} from './http-api-transport.backend';\nimport { HttpApiReadClient, defaultHttpApiFetch } from './http-api-read-client.backend';\nimport {\n HttpApiTranslationRefusal,\n translateHttpApiReadInputs,\n} from './http-api-filter-translation.backend';\nimport type { HttpApiTranslatedQuery } from './http-api-query.backend';\nimport {\n compileODataCollectionRead,\n compileODataCountRead,\n compileODataKeyAddressedRead,\n type ODataCompiledRequest,\n} from './odata-query-compiler.backend';\nimport {\n RestJsonTranslationRefusal,\n compileRestJsonCollectionRead,\n compileRestJsonDeclaredErasure,\n compileRestJsonKeyAddressedRead,\n type RestJsonCompiledRequest,\n} from './rest-json-query-compiler.backend';\nimport {\n HttpApiRemoteContractError,\n projectHttpApiRemoteRow,\n resolveHttpApiResultPath,\n} from './http-api-row-projection.backend';\nimport {\n compileOdooCanonicalDelete,\n compileOdooCollectionRead,\n compileOdooCountRead,\n compileOdooKeyAddressedRead,\n type OdooCompiledCall,\n} from './odoo-jsonrpc-compiler.backend';\nimport {\n HttpApiProviderAccessError,\n type HttpApiProviderAccessResolver,\n} from './http-api-provider-access.backend';\n\ntype AnyOperation = { operationIdentifier: string; isOperationDefault?: boolean } & Record<string, unknown>;\n\ntype ListCallOptions = RepositoryOptions & {\n listOptions?: Partial<Resources_PaginationRequest> & { sort?: Record<string, 1 | -1> };\n};\n\n/**\n * The audit seam, structural + lazily resolved (the authorizations-service precedent): the\n * adapter never holds the service, only a thunk the registry handler builds off the container.\n * Absent binding (unit harnesses, partial containers) means no emission — and emission failure\n * must never fail the read it observes.\n */\nexport type HttpApiAuditLogsResolver = () => {\n logHttpApiReadThroughAccess?: (\n data: Record<string, unknown>,\n requestExecutionContext?: ExecutionContext<any>,\n ) => Promise<void>;\n} | undefined;\n\n/**\n * A stance-6b external erasure that stopped mid-way — `deletedCount` is what ALREADY applied\n * remotely before the failure, which is the number that decides PARTIAL (some rows gone, some\n * live) versus FAILED (nothing applied). Deletions are idempotent by key, so the remediation is a\n * re-run of the subject erasure: discovery finds only the surviving rows.\n */\nexport class HttpApiExternalErasureError extends Error {\n constructor(\n message: string,\n public readonly deletedCount: number,\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = 'HttpApiExternalErasureError';\n }\n}\n\nconst READ_FAMILY: ReadonlySet<CoreResourceOperation> = new Set([\n CoreResourceOperation.READ,\n CoreResourceOperation.LIST,\n CoreResourceOperation.COUNT,\n CoreResourceOperation.SEARCH,\n]);\n\nexport class HttpApiResourceRepositoryBackendService {\n private readonly resourceConfiguration: any;\n private readonly binding: HttpApiResourceBinding;\n private readonly operationsMap = new Map<string, AnyOperation>();\n private readonly readClient: HttpApiReadClient;\n private readonly logDebug: (message: string, data?: unknown) => void;\n\n constructor(\n resourceType: ResourceType,\n private readonly logger: LoggerService,\n private readonly errorBuilder: ErrorBuilderBackendService,\n private readonly resourceRegistry: ResourcesRegistryBackendService,\n private readonly providerAccessResolver: HttpApiProviderAccessResolver,\n private readonly fetchImpl: HttpApiFetchLike = defaultHttpApiFetch,\n private readonly auditLogsResolver?: HttpApiAuditLogsResolver,\n ) {\n this.resourceConfiguration = this.resourceRegistry.getResourceConfiguration(resourceType);\n const binding = (this.resourceConfiguration as { httpApiBinding?: HttpApiResourceBinding }).httpApiBinding;\n if (!binding) {\n // The factory enforces presence at authoring; this is the fail-closed backstop for a\n // hand-built configuration reaching construction without one.\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: { reason: 'http_api_resource_without_binding', resourceType },\n });\n }\n this.binding = binding;\n // PR-29: ALL wire mechanics live in the ONE shared client (also consumed by the pipeline\n // extraction source) — this class owns translation/projection/scope/audit/erasure, never framing.\n this.readClient = new HttpApiReadClient(binding, providerAccessResolver, fetchImpl);\n this.logDebug = this.logger.debugByType(`HttpApiRepositoryResource_${resourceType}`);\n this.logger.setDebugTypeLogging(`HttpApiRepositoryResource_${resourceType}`, false);\n\n for (const operation of (this.resourceConfiguration.operations ?? []) as AnyOperation[]) {\n try {\n const path = ResourcesConfig_OperationPathUtils.extractOperationRepositoryPath(operation as never);\n this.operationsMap.set(ResourcesConfig_OperationPathUtils.createOperationRepositoryPathKey(path), operation);\n } catch {\n // An operation with no repository-resolvable identity (no core op, no\n // resourceOperationLike) is simply not addressable through this transport. NOTE this is\n // MORE tolerant than the Mongo sibling's map construction (which propagates); tolerated\n // here because a custom operation with no repository routing is legal on a read-only\n // resource and every read-family core op resolves.\n }\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Dispatch (mirrors the sibling adapters: path → key → operationsMap → doOperation)\n // ─────────────────────────────────────────────────────────────────────────────\n\n public async doByPath<T = any, U = any>(\n operationRepositoryPath: Parameters<typeof ResourcesConfig_OperationPathUtils.createOperationRepositoryPathKey>[0],\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: any,\n data?: U,\n options?: RepositoryOptions,\n ): Promise<T> {\n const key = ResourcesConfig_OperationPathUtils.createOperationRepositoryPathKey(operationRepositoryPath);\n return this.doByKey(key, executionContext, id_or_ids_or_filter, data, options);\n }\n\n public async doByKey<T = any, U = any>(\n operationRepositoryPathKey: string,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: any,\n data?: U,\n options?: RepositoryOptions,\n ): Promise<T> {\n ResourcesConfig_OperationPathUtils.validateOperationRepositoryPathKey(operationRepositoryPathKey);\n const operation = this.operationsMap.get(operationRepositoryPathKey);\n if (!operation) {\n // The TYPE now agrees with the LABEL this site already carried. It declared\n // `ErrorCustomMessageReference.CONFIGURATION` with `reason: 'operation_not_found_on_http_api_repository'`\n // and typed the same call `NOT_FOUND` — the classification and the label contradicting each\n // other in one expression, where an author had clearly worked out which one was true.\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: {\n reason: 'operation_not_found_on_http_api_repository',\n operationRepositoryPathKey,\n resourceType: this.resourceConfiguration.resourceIdentifier,\n },\n });\n }\n return this.doOperation(operation, executionContext, id_or_ids_or_filter, data, options);\n }\n\n public async doByExecutionContext<T = any>(\n executionContext: ExecutionContext<any>,\n data?: any,\n options?: RepositoryOptions,\n ): Promise<T> {\n const operation = executionContext.operation as unknown as AnyOperation;\n const idFromContext = executionContext.getContextResourceId(\n this.resourceConfiguration.resourceFieldIdentifier,\n );\n return this.doOperation(operation, executionContext, idFromContext, data, options);\n }\n\n private async doOperation(\n operation: AnyOperation,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: any,\n data?: any,\n options?: RepositoryOptions,\n ): Promise<any> {\n const operationIdentifier = ResourceOperationsUtils.getCoreResourceOperationFromOperation(operation as never);\n if (!operationIdentifier || !READ_FAMILY.has(operationIdentifier)) {\n throw this.readOnlyRefusal(String(operationIdentifier ?? operation.operationIdentifier), executionContext);\n }\n switch (operationIdentifier) {\n case CoreResourceOperation.READ:\n if (Array.isArray(id_or_ids_or_filter)) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n context: { reason: 'read_received_id_array', resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n return this._doRead(operation, executionContext, id_or_ids_or_filter, options);\n case CoreResourceOperation.LIST: {\n const idsToList = typeof id_or_ids_or_filter === 'string' ? [id_or_ids_or_filter] : id_or_ids_or_filter;\n return this._doList(operation, executionContext, idsToList, options as ListCallOptions);\n }\n case CoreResourceOperation.COUNT:\n return this._doCount(operation, executionContext, (data?.filter as Record<string, unknown>) ?? {}, options);\n case CoreResourceOperation.SEARCH:\n return this._doSearch(operation, executionContext, data?.query || '', (data?.filter as Record<string, unknown>) ?? {}, {\n ...options,\n searchOptions: (options as { searchOptions?: Record<string, unknown> } | undefined)?.searchOptions ?? {},\n });\n default:\n throw this.readOnlyRefusal(String(operationIdentifier), executionContext);\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Public read-family members (operation resolution mirrors the siblings)\n // ─────────────────────────────────────────────────────────────────────────────\n\n public async read<T = undefined>(\n executionContext: ExecutionContext<any>,\n id_or_filter: any,\n options?: RepositoryOptions,\n ): Promise<any> {\n const operation = this.findDefaultOperation(CoreResourceOperation.READ)\n ?? this.syntheticOperation(CoreResourceOperation.READ);\n return this._doRead(operation, executionContext, id_or_filter, options);\n }\n\n public async readForInternalScan<T = undefined>(\n executionContext: ExecutionContext<any>,\n id_or_filter: any,\n options?: RepositoryOptions,\n ): Promise<any> {\n return this._doRead(this.syntheticOperation(CoreResourceOperation.READ), executionContext, id_or_filter, options);\n }\n\n public async list<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: any,\n options?: ListCallOptions,\n ): Promise<any> {\n const operation = this.findDefaultOperation(CoreResourceOperation.LIST);\n if (!operation) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n context: {\n reason: 'no default LIST operation declared on this resource',\n resourceType: this.resourceConfiguration.resourceIdentifier,\n },\n });\n }\n return this._doList(operation, executionContext, ids_or_filter, options);\n }\n\n public async listForInternalScan<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: any,\n options?: ListCallOptions,\n ): Promise<any> {\n const operation = this.findDefaultOperation(CoreResourceOperation.LIST)\n ?? this.syntheticOperation(CoreResourceOperation.LIST);\n return this._doList(operation, executionContext, ids_or_filter, options);\n }\n\n public async search<T = any>(\n executionContext: ExecutionContext<any>,\n searchQuery: string,\n filter?: any,\n searchOptions?: any,\n options?: RepositoryOptions,\n ): Promise<Resources_PaginatedResult<T>> {\n const operation = this.findDefaultOperation(CoreResourceOperation.SEARCH);\n if (!operation) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n context: { reason: 'no default SEARCH operation declared', resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n return this._doSearch(operation, executionContext, searchQuery, filter ?? {}, { ...options, searchOptions: searchOptions ?? {} });\n }\n\n public async count(\n executionContext: ExecutionContext<any>,\n filter?: any,\n options?: RepositoryOptions,\n ): Promise<{ count: number }> {\n const operation = this.findDefaultOperation(CoreResourceOperation.COUNT)\n ?? this.syntheticOperation(CoreResourceOperation.COUNT);\n return this._doCount(operation, executionContext, filter ?? {}, options);\n }\n\n public supportsOperation(operationIdentifier: string): boolean {\n // Sibling-parity: capability means a DEFAULT variant exists (both platform adapters require\n // `isOperationDefault === true`), not merely that any variant mentions the identifier.\n return (this.resourceConfiguration.operations as AnyOperation[]).some(\n (operation) => operation.operationIdentifier === operationIdentifier && operation.isOperationDefault === true,\n );\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Read-family execution\n // ─────────────────────────────────────────────────────────────────────────────\n\n private async _doRead(\n operation: AnyOperation,\n executionContext: ExecutionContext<any>,\n id_or_filter: any,\n options?: RepositoryOptions,\n ): Promise<Record<string, unknown> | null> {\n return this.guarded(executionContext, async () => {\n if (typeof id_or_filter === 'string') {\n return this.readByKeyWithScopeCheck(executionContext, id_or_filter, options);\n }\n\n // A filter of exactly `{ _id: <string> }` IS a key-addressed read — the write-integrity FK\n // probe's shape (`{ _id: fkValue }`, with `excludeContextualFilter: true`) — and must work\n // on BOTH dialects, so it routes through the key path rather than the collection query.\n const rawFilter = (id_or_filter as { filter?: Record<string, unknown> })?.filter\n ?? (id_or_filter as Record<string, unknown>) ?? {};\n const filterKeys = Object.keys(rawFilter);\n if (filterKeys.length === 1 && filterKeys[0] === '_id' && typeof rawFilter._id === 'string') {\n return this.readByKeyWithScopeCheck(executionContext, rawFilter._id, options);\n }\n\n // Filter-shaped READ (child fetches, business-key-less lookups): translate + take the\n // first row of a limit-1 collection query.\n const query = this.translate(executionContext, rawFilter, options, { limit: 1, offset: 0 });\n if (query.matchNothing) return null;\n const rows = await this.executeCollectionRead(executionContext, query, operation);\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.READ, { rowCount: rows.length }); // site 2/5\n return rows.length > 0 ? projectHttpApiRemoteRow(this.binding, rows[0]) : null;\n });\n }\n\n /**\n * Key-addressed single-row read WITH the tenant-scope check (paper B T1 / requirement R4).\n *\n * A key-addressed read has no `$filter`, so on a SCOPE_FILTER_PUSHDOWN binding the scope\n * predicate is enforced POST-FETCH against the raw remote row: a row whose declared remote\n * scope field does not carry the caller's scope value answers `null` — exactly what the Mongo\n * sibling's conjoined contextual filter yields for an out-of-scope id. Skipped only by the\n * engine's own bypass (`excludeContextualFilter: true` — internal probes) and on\n * SINGLE_TENANT bindings, where scope is N/A by declared stance.\n */\n private async readByKeyWithScopeCheck(\n executionContext: ExecutionContext<any>,\n resourceId: string,\n options?: RepositoryOptions,\n ): Promise<Record<string, unknown> | null> {\n // Assert decodability BEFORE the remote call: an id this binding could not have synthesized\n // is a VALIDATION refusal, never a silent 404.\n resolveHttpApiKeyComponents(this.binding, resourceId);\n\n // Resolve the tenant scope BEFORE spending the remote call, so a scope-less pushdown context\n // refuses without touching the target — same ordering as the translation boundary.\n let requiredScope: { remoteField: string; value: string } | undefined;\n if (\n options?.excludeContextualFilter !== true\n && this.binding.tenancy.stance === HttpApiTenancyStance.SCOPE_FILTER_PUSHDOWN\n ) {\n const remoteScopeField = this.binding.tenancy.remoteScopeField;\n const primaryScopeFieldIdentifier = this.resourceConfiguration.resourcePrimaryScope\n ? PRIMARY_SCOPE_TO_FIELD_IDENTIFIER[this.resourceConfiguration.resourcePrimaryScope as keyof typeof PRIMARY_SCOPE_TO_FIELD_IDENTIFIER]\n : undefined;\n const scopeValue = primaryScopeFieldIdentifier\n ? executionContext.getContextResourceId(primaryScopeFieldIdentifier as never)\n : undefined;\n if (typeof scopeValue !== 'string' || scopeValue.length === 0) {\n // Same fail-closed refusal as the translation boundary: no scope, no remote row.\n throw new HttpApiTranslationRefusal(\n `Resource '${this.resourceConfiguration.resourceIdentifier}' declares SCOPE_FILTER_PUSHDOWN tenancy but the execution context carries no `\n + `'${String(primaryScopeFieldIdentifier)}' scope value — refusing an unscoped key-addressed read.`,\n );\n }\n requiredScope = { remoteField: remoteScopeField, value: scopeValue };\n }\n\n const body = await this.executeKeyAddressedRead(executionContext, resourceId);\n // Site 1/5: a remote round-trip happened whether or not a row came back (or survives the\n // scope check below) — the trail records EXTERNAL access, not what was served.\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.READ, {\n resourceId, rowCount: body === null ? 0 : 1,\n });\n if (body === null) return null;\n const rawRow = body as Record<string, unknown>;\n\n if (\n requiredScope !== undefined\n && String(rawRow[requiredScope.remoteField]) !== requiredScope.value\n ) {\n // Out-of-scope row: indistinguishable from \"no row\" for this caller, by design — exactly\n // what the Mongo sibling's conjoined contextual filter yields for an out-of-scope id.\n return null;\n }\n\n return projectHttpApiRemoteRow(this.binding, rawRow);\n }\n\n private async _doList(\n operation: AnyOperation,\n executionContext: ExecutionContext<any>,\n ids_or_filter: any,\n options?: ListCallOptions,\n ): Promise<any> {\n return this.guarded(executionContext, async () => {\n const paginated = options?.paginated ?? false;\n const listOptions = options?.listOptions;\n const hasPagination = listOptions?.page !== undefined || listOptions?.limit !== undefined;\n\n // Sibling-parity page math (measured: default page size 20, ceiling from the operation).\n const maxLimit = (operation as { maxPaginatedResultPerPageLimit?: number }).maxPaginatedResultPerPageLimit || 100;\n const page = hasPagination ? Math.max(1, listOptions?.page || 1) : 1;\n const limit = Math.min(maxLimit, Math.max(1, listOptions?.limit || 20));\n const bounded = paginated || hasPagination;\n\n const filter = Array.isArray(ids_or_filter)\n ? { _id: { $in: ids_or_filter } }\n : (ids_or_filter as Record<string, unknown>) ?? {};\n\n const query = this.translate(executionContext, filter, options, {\n // An unpaginated internal list against a REMOTE system is still bounded by the\n // binding's page ceiling — \"the whole entity set\" is never a single call (paper B, T5).\n limit: bounded ? limit : maxLimit,\n offset: bounded ? (page - 1) * limit : 0,\n }, listOptions?.sort, (operation as { sortFields?: readonly string[] }).sortFields);\n if (!bounded) {\n // The sibling's unpaginated list returns the FULL set; this adapter caps at the ceiling.\n // Named once so a truncated internal scan never reads as \"covered everything\".\n this.logDebug(\n `Unpaginated internal LIST on '${this.resourceConfiguration.resourceIdentifier}' is capped at ${maxLimit} remote rows (paper B, T5).`,\n );\n }\n\n if (query.matchNothing) {\n return paginated\n ? { data: [], pagination: { page, limit, total: 0, totalPages: 0 } }\n : [];\n }\n\n if (!paginated) {\n const rows = await this.executeCollectionRead(executionContext, query, operation);\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.LIST, { rowCount: rows.length }); // site 3/5\n return rows.map((row) => projectHttpApiRemoteRow(this.binding, row));\n }\n\n const { rows, total } = await this.executeCollectionReadWithTotal(executionContext, query, operation);\n // Site 3/5 (paginated shape): the list and the count that totals its envelope are ONE access.\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.LIST, { rowCount: rows.length });\n return {\n data: rows.map((row) => projectHttpApiRemoteRow(this.binding, row)),\n pagination: { page, limit, total, totalPages: limit > 0 ? Math.ceil(total / limit) : 1 },\n };\n });\n }\n\n private async _doCount(\n operation: AnyOperation,\n executionContext: ExecutionContext<any>,\n filter: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<{ count: number }> {\n return this.guarded(executionContext, async () => {\n const query = this.translate(executionContext, filter, options);\n if (query.matchNothing) return { count: 0 };\n const count = await this.executeCountRead(executionContext, query, operation);\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.COUNT, { rowCount: count }); // site 4/5\n return { count };\n });\n }\n\n private async _doSearch(\n operation: AnyOperation,\n executionContext: ExecutionContext<any>,\n searchQuery: string,\n filter: Record<string, unknown>,\n options: RepositoryOptions & { searchOptions: Record<string, unknown> },\n ): Promise<Resources_PaginatedResult<any>> {\n return this.guarded(executionContext, async () => {\n const searchOptions = options.searchOptions as { page?: number; limit?: number; sort?: Record<string, 1 | -1> };\n const maxLimit = (operation as { maxPaginatedResultPerPageLimit?: number }).maxPaginatedResultPerPageLimit || 50;\n const page = Math.max(1, searchOptions.page || 1);\n const limit = Math.min(maxLimit, Math.max(1, searchOptions.limit || 20));\n\n const query = this.translate(\n executionContext, filter, options,\n { limit, offset: (page - 1) * limit },\n searchOptions.sort,\n (operation as { sortFields?: readonly string[] }).sortFields,\n );\n\n if (searchQuery.trim().length > 0) {\n const searchableFields = ((operation as { searchableFields?: unknown[] }).searchableFields ?? [])\n .filter((entry): entry is string => typeof entry === 'string');\n if (searchableFields.length === 0) {\n throw new HttpApiTranslationRefusal(\n 'SEARCH on an HTTP_API resource requires declared own-field searchableFields (the Mongo $text fallback and relational descriptors have no remote translation — paper B).',\n );\n }\n const rawOptions = (operation as { searchableOptions?: { caseSensitive?: boolean; fullMatchOnly?: boolean } }).searchableOptions;\n query.search = {\n localFields: searchableFields,\n query: searchQuery,\n caseSensitive: rawOptions?.caseSensitive === true,\n fullMatchOnly: rawOptions?.fullMatchOnly === true,\n };\n }\n\n if (query.matchNothing) {\n return { data: [], pagination: { page, limit, total: 0, totalPages: 0 } };\n }\n const { rows, total } = await this.executeCollectionReadWithTotal(executionContext, query, operation, CoreResourceOperation.SEARCH);\n this.recordReadThroughAccess(executionContext, CoreResourceOperation.SEARCH, { rowCount: rows.length }); // site 5/5\n return {\n data: rows.map((row) => projectHttpApiRemoteRow(this.binding, row)),\n pagination: { page, limit, total, totalPages: limit > 0 ? Math.ceil(total / limit) : 1 },\n };\n });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Remote execution per dialect\n // ─────────────────────────────────────────────────────────────────────────────\n\n private translate(\n executionContext: ExecutionContext<any>,\n filter: Record<string, unknown>,\n options: RepositoryOptions | undefined,\n pagination?: { limit: number; offset: number },\n sort?: Record<string, 1 | -1>,\n declaredSortFields?: readonly string[],\n ): HttpApiTranslatedQuery {\n return translateHttpApiReadInputs({\n executionContext,\n binding: this.binding,\n resourceConfiguration: this.resourceConfiguration,\n filter,\n excludeContextualFilter: options?.excludeContextualFilter,\n sort,\n declaredSortFields,\n pagination,\n });\n }\n\n private restOperationSpec(member: 'read' | 'list' | 'count' | 'search'): any {\n if (this.binding.dialect !== HttpApiTransportDialect.REST_JSON) return undefined;\n const spec = this.binding.operations[member];\n if (!spec) {\n throw new RestJsonTranslationRefusal(\n `This REST_JSON binding declares no '${member}' operation — the member is refused for this binding, never emulated.`,\n );\n }\n return spec;\n }\n\n private async executeKeyAddressedRead(\n executionContext: ExecutionContext<any>,\n resourceId: string,\n ): Promise<unknown | null> {\n let body: unknown;\n if (this.binding.dialect === HttpApiTransportDialect.ODATA) {\n const compiled = compileODataKeyAddressedRead(this.binding, resourceId);\n const response = await this.readClient.odataGetOrNull(executionContext, compiled);\n if (response === null) return null;\n body = response;\n } else if (this.binding.dialect === HttpApiTransportDialect.ODOO_JSONRPC) {\n // `read([[id]])` answers an ARRAY; empty = the documented \"no such row\".\n const rows = this.expectRowArray(\n await this.readClient.odooExecuteKw(executionContext, compileOdooKeyAddressedRead(this.binding, resourceId)),\n \"the Odoo 'read' result array\",\n );\n return rows.length > 0 ? rows[0] : null;\n } else {\n const spec = this.restOperationSpec('read');\n const compiled = compileRestJsonKeyAddressedRead(this.binding, spec, resourceId);\n const response = await this.readClient.restJsonReadOrNull(executionContext, compiled);\n if (response === null) return null;\n body = response;\n }\n return body;\n }\n\n private async executeCollectionRead(\n executionContext: ExecutionContext<any>,\n query: HttpApiTranslatedQuery,\n _operation: AnyOperation,\n member: 'list' | 'search' = 'list',\n ): Promise<Array<Record<string, unknown>>> {\n if (this.binding.dialect === HttpApiTransportDialect.ODATA) {\n const compiled = compileODataCollectionRead(this.binding, query);\n const body = await this.readClient.odataGet(executionContext, compiled);\n return this.expectRowArray((body as { value?: unknown })?.value, \"the OData 'value' array\");\n }\n if (this.binding.dialect === HttpApiTransportDialect.ODOO_JSONRPC) {\n return this.expectRowArray(\n await this.readClient.odooExecuteKw(executionContext, compileOdooCollectionRead(this.binding, query)),\n \"the Odoo 'search_read' result array\",\n );\n }\n const spec = this.restOperationSpec(member === 'search' ? 'search' : 'list');\n const compiled = compileRestJsonCollectionRead(this.binding, spec, query);\n const body = await this.readClient.restJson(executionContext, compiled);\n return this.expectRowArray(resolveHttpApiResultPath(body, compiled.resultPath), `the declared resultPath '${compiled.resultPath ?? '(body)'}'`);\n }\n\n private async executeCollectionReadWithTotal(\n executionContext: ExecutionContext<any>,\n query: HttpApiTranslatedQuery,\n operation: AnyOperation,\n searchMember?: CoreResourceOperation.SEARCH,\n ): Promise<{ rows: Array<Record<string, unknown>>; total: number }> {\n if (this.binding.dialect === HttpApiTransportDialect.ODATA) {\n const compiled = compileODataCollectionRead(this.binding, query, { count: true });\n const body = await this.readClient.odataGet(executionContext, compiled) as Record<string, unknown>;\n const rows = this.expectRowArray(body?.value, \"the OData 'value' array\");\n const total = body?.['@odata.count'];\n if (typeof total !== 'number') {\n throw new HttpApiTranslationRefusal(\n \"A paginated envelope needs a total, but the target answered no '@odata.count' — the target does not honor $count=true; only non-paginated reads are available against it.\",\n );\n }\n return { rows, total };\n }\n // Resolve the count declaration FIRST (REST_JSON only — Odoo's search_count is generic):\n // a paginated envelope needs a total, and an undeclared count operation must refuse before\n // any remote list call is spent.\n if (this.binding.dialect === HttpApiTransportDialect.REST_JSON) {\n this.restOperationSpec('count');\n }\n const rows = await this.executeCollectionRead(executionContext, query, operation, searchMember ? 'search' : 'list');\n const total = await this.executeCountRead(executionContext, { ...query, pagination: undefined, sort: [] }, operation);\n return { rows, total };\n }\n\n private async executeCountRead(\n executionContext: ExecutionContext<any>,\n query: HttpApiTranslatedQuery,\n _operation: AnyOperation,\n ): Promise<number> {\n if (this.binding.dialect === HttpApiTransportDialect.ODATA) {\n const compiled = compileODataCountRead(this.binding, query);\n const body = await this.readClient.odataGet(executionContext, compiled);\n const count = typeof body === 'number' ? body : Number(body);\n if (!Number.isFinite(count)) {\n throw new HttpApiTranslationRefusal(`The OData /$count endpoint answered a non-numeric body (${typeof body}).`);\n }\n return count;\n }\n if (this.binding.dialect === HttpApiTransportDialect.ODOO_JSONRPC) {\n const result = await this.readClient.odooExecuteKw(executionContext, compileOdooCountRead(this.binding, query));\n if (typeof result !== 'number' || !Number.isFinite(result)) {\n throw new HttpApiRemoteContractError(`Odoo 'search_count' answered a non-numeric result (${typeof result}).`);\n }\n return result;\n }\n const spec = this.restOperationSpec('count');\n const compiled = compileRestJsonCollectionRead(this.binding, spec, { ...query, pagination: undefined });\n const body = await this.readClient.restJson(executionContext, compiled);\n const payload = resolveHttpApiResultPath(body, compiled.resultPath);\n const count = typeof payload === 'number' ? payload : Number(payload);\n if (!Number.isFinite(count)) {\n throw new HttpApiTranslationRefusal(\n `The declared count operation answered a non-numeric payload at '${compiled.resultPath ?? '(body)'}'.`,\n );\n }\n return count;\n }\n\n // ── Wire mechanics: see HttpApiReadClient (PR-29 — one implementation, two consumers) ──\n\n // ── Read-through audit trail (ETL D8/R6) ─────────────────────────────────────\n\n /**\n * Record one read-through access — the row that keeps attribution alive through the shared\n * service principal (R12). Fire-and-forget and feature-detected per the house pattern\n * (`recordCrossTenantAdministrativeAccess`): a partial audit binding or a store failure must\n * never fail the read it observes. Emitted ONLY after a remote round-trip actually happened —\n * match-nothing short-circuits touch no external system and record nothing.\n *\n * Emission lives at the ADAPTER, deliberately inverting the services-tier precedent\n * (`recordPlatformDirectoryAccess`'s \"the repository exists once per adapter\" argument):\n * HTTP_API has exactly ONE adapter, and it is the only tier that witnesses EVERY remote access\n * — repository-direct probes (write-integrity's `readForInternalScan`) never pass the\n * services tier at all. Call sites, enumerated: `readByKeyWithScopeCheck`, `_doRead`'s\n * filter branch, `_doList` (both shapes), `_doCount`, `_doSearch`.\n *\n * assurance-control: WILDO.AUDIT.ATTRIBUTION — external read-through access recorded with the\n * real initiating user carried through the shared service principal.\n */\n private recordReadThroughAccess(\n executionContext: ExecutionContext<any>,\n operationIdentifier: CoreResourceOperation,\n extras: { resourceId?: string; rowCount?: number } = {},\n ): void {\n try {\n const auditLogsService = this.auditLogsResolver?.();\n if (typeof auditLogsService?.logHttpApiReadThroughAccess !== 'function') return;\n const initiatorIds = (executionContext as { initiatorIds?: { userId?: string; organizationId?: string } }).initiatorIds;\n void auditLogsService.logHttpApiReadThroughAccess({\n resourceType: String(this.resourceConfiguration.resourceIdentifier),\n operationIdentifier: String(operationIdentifier),\n providerRef: this.binding.providerRef,\n remoteEntityRef: this.binding.entityRef,\n dialect: this.binding.dialect,\n initiatorUserId: initiatorIds?.userId,\n executionType: (executionContext as { executionType?: string }).executionType,\n organizationId: initiatorIds?.organizationId\n ?? executionContext.getContextResourceId?.('organizationId' as never),\n ...extras,\n }, executionContext)?.catch?.(() => undefined);\n } catch {\n // Observation only — never the reason a read fails.\n }\n }\n\n // ── D6 stance 6b: the declared external-erasure door ─────────────────────────\n\n /**\n * The ONE write slice 1 sanctions (the stance JSDoc's \"a single declared write\"): delete every\n * remote row linked to ONE erased subject through the binding's DECLARED erasure operation.\n * Callable only by the subject-erasure external effect — every generic write member of this\n * repository stays refused (D3), and the boot-time B1 sweep keeps lifecycle cascades away from\n * HTTP_API children, so this door cannot be reached by an ordinary teardown.\n *\n * ## Identity-less by design\n *\n * The internal context below is inert on this path, verified per consumer: translation runs\n * `excludeContextualFilter` (an erasure must reach the subject's rows in EVERY tenant — the FK\n * equality is the confinement), and `resolveAccess` ignores the context for SERVICE_PRINCIPAL.\n * Attribution lives in the `HTTP_API_EXTERNAL_ERASURE` audit row the calling effect emits;\n * discovery reads here deliberately do NOT emit read-through events (the read exists only to\n * address the deletion the event already records — double-recording would be noise with no\n * initiator).\n *\n * ## Discovery deletes as it goes\n *\n * Each iteration re-queries PAGE ONE (offset 0): deleting shifts pagination windows, so paging\n * forward would skip every second page. A page whose leading row survives two consecutive\n * iterations means the target is not actually deleting — refused loudly rather than looping.\n *\n * ## Failure semantics\n *\n * Throws {@link HttpApiExternalErasureError} carrying what already applied. A retried transport\n * call that landed remotely before its response was lost can surface as an Odoo `unlink` error\n * on missing ids — reported as PARTIAL by the effect, and self-healing on the next erasure run\n * (discovery finds only survivors; a remote 404 on a key-addressed DELETE counts as already\n * gone for the same reason).\n */\n public async executeDeclaredSubjectLinkErasure(\n localFkField: string,\n subjectId: string,\n ): Promise<{ deletedCount: number }> {\n if (this.binding.erasure.stance !== HttpApiErasureStance.EXTERNAL_ERASURE_OPERATION) {\n throw new HttpApiTranslationRefusal(\n `Resource '${String(this.resourceConfiguration.resourceIdentifier)}' declares erasure stance '${this.binding.erasure.stance}' — the external-erasure door is only defined for EXTERNAL_ERASURE_OPERATION (D6 stance 6b).`,\n );\n }\n\n const executionContext = this.systemErasureExecutionContext();\n let deletedCount = 0;\n let previousLeadingId: string | undefined;\n\n for (let iteration = 0; iteration < HttpApiResourceRepositoryBackendService.ERASURE_MAX_DISCOVERY_ITERATIONS; iteration++) {\n let rowIds: string[];\n try {\n const query = this.translate(\n executionContext,\n { [localFkField]: subjectId },\n { excludeContextualFilter: true },\n { limit: HttpApiResourceRepositoryBackendService.ERASURE_DISCOVERY_PAGE, offset: 0 },\n );\n const rows = await this.executeCollectionRead(\n executionContext,\n query,\n this.syntheticOperation(CoreResourceOperation.LIST),\n );\n rowIds = rows.map((row) => String(projectHttpApiRemoteRow(this.binding, row)._id));\n } catch (error) {\n throw new HttpApiExternalErasureError(\n `External-erasure discovery failed for '${String(this.resourceConfiguration.resourceIdentifier)}' (link field '${localFkField}'): ${error instanceof Error ? error.message : String(error)}`,\n deletedCount,\n error,\n );\n }\n\n if (rowIds.length === 0) {\n return { deletedCount };\n }\n if (rowIds[0] === previousLeadingId) {\n throw new HttpApiExternalErasureError(\n `The target acknowledged the delete of row '${rowIds[0]}' but discovery still returns it — the declared erasure operation is not actually deleting; refusing to loop.`,\n deletedCount,\n );\n }\n previousLeadingId = rowIds[0];\n\n try {\n await this.deleteRemoteRowsByIds(executionContext, rowIds);\n } catch (error) {\n // A mid-page per-row failure carries what THAT page already applied — losing it would\n // report a PARTIAL as a clean FAILED and invite a retry the registry believes is safe.\n const appliedInFailedPage = error instanceof HttpApiExternalErasureError ? error.deletedCount : 0;\n throw new HttpApiExternalErasureError(\n `The declared erasure operation failed for '${String(this.resourceConfiguration.resourceIdentifier)}' after ${deletedCount + appliedInFailedPage} deletion(s): ${error instanceof Error ? error.message : String(error)}`,\n deletedCount + appliedInFailedPage,\n error,\n );\n }\n deletedCount += rowIds.length;\n }\n\n throw new HttpApiExternalErasureError(\n `External erasure exceeded ${HttpApiResourceRepositoryBackendService.ERASURE_MAX_DISCOVERY_ITERATIONS} discovery pages for one subject — refusing an unbounded remote loop.`,\n deletedCount,\n );\n }\n\n /**\n * Best-effort remote count of rows linked to one subject — the stance-6c acknowledgement's\n * evidence (`remainingRowCount` on the CRITICAL audit row). Throws on any refusal or transport\n * failure; the caller records ABSENCE rather than a fabricated zero.\n */\n public async countRowsLinkedToSubject(localFkField: string, subjectId: string): Promise<number> {\n const executionContext = this.systemErasureExecutionContext();\n const query = this.translate(\n executionContext,\n { [localFkField]: subjectId },\n { excludeContextualFilter: true },\n );\n return this.executeCountRead(executionContext, query, this.syntheticOperation(CoreResourceOperation.COUNT));\n }\n\n private static readonly ERASURE_DISCOVERY_PAGE = 50;\n private static readonly ERASURE_MAX_DISCOVERY_ITERATIONS = 200;\n\n /**\n * The minimal internal context the erasure path runs under. Structurally an ExecutionContext,\n * deliberately identity-less (a system erasure carries no request identity — the same doctrine\n * as the file-teardown gates); every consumer on this path is verified inert against it, per\n * the door's JSDoc.\n */\n private systemErasureExecutionContext(): ExecutionContext<any> {\n return {\n getContextResourceId: () => undefined,\n getContextResourceIds: () => new Map(),\n operation: undefined,\n } as unknown as ExecutionContext<any>;\n }\n\n /** Delete one discovered page of rows through the DECLARED erasure operation, per dialect. */\n private async deleteRemoteRowsByIds(\n executionContext: ExecutionContext<any>,\n rowIds: readonly string[],\n ): Promise<void> {\n if (this.binding.dialect === HttpApiTransportDialect.ODOO_JSONRPC) {\n // Odoo's canonical delete is ONE batched `unlink [[ids]]` per page.\n const integerIds = rowIds.map((rowId) => Number(resolveHttpApiKeyComponents(this.binding, rowId)[0]));\n await this.readClient.odooExecuteKw(executionContext, compileOdooCanonicalDelete(integerIds));\n return;\n }\n\n if (this.binding.dialect === HttpApiTransportDialect.ODATA) {\n // OData's canonical delete: `DELETE /EntitySet(key)` per row; 404 = already gone. A per-row\n // failure surfaces WITH the count that already applied in this page (PARTIAL accuracy).\n let appliedInPage = 0;\n for (const rowId of rowIds) {\n const compiled = compileODataKeyAddressedRead(this.binding, rowId);\n try {\n await this.readClient.odataDeleteByPath(executionContext, compiled.path);\n } catch (error) {\n throw new HttpApiExternalErasureError(\n `Canonical DELETE failed for row '${rowId}': ${error instanceof Error ? error.message : String(error)}`,\n appliedInPage,\n error,\n );\n }\n appliedInPage += 1;\n }\n return;\n }\n\n // REST_JSON: the EXPLICIT declared operation (dialect coherence guarantees the form).\n const declaredOperation = this.binding.erasure.stance === HttpApiErasureStance.EXTERNAL_ERASURE_OPERATION\n ? this.binding.erasure.operation\n : undefined;\n if (!declaredOperation || 'useCanonicalDelete' in declaredOperation) {\n throw new HttpApiTranslationRefusal(\n 'A REST_JSON external erasure needs the EXPLICIT declared operation spec — the boot-time dialect coherence should have refused this binding.',\n );\n }\n const spec: HttpApiErasureOperationSpec = declaredOperation;\n let appliedInPage = 0;\n for (const rowId of rowIds) {\n const compiled = compileRestJsonDeclaredErasure(this.binding, spec, rowId);\n try {\n await this.readClient.restDeclaredErasureCall(executionContext, compiled);\n } catch (error) {\n throw new HttpApiExternalErasureError(\n `Declared erasure operation failed for row '${rowId}': ${error instanceof Error ? error.message : String(error)}`,\n appliedInPage,\n error,\n );\n }\n appliedInPage += 1;\n }\n }\n\n private expectRowArray(candidate: unknown, where: string): Array<Record<string, unknown>> {\n if (!Array.isArray(candidate)) {\n // A remote-CONTRACT breach, not a translation refusal: the query was legal, the answer is not.\n throw new HttpApiRemoteContractError(`The remote response carries no row array at ${where}.`);\n }\n return candidate as Array<Record<string, unknown>>;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Error projection + refusals\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Map the module-level error vocabulary into the engine's error projection, once. */\n private async guarded<T>(executionContext: ExecutionContext<any>, work: () => Promise<T>): Promise<T> {\n try {\n return await work();\n } catch (error) {\n if (error instanceof HttpApiTranslationRefusal || error instanceof RestJsonTranslationRefusal || error instanceof HttpApiRemoteContractError) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: { reason: 'http_api_untranslatable_shape', message: error.message, resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n if (error instanceof HttpApiProviderAccessError) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: { reason: 'http_api_provider_access_unresolvable', message: error.message, resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n if (error instanceof HttpApiTransportError) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: { reason: 'http_api_remote_call_failed', message: error.message, ...error.detail, resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n // Codec errors (undecodable / non-canonical / missing key components) are the shared\n // authority's TYPED refusal: LOUD VALIDATION by design, classified by instance.\n if (error instanceof HttpApiResourceIdError) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.RESOURCE_ID_VALIDATION_FAILED,\n context: { reason: 'http_api_id_refused', message: error.message, resourceType: this.resourceConfiguration.resourceIdentifier },\n });\n }\n throw error;\n }\n }\n\n private readOnlyRefusal(member: string, executionContext?: ExecutionContext<any>): ReturnType<ErrorBuilderBackendService['buildError']> {\n return this.errorBuilder.buildError(ErrorType.CONFIGURATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: {\n reason: 'http_api_repository_member_unsupported',\n member,\n message: `'${member}' is not available on an HTTP_API-backed resource in slice 1 (read-only — ETL decision D3/D10). `\n + 'Reads: read/list/count/search and the internal-scan variants.',\n resourceType: this.resourceConfiguration.resourceIdentifier,\n },\n });\n }\n\n private findDefaultOperation(operationIdentifier: CoreResourceOperation): AnyOperation | undefined {\n return (this.resourceConfiguration.operations as AnyOperation[]).find(\n (operation) => operation.operationIdentifier === operationIdentifier && operation.isOperationDefault === true,\n );\n }\n\n private syntheticOperation(operationIdentifier: CoreResourceOperation): AnyOperation {\n return {\n operationIdentifier,\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isOperationDefault: true,\n } as unknown as AnyOperation;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // The refused remainder of the contract (D2: implemented, never omitted; D3: read-only)\n // ─────────────────────────────────────────────────────────────────────────────\n\n public async create(): Promise<never> { throw this.readOnlyRefusal('create'); }\n public async createMany(): Promise<never> { throw this.readOnlyRefusal('createMany'); }\n public async update(): Promise<never> { throw this.readOnlyRefusal('update'); }\n public async updateMany(): Promise<never> { throw this.readOnlyRefusal('updateMany'); }\n public async delete(): Promise<never> { throw this.readOnlyRefusal('delete'); }\n public async deleteMany(): Promise<never> { throw this.readOnlyRefusal('deleteMany'); }\n public async atomicIncrementField(): Promise<never> { throw this.readOnlyRefusal('atomicIncrementField'); }\n public async atomicConditionalSet(): Promise<never> { throw this.readOnlyRefusal('atomicConditionalSet'); }\n public async atomicGuardedMutation(): Promise<never> { throw this.readOnlyRefusal('atomicGuardedMutation'); }\n public async updateManyByRawFilter(): Promise<never> { throw this.readOnlyRefusal('updateManyByRawFilter'); }\n public async deleteManyByRawFilter(): Promise<never> { throw this.readOnlyRefusal('deleteManyByRawFilter'); }\n public async insertRawDocument(): Promise<never> { throw this.readOnlyRefusal('insertRawDocument'); }\n public async findManyByRawFilter(): Promise<never> { throw this.readOnlyRefusal('findManyByRawFilter (raw filters are refused — T-set only, paper B R1)'); }\n public async countByRawFilter(): Promise<never> { throw this.readOnlyRefusal('countByRawFilter (raw filters are refused — T-set only, paper B R1)'); }\n public async readUnscopedByKey(): Promise<never> { throw this.readOnlyRefusal('readUnscopedByKey (raw filters are refused — T-set only, paper B R1)'); }\n public async findScopeRelatedTargetIds(): Promise<never> { throw this.readOnlyRefusal('findScopeRelatedTargetIds (an HTTP_API resource cannot serve as a scope junction in slice 1)'); }\n public async aggregateField(): Promise<never> { throw this.readOnlyRefusal('aggregateField (remote aggregation is refused — ETL decision D10)'); }\n public async findByBusinessKey(): Promise<never> { throw this.readOnlyRefusal('findByBusinessKey (data-seeding never targets an HTTP_API resource)'); }\n public async findManyByBusinessKeys(): Promise<never> { throw this.readOnlyRefusal('findManyByBusinessKeys (data-seeding never targets an HTTP_API resource)'); }\n public async upsertByBusinessKey(): Promise<never> { throw this.readOnlyRefusal('upsertByBusinessKey'); }\n public async upsertByFilter(): Promise<never> { throw this.readOnlyRefusal('upsertByFilter'); }\n public async updateSeedMetadata(): Promise<never> { throw this.readOnlyRefusal('updateSeedMetadata'); }\n}\n"]}
|
package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"odata-query-compiler.backend.d.ts","sourceRoot":"","sources":["../../../../../../../src/base-classes/services/repositories/http-api/odata-query-compiler.backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACzB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,KAAK,EAEV,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,aAAa,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAC/C;AAgDD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,MAAM,GACjB,MAAM,CASR;AAED,0CAA0C;AAC1C,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,MAAM,GACjB,oBAAoB,CAKtB;AAoCD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,sBAAsB,EAC7B,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,oBAAoB,CA8CtB;AAED;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,iBAAiB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAClD,OAAO,EAAE;IACP,iFAAiF;IACjF,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,yFAAyF;IACzF,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IACnE,QAAQ,EAAE,MAAM,CAAC;CAClB,GACA,oBAAoB,
|
|
1
|
+
{"version":3,"file":"odata-query-compiler.backend.d.ts","sourceRoot":"","sources":["../../../../../../../src/base-classes/services/repositories/http-api/odata-query-compiler.backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACzB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,KAAK,EAEV,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,aAAa,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAC/C;AAgDD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,MAAM,GACjB,MAAM,CASR;AAED,0CAA0C;AAC1C,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,MAAM,GACjB,oBAAoB,CAKtB;AAoCD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,sBAAsB,EAC7B,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,oBAAoB,CA8CtB;AAED;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,iBAAiB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAClD,OAAO,EAAE;IACP,iFAAiF;IACjF,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,yFAAyF;IACzF,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IACnE,QAAQ,EAAE,MAAM,CAAC;CAClB,GACA,oBAAoB,CA4BtB;AAED,oFAAoF;AACpF,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,sBAAsB,GAC5B,oBAAoB,CAQtB"}
|
package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js
CHANGED
|
@@ -161,8 +161,24 @@ export function compileODataCollectionRead(binding, query, options) {
|
|
|
161
161
|
* per run.
|
|
162
162
|
*/
|
|
163
163
|
export function compileODataExtractionFirstPage(binding, options) {
|
|
164
|
+
// `$orderby` on the KEY components, ascending, is not decoration — it is what makes the paged
|
|
165
|
+
// extraction drift-safe, and following `@odata.nextLink` alone does NOT provide it.
|
|
166
|
+
//
|
|
167
|
+
// Dataverse builds its paging cookie from the LAST ROW of the previous page under the query's
|
|
168
|
+
// own order, and its documentation is explicit that without a deterministic order "the same
|
|
169
|
+
// record can appear in more than one page" — it recommends ordering on the primary key, which is
|
|
170
|
+
// exactly what a binding's `keyFields` are. A duplicated row would be re-upserted (harmless), but
|
|
171
|
+
// a SKIPPED one is silently absent from a COMPLETE pass, and a complete pass is what authorizes
|
|
172
|
+
// the orphan stage — so a skip does not merely lose a row, it can orphan a live one.
|
|
173
|
+
// spec-cite: Microsoft Learn, "Page results using OData from Microsoft Dataverse Web API" —
|
|
174
|
+
// "Deterministic ordering is important" / "Without proper ordering, the same record can appear in
|
|
175
|
+
// more than one page."
|
|
176
|
+
//
|
|
177
|
+
// Key components are ordered as DECLARED: the schema already fixes their order for the composite
|
|
178
|
+
// key predicate, so reusing it keeps one source for "the key's component order".
|
|
164
179
|
const params = {
|
|
165
180
|
$select: [...new Set(options.selectRemoteFields)].join(','),
|
|
181
|
+
$orderby: binding.keyFields.map((keyField) => `${keyField.remoteField} asc`).join(','),
|
|
166
182
|
$top: String(options.pageSize),
|
|
167
183
|
};
|
|
168
184
|
const filterFragments = Object.entries(options.sourceFilter ?? {}).map(([remoteField, value]) => `${remoteField} eq ${odataScalarLiteral(value)}`);
|
package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"odata-query-compiler.backend.js","sourceRoot":"","sources":["../../../../../../../src/base-classes/services/repositories/http-api/odata-query-compiler.backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,2BAA2B,GAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,wBAAwB,GAGzB,MAAM,qCAAqC,CAAC;AAoB7C,SAAS,cAAc,CAAC,OAA0B,EAAE,UAAkB;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;IACvF,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC;AACpD,CAAC;AAED,6EAA6E;AAC7E,SAAS,kBAAkB,CAAC,KAAa;IACvC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;AAC1C,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAyB;IACnD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAChE,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IACtD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,wBAAwB,CAAC,KAA+B,EAAE,KAAsB;IACvF,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,wBAAwB,CAAC,MAAM;YAClC,OAAO,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,KAAK,wBAAwB,CAAC,OAAO,CAAC;QACtC,KAAK,wBAAwB,CAAC,IAAI,CAAC;QACnC,KAAK,wBAAwB,CAAC,YAAY;YACxC,+EAA+E;YAC/E,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,wBAAwB,CAAC,SAAiB;IACjD,OAAO,SAAS;SACb,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAA0B,EAC1B,UAAkB;IAElB,MAAM,UAAU,GAAG,2BAA2B,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACpE,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,wBAAwB,CAAC,IAAI,wBAAwB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC9G,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CACjC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,WAAW,IAAI,wBAAwB,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAC9G,CAAC;IACF,OAAO,wBAAwB,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,4BAA4B,CAC1C,OAA0B,EAC1B,UAAkB;IAElB,OAAO;QACL,IAAI,EAAE,IAAI,OAAO,CAAC,SAAS,GAAG,wBAAwB,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE;QAC7E,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,OAA0B,EAAE,GAAsB;IAC5E,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QAC3B,MAAM,UAAU,GAAG,2BAA2B,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC5D,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CACrC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,WAAW,OAAO,wBAAwB,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CACjH,CAAC;QACF,OAAO,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;IAChF,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;AACnE,CAAC;AAED,SAAS,mBAAmB,CAC1B,OAA0B,EAC1B,MAAqD;IAErD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;QACrD,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACxD,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC,aAAa;gBACzB,CAAC,CAAC,GAAG,WAAW,OAAO,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBACzD,CAAC,CAAC,WAAW,WAAW,QAAQ,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QACrF,CAAC;QACD,OAAO,MAAM,CAAC,aAAa;YACzB,CAAC,CAAC,YAAY,WAAW,IAAI,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG;YAChE,CAAC,CAAC,oBAAoB,WAAW,KAAK,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC;IAC5F,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;AAC5E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAA0B,EAC1B,KAA6B,EAC7B,OAA6B;IAE7B,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,kHAAkH,CACnH,CAAC;IACJ,CAAC;IAED,MAAM,eAAe,GAAa,EAAE,CAAC;IACrC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,OAAO,kBAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,eAAe,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACvC,eAAe,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/G,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAC9D,IAAI,KAAK,CAAC,GAAG;YAAE,eAAe,CAAC,IAAI,CAAC,GAAG,WAAW,OAAO,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACpF,IAAI,KAAK,CAAC,GAAG;YAAE,eAAe,CAAC,IAAI,CAAC,GAAG,WAAW,OAAO,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,eAAe,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI;aACzB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;aAChG,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,IAAI,OAAO,EAAE,KAAK,EAAE,CAAC;QACnB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC;AACnD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,+BAA+B,CAC7C,OAAkD,EAClD,OAMC;IAED,MAAM,MAAM,GAA2B;QACrC,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAC3D,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;KAC/B,CAAC;IACF,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,GAAG,CACpE,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,WAAW,OAAO,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAC3E,CAAC;IACF,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC;AACnD,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,qBAAqB,CACnC,OAA0B,EAC1B,KAA6B;IAE7B,MAAM,UAAU,GAAG,0BAA0B,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,EAAE,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;IACxC,OAAO,MAAM,CAAC,QAAQ,CAAC;IACvB,OAAO,MAAM,CAAC,IAAI,CAAC;IACnB,OAAO,MAAM,CAAC,KAAK,CAAC;IACpB,OAAO,MAAM,CAAC,MAAM,CAAC;IACrB,OAAO,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,IAAI,SAAS,EAAE,MAAM,EAAE,CAAC;AACvD,CAAC","sourcesContent":["/**\n * OData v4 compiler: {@link HttpApiTranslatedQuery} + binding → URL path + query parameters.\n *\n * One generic implementation for every OData target (SAP S/4HANA, Dataverse — ETL decision D0).\n * Purely mechanical: every predicate arriving here is ALREADY admitted by the T-set translation;\n * this module never widens or narrows a query, it only spells it.\n *\n * Key-literal spelling follows the component CODEC declared on the binding (paper A): string\n * components are quoted with doubled single-quotes, integer/guid/datetime components are\n * unquoted — the OData v4 primitive-literal forms.\n */\n\nimport {\n resolveHttpApiKeyComponents,\n} from '@wildo-ai/saas-models';\nimport {\n HttpApiKeyComponentCodec,\n type HttpApiKeyField,\n type HttpApiFieldMapping,\n} from '@wildo-ai/saas-models/external-data';\n\nimport type {\n HttpApiQueryScalar,\n HttpApiTranslatedQuery,\n} from './http-api-query.backend';\n\nexport interface ODataCompiledRequest {\n /** Path relative to the provider base URL, starting with '/'. */\n path: string;\n /** Query parameters, unencoded values (the transport URL-encodes once). */\n params: Record<string, string>;\n}\n\ninterface ODataBindingShape {\n entityRef: string;\n keyFields: readonly HttpApiKeyField[];\n fieldMappings: readonly HttpApiFieldMapping[];\n}\n\nfunction remoteFieldFor(binding: ODataBindingShape, localField: string): string {\n const mapping = binding.fieldMappings.find((entry) => entry.localField === localField);\n return mapping ? mapping.remoteField : localField;\n}\n\n/** OData string literal: single quotes doubled, wrapped in single quotes. */\nfunction odataStringLiteral(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\nfunction odataScalarLiteral(value: HttpApiQueryScalar): string {\n if (typeof value === 'string') return odataStringLiteral(value);\n if (value instanceof Date) return value.toISOString();\n return String(value);\n}\n\nfunction odataKeyComponentLiteral(codec: HttpApiKeyComponentCodec, value: string | number): string {\n switch (codec) {\n case HttpApiKeyComponentCodec.STRING:\n return odataStringLiteral(String(value));\n case HttpApiKeyComponentCodec.INTEGER:\n case HttpApiKeyComponentCodec.GUID:\n case HttpApiKeyComponentCodec.DATETIME_ISO:\n // OData v4 spells guid and datetimeoffset literals UNQUOTED in key predicates.\n return String(value);\n }\n}\n\n/**\n * Percent-encode the characters that break a URL PATH segment, leaving the predicate's\n * structural characters (`( ) = , '`) intact. `%` first, or the encoding re-encodes itself.\n * Applied to the finished predicate because these characters are never structural in one.\n * (The transport encodes QUERY params separately — this function must not run on `$filter`\n * fragments, or values would be double-encoded.)\n */\nfunction encodeODataPathPredicate(predicate: string): string {\n return predicate\n .replace(/%/g, '%25')\n .replace(/ /g, '%20')\n .replace(/\\?/g, '%3F')\n .replace(/#/g, '%23')\n .replace(/&/g, '%26')\n .replace(/\\+/g, '%2B')\n .replace(/\\//g, '%2F');\n}\n\n/**\n * The canonical key predicate for ONE row, from its synthesized id: `(K1=lit,K2=lit)` — or the\n * single-component short form `(lit)` when the binding declares one key field. PATH-encoded:\n * this predicate is only ever used as a URL path segment (the id-set `$filter` spelling lives in\n * `compileIdSetFilter`, which the transport's query-param encoding covers).\n */\nexport function compileODataKeyPredicate(\n binding: ODataBindingShape,\n resourceId: string,\n): string {\n const components = resolveHttpApiKeyComponents(binding, resourceId);\n if (binding.keyFields.length === 1) {\n return encodeODataPathPredicate(`(${odataKeyComponentLiteral(binding.keyFields[0].codec, components[0])})`);\n }\n const parts = binding.keyFields.map(\n (keyField, index) => `${keyField.remoteField}=${odataKeyComponentLiteral(keyField.codec, components[index])}`,\n );\n return encodeODataPathPredicate(`(${parts.join(',')})`);\n}\n\n/** Single-row read: `/EntitySet(key)`. */\nexport function compileODataKeyAddressedRead(\n binding: ODataBindingShape,\n resourceId: string,\n): ODataCompiledRequest {\n return {\n path: `/${binding.entityRef}${compileODataKeyPredicate(binding, resourceId)}`,\n params: {},\n };\n}\n\n/**\n * The id-set predicate (T2): a disjunction of full key predicates. Spelled as an `or`-chain of\n * per-component conjunctions — portable across OData v4.0 targets (`in` is 4.01-only, and only\n * expresses single-property membership anyway).\n */\nfunction compileIdSetFilter(binding: ODataBindingShape, ids: readonly string[]): string {\n const perId = ids.map((id) => {\n const components = resolveHttpApiKeyComponents(binding, id);\n const conjuncts = binding.keyFields.map(\n (keyField, index) => `${keyField.remoteField} eq ${odataKeyComponentLiteral(keyField.codec, components[index])}`,\n );\n return conjuncts.length === 1 ? conjuncts[0] : `(${conjuncts.join(' and ')})`;\n });\n return perId.length === 1 ? perId[0] : `(${perId.join(' or ')})`;\n}\n\nfunction compileSearchFilter(\n binding: ODataBindingShape,\n search: NonNullable<HttpApiTranslatedQuery['search']>,\n): string {\n const branches = search.localFields.map((localField) => {\n const remoteField = remoteFieldFor(binding, localField);\n if (search.fullMatchOnly) {\n return search.caseSensitive\n ? `${remoteField} eq ${odataStringLiteral(search.query)}`\n : `tolower(${remoteField}) eq ${odataStringLiteral(search.query.toLowerCase())}`;\n }\n return search.caseSensitive\n ? `contains(${remoteField},${odataStringLiteral(search.query)})`\n : `contains(tolower(${remoteField}),${odataStringLiteral(search.query.toLowerCase())})`;\n });\n return branches.length === 1 ? branches[0] : `(${branches.join(' or ')})`;\n}\n\n/**\n * Collection read (LIST/SEARCH/COUNT): `/EntitySet?$filter=…&$orderby=…&$top=…&$skip=…`.\n *\n * `matchNothing` MUST be short-circuited by the caller before compiling — compiling it is a\n * defect, and this module throws rather than spelling a query that could accidentally match.\n */\nexport function compileODataCollectionRead(\n binding: ODataBindingShape,\n query: HttpApiTranslatedQuery,\n options?: { count?: boolean },\n): ODataCompiledRequest {\n if (query.matchNothing) {\n throw new Error(\n 'A match-nothing query must be answered locally with an empty page — compiling it into OData risks matching rows.',\n );\n }\n\n const filterFragments: string[] = [];\n if (query.scope) {\n filterFragments.push(`${query.scope.remoteField} eq ${odataStringLiteral(query.scope.value)}`);\n }\n if (query.idIn) {\n filterFragments.push(compileIdSetFilter(binding, query.idIn));\n }\n for (const equals of query.fieldEquals) {\n filterFragments.push(`${remoteFieldFor(binding, equals.localField)} eq ${odataScalarLiteral(equals.value)}`);\n }\n for (const range of query.dateRanges) {\n const remoteField = remoteFieldFor(binding, range.localField);\n if (range.gte) filterFragments.push(`${remoteField} ge ${range.gte.toISOString()}`);\n if (range.lte) filterFragments.push(`${remoteField} le ${range.lte.toISOString()}`);\n }\n if (query.search) {\n filterFragments.push(compileSearchFilter(binding, query.search));\n }\n\n const params: Record<string, string> = {};\n if (filterFragments.length > 0) {\n params.$filter = filterFragments.join(' and ');\n }\n if (query.sort.length > 0) {\n params.$orderby = query.sort\n .map((key) => `${remoteFieldFor(binding, key.localField)}${key.direction === -1 ? ' desc' : ''}`)\n .join(',');\n }\n if (query.pagination) {\n params.$top = String(query.pagination.limit);\n if (query.pagination.offset > 0) {\n params.$skip = String(query.pagination.offset);\n }\n }\n if (options?.count) {\n params.$count = 'true';\n }\n\n return { path: `/${binding.entityRef}`, params };\n}\n\n/**\n * The ETL extraction FIRST page (partial-resource paper, D-P10 / PR-5): `$select` confined to\n * exactly the fields the pipeline maps (data minimization by construction — un-mapped personal\n * data never enters the process), an optional declared equality filter, `$top` as the page bound.\n * Subsequent pages are NOT compiled locally — the extraction follows the server's own\n * `@odata.nextLink` (drift-safe server-driven paging), so this function is only ever called once\n * per run.\n */\nexport function compileODataExtractionFirstPage(\n binding: ODataBindingShape & { entityRef: string },\n options: {\n /** REMOTE field names to select — the mapped fields plus every key component. */\n selectRemoteFields: readonly string[];\n /** Declared REMOTE-field equality conjunction (`sourceFilter`), already remote-named. */\n sourceFilter?: Readonly<Record<string, string | number | boolean>>;\n pageSize: number;\n },\n): ODataCompiledRequest {\n const params: Record<string, string> = {\n $select: [...new Set(options.selectRemoteFields)].join(','),\n $top: String(options.pageSize),\n };\n const filterFragments = Object.entries(options.sourceFilter ?? {}).map(\n ([remoteField, value]) => `${remoteField} eq ${odataScalarLiteral(value)}`,\n );\n if (filterFragments.length > 0) {\n params.$filter = filterFragments.join(' and ');\n }\n return { path: `/${binding.entityRef}`, params };\n}\n\n/** COUNT-only read: `/EntitySet/$count?$filter=…` — the body is the bare number. */\nexport function compileODataCountRead(\n binding: ODataBindingShape,\n query: HttpApiTranslatedQuery,\n): ODataCompiledRequest {\n const collection = compileODataCollectionRead(binding, query);\n const params = { ...collection.params };\n delete params.$orderby;\n delete params.$top;\n delete params.$skip;\n delete params.$count;\n return { path: `${collection.path}/$count`, params };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"odata-query-compiler.backend.js","sourceRoot":"","sources":["../../../../../../../src/base-classes/services/repositories/http-api/odata-query-compiler.backend.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * OData v4 compiler: {@link HttpApiTranslatedQuery} + binding → URL path + query parameters.\n *\n * One generic implementation for every OData target (SAP S/4HANA, Dataverse — ETL decision D0).\n * Purely mechanical: every predicate arriving here is ALREADY admitted by the T-set translation;\n * this module never widens or narrows a query, it only spells it.\n *\n * Key-literal spelling follows the component CODEC declared on the binding (paper A): string\n * components are quoted with doubled single-quotes, integer/guid/datetime components are\n * unquoted — the OData v4 primitive-literal forms.\n */\n\nimport {\n resolveHttpApiKeyComponents,\n} from '@wildo-ai/saas-models';\nimport {\n HttpApiKeyComponentCodec,\n type HttpApiKeyField,\n type HttpApiFieldMapping,\n} from '@wildo-ai/saas-models/external-data';\n\nimport type {\n HttpApiQueryScalar,\n HttpApiTranslatedQuery,\n} from './http-api-query.backend';\n\nexport interface ODataCompiledRequest {\n /** Path relative to the provider base URL, starting with '/'. */\n path: string;\n /** Query parameters, unencoded values (the transport URL-encodes once). */\n params: Record<string, string>;\n}\n\ninterface ODataBindingShape {\n entityRef: string;\n keyFields: readonly HttpApiKeyField[];\n fieldMappings: readonly HttpApiFieldMapping[];\n}\n\nfunction remoteFieldFor(binding: ODataBindingShape, localField: string): string {\n const mapping = binding.fieldMappings.find((entry) => entry.localField === localField);\n return mapping ? mapping.remoteField : localField;\n}\n\n/** OData string literal: single quotes doubled, wrapped in single quotes. */\nfunction odataStringLiteral(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\nfunction odataScalarLiteral(value: HttpApiQueryScalar): string {\n if (typeof value === 'string') return odataStringLiteral(value);\n if (value instanceof Date) return value.toISOString();\n return String(value);\n}\n\nfunction odataKeyComponentLiteral(codec: HttpApiKeyComponentCodec, value: string | number): string {\n switch (codec) {\n case HttpApiKeyComponentCodec.STRING:\n return odataStringLiteral(String(value));\n case HttpApiKeyComponentCodec.INTEGER:\n case HttpApiKeyComponentCodec.GUID:\n case HttpApiKeyComponentCodec.DATETIME_ISO:\n // OData v4 spells guid and datetimeoffset literals UNQUOTED in key predicates.\n return String(value);\n }\n}\n\n/**\n * Percent-encode the characters that break a URL PATH segment, leaving the predicate's\n * structural characters (`( ) = , '`) intact. `%` first, or the encoding re-encodes itself.\n * Applied to the finished predicate because these characters are never structural in one.\n * (The transport encodes QUERY params separately — this function must not run on `$filter`\n * fragments, or values would be double-encoded.)\n */\nfunction encodeODataPathPredicate(predicate: string): string {\n return predicate\n .replace(/%/g, '%25')\n .replace(/ /g, '%20')\n .replace(/\\?/g, '%3F')\n .replace(/#/g, '%23')\n .replace(/&/g, '%26')\n .replace(/\\+/g, '%2B')\n .replace(/\\//g, '%2F');\n}\n\n/**\n * The canonical key predicate for ONE row, from its synthesized id: `(K1=lit,K2=lit)` — or the\n * single-component short form `(lit)` when the binding declares one key field. PATH-encoded:\n * this predicate is only ever used as a URL path segment (the id-set `$filter` spelling lives in\n * `compileIdSetFilter`, which the transport's query-param encoding covers).\n */\nexport function compileODataKeyPredicate(\n binding: ODataBindingShape,\n resourceId: string,\n): string {\n const components = resolveHttpApiKeyComponents(binding, resourceId);\n if (binding.keyFields.length === 1) {\n return encodeODataPathPredicate(`(${odataKeyComponentLiteral(binding.keyFields[0].codec, components[0])})`);\n }\n const parts = binding.keyFields.map(\n (keyField, index) => `${keyField.remoteField}=${odataKeyComponentLiteral(keyField.codec, components[index])}`,\n );\n return encodeODataPathPredicate(`(${parts.join(',')})`);\n}\n\n/** Single-row read: `/EntitySet(key)`. */\nexport function compileODataKeyAddressedRead(\n binding: ODataBindingShape,\n resourceId: string,\n): ODataCompiledRequest {\n return {\n path: `/${binding.entityRef}${compileODataKeyPredicate(binding, resourceId)}`,\n params: {},\n };\n}\n\n/**\n * The id-set predicate (T2): a disjunction of full key predicates. Spelled as an `or`-chain of\n * per-component conjunctions — portable across OData v4.0 targets (`in` is 4.01-only, and only\n * expresses single-property membership anyway).\n */\nfunction compileIdSetFilter(binding: ODataBindingShape, ids: readonly string[]): string {\n const perId = ids.map((id) => {\n const components = resolveHttpApiKeyComponents(binding, id);\n const conjuncts = binding.keyFields.map(\n (keyField, index) => `${keyField.remoteField} eq ${odataKeyComponentLiteral(keyField.codec, components[index])}`,\n );\n return conjuncts.length === 1 ? conjuncts[0] : `(${conjuncts.join(' and ')})`;\n });\n return perId.length === 1 ? perId[0] : `(${perId.join(' or ')})`;\n}\n\nfunction compileSearchFilter(\n binding: ODataBindingShape,\n search: NonNullable<HttpApiTranslatedQuery['search']>,\n): string {\n const branches = search.localFields.map((localField) => {\n const remoteField = remoteFieldFor(binding, localField);\n if (search.fullMatchOnly) {\n return search.caseSensitive\n ? `${remoteField} eq ${odataStringLiteral(search.query)}`\n : `tolower(${remoteField}) eq ${odataStringLiteral(search.query.toLowerCase())}`;\n }\n return search.caseSensitive\n ? `contains(${remoteField},${odataStringLiteral(search.query)})`\n : `contains(tolower(${remoteField}),${odataStringLiteral(search.query.toLowerCase())})`;\n });\n return branches.length === 1 ? branches[0] : `(${branches.join(' or ')})`;\n}\n\n/**\n * Collection read (LIST/SEARCH/COUNT): `/EntitySet?$filter=…&$orderby=…&$top=…&$skip=…`.\n *\n * `matchNothing` MUST be short-circuited by the caller before compiling — compiling it is a\n * defect, and this module throws rather than spelling a query that could accidentally match.\n */\nexport function compileODataCollectionRead(\n binding: ODataBindingShape,\n query: HttpApiTranslatedQuery,\n options?: { count?: boolean },\n): ODataCompiledRequest {\n if (query.matchNothing) {\n throw new Error(\n 'A match-nothing query must be answered locally with an empty page — compiling it into OData risks matching rows.',\n );\n }\n\n const filterFragments: string[] = [];\n if (query.scope) {\n filterFragments.push(`${query.scope.remoteField} eq ${odataStringLiteral(query.scope.value)}`);\n }\n if (query.idIn) {\n filterFragments.push(compileIdSetFilter(binding, query.idIn));\n }\n for (const equals of query.fieldEquals) {\n filterFragments.push(`${remoteFieldFor(binding, equals.localField)} eq ${odataScalarLiteral(equals.value)}`);\n }\n for (const range of query.dateRanges) {\n const remoteField = remoteFieldFor(binding, range.localField);\n if (range.gte) filterFragments.push(`${remoteField} ge ${range.gte.toISOString()}`);\n if (range.lte) filterFragments.push(`${remoteField} le ${range.lte.toISOString()}`);\n }\n if (query.search) {\n filterFragments.push(compileSearchFilter(binding, query.search));\n }\n\n const params: Record<string, string> = {};\n if (filterFragments.length > 0) {\n params.$filter = filterFragments.join(' and ');\n }\n if (query.sort.length > 0) {\n params.$orderby = query.sort\n .map((key) => `${remoteFieldFor(binding, key.localField)}${key.direction === -1 ? ' desc' : ''}`)\n .join(',');\n }\n if (query.pagination) {\n params.$top = String(query.pagination.limit);\n if (query.pagination.offset > 0) {\n params.$skip = String(query.pagination.offset);\n }\n }\n if (options?.count) {\n params.$count = 'true';\n }\n\n return { path: `/${binding.entityRef}`, params };\n}\n\n/**\n * The ETL extraction FIRST page (partial-resource paper, D-P10 / PR-5): `$select` confined to\n * exactly the fields the pipeline maps (data minimization by construction — un-mapped personal\n * data never enters the process), an optional declared equality filter, `$top` as the page bound.\n * Subsequent pages are NOT compiled locally — the extraction follows the server's own\n * `@odata.nextLink` (drift-safe server-driven paging), so this function is only ever called once\n * per run.\n */\nexport function compileODataExtractionFirstPage(\n binding: ODataBindingShape & { entityRef: string },\n options: {\n /** REMOTE field names to select — the mapped fields plus every key component. */\n selectRemoteFields: readonly string[];\n /** Declared REMOTE-field equality conjunction (`sourceFilter`), already remote-named. */\n sourceFilter?: Readonly<Record<string, string | number | boolean>>;\n pageSize: number;\n },\n): ODataCompiledRequest {\n // `$orderby` on the KEY components, ascending, is not decoration — it is what makes the paged\n // extraction drift-safe, and following `@odata.nextLink` alone does NOT provide it.\n //\n // Dataverse builds its paging cookie from the LAST ROW of the previous page under the query's\n // own order, and its documentation is explicit that without a deterministic order \"the same\n // record can appear in more than one page\" — it recommends ordering on the primary key, which is\n // exactly what a binding's `keyFields` are. A duplicated row would be re-upserted (harmless), but\n // a SKIPPED one is silently absent from a COMPLETE pass, and a complete pass is what authorizes\n // the orphan stage — so a skip does not merely lose a row, it can orphan a live one.\n // spec-cite: Microsoft Learn, \"Page results using OData from Microsoft Dataverse Web API\" —\n // \"Deterministic ordering is important\" / \"Without proper ordering, the same record can appear in\n // more than one page.\"\n //\n // Key components are ordered as DECLARED: the schema already fixes their order for the composite\n // key predicate, so reusing it keeps one source for \"the key's component order\".\n const params: Record<string, string> = {\n $select: [...new Set(options.selectRemoteFields)].join(','),\n $orderby: binding.keyFields.map((keyField) => `${keyField.remoteField} asc`).join(','),\n $top: String(options.pageSize),\n };\n const filterFragments = Object.entries(options.sourceFilter ?? {}).map(\n ([remoteField, value]) => `${remoteField} eq ${odataScalarLiteral(value)}`,\n );\n if (filterFragments.length > 0) {\n params.$filter = filterFragments.join(' and ');\n }\n return { path: `/${binding.entityRef}`, params };\n}\n\n/** COUNT-only read: `/EntitySet/$count?$filter=…` — the body is the bare number. */\nexport function compileODataCountRead(\n binding: ODataBindingShape,\n query: HttpApiTranslatedQuery,\n): ODataCompiledRequest {\n const collection = compileODataCollectionRead(binding, query);\n const params = { ...collection.params };\n delete params.$orderby;\n delete params.$top;\n delete params.$skip;\n delete params.$count;\n return { path: `${collection.path}/$count`, params };\n}\n"]}
|
package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts
CHANGED
|
@@ -6,8 +6,13 @@
|
|
|
6
6
|
*
|
|
7
7
|
* The infrastructure tier is a deliberate bypass: its doors sit BELOW the service tier, take a
|
|
8
8
|
* pre-built filter or an already-final document, and run no declared operation and no authorization.
|
|
9
|
-
* Its clearest warrant is field-uniqueness
|
|
10
|
-
*
|
|
9
|
+
* Its clearest warrant is the field-uniqueness check behind the `validate-field` route. A field
|
|
10
|
+
* declared unique with `scope: 'global'` must be counted across the ENTIRE collection — "no additional
|
|
11
|
+
* filter (intentional — check entire collection)" — including tenants the caller cannot see, and the
|
|
12
|
+
* answer returned as nothing but a number. A declared operation cannot serve that: `buildContextualFilter`
|
|
13
|
+
* would scope the count to the caller's tenant and the answer would simply be wrong. So the door
|
|
14
|
+
* deliberately waives tenant scoping and deliberately does NOT waive the retention hide, because
|
|
15
|
+
* counting a hidden row would turn the same number into an existence oracle.
|
|
11
16
|
*
|
|
12
17
|
* Its WEAKEST warrant is the one the tier has most often cited, and issue #100 asked for it to be
|
|
13
18
|
* settled: "a consumable token is minted by a system action and consumed BEFORE authentication, so
|
|
@@ -17,7 +22,14 @@
|
|
|
17
22
|
* fail-closes unless the resource opts in with `systemAccessPolicy.create = ALLOWED`, synthesises an
|
|
18
23
|
* APPLICATION-scope super-admin context, and dispatches the resource's OWN declared CREATE —
|
|
19
24
|
* which `CONSUMABLE_TOKENS` declares. So the framework does not owe a new "system principal"
|
|
20
|
-
* vocabulary
|
|
25
|
+
* vocabulary.
|
|
26
|
+
*
|
|
27
|
+
* That settles the FRAMEWORK question and deliberately does not settle the CALLER's: this door turns
|
|
28
|
+
* out to have a second, stronger reason to bypass the declared pipeline. `createsOneOffSession` is
|
|
29
|
+
* sealed `.excludeFromCreate()` so that no repository-create path can mint a session-establishing
|
|
30
|
+
* token, which is what makes `createToken` the sole minter and therefore the single funnel enforcing
|
|
31
|
+
* the impersonation-credential lifetime ceiling. A raw door is the shape that seal depends on. See
|
|
32
|
+
* `INSERT_DOCUMENT / authorization` below, and issue #102.
|
|
21
33
|
*
|
|
22
34
|
* What was missing is not correctness, it is a CONTRACT. Each door carried its own hand-written prose
|
|
23
35
|
* about which cross-cutting invariant it upheld and which it skipped, so the tier's posture existed
|
|
@@ -31,10 +43,10 @@
|
|
|
31
43
|
* EITHER enum fails to compile until every new cell is filled in. That is the property this file is
|
|
32
44
|
* for: the missing case becomes a compiler error rather than something a reviewer has to notice.
|
|
33
45
|
*
|
|
34
|
-
* ## The tier is
|
|
46
|
+
* ## The tier is NINE doors, not the four that share a name
|
|
35
47
|
*
|
|
36
48
|
* Issue #100 listed four, all suffixed `*ForInfrastructure`. That is the population the SUFFIX
|
|
37
|
-
* describes, and it
|
|
49
|
+
* describes, and it was half the tier. Four more handler members have the identical posture under a
|
|
38
50
|
* different name — `atomicIncrementField` and `atomicConditionalSet` carry, verbatim, the same
|
|
39
51
|
* `@internal Framework-internal infrastructure primitive — NOT part of the operation lifecycle. The
|
|
40
52
|
* caller owns authorization, scope-aware filter construction, and audit logging.` that the suffixed
|
|
@@ -80,6 +92,8 @@ export declare enum InfrastructureDoor {
|
|
|
80
92
|
INSERT_DOCUMENT = "insertDocumentForInfrastructure",
|
|
81
93
|
/** Multi-row guarded write (token revocation by relatedId, usage-record marking). */
|
|
82
94
|
BULK_UPDATE = "bulkUpdateForInfrastructure",
|
|
95
|
+
/** Multi-row DELETE (the consumable-token retention sweep). */
|
|
96
|
+
DELETE_MANY = "deleteManyForInfrastructure",
|
|
83
97
|
/** Single-row compare-and-swap write. */
|
|
84
98
|
ATOMIC_GUARDED_MUTATION = "atomicGuardedMutation",
|
|
85
99
|
/** Single-row counter increment (metering, quota accounting). */
|
|
@@ -103,7 +117,7 @@ export declare enum InfrastructureDoor {
|
|
|
103
117
|
* it, and the family has broken it in production (retention hide, transaction participation,
|
|
104
118
|
* adapter neutrality).
|
|
105
119
|
*
|
|
106
|
-
* This set is OPEN. Adding a member is the point: it immediately breaks compilation at
|
|
120
|
+
* This set is OPEN. Adding a member is the point: it immediately breaks compilation at every door
|
|
107
121
|
* until each declares a posture. Candidates DELIBERATELY excluded are recorded as data in
|
|
108
122
|
* {@link INFRASTRUCTURE_CONCERN_CANDIDATES_EXCLUDED} rather than left absent — an absence is
|
|
109
123
|
* indistinguishable from an oversight, which is the shape this whole file is about.
|