@wildo-ai/saas-backend-lib 1.1.12 → 1.1.13
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/models/manual-controllers.backend.definition.d.ts.map +1 -1
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.js +2 -0
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.d.ts +4 -0
- package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.js +20 -5
- package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts +3 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.js +10 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts +22 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.js +25 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.d.ts +38 -3
- package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.js +68 -5
- package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts +2 -2
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js +6 -3
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts +83 -0
- 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 +217 -14
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.d.ts +32 -0
- package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.d.ts.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.js +36 -0
- package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.js.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.d.ts +38 -0
- package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.d.ts.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.js +83 -0
- package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.js.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.d.ts +36 -0
- package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.d.ts.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.js +51 -0
- package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.js.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.d.ts +46 -0
- package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.d.ts.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.js +68 -0
- package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.js.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seal-store.backend.d.ts +27 -0
- package/dist/esm/compliance/approval-seals/approval-seal-store.backend.d.ts.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seal-store.backend.js +42 -3
- package/dist/esm/compliance/approval-seals/approval-seal-store.backend.js.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.d.ts +26 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.d.ts.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.js +10 -0
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.js.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.d.ts +10 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.d.ts.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.js +60 -28
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.js.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.d.ts +90 -0
- package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.d.ts.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.js +373 -0
- package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.js.map +1 -0
- package/dist/esm/compliance/approval-seals/decision-presentation.backend.d.ts +29 -2
- package/dist/esm/compliance/approval-seals/decision-presentation.backend.d.ts.map +1 -1
- package/dist/esm/compliance/approval-seals/decision-presentation.backend.js +40 -3
- package/dist/esm/compliance/approval-seals/decision-presentation.backend.js.map +1 -1
- package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.d.ts.map +1 -1
- package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.js +34 -6
- package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.js.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.d.ts +30 -6
- package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.d.ts.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.js +67 -22
- package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.js.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.js +18 -1
- package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.js.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.d.ts +66 -1
- package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.js +161 -14
- package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.js.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.d.ts +47 -0
- package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.d.ts.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.js.map +1 -1
- package/dist/esm/external-providers/services/content-safety.backend.service.d.ts +27 -2
- package/dist/esm/external-providers/services/content-safety.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/content-safety.backend.service.js +46 -1
- package/dist/esm/external-providers/services/content-safety.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/embeddings.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/embeddings.backend.service.js +2 -0
- package/dist/esm/external-providers/services/embeddings.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +11 -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 +23 -0
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/provider-service-account-token.backend.d.ts +19 -1
- package/dist/esm/external-providers/services/provider-service-account-token.backend.d.ts.map +1 -1
- package/dist/esm/external-providers/services/provider-service-account-token.backend.js +41 -1
- package/dist/esm/external-providers/services/provider-service-account-token.backend.js.map +1 -1
- package/dist/esm/files/utils/file-parent-read-context.backend.d.ts +27 -2
- package/dist/esm/files/utils/file-parent-read-context.backend.d.ts.map +1 -1
- package/dist/esm/files/utils/file-parent-read-context.backend.js +23 -4
- package/dist/esm/files/utils/file-parent-read-context.backend.js.map +1 -1
- package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.d.ts +26 -0
- package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.js +100 -8
- package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.js.map +1 -1
- package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.d.ts +3 -1
- package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.d.ts.map +1 -1
- package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.js +8 -2
- package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.js.map +1 -1
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts +43 -0
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.js +37 -0
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.js.map +1 -1
- package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.d.ts +7 -0
- package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.js +8 -3
- package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts +31 -6
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/agents.backend.service.js +78 -30
- package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.js +4 -0
- package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts +28 -2
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.js +132 -22
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.js +12 -8
- package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts +5 -0
- package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/flows-actors-registry.service.js +18 -2
- package/dist/esm/flows-actors/services/flows-actors-registry.service.js.map +1 -1
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts +33 -0
- 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 +58 -0
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.d.ts +12 -1
- package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.d.ts.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.js +23 -4
- package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.js.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.d.ts +12 -1
- package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.d.ts.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.js +55 -17
- package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.js.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-store.backend.service.d.ts +22 -1
- package/dist/esm/inbound/services/inbound-delivery-store.backend.service.d.ts.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-store.backend.service.js +52 -9
- package/dist/esm/inbound/services/inbound-delivery-store.backend.service.js.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.d.ts +79 -0
- package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.d.ts.map +1 -0
- package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.js +211 -0
- package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.js.map +1 -0
- package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.d.ts +2 -2
- package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.d.ts.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.js +9 -1
- package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- 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 +6 -0
- package/dist/esm/inject/models/container.js.map +1 -1
- package/dist/esm/inject/models/service-types.d.ts +5 -0
- package/dist/esm/inject/models/service-types.d.ts.map +1 -1
- package/dist/esm/inject/models/service-types.js +3 -0
- package/dist/esm/inject/models/service-types.js.map +1 -1
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts +5 -0
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.js.map +1 -1
- package/dist/esm/monitoring/observability/services/metrics.service.d.ts +34 -1
- package/dist/esm/monitoring/observability/services/metrics.service.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/services/metrics.service.js +49 -0
- package/dist/esm/monitoring/observability/services/metrics.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts +6 -1
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js +15 -4
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.js +3 -1
- package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/runtime/services/http-server.backend.service.d.ts +3 -1
- package/dist/esm/runtime/services/http-server.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/services/http-server.backend.service.js +11 -3
- package/dist/esm/runtime/services/http-server.backend.service.js.map +1 -1
- package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.d.ts +22 -0
- package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.d.ts.map +1 -1
- package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.js +54 -0
- package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts +51 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.js +87 -15
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.js +5 -2
- package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js +65 -24
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts +64 -1
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js +84 -2
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts +14 -0
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js +13 -5
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.js +6 -2
- package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.d.ts +7 -0
- package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.js +65 -20
- package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.js +11 -4
- package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/users/services/user-self-custom-implementations.backend.d.ts.map +1 -1
- package/dist/esm/users/services/user-self-custom-implementations.backend.js +4 -2
- package/dist/esm/users/services/user-self-custom-implementations.backend.js.map +1 -1
- package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.js +16 -0
- package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +10 -10
package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.js
CHANGED
|
@@ -20,8 +20,17 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
20
20
|
*
|
|
21
21
|
* The order is the approval seal relay's: write the files UNLINKED, move the request (the move names them), then link
|
|
22
22
|
* them. A move that is lost (another re-read moved the request first) discards the files at once; they are unlinked in
|
|
23
|
-
* any case, so the files cleanup removes them.
|
|
24
|
-
*
|
|
23
|
+
* any case, so the files cleanup removes them.
|
|
24
|
+
*
|
|
25
|
+
* A link that does not happen at once is NOT lost. The signed document is scanned where a scanner runs, and a file is
|
|
26
|
+
* not linkable while its scan is in flight (`FILE_LINKABLE_STATUSES` leaves `SCANNING` out), so with a scanner the first
|
|
27
|
+
* link of a signed document is refused nearly every time. The link therefore answers what happened
|
|
28
|
+
* ({@link SignatureRequestEvidenceLinkOutcome}) instead of retrying blindly, and the signature-request poll links every
|
|
29
|
+
* evidence file of a recently SIGNED request that is not linked yet (`linkPendingEvidence`), for longer than the files
|
|
30
|
+
* cleanup waits before it removes an unlinked file. Only a file that can never be this request's (gone, infected,
|
|
31
|
+
* quarantined, failed, or linked elsewhere) is LOST, and that is logged at error and counted.
|
|
32
|
+
* (Until 2026-11-12 the link was tried three times in a row and then logged as lost: with a scanner, every signed
|
|
33
|
+
* document was lost.)
|
|
25
34
|
*
|
|
26
35
|
* Scanning: the signed document's bytes come from the vendor. Where the application runs a scanner, they are scanned
|
|
27
36
|
* before anything may serve them; where it runs none, they are kept unscanned rather than not kept, because the evidence
|
|
@@ -29,12 +38,37 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
29
38
|
* (a signature, its field and appearance, a DSS) before anything is written.
|
|
30
39
|
*/
|
|
31
40
|
import { inject, injectable, optional } from 'inversify';
|
|
32
|
-
import { CORE_APP_ROLES, CoreResourceOperation, CoreResourceType, FileDerivationRole, ResourcePrimaryScope } from '@wildo-ai/saas-models';
|
|
41
|
+
import { CORE_APP_ROLES, CoreResourceOperation, CoreResourceType, FILE_LINKABLE_STATUSES, FileDerivationRole, FileStatus, ResourcePrimaryScope } from '@wildo-ai/saas-models';
|
|
33
42
|
import { SAAS_SERVICE_TYPES } from '../../inject/models/service-types.js';
|
|
34
43
|
import { ServerProducedFileScan, writeServerProducedFile } from '../../files/services/server-produced-file-writer.backend.js';
|
|
35
44
|
import { describeCaughtError } from '../../errors/utils/error-log-level-classification.backend.utils.js';
|
|
36
|
-
/**
|
|
37
|
-
|
|
45
|
+
/**
|
|
46
|
+
* What one link of an evidence file to its SIGNED request did. Total over the file's states: the caller decides from it
|
|
47
|
+
* whether a later poll must try again.
|
|
48
|
+
*/
|
|
49
|
+
export var SignatureRequestEvidenceLinkOutcome;
|
|
50
|
+
(function (SignatureRequestEvidenceLinkOutcome) {
|
|
51
|
+
/** Linked now. */
|
|
52
|
+
SignatureRequestEvidenceLinkOutcome["LINKED"] = "linked";
|
|
53
|
+
/** Already linked to this request and field (a later poll's link, or an earlier one that succeeded). */
|
|
54
|
+
SignatureRequestEvidenceLinkOutcome["ALREADY_LINKED"] = "already_linked";
|
|
55
|
+
/** Not linkable yet: its scan (or its upload) has not ended. A later poll links it. */
|
|
56
|
+
SignatureRequestEvidenceLinkOutcome["NOT_YET_LINKABLE"] = "not_yet_linkable";
|
|
57
|
+
/** The link failed for a reason that may pass (the store could not be read or written). A later poll tries again. */
|
|
58
|
+
SignatureRequestEvidenceLinkOutcome["FAILED"] = "failed";
|
|
59
|
+
/**
|
|
60
|
+
* It can never be this request's: gone, or in a state no link leaves (infected, quarantined, failed, deleted, orphaned),
|
|
61
|
+
* or linked to another record. The request names evidence that is not kept.
|
|
62
|
+
*/
|
|
63
|
+
SignatureRequestEvidenceLinkOutcome["LOST"] = "lost";
|
|
64
|
+
})(SignatureRequestEvidenceLinkOutcome || (SignatureRequestEvidenceLinkOutcome = {}));
|
|
65
|
+
/** The outcomes a later poll must link again. */
|
|
66
|
+
export const SIGNATURE_EVIDENCE_LINK_RETRIED = new Set([
|
|
67
|
+
SignatureRequestEvidenceLinkOutcome.NOT_YET_LINKABLE,
|
|
68
|
+
SignatureRequestEvidenceLinkOutcome.FAILED,
|
|
69
|
+
]);
|
|
70
|
+
/** File states whose link is only waiting: a scan in flight, an upload not finished. */
|
|
71
|
+
const EVIDENCE_FILE_STATES_AWAITING_LINK = new Set([FileStatus.SCANNING, FileStatus.PENDING]);
|
|
38
72
|
/** The request's two evidence fields. */
|
|
39
73
|
export var SignatureRequestEvidenceField;
|
|
40
74
|
(function (SignatureRequestEvidenceField) {
|
|
@@ -49,12 +83,14 @@ let SignatureRequestEvidenceFilesBackendService = class SignatureRequestEvidence
|
|
|
49
83
|
fileWriter;
|
|
50
84
|
files;
|
|
51
85
|
contexts;
|
|
86
|
+
repositories;
|
|
52
87
|
resources;
|
|
53
|
-
constructor(logger, fileWriter, files, contexts, resources) {
|
|
88
|
+
constructor(logger, fileWriter, files, contexts, repositories, resources) {
|
|
54
89
|
this.logger = logger;
|
|
55
90
|
this.fileWriter = fileWriter;
|
|
56
91
|
this.files = files;
|
|
57
92
|
this.contexts = contexts;
|
|
93
|
+
this.repositories = repositories;
|
|
58
94
|
this.resources = resources;
|
|
59
95
|
}
|
|
60
96
|
async write(input) {
|
|
@@ -76,21 +112,29 @@ let SignatureRequestEvidenceFilesBackendService = class SignatureRequestEvidence
|
|
|
76
112
|
return written.fileId;
|
|
77
113
|
}
|
|
78
114
|
async link(fileId, request, field) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
catch (error) {
|
|
88
|
-
lastError = error;
|
|
115
|
+
const requestId = String(request._id);
|
|
116
|
+
try {
|
|
117
|
+
const file = await this.repositories.readUnscopedByKey(CoreResourceType.FILES, { _id: fileId });
|
|
118
|
+
if (!file?.status)
|
|
119
|
+
return SignatureRequestEvidenceLinkOutcome.LOST;
|
|
120
|
+
if (file.status === FileStatus.LINKED) {
|
|
121
|
+
const ours = file.linkedResourceType === CoreResourceType.SIGNATURE_REQUESTS && String(file.linkedResourceId) === requestId && file.linkedFieldName === field;
|
|
122
|
+
return ours ? SignatureRequestEvidenceLinkOutcome.ALREADY_LINKED : SignatureRequestEvidenceLinkOutcome.LOST;
|
|
89
123
|
}
|
|
124
|
+
if (EVIDENCE_FILE_STATES_AWAITING_LINK.has(file.status))
|
|
125
|
+
return SignatureRequestEvidenceLinkOutcome.NOT_YET_LINKABLE;
|
|
126
|
+
if (!FILE_LINKABLE_STATUSES.has(file.status))
|
|
127
|
+
return SignatureRequestEvidenceLinkOutcome.LOST;
|
|
128
|
+
await this.files.linkFileToResource(fileId, CoreResourceType.SIGNATURE_REQUESTS, requestId, field, await this.internalContext(), undefined, request);
|
|
129
|
+
return SignatureRequestEvidenceLinkOutcome.LINKED;
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
// A file whose scan began between the read and the link, or a store that did not answer: the next poll tries again.
|
|
133
|
+
this.logger.warn('[signature-requests] An evidence file could not be linked to its signature request now; the poll tries again', {
|
|
134
|
+
signatureRequestId: requestId, fileId, field, error: describeCaughtError(error),
|
|
135
|
+
});
|
|
136
|
+
return SignatureRequestEvidenceLinkOutcome.FAILED;
|
|
90
137
|
}
|
|
91
|
-
this.logger.error('[signature-requests] An evidence file could not be linked to its signature request; the files cleanup will remove it and the request will name a file that is gone', {
|
|
92
|
-
signatureRequestId: String(request._id), fileId, field, attempts: EVIDENCE_LINK_ATTEMPTS, error: describeCaughtError(lastError),
|
|
93
|
-
});
|
|
94
138
|
}
|
|
95
139
|
async discard(fileId) {
|
|
96
140
|
try {
|
|
@@ -118,9 +162,10 @@ SignatureRequestEvidenceFilesBackendService = __decorate([
|
|
|
118
162
|
__param(1, inject(SAAS_SERVICE_TYPES.ServerProducedFileWriterDependencies)),
|
|
119
163
|
__param(2, inject(SAAS_SERVICE_TYPES.FilesBackendService)),
|
|
120
164
|
__param(3, inject(SAAS_SERVICE_TYPES.ExecutionContextCreatorBackendService)),
|
|
121
|
-
__param(4, inject(SAAS_SERVICE_TYPES.
|
|
122
|
-
__param(
|
|
123
|
-
|
|
165
|
+
__param(4, inject(SAAS_SERVICE_TYPES.RepositoriesRegistryHandlerService)),
|
|
166
|
+
__param(5, inject(SAAS_SERVICE_TYPES.ResourceRegistryService)),
|
|
167
|
+
__param(5, optional()),
|
|
168
|
+
__metadata("design:paramtypes", [Object, Object, Object, Object, Object, Object])
|
|
124
169
|
], SignatureRequestEvidenceFilesBackendService);
|
|
125
170
|
export { SignatureRequestEvidenceFilesBackendService };
|
|
126
171
|
//# sourceMappingURL=signature-request-evidence-files.backend.js.map
|
package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature-request-evidence-files.backend.js","sourceRoot":"","sources":["../../../../src/compliance/electronic-signatures/signature-request-evidence-files.backend.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * # Where a SIGNED request keeps its evidence (#2293)\n *\n * Two files of the request's own, written when the signed document validates and named in the SAME write that makes the\n * request SIGNED: the signed document the vendor returned (`signedDocument`, derived from the original as a\n * `VENDOR_SIGNED_COPY`) and the validation's evidence (`validationEvidence`, JSON). They go with the request, so with the\n * deliverable's record (#2924), and its holds keep them (#2902).\n *\n * The order is the approval seal relay's: write the files UNLINKED, move the request (the move names them), then link\n * them. A move that is lost (another re-read moved the request first) discards the files at once; they are unlinked in\n * any case, so the files cleanup removes them. A link that fails leaves the request naming a file the cleanup will\n * remove: logged at error, as the relay does for its manifested copy.\n *\n * Scanning: the signed document's bytes come from the vendor. Where the application runs a scanner, they are scanned\n * before anything may serve them; where it runs none, they are kept unscanned rather than not kept, because the evidence\n * of a signature cannot be produced again. What the vendor appended was confined by the structure check of the validator\n * (a signature, its field and appearance, a DSS) before anything is written.\n */\nimport { inject, injectable, optional } from 'inversify';\nimport { CORE_APP_ROLES, CoreResourceOperation, CoreResourceType, FileDerivationRole, ResourcePrimaryScope, type ResourceType } from '@wildo-ai/saas-models';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { FilesBackendService } from '~wildo-backend-lib/files/services/files.backend.service';\nimport type { ExecutionContextCreatorBackendService } from '~wildo-backend-lib/runtime/services/execution-context-creator.backend.service';\nimport type { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport { ServerProducedFileScan, writeServerProducedFile, type ServerProducedFileWriterDependencies } from '~wildo-backend-lib/files/services/server-produced-file-writer.backend';\nimport { describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\n\n/** How many times linking an evidence file to its SIGNED request is tried before it is logged as lost. */\nexport const EVIDENCE_LINK_ATTEMPTS = 3;\n\n/** The request's two evidence fields. */\nexport enum SignatureRequestEvidenceField {\n /** The signed document the vendor returned. */\n SIGNED_DOCUMENT = 'signedDocument',\n /** The validation's evidence, as JSON. */\n VALIDATION_EVIDENCE = 'validationEvidence',\n}\n\n/** What the signature-request service asks of the evidence store. A port, so a unit test holds its files in memory. */\nexport interface SignatureRequestEvidenceFiles {\n /** Write one evidence file of the request, unlinked; answers its id. Throws when it cannot be written. */\n write(input: {\n readonly request: Readonly<Record<string, unknown>>;\n readonly field: SignatureRequestEvidenceField;\n readonly bytes: Uint8Array;\n readonly mimeType: string;\n readonly filename: string;\n }): Promise<string>;\n /** Link a file the request names to it, so the teardown and the holds find it. Never throws. */\n link(fileId: string, request: Readonly<Record<string, unknown>>, field: SignatureRequestEvidenceField): Promise<void>;\n /** Delete a file whose request move was lost. Never throws: an unlinked file is the cleanup's otherwise. */\n discard(fileId: string): Promise<void>;\n}\n\n/** The engine's evidence store: the server-produced file writer and the files service. */\n@injectable()\nexport class SignatureRequestEvidenceFilesBackendService implements SignatureRequestEvidenceFiles {\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) private readonly logger: Pick<LoggerService, 'error' | 'warn'>,\n @inject(SAAS_SERVICE_TYPES.ServerProducedFileWriterDependencies) private readonly fileWriter: ServerProducedFileWriterDependencies,\n @inject(SAAS_SERVICE_TYPES.FilesBackendService) private readonly files: Pick<FilesBackendService, 'linkFileToResource' | 'deleteDetachedFile'>,\n @inject(SAAS_SERVICE_TYPES.ExecutionContextCreatorBackendService) private readonly contexts: Pick<ExecutionContextCreatorBackendService, 'createForInternalOperation'>,\n @inject(SAAS_SERVICE_TYPES.ResourceRegistryService) @optional() private readonly resources?: Pick<ResourcesRegistryBackendService, 'getServiceOperationPathDefault'>,\n ) {}\n\n async write(input: Parameters<SignatureRequestEvidenceFiles['write']>[0]): Promise<string> {\n const signedDocument = input.field === SignatureRequestEvidenceField.SIGNED_DOCUMENT;\n const originalFileId = typeof input.request.originalFileId === 'string' ? input.request.originalFileId : undefined;\n const written = await writeServerProducedFile(this.fileWriter, {\n resourceType: CoreResourceType.SIGNATURE_REQUESTS as ResourceType,\n fieldName: input.field,\n bytes: Buffer.from(input.bytes),\n mimeType: input.mimeType,\n filename: input.filename,\n scopeOwnerRow: input.request,\n executionContext: await this.internalContext(),\n // The vendor's bytes are scanned where a scanner runs; the engine's own JSON is not (see the module header).\n scan: signedDocument && this.fileWriter.fileScanning ? ServerProducedFileScan.REQUIRED : ServerProducedFileScan.NONE,\n ...(signedDocument && originalFileId ? { derivedFrom: { fileId: originalFileId, role: FileDerivationRole.VENDOR_SIGNED_COPY } } : {}),\n describedAs: signedDocument ? 'vendor-signed document' : 'signature validation evidence',\n });\n return written.fileId;\n }\n\n async link(fileId: string, request: Readonly<Record<string, unknown>>, field: SignatureRequestEvidenceField): Promise<void> {\n // A few attempts: a request already SIGNED names this file, and an unlinked file is the cleanup's, so a link that\n // fails for good loses evidence that cannot be produced again (stated residual: no later run re-links it).\n let lastError: unknown;\n for (let attempt = 0; attempt < EVIDENCE_LINK_ATTEMPTS; attempt += 1) {\n try {\n await this.files.linkFileToResource(fileId, CoreResourceType.SIGNATURE_REQUESTS as ResourceType, String(request._id), field, await this.internalContext(), undefined, request as Record<string, unknown>);\n return;\n } catch (error) {\n lastError = error;\n }\n }\n this.logger.error('[signature-requests] An evidence file could not be linked to its signature request; the files cleanup will remove it and the request will name a file that is gone', {\n signatureRequestId: String(request._id), fileId, field, attempts: EVIDENCE_LINK_ATTEMPTS, error: describeCaughtError(lastError),\n });\n }\n\n async discard(fileId: string): Promise<void> {\n try {\n await this.files.deleteDetachedFile(fileId, await this.internalContext());\n } catch (error) {\n this.logger.warn('[signature-requests] An evidence file whose request move was lost could not be deleted now; it is unlinked, so the files cleanup removes it', {\n fileId, error: describeCaughtError(error),\n });\n }\n }\n\n /** The application's own context for these files, as a super-administrator would act (the relay's). */\n private internalContext() {\n return this.contexts.createForInternalOperation({\n operation: this.resources?.getServiceOperationPathDefault(CoreResourceType.SIGNATURE_REQUESTS, CoreResourceOperation.READ),\n contextResourcesFieldIdentifier: new Map(),\n initiatorIds: null,\n initiatorRoles: [{ roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN], relatedPrimaryScope: ResourcePrimaryScope.APPLICATION }],\n } as never);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"signature-request-evidence-files.backend.js","sourceRoot":"","sources":["../../../../src/compliance/electronic-signatures/signature-request-evidence-files.backend.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * # Where a SIGNED request keeps its evidence (#2293)\n *\n * Two files of the request's own, written when the signed document validates and named in the SAME write that makes the\n * request SIGNED: the signed document the vendor returned (`signedDocument`, derived from the original as a\n * `VENDOR_SIGNED_COPY`) and the validation's evidence (`validationEvidence`, JSON). They go with the request, so with the\n * deliverable's record (#2924), and its holds keep them (#2902).\n *\n * The order is the approval seal relay's: write the files UNLINKED, move the request (the move names them), then link\n * them. A move that is lost (another re-read moved the request first) discards the files at once; they are unlinked in\n * any case, so the files cleanup removes them.\n *\n * A link that does not happen at once is NOT lost. The signed document is scanned where a scanner runs, and a file is\n * not linkable while its scan is in flight (`FILE_LINKABLE_STATUSES` leaves `SCANNING` out), so with a scanner the first\n * link of a signed document is refused nearly every time. The link therefore answers what happened\n * ({@link SignatureRequestEvidenceLinkOutcome}) instead of retrying blindly, and the signature-request poll links every\n * evidence file of a recently SIGNED request that is not linked yet (`linkPendingEvidence`), for longer than the files\n * cleanup waits before it removes an unlinked file. Only a file that can never be this request's (gone, infected,\n * quarantined, failed, or linked elsewhere) is LOST, and that is logged at error and counted.\n * (Until 2026-11-12 the link was tried three times in a row and then logged as lost: with a scanner, every signed\n * document was lost.)\n *\n * Scanning: the signed document's bytes come from the vendor. Where the application runs a scanner, they are scanned\n * before anything may serve them; where it runs none, they are kept unscanned rather than not kept, because the evidence\n * of a signature cannot be produced again. What the vendor appended was confined by the structure check of the validator\n * (a signature, its field and appearance, a DSS) before anything is written.\n */\nimport { inject, injectable, optional } from 'inversify';\nimport { CORE_APP_ROLES, CoreResourceOperation, CoreResourceType, FILE_LINKABLE_STATUSES, FileDerivationRole, FileStatus, ResourcePrimaryScope, type ResourceType } from '@wildo-ai/saas-models';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { FilesBackendService } from '~wildo-backend-lib/files/services/files.backend.service';\nimport type { ExecutionContextCreatorBackendService } from '~wildo-backend-lib/runtime/services/execution-context-creator.backend.service';\nimport type { RepositoriesRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/repositories/repositories-registry-handler.backend.service';\nimport type { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport { ServerProducedFileScan, writeServerProducedFile, type ServerProducedFileWriterDependencies } from '~wildo-backend-lib/files/services/server-produced-file-writer.backend';\nimport { describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\n\n/**\n * What one link of an evidence file to its SIGNED request did. Total over the file's states: the caller decides from it\n * whether a later poll must try again.\n */\nexport enum SignatureRequestEvidenceLinkOutcome {\n /** Linked now. */\n LINKED = 'linked',\n /** Already linked to this request and field (a later poll's link, or an earlier one that succeeded). */\n ALREADY_LINKED = 'already_linked',\n /** Not linkable yet: its scan (or its upload) has not ended. A later poll links it. */\n NOT_YET_LINKABLE = 'not_yet_linkable',\n /** The link failed for a reason that may pass (the store could not be read or written). A later poll tries again. */\n FAILED = 'failed',\n /**\n * It can never be this request's: gone, or in a state no link leaves (infected, quarantined, failed, deleted, orphaned),\n * or linked to another record. The request names evidence that is not kept.\n */\n LOST = 'lost',\n}\n\n/** The outcomes a later poll must link again. */\nexport const SIGNATURE_EVIDENCE_LINK_RETRIED: ReadonlySet<SignatureRequestEvidenceLinkOutcome> = new Set([\n SignatureRequestEvidenceLinkOutcome.NOT_YET_LINKABLE,\n SignatureRequestEvidenceLinkOutcome.FAILED,\n]);\n\n/** File states whose link is only waiting: a scan in flight, an upload not finished. */\nconst EVIDENCE_FILE_STATES_AWAITING_LINK: ReadonlySet<FileStatus> = new Set([FileStatus.SCANNING, FileStatus.PENDING]);\n\n/** The request's two evidence fields. */\nexport enum SignatureRequestEvidenceField {\n /** The signed document the vendor returned. */\n SIGNED_DOCUMENT = 'signedDocument',\n /** The validation's evidence, as JSON. */\n VALIDATION_EVIDENCE = 'validationEvidence',\n}\n\n/** What the signature-request service asks of the evidence store. A port, so a unit test holds its files in memory. */\nexport interface SignatureRequestEvidenceFiles {\n /** Write one evidence file of the request, unlinked; answers its id. Throws when it cannot be written. */\n write(input: {\n readonly request: Readonly<Record<string, unknown>>;\n readonly field: SignatureRequestEvidenceField;\n readonly bytes: Uint8Array;\n readonly mimeType: string;\n readonly filename: string;\n }): Promise<string>;\n /** Link a file the request names to it, so the teardown and the holds find it, and answer what happened. Never throws. */\n link(fileId: string, request: Readonly<Record<string, unknown>>, field: SignatureRequestEvidenceField): Promise<SignatureRequestEvidenceLinkOutcome>;\n /** Delete a file whose request move was lost. Never throws: an unlinked file is the cleanup's otherwise. */\n discard(fileId: string): Promise<void>;\n}\n\n/** The engine's evidence store: the server-produced file writer and the files service. */\n@injectable()\nexport class SignatureRequestEvidenceFilesBackendService implements SignatureRequestEvidenceFiles {\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) private readonly logger: Pick<LoggerService, 'warn'>,\n @inject(SAAS_SERVICE_TYPES.ServerProducedFileWriterDependencies) private readonly fileWriter: ServerProducedFileWriterDependencies,\n @inject(SAAS_SERVICE_TYPES.FilesBackendService) private readonly files: Pick<FilesBackendService, 'linkFileToResource' | 'deleteDetachedFile'>,\n @inject(SAAS_SERVICE_TYPES.ExecutionContextCreatorBackendService) private readonly contexts: Pick<ExecutionContextCreatorBackendService, 'createForInternalOperation'>,\n /** The file's state, read as the inbound-email receiver reads its stored files: the infrastructure read, no access check. */\n @inject(SAAS_SERVICE_TYPES.RepositoriesRegistryHandlerService) private readonly repositories: Pick<RepositoriesRegistryHandlerBackendService, 'readUnscopedByKey'>,\n @inject(SAAS_SERVICE_TYPES.ResourceRegistryService) @optional() private readonly resources?: Pick<ResourcesRegistryBackendService, 'getServiceOperationPathDefault'>,\n ) {}\n\n async write(input: Parameters<SignatureRequestEvidenceFiles['write']>[0]): Promise<string> {\n const signedDocument = input.field === SignatureRequestEvidenceField.SIGNED_DOCUMENT;\n const originalFileId = typeof input.request.originalFileId === 'string' ? input.request.originalFileId : undefined;\n const written = await writeServerProducedFile(this.fileWriter, {\n resourceType: CoreResourceType.SIGNATURE_REQUESTS as ResourceType,\n fieldName: input.field,\n bytes: Buffer.from(input.bytes),\n mimeType: input.mimeType,\n filename: input.filename,\n scopeOwnerRow: input.request,\n executionContext: await this.internalContext(),\n // The vendor's bytes are scanned where a scanner runs; the engine's own JSON is not (see the module header).\n scan: signedDocument && this.fileWriter.fileScanning ? ServerProducedFileScan.REQUIRED : ServerProducedFileScan.NONE,\n ...(signedDocument && originalFileId ? { derivedFrom: { fileId: originalFileId, role: FileDerivationRole.VENDOR_SIGNED_COPY } } : {}),\n describedAs: signedDocument ? 'vendor-signed document' : 'signature validation evidence',\n });\n return written.fileId;\n }\n\n async link(fileId: string, request: Readonly<Record<string, unknown>>, field: SignatureRequestEvidenceField): Promise<SignatureRequestEvidenceLinkOutcome> {\n const requestId = String(request._id);\n try {\n const file = await this.repositories.readUnscopedByKey<{ status?: FileStatus; linkedResourceType?: string; linkedResourceId?: unknown; linkedFieldName?: string }>(\n CoreResourceType.FILES, { _id: fileId },\n );\n if (!file?.status) return SignatureRequestEvidenceLinkOutcome.LOST;\n if (file.status === FileStatus.LINKED) {\n const ours = file.linkedResourceType === CoreResourceType.SIGNATURE_REQUESTS && String(file.linkedResourceId) === requestId && file.linkedFieldName === field;\n return ours ? SignatureRequestEvidenceLinkOutcome.ALREADY_LINKED : SignatureRequestEvidenceLinkOutcome.LOST;\n }\n if (EVIDENCE_FILE_STATES_AWAITING_LINK.has(file.status)) return SignatureRequestEvidenceLinkOutcome.NOT_YET_LINKABLE;\n if (!FILE_LINKABLE_STATUSES.has(file.status)) return SignatureRequestEvidenceLinkOutcome.LOST;\n await this.files.linkFileToResource(fileId, CoreResourceType.SIGNATURE_REQUESTS as ResourceType, requestId, field, await this.internalContext(), undefined, request as Record<string, unknown>);\n return SignatureRequestEvidenceLinkOutcome.LINKED;\n } catch (error) {\n // A file whose scan began between the read and the link, or a store that did not answer: the next poll tries again.\n this.logger.warn('[signature-requests] An evidence file could not be linked to its signature request now; the poll tries again', {\n signatureRequestId: requestId, fileId, field, error: describeCaughtError(error),\n });\n return SignatureRequestEvidenceLinkOutcome.FAILED;\n }\n }\n\n async discard(fileId: string): Promise<void> {\n try {\n await this.files.deleteDetachedFile(fileId, await this.internalContext());\n } catch (error) {\n this.logger.warn('[signature-requests] An evidence file whose request move was lost could not be deleted now; it is unlinked, so the files cleanup removes it', {\n fileId, error: describeCaughtError(error),\n });\n }\n }\n\n /** The application's own context for these files, as a super-administrator would act (the relay's). */\n private internalContext() {\n return this.contexts.createForInternalOperation({\n operation: this.resources?.getServiceOperationPathDefault(CoreResourceType.SIGNATURE_REQUESTS, CoreResourceOperation.READ),\n contextResourcesFieldIdentifier: new Map(),\n initiatorIds: null,\n initiatorRoles: [{ roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN], relatedPrimaryScope: ResourcePrimaryScope.APPLICATION }],\n } as never);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature-request-poll.batch.backend.service.d.ts","sourceRoot":"","sources":["../../../../src/compliance/electronic-signatures/signature-request-poll.batch.backend.service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"signature-request-poll.batch.backend.service.d.ts","sourceRoot":"","sources":["../../../../src/compliance/electronic-signatures/signature-request-poll.batch.backend.service.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,iCAAiC,EAAE,MAAM,4FAA4F,CAAC;AAsC/I,wBAAgB,+BAA+B,IAAI,UAAU,CAAC,OAAO,iCAAiC,CAAC,CA0BtG"}
|
package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.js
CHANGED
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
* It also SENDS the deliverables approved since the last run whose tool declares an electronic signature
|
|
10
10
|
* (`SignatureRequestTriggerBackendService`), before re-reading, so a request sent this run is read on the next.
|
|
11
11
|
*
|
|
12
|
+
* Then it LINKS the evidence files of the requests SIGNED in the last two days that are not linked yet
|
|
13
|
+
* (`linkPendingEvidence`): a signed document is scanned on write where a scanner runs, and a file is not linkable until
|
|
14
|
+
* its scan ends, so its link is usually this run's work rather than the re-read's.
|
|
15
|
+
*
|
|
12
16
|
* This output is the run's durable record: a steady `notRead` means a vendor is down or a provider answers unusably, and a
|
|
13
17
|
* steady `deferredByBudget` means the bounds are too small for the open population.
|
|
14
18
|
*/
|
|
@@ -36,6 +40,14 @@ const SignatureRequestPollOutputSchema = z.strictObject({
|
|
|
36
40
|
dispatchSent: Count,
|
|
37
41
|
/** Deliverables whose sending was refused this run; each is logged. */
|
|
38
42
|
dispatchRefused: Count,
|
|
43
|
+
/** SIGNED requests of the last two days whose evidence files were looked at. */
|
|
44
|
+
evidenceExamined: Count,
|
|
45
|
+
/** Evidence files linked this run. */
|
|
46
|
+
evidenceLinked: Count,
|
|
47
|
+
/** Evidence files not linkable yet (scan in flight) or whose link failed for now: the next run tries again. */
|
|
48
|
+
evidenceLinkPending: Count,
|
|
49
|
+
/** Evidence files that can never be linked: a SIGNED request names evidence nothing keeps. Each is logged once. */
|
|
50
|
+
evidenceLost: Count,
|
|
39
51
|
durationMs: Count,
|
|
40
52
|
});
|
|
41
53
|
export function createSignatureRequestPollBatch() {
|
|
@@ -56,7 +68,12 @@ export function createSignatureRequestPollBatch() {
|
|
|
56
68
|
const startTime = Date.now();
|
|
57
69
|
const dispatch = await dependencies.trigger.sendSealedDeliverables();
|
|
58
70
|
const report = await dependencies.signatureRequests.pollOpenRequests();
|
|
59
|
-
|
|
71
|
+
const evidence = await dependencies.signatureRequests.linkPendingEvidence();
|
|
72
|
+
return {
|
|
73
|
+
...report, dispatchExamined: dispatch.examined, dispatchSent: dispatch.sent, dispatchRefused: dispatch.refused,
|
|
74
|
+
evidenceExamined: evidence.examined, evidenceLinked: evidence.linked, evidenceLinkPending: evidence.pending, evidenceLost: evidence.lost,
|
|
75
|
+
durationMs: Date.now() - startTime,
|
|
76
|
+
};
|
|
60
77
|
},
|
|
61
78
|
});
|
|
62
79
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature-request-poll.batch.backend.service.js","sourceRoot":"","sources":["../../../../src/compliance/electronic-signatures/signature-request-poll.batch.backend.service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"signature-request-poll.batch.backend.service.js","sourceRoot":"","sources":["../../../../src/compliance/electronic-signatures/signature-request-poll.batch.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iCAAiC,EAAE,MAAM,4FAA4F,CAAC;AAC/I,OAAO,EAAE,4CAA4C,EAAE,MAAM,gFAAgF,CAAC;AAC9I,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAIpF,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAEtC,MAAM,gCAAgC,GAAG,CAAC,CAAC,YAAY,CAAC;IACtD,sCAAsC;IACtC,QAAQ,EAAE,KAAK;IACf,kCAAkC;IAClC,KAAK,EAAE,KAAK;IACZ,oHAAoH;IACpH,SAAS,EAAE,KAAK;IAChB,qFAAqF;IACrF,OAAO,EAAE,KAAK;IACd,4CAA4C;IAC5C,QAAQ,EAAE,KAAK;IACf,kFAAkF;IAClF,gBAAgB,EAAE,KAAK;IACvB,uFAAuF;IACvF,gBAAgB,EAAE,KAAK;IACvB,gDAAgD;IAChD,YAAY,EAAE,KAAK;IACnB,uEAAuE;IACvE,eAAe,EAAE,KAAK;IACtB,gFAAgF;IAChF,gBAAgB,EAAE,KAAK;IACvB,sCAAsC;IACtC,cAAc,EAAE,KAAK;IACrB,+GAA+G;IAC/G,mBAAmB,EAAE,KAAK;IAC1B,mHAAmH;IACnH,YAAY,EAAE,KAAK;IACnB,UAAU,EAAE,KAAK;CAClB,CAAC,CAAC;AAEH,MAAM,UAAU,+BAA+B;IAC7C,OAAO,iCAAiC,CAAC;QACvC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACnB,MAAM,EAAE,gCAAgC;QACxC,oBAAoB,EAAE;YACpB,IAAI,EAAE,4CAA4C,CAAC,IAAI;YACvD,kBAAkB,EAAE,4CAA4C,CAAC,kBAAkB;YACnF,mBAAmB,EAAE,4CAA4C,CAAC,mBAAmB;YACrF,iBAAiB,EAAE,4CAA4C,CAAC,cAAc;SAC/E;QACD,mBAAmB,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;YACjC,iBAAiB,EAAE,GAAG,CAAkC,kBAAkB,CAAC,wBAAwB,CAAC;YACpG,OAAO,EAAE,GAAG,CAAwC,kBAAkB,CAAC,8BAA8B,CAAC;SACvG,CAAC;QACF,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;YAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC;YACrE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;YACvE,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,iBAAiB,CAAC,mBAAmB,EAAE,CAAC;YAC5E,OAAO;gBACL,GAAG,MAAM,EAAE,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,CAAC,OAAO;gBAC9G,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,EAAE,cAAc,EAAE,QAAQ,CAAC,MAAM,EAAE,mBAAmB,EAAE,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,IAAI;gBACxI,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACnC,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Signature Request Poll — the scheduled re-read of open signature requests (#2293).\n *\n * A vendor's notification only triggers a re-read (#2909), and a vendor that notifies nothing, or a notification lost on\n * the way, would leave a request open for ever. This batch re-reads the open requests every five minutes, oldest move\n * first, within a per-tenant and per-provider bound (`DEFAULT_SIGNATURE_REQUEST_POLL_BOUNDS`), so one tenant or one vendor\n * cannot use the run up.\n *\n * It also SENDS the deliverables approved since the last run whose tool declares an electronic signature\n * (`SignatureRequestTriggerBackendService`), before re-reading, so a request sent this run is read on the next.\n *\n * Then it LINKS the evidence files of the requests SIGNED in the last two days that are not linked yet\n * (`linkPendingEvidence`): a signed document is scanned on write where a scanner runs, and a file is not linkable until\n * its scan ends, so its link is usually this run's work rather than the re-read's.\n *\n * This output is the run's durable record: a steady `notRead` means a vendor is down or a provider answers unusably, and a\n * steady `deferredByBudget` means the bounds are too small for the open population.\n */\nimport { z } from 'zod';\nimport { createCustomBatchExecutionService } from '~wildo-backend-lib/base-classes/services/batches/batches-cronjobs-custom-execution.service';\nimport { ENGINE_SIGNATURE_REQUEST_POLL_BATCH_MANIFEST } from '~wildo-backend-lib/base-classes/services/batches/engine-custom-batch-manifests';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { SignatureRequestsBackendService } from './signature-requests.backend.service';\nimport type { SignatureRequestTriggerBackendService } from './signature-request-trigger.backend.service';\n\nconst Count = z.number().int().min(0);\n\nconst SignatureRequestPollOutputSchema = z.strictObject({\n /** Open requests re-read this run. */\n examined: Count,\n /** Requests whose state moved. */\n moved: Count,\n /** Requests the vendor's answer left where they were (including a complete one whose evidence did not validate). */\n unchanged: Count,\n /** Requests whose vendor could not be read, or answered unusably; each is logged. */\n notRead: Count,\n /** Requests another re-read moved first. */\n lostRace: Count,\n /** Open requests left for a later run by the per-tenant or per-provider bound. */\n deferredByBudget: Count,\n /** Sealed approvals whose tool declares a signature, examined for sending this run. */\n dispatchExamined: Count,\n /** Deliverables sent for signature this run. */\n dispatchSent: Count,\n /** Deliverables whose sending was refused this run; each is logged. */\n dispatchRefused: Count,\n /** SIGNED requests of the last two days whose evidence files were looked at. */\n evidenceExamined: Count,\n /** Evidence files linked this run. */\n evidenceLinked: Count,\n /** Evidence files not linkable yet (scan in flight) or whose link failed for now: the next run tries again. */\n evidenceLinkPending: Count,\n /** Evidence files that can never be linked: a SIGNED request names evidence nothing keeps. Each is logged once. */\n evidenceLost: Count,\n durationMs: Count,\n});\n\nexport function createSignatureRequestPollBatch(): ReturnType<typeof createCustomBatchExecutionService> {\n return createCustomBatchExecutionService({\n input: z.object({}),\n output: SignatureRequestPollOutputSchema,\n batchCronjob_Context: {\n kind: ENGINE_SIGNATURE_REQUEST_POLL_BATCH_MANIFEST.kind,\n resourceIdentifier: ENGINE_SIGNATURE_REQUEST_POLL_BATCH_MANIFEST.resourceIdentifier,\n operationIdentifier: ENGINE_SIGNATURE_REQUEST_POLL_BATCH_MANIFEST.operationIdentifier,\n cronJobExpression: ENGINE_SIGNATURE_REQUEST_POLL_BATCH_MANIFEST.cronExpression,\n },\n resolveDependencies: ({ get }) => ({\n signatureRequests: get<SignatureRequestsBackendService>(SAAS_SERVICE_TYPES.SignatureRequestsService),\n trigger: get<SignatureRequestTriggerBackendService>(SAAS_SERVICE_TYPES.SignatureRequestTriggerService),\n }),\n doHandle: async (_input, { dependencies }) => {\n const startTime = Date.now();\n const dispatch = await dependencies.trigger.sendSealedDeliverables();\n const report = await dependencies.signatureRequests.pollOpenRequests();\n const evidence = await dependencies.signatureRequests.linkPendingEvidence();\n return {\n ...report, dispatchExamined: dispatch.examined, dispatchSent: dispatch.sent, dispatchRefused: dispatch.refused,\n evidenceExamined: evidence.examined, evidenceLinked: evidence.linked, evidenceLinkPending: evidence.pending, evidenceLost: evidence.lost,\n durationMs: Date.now() - startTime,\n };\n },\n });\n}\n"]}
|
|
@@ -9,6 +9,7 @@ import type { ElectronicSignatureBackendService } from '../../external-providers
|
|
|
9
9
|
import type { AuditLogsBackendService } from '../../compliance/audit-trails/services/audit-logs.backend.service';
|
|
10
10
|
import { type SignedDocumentValidator } from './signed-document-validation.backend';
|
|
11
11
|
import { type SignatureRequestEvidenceFiles } from './signature-request-evidence-files.backend';
|
|
12
|
+
import type { MetricsService } from '../../monitoring/observability/services/metrics.service';
|
|
12
13
|
/** Why a deliverable was not sent. */
|
|
13
14
|
export declare enum SignatureRequestSendRefusal {
|
|
14
15
|
SEAL_NOT_FOUND = "seal_not_found",
|
|
@@ -55,6 +56,43 @@ export type SendForSignatureResult = {
|
|
|
55
56
|
readonly retryable: boolean;
|
|
56
57
|
readonly signatureRequestId?: string;
|
|
57
58
|
};
|
|
59
|
+
/**
|
|
60
|
+
* Why a request the vendor reported complete was not made SIGNED by its evidence: the label of
|
|
61
|
+
* `signature_request_evidence_refused_total`, and what the re-read's reason explains in words.
|
|
62
|
+
*/
|
|
63
|
+
export declare enum SignatureRequestEvidenceFailure {
|
|
64
|
+
/** No signed-document validator is bound in this runtime. */
|
|
65
|
+
NO_VALIDATOR = "no_validator",
|
|
66
|
+
/** The vendor split the request into several documents; one signed document per request is kept. */
|
|
67
|
+
SPLIT_REQUEST = "split_request",
|
|
68
|
+
/** The provider declares no evidence policy (trust anchors). */
|
|
69
|
+
NO_EVIDENCE_POLICY = "no_evidence_policy",
|
|
70
|
+
/** The signed document could not be downloaded. */
|
|
71
|
+
DOWNLOAD_FAILED = "download_failed",
|
|
72
|
+
/** The document did not validate (tampered, updated after signing, untrusted chain, refused algorithm, revocation). */
|
|
73
|
+
REJECTED = "rejected",
|
|
74
|
+
/** The document validated and proves another signer or a lower level than required: the request FAILS. */
|
|
75
|
+
MISMATCHED = "mismatched",
|
|
76
|
+
/** The document validated and its evidence could not be written: the request stays open and is read again. */
|
|
77
|
+
NOT_KEPT = "not_kept"
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* How long after a request became SIGNED the poll keeps linking its evidence files (#2293). Longer than the files
|
|
81
|
+
* cleanup waits before it removes an unlinked file (a day after its scan ended, its default `unlinkedThresholdMs`), so a
|
|
82
|
+
* scan that ends late is still linked; a file the cleanup removed first is reported lost.
|
|
83
|
+
*/
|
|
84
|
+
export declare const SIGNATURE_EVIDENCE_LINK_WINDOW_MS: number;
|
|
85
|
+
/** What one evidence-link pass of the poll did. */
|
|
86
|
+
export interface SignatureEvidenceLinkReport {
|
|
87
|
+
/** SIGNED requests of the window whose evidence was looked at. */
|
|
88
|
+
readonly examined: number;
|
|
89
|
+
/** Evidence files linked by this pass. */
|
|
90
|
+
readonly linked: number;
|
|
91
|
+
/** Evidence files still not linkable (their scan has not ended) or whose link failed for now: the next pass tries again. */
|
|
92
|
+
readonly pending: number;
|
|
93
|
+
/** Evidence files that can never be linked: the request names evidence nothing keeps. Each is logged once. */
|
|
94
|
+
readonly lost: number;
|
|
95
|
+
}
|
|
58
96
|
/** What the send path reads and writes through. Structural, so a test hands in what it holds. */
|
|
59
97
|
export type SignatureRequestsRepositories = Pick<RepositoriesRegistryHandlerBackendService, 'findManyForInfrastructure' | 'insertDocumentForInfrastructure' | 'deleteManyForInfrastructure' | 'atomicGuardedMutation'>;
|
|
60
98
|
export type SignatureRequestsFiles = Pick<FilesBackendService, 'getFile' | 'ensureContentHash' | 'readFileBytes'>;
|
|
@@ -105,9 +143,15 @@ export declare class SignatureRequestsBackendService {
|
|
|
105
143
|
/** Where a SIGNED request keeps its signed document and its validation's evidence. Absent, nothing becomes SIGNED. */
|
|
106
144
|
private readonly evidenceFiles?;
|
|
107
145
|
private readonly auditLogs?;
|
|
146
|
+
private readonly metrics?;
|
|
108
147
|
constructor(logger: LoggerService, repositories: SignatureRequestsRepositories, executionContextCreator: Pick<ExecutionContextCreatorBackendService, 'createForInternalSystemOperation'>, transport: SignatureRequestsTransport, files?: SignatureRequestsFiles, validator?: SignedDocumentValidator, errorBuilder?: Pick<ErrorBuilderBackendService, 'buildError'>,
|
|
109
148
|
/** Where a SIGNED request keeps its signed document and its validation's evidence. Absent, nothing becomes SIGNED. */
|
|
110
|
-
evidenceFiles?: SignatureRequestEvidenceFiles, auditLogs?: Pick<AuditLogsBackendService, 'logSignatureRequestEvent'
|
|
149
|
+
evidenceFiles?: SignatureRequestEvidenceFiles, auditLogs?: Pick<AuditLogsBackendService, 'logSignatureRequestEvent'>, metrics?: Pick<MetricsService, 'recordSignatureRequestSent' | 'recordSignatureRequestMoved' | 'recordSignatureRequestEvidenceRefused' | 'recordSignatureRequestVendorNotRead' | 'recordSignatureRequestEvidenceLink'>,
|
|
150
|
+
/** A test seam, `@unmanaged()`: the container's instance reads the system clock (Inversify counts every parameter). */
|
|
151
|
+
clock?: () => Date);
|
|
152
|
+
private readonly clock;
|
|
153
|
+
/** Evidence files already reported lost by this process, so a lost file is logged once rather than every poll. */
|
|
154
|
+
private readonly reportedLostEvidence;
|
|
111
155
|
/**
|
|
112
156
|
* The removal effect of `signatureRequests` (#2293), registered at startup with the evidence teardown: before the rows of
|
|
113
157
|
* requests whose record goes are destroyed, every OPEN one is cancelled at its vendor, and deleted there where its
|
|
@@ -126,6 +170,7 @@ export declare class SignatureRequestsBackendService {
|
|
|
126
170
|
* for the seal's bind check, so the sealed-deliverable gate is marked as that check is.)
|
|
127
171
|
*/
|
|
128
172
|
sendForSignature(input: SendForSignatureInput): Promise<SendForSignatureResult>;
|
|
173
|
+
private sendOnce;
|
|
129
174
|
/**
|
|
130
175
|
* Re-read one request at its vendor, through the provider it was sent through, and move it as its one transition
|
|
131
176
|
* function says. Used by the poll and by a vendor notification's re-read trigger (#2909): a notification is never
|
|
@@ -160,6 +205,26 @@ export declare class SignatureRequestsBackendService {
|
|
|
160
205
|
* several references cannot keep its evidence in the request's own fields and is left open (stated, never guessed).
|
|
161
206
|
*/
|
|
162
207
|
private validateEvidence;
|
|
208
|
+
/**
|
|
209
|
+
* Link the evidence files of the requests that became SIGNED in the last {@link SIGNATURE_EVIDENCE_LINK_WINDOW_MS} and
|
|
210
|
+
* are not linked yet (#2293). Run by the poll. A file whose scan has not ended is linked by a later run; one that can
|
|
211
|
+
* never be linked is reported lost, once. Without this, a signed document scanned on write was never linked (its link
|
|
212
|
+
* is refused while it is SCANNING) and the files cleanup removed it a day later. Never throws for one request.
|
|
213
|
+
*
|
|
214
|
+
* Read cost, stated: each run reads every SIGNED request of the window and each of its two files once, a primary-key read
|
|
215
|
+
* per file, up to {@link SIGNATURE_EVIDENCE_LINK_SCAN_LIMIT} requests.
|
|
216
|
+
*/
|
|
217
|
+
linkPendingEvidence(): Promise<SignatureEvidenceLinkReport>;
|
|
218
|
+
/**
|
|
219
|
+
* Link one evidence file and say what happened: a lost file at error (once per process, with its metric), a link left
|
|
220
|
+
* for a later poll at info. Never throws; the port never does.
|
|
221
|
+
*/
|
|
222
|
+
private linkEvidenceFile;
|
|
223
|
+
/**
|
|
224
|
+
* The SIGNED requests validated in the link window, oldest first, a page at a time. Pages advance on `validatedAt`, ids
|
|
225
|
+
* already seen skipped, so requests validated in the same instant are not lost between pages (the trigger's paging).
|
|
226
|
+
*/
|
|
227
|
+
private signedInLinkWindow;
|
|
163
228
|
/** Write the request's two evidence files, unlinked. A reason when they cannot be kept: the request then stays open. */
|
|
164
229
|
private keepEvidence;
|
|
165
230
|
/** One request event on the trail. Never throws: the request's state is the record, the trail observes it. */
|
package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature-requests.backend.service.d.ts","sourceRoot":"","sources":["../../../../src/compliance/electronic-signatures/signature-requests.backend.service.ts"],"names":[],"mappings":"AAgCA,OAAO,EAQL,sBAAsB,EACtB,4BAA4B,EAC5B,sBAAsB,EACtB,kCAAkC,EAKnC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,uCAAuC,EACvC,KAAK,yBAAyB,EAC/B,MAAM,sCAAsC,CAAC;AAG9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAC;AAClG,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kEAAkE,CAAC;AACnH,OAAO,KAAK,EAAE,yCAAyC,EAAE,MAAM,qGAAqG,CAAC;AACrK,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,+EAA+E,CAAC;AAC3I,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yDAAyD,CAAC;AACnG,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,qFAAqF,CAAC;AAI7I,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gFAAgF,CAAC;AAC9H,OAAO,EAAsD,KAAK,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AACxI,OAAO,
|
|
1
|
+
{"version":3,"file":"signature-requests.backend.service.d.ts","sourceRoot":"","sources":["../../../../src/compliance/electronic-signatures/signature-requests.backend.service.ts"],"names":[],"mappings":"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"}
|