@baruk/core 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.baruk-provenance.json +4 -4
- package/CHANGELOG.md +42 -0
- package/dist/audit/repository.d.ts +33 -1
- package/dist/audit/repository.d.ts.map +1 -1
- package/dist/audit/repository.js +41 -7
- package/dist/audit/repository.js.map +1 -1
- package/dist/auth/service.d.ts +21 -0
- package/dist/auth/service.d.ts.map +1 -1
- package/dist/auth/service.js +46 -1
- package/dist/auth/service.js.map +1 -1
- package/dist/billing/ar-repository.d.ts +41 -1
- package/dist/billing/ar-repository.d.ts.map +1 -1
- package/dist/billing/ar-repository.js +82 -6
- package/dist/billing/ar-repository.js.map +1 -1
- package/dist/billing/provider-account.d.ts +38 -0
- package/dist/billing/provider-account.d.ts.map +1 -1
- package/dist/billing/provider-account.js +58 -2
- package/dist/billing/provider-account.js.map +1 -1
- package/dist/billing/repository.d.ts +44 -0
- package/dist/billing/repository.d.ts.map +1 -1
- package/dist/billing/repository.js +49 -5
- package/dist/billing/repository.js.map +1 -1
- package/dist/cjs/audit/repository.js +41 -7
- package/dist/cjs/audit/repository.js.map +1 -1
- package/dist/cjs/auth/service.js +46 -1
- package/dist/cjs/auth/service.js.map +1 -1
- package/dist/cjs/billing/ar-repository.js +82 -6
- package/dist/cjs/billing/ar-repository.js.map +1 -1
- package/dist/cjs/billing/provider-account.js +60 -1
- package/dist/cjs/billing/provider-account.js.map +1 -1
- package/dist/cjs/billing/repository.js +51 -5
- package/dist/cjs/billing/repository.js.map +1 -1
- package/dist/cjs/clients/ibge.js +117 -0
- package/dist/cjs/clients/ibge.js.map +1 -0
- package/dist/cjs/clients/registry/http.js +157 -0
- package/dist/cjs/clients/registry/http.js.map +1 -0
- package/dist/cjs/clients/registry/ibge-municipios.js +28 -0
- package/dist/cjs/clients/registry/ibge-municipios.js.map +1 -0
- package/dist/cjs/clients/registry/ibge.js +63 -0
- package/dist/cjs/clients/registry/ibge.js.map +1 -0
- package/dist/cjs/clients/registry/lookup.js +191 -0
- package/dist/cjs/clients/registry/lookup.js.map +1 -0
- package/dist/cjs/clients/registry/provider.js +34 -0
- package/dist/cjs/clients/registry/provider.js.map +1 -0
- package/dist/cjs/clients/registry/resolve.js +47 -0
- package/dist/cjs/clients/registry/resolve.js.map +1 -0
- package/dist/cjs/clients/registry/serpro.js +149 -0
- package/dist/cjs/clients/registry/serpro.js.map +1 -0
- package/dist/cjs/clients/registry/service.js +230 -0
- package/dist/cjs/clients/registry/service.js.map +1 -0
- package/dist/cjs/clients/registry/synthetic.js +165 -0
- package/dist/cjs/clients/registry/synthetic.js.map +1 -0
- package/dist/cjs/clients/repository.js +190 -9
- package/dist/cjs/clients/repository.js.map +1 -1
- package/dist/cjs/collection/branding.js +190 -0
- package/dist/cjs/collection/branding.js.map +1 -1
- package/dist/cjs/collection/clearance-store.js +74 -0
- package/dist/cjs/collection/clearance-store.js.map +1 -0
- package/dist/cjs/collection/communication-runtime.js +65 -2
- package/dist/cjs/collection/communication-runtime.js.map +1 -1
- package/dist/cjs/collection/engine.js +20 -0
- package/dist/cjs/collection/engine.js.map +1 -1
- package/dist/cjs/collection/policy.js +29 -1
- package/dist/cjs/collection/policy.js.map +1 -1
- package/dist/cjs/communication/clearance.js +18 -0
- package/dist/cjs/communication/clearance.js.map +1 -0
- package/dist/cjs/communication/dry-run-scenario.js +5 -0
- package/dist/cjs/communication/dry-run-scenario.js.map +1 -1
- package/dist/cjs/communication/engine.js +12 -0
- package/dist/cjs/communication/engine.js.map +1 -1
- package/dist/cjs/communication/policy.js.map +1 -1
- package/dist/cjs/competence/business-days.js +155 -0
- package/dist/cjs/competence/business-days.js.map +1 -0
- package/dist/cjs/competence/catalog-validation.js +174 -0
- package/dist/cjs/competence/catalog-validation.js.map +1 -0
- package/dist/cjs/competence/obligation-preview.js +190 -0
- package/dist/cjs/competence/obligation-preview.js.map +1 -0
- package/dist/cjs/competence/repository.js +330 -17
- package/dist/cjs/competence/repository.js.map +1 -1
- package/dist/cjs/dashboard/pilot-panel.js +90 -0
- package/dist/cjs/dashboard/pilot-panel.js.map +1 -0
- package/dist/cjs/dashboard/repository.js +11 -1
- package/dist/cjs/dashboard/repository.js.map +1 -1
- package/dist/cjs/db/client.js +17 -11
- package/dist/cjs/db/client.js.map +1 -1
- package/dist/cjs/db/provision-e2e-identity.js +116 -0
- package/dist/cjs/db/provision-e2e-identity.js.map +1 -0
- package/dist/cjs/fiscal/applicability.js +164 -0
- package/dist/cjs/fiscal/applicability.js.map +1 -0
- package/dist/cjs/fiscal/collection/authorization.js +186 -0
- package/dist/cjs/fiscal/collection/authorization.js.map +1 -0
- package/dist/cjs/fiscal/collection/competence.js +97 -0
- package/dist/cjs/fiscal/collection/competence.js.map +1 -0
- package/dist/cjs/fiscal/collection/first-contact.js +204 -0
- package/dist/cjs/fiscal/collection/first-contact.js.map +1 -0
- package/dist/cjs/fiscal/collection/plan.js +122 -0
- package/dist/cjs/fiscal/collection/plan.js.map +1 -0
- package/dist/cjs/fiscal/conditions.js +198 -0
- package/dist/cjs/fiscal/conditions.js.map +1 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-contract.js +390 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-contract.js.map +1 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-endpoint.js +108 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-endpoint.js.map +1 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-envelope.js +220 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-envelope.js.map +1 -0
- package/dist/cjs/fiscal/coverage/model.js +137 -0
- package/dist/cjs/fiscal/coverage/model.js.map +1 -0
- package/dist/cjs/fiscal/coverage/requests.js +99 -0
- package/dist/cjs/fiscal/coverage/requests.js.map +1 -0
- package/dist/cjs/fiscal/credentials/inspect.js +182 -0
- package/dist/cjs/fiscal/credentials/inspect.js.map +1 -0
- package/dist/cjs/fiscal/credentials/material.js +168 -0
- package/dist/cjs/fiscal/credentials/material.js.map +1 -0
- package/dist/cjs/fiscal/credentials/onboarding.js +266 -0
- package/dist/cjs/fiscal/credentials/onboarding.js.map +1 -0
- package/dist/cjs/fiscal/credentials/readiness.js +190 -0
- package/dist/cjs/fiscal/credentials/readiness.js.map +1 -0
- package/dist/cjs/fiscal/eligibility.js +199 -0
- package/dist/cjs/fiscal/eligibility.js.map +1 -0
- package/dist/cjs/fiscal/enrollment.js +134 -0
- package/dist/cjs/fiscal/enrollment.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/__fixtures__/nfse.js +128 -0
- package/dist/cjs/fiscal/ingestion/__fixtures__/nfse.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/adn-transport.js +229 -0
- package/dist/cjs/fiscal/ingestion/adn-transport.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/direction.js +36 -0
- package/dist/cjs/fiscal/ingestion/direction.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/nfse-adn.js +228 -0
- package/dist/cjs/fiscal/ingestion/nfse-adn.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/pipeline.js +704 -0
- package/dist/cjs/fiscal/ingestion/pipeline.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/provider.js +51 -0
- package/dist/cjs/fiscal/ingestion/provider.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/repository.js +132 -0
- package/dist/cjs/fiscal/ingestion/repository.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/synthetic-provider.js +103 -0
- package/dist/cjs/fiscal/ingestion/synthetic-provider.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport-types.js +13 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport-types.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport.js +61 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/xml-reader.js +121 -0
- package/dist/cjs/fiscal/ingestion/xml-reader.js.map +1 -0
- package/dist/cjs/fiscal/repository.js +470 -0
- package/dist/cjs/fiscal/repository.js.map +1 -0
- package/dist/cjs/fiscal/sync/circuit.js +124 -0
- package/dist/cjs/fiscal/sync/circuit.js.map +1 -0
- package/dist/cjs/fiscal/sync/intervention.js +140 -0
- package/dist/cjs/fiscal/sync/intervention.js.map +1 -0
- package/dist/cjs/fiscal/sync/lease.js +146 -0
- package/dist/cjs/fiscal/sync/lease.js.map +1 -0
- package/dist/cjs/fiscal/sync/observability.js +244 -0
- package/dist/cjs/fiscal/sync/observability.js.map +1 -0
- package/dist/cjs/fiscal/sync/orchestrator.js +490 -0
- package/dist/cjs/fiscal/sync/orchestrator.js.map +1 -0
- package/dist/cjs/fiscal/sync/policy.js +143 -0
- package/dist/cjs/fiscal/sync/policy.js.map +1 -0
- package/dist/cjs/fiscal/sync/reprocess.js +241 -0
- package/dist/cjs/fiscal/sync/reprocess.js.map +1 -0
- package/dist/cjs/fiscal/sync/retry.js +183 -0
- package/dist/cjs/fiscal/sync/retry.js.map +1 -0
- package/dist/cjs/fiscal/sync/secret-boundary.js +123 -0
- package/dist/cjs/fiscal/sync/secret-boundary.js.map +1 -0
- package/dist/cjs/fiscal/transport/https.js +309 -0
- package/dist/cjs/fiscal/transport/https.js.map +1 -0
- package/dist/cjs/fiscal/transport/synthetic-tls.js +380 -0
- package/dist/cjs/fiscal/transport/synthetic-tls.js.map +1 -0
- package/dist/cjs/fiscal/transport/types.js +93 -0
- package/dist/cjs/fiscal/transport/types.js.map +1 -0
- package/dist/cjs/import/br-documents.js +85 -0
- package/dist/cjs/import/br-documents.js.map +1 -0
- package/dist/cjs/import/clients-import.js +347 -40
- package/dist/cjs/import/clients-import.js.map +1 -1
- package/dist/cjs/index.js +461 -73
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/legal/documents.js +164 -19
- package/dist/cjs/legal/documents.js.map +1 -1
- package/dist/cjs/legal/index.js +3 -1
- package/dist/cjs/legal/index.js.map +1 -1
- package/dist/cjs/legal/types.js.map +1 -1
- package/dist/cjs/onboarding/persistence.js +4 -4
- package/dist/cjs/onboarding/persistence.js.map +1 -1
- package/dist/cjs/pilot/go-live-checklist.js +212 -0
- package/dist/cjs/pilot/go-live-checklist.js.map +1 -0
- package/dist/cjs/pilot/milestone.js +79 -0
- package/dist/cjs/pilot/milestone.js.map +1 -0
- package/dist/cjs/platform/capabilities.js +173 -0
- package/dist/cjs/platform/capabilities.js.map +1 -0
- package/dist/cjs/platform/job-contract.js +411 -0
- package/dist/cjs/platform/job-contract.js.map +1 -0
- package/dist/cjs/rbac/catalog.js +110 -0
- package/dist/cjs/rbac/catalog.js.map +1 -1
- package/dist/cjs/subscription-billing/index.js +9 -1
- package/dist/cjs/subscription-billing/index.js.map +1 -1
- package/dist/cjs/subscription-billing/platform-exemption.js +121 -0
- package/dist/cjs/subscription-billing/platform-exemption.js.map +1 -0
- package/dist/cjs/subscription-billing/service.js +246 -78
- package/dist/cjs/subscription-billing/service.js.map +1 -1
- package/dist/cjs/tenancy/features.js +131 -0
- package/dist/cjs/tenancy/features.js.map +1 -0
- package/dist/cjs/tenancy/settings.js +224 -0
- package/dist/cjs/tenancy/settings.js.map +1 -0
- package/dist/cjs/users/repository.js +24 -1
- package/dist/cjs/users/repository.js.map +1 -1
- package/dist/cjs/vault/repository.js +92 -5
- package/dist/cjs/vault/repository.js.map +1 -1
- package/dist/clients/ibge.d.ts +17 -0
- package/dist/clients/ibge.d.ts.map +1 -0
- package/dist/clients/ibge.js +112 -0
- package/dist/clients/ibge.js.map +1 -0
- package/dist/clients/registry/http.d.ts +61 -0
- package/dist/clients/registry/http.d.ts.map +1 -0
- package/dist/clients/registry/http.js +151 -0
- package/dist/clients/registry/http.js.map +1 -0
- package/dist/clients/registry/ibge-municipios.d.ts +25 -0
- package/dist/clients/registry/ibge-municipios.d.ts.map +1 -0
- package/dist/clients/registry/ibge-municipios.js +25 -0
- package/dist/clients/registry/ibge-municipios.js.map +1 -0
- package/dist/clients/registry/ibge.d.ts +62 -0
- package/dist/clients/registry/ibge.d.ts.map +1 -0
- package/dist/clients/registry/ibge.js +57 -0
- package/dist/clients/registry/ibge.js.map +1 -0
- package/dist/clients/registry/lookup.d.ts +94 -0
- package/dist/clients/registry/lookup.d.ts.map +1 -0
- package/dist/clients/registry/lookup.js +184 -0
- package/dist/clients/registry/lookup.js.map +1 -0
- package/dist/clients/registry/provider.d.ts +124 -0
- package/dist/clients/registry/provider.d.ts.map +1 -0
- package/dist/clients/registry/provider.js +39 -0
- package/dist/clients/registry/provider.js.map +1 -0
- package/dist/clients/registry/resolve.d.ts +36 -0
- package/dist/clients/registry/resolve.d.ts.map +1 -0
- package/dist/clients/registry/resolve.js +44 -0
- package/dist/clients/registry/resolve.js.map +1 -0
- package/dist/clients/registry/serpro.d.ts +57 -0
- package/dist/clients/registry/serpro.d.ts.map +1 -0
- package/dist/clients/registry/serpro.js +143 -0
- package/dist/clients/registry/serpro.js.map +1 -0
- package/dist/clients/registry/service.d.ts +59 -0
- package/dist/clients/registry/service.d.ts.map +1 -0
- package/dist/clients/registry/service.js +225 -0
- package/dist/clients/registry/service.js.map +1 -0
- package/dist/clients/registry/synthetic.d.ts +30 -0
- package/dist/clients/registry/synthetic.d.ts.map +1 -0
- package/dist/clients/registry/synthetic.js +161 -0
- package/dist/clients/registry/synthetic.js.map +1 -0
- package/dist/clients/repository.d.ts +158 -0
- package/dist/clients/repository.d.ts.map +1 -1
- package/dist/clients/repository.js +186 -9
- package/dist/clients/repository.js.map +1 -1
- package/dist/collection/branding.d.ts +65 -0
- package/dist/collection/branding.d.ts.map +1 -1
- package/dist/collection/branding.js +186 -0
- package/dist/collection/branding.js.map +1 -1
- package/dist/collection/clearance-store.d.ts +39 -0
- package/dist/collection/clearance-store.d.ts.map +1 -0
- package/dist/collection/clearance-store.js +69 -0
- package/dist/collection/clearance-store.js.map +1 -0
- package/dist/collection/communication-runtime.d.ts +37 -0
- package/dist/collection/communication-runtime.d.ts.map +1 -1
- package/dist/collection/communication-runtime.js +63 -1
- package/dist/collection/communication-runtime.js.map +1 -1
- package/dist/collection/engine.d.ts +23 -0
- package/dist/collection/engine.d.ts.map +1 -1
- package/dist/collection/engine.js +20 -0
- package/dist/collection/engine.js.map +1 -1
- package/dist/collection/policy.d.ts +25 -0
- package/dist/collection/policy.d.ts.map +1 -1
- package/dist/collection/policy.js +27 -0
- package/dist/collection/policy.js.map +1 -1
- package/dist/communication/clearance.d.ts +53 -0
- package/dist/communication/clearance.d.ts.map +1 -0
- package/dist/communication/clearance.js +15 -0
- package/dist/communication/clearance.js.map +1 -0
- package/dist/communication/dry-run-scenario.d.ts.map +1 -1
- package/dist/communication/dry-run-scenario.js +5 -0
- package/dist/communication/dry-run-scenario.js.map +1 -1
- package/dist/communication/engine.d.ts +10 -0
- package/dist/communication/engine.d.ts.map +1 -1
- package/dist/communication/engine.js +12 -0
- package/dist/communication/engine.js.map +1 -1
- package/dist/communication/policy.d.ts +16 -0
- package/dist/communication/policy.d.ts.map +1 -1
- package/dist/communication/policy.js.map +1 -1
- package/dist/competence/business-days.d.ts +51 -0
- package/dist/competence/business-days.d.ts.map +1 -0
- package/dist/competence/business-days.js +145 -0
- package/dist/competence/business-days.js.map +1 -0
- package/dist/competence/catalog-validation.d.ts +86 -0
- package/dist/competence/catalog-validation.d.ts.map +1 -0
- package/dist/competence/catalog-validation.js +168 -0
- package/dist/competence/catalog-validation.js.map +1 -0
- package/dist/competence/obligation-preview.d.ts +103 -0
- package/dist/competence/obligation-preview.d.ts.map +1 -0
- package/dist/competence/obligation-preview.js +184 -0
- package/dist/competence/obligation-preview.js.map +1 -0
- package/dist/competence/repository.d.ts +139 -1
- package/dist/competence/repository.d.ts.map +1 -1
- package/dist/competence/repository.js +325 -17
- package/dist/competence/repository.js.map +1 -1
- package/dist/dashboard/pilot-panel.d.ts +100 -0
- package/dist/dashboard/pilot-panel.d.ts.map +1 -0
- package/dist/dashboard/pilot-panel.js +87 -0
- package/dist/dashboard/pilot-panel.js.map +1 -0
- package/dist/dashboard/repository.d.ts.map +1 -1
- package/dist/dashboard/repository.js +11 -1
- package/dist/dashboard/repository.js.map +1 -1
- package/dist/db/client.d.ts +45 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +16 -11
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrate.d.ts +36 -1
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +199 -32
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/provision-e2e-identity.d.ts +2 -0
- package/dist/db/provision-e2e-identity.d.ts.map +1 -0
- package/dist/db/provision-e2e-identity.js +114 -0
- package/dist/db/provision-e2e-identity.js.map +1 -0
- package/dist/fiscal/applicability.d.ts +73 -0
- package/dist/fiscal/applicability.d.ts.map +1 -0
- package/dist/fiscal/applicability.js +160 -0
- package/dist/fiscal/applicability.js.map +1 -0
- package/dist/fiscal/collection/authorization.d.ts +152 -0
- package/dist/fiscal/collection/authorization.d.ts.map +1 -0
- package/dist/fiscal/collection/authorization.js +178 -0
- package/dist/fiscal/collection/authorization.js.map +1 -0
- package/dist/fiscal/collection/competence.d.ts +66 -0
- package/dist/fiscal/collection/competence.d.ts.map +1 -0
- package/dist/fiscal/collection/competence.js +90 -0
- package/dist/fiscal/collection/competence.js.map +1 -0
- package/dist/fiscal/collection/first-contact.d.ts +103 -0
- package/dist/fiscal/collection/first-contact.d.ts.map +1 -0
- package/dist/fiscal/collection/first-contact.js +201 -0
- package/dist/fiscal/collection/first-contact.js.map +1 -0
- package/dist/fiscal/collection/plan.d.ts +74 -0
- package/dist/fiscal/collection/plan.d.ts.map +1 -0
- package/dist/fiscal/collection/plan.js +119 -0
- package/dist/fiscal/collection/plan.js.map +1 -0
- package/dist/fiscal/conditions.d.ts +99 -0
- package/dist/fiscal/conditions.d.ts.map +1 -0
- package/dist/fiscal/conditions.js +190 -0
- package/dist/fiscal/conditions.js.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-contract.d.ts +315 -0
- package/dist/fiscal/contracts/nfse-adn-contract.d.ts.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-contract.js +386 -0
- package/dist/fiscal/contracts/nfse-adn-contract.js.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.d.ts +13 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.d.ts.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.js +103 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.js.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.d.ts +77 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.d.ts.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.js +215 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.js.map +1 -0
- package/dist/fiscal/coverage/model.d.ts +114 -0
- package/dist/fiscal/coverage/model.d.ts.map +1 -0
- package/dist/fiscal/coverage/model.js +130 -0
- package/dist/fiscal/coverage/model.js.map +1 -0
- package/dist/fiscal/coverage/requests.d.ts +70 -0
- package/dist/fiscal/coverage/requests.d.ts.map +1 -0
- package/dist/fiscal/coverage/requests.js +95 -0
- package/dist/fiscal/coverage/requests.js.map +1 -0
- package/dist/fiscal/credentials/inspect.d.ts +114 -0
- package/dist/fiscal/credentials/inspect.d.ts.map +1 -0
- package/dist/fiscal/credentials/inspect.js +178 -0
- package/dist/fiscal/credentials/inspect.js.map +1 -0
- package/dist/fiscal/credentials/material.d.ts +81 -0
- package/dist/fiscal/credentials/material.d.ts.map +1 -0
- package/dist/fiscal/credentials/material.js +164 -0
- package/dist/fiscal/credentials/material.js.map +1 -0
- package/dist/fiscal/credentials/onboarding.d.ts +119 -0
- package/dist/fiscal/credentials/onboarding.d.ts.map +1 -0
- package/dist/fiscal/credentials/onboarding.js +259 -0
- package/dist/fiscal/credentials/onboarding.js.map +1 -0
- package/dist/fiscal/credentials/readiness.d.ts +119 -0
- package/dist/fiscal/credentials/readiness.d.ts.map +1 -0
- package/dist/fiscal/credentials/readiness.js +186 -0
- package/dist/fiscal/credentials/readiness.js.map +1 -0
- package/dist/fiscal/eligibility.d.ts +106 -0
- package/dist/fiscal/eligibility.d.ts.map +1 -0
- package/dist/fiscal/eligibility.js +194 -0
- package/dist/fiscal/eligibility.js.map +1 -0
- package/dist/fiscal/enrollment.d.ts +91 -0
- package/dist/fiscal/enrollment.d.ts.map +1 -0
- package/dist/fiscal/enrollment.js +126 -0
- package/dist/fiscal/enrollment.js.map +1 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.d.ts +57 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.d.ts.map +1 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.js +121 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.js.map +1 -0
- package/dist/fiscal/ingestion/adn-transport.d.ts +123 -0
- package/dist/fiscal/ingestion/adn-transport.d.ts.map +1 -0
- package/dist/fiscal/ingestion/adn-transport.js +220 -0
- package/dist/fiscal/ingestion/adn-transport.js.map +1 -0
- package/dist/fiscal/ingestion/direction.d.ts +60 -0
- package/dist/fiscal/ingestion/direction.d.ts.map +1 -0
- package/dist/fiscal/ingestion/direction.js +32 -0
- package/dist/fiscal/ingestion/direction.js.map +1 -0
- package/dist/fiscal/ingestion/nfse-adn.d.ts +91 -0
- package/dist/fiscal/ingestion/nfse-adn.d.ts.map +1 -0
- package/dist/fiscal/ingestion/nfse-adn.js +222 -0
- package/dist/fiscal/ingestion/nfse-adn.js.map +1 -0
- package/dist/fiscal/ingestion/pipeline.d.ts +168 -0
- package/dist/fiscal/ingestion/pipeline.d.ts.map +1 -0
- package/dist/fiscal/ingestion/pipeline.js +699 -0
- package/dist/fiscal/ingestion/pipeline.js.map +1 -0
- package/dist/fiscal/ingestion/provider.d.ts +206 -0
- package/dist/fiscal/ingestion/provider.d.ts.map +1 -0
- package/dist/fiscal/ingestion/provider.js +47 -0
- package/dist/fiscal/ingestion/provider.js.map +1 -0
- package/dist/fiscal/ingestion/repository.d.ts +82 -0
- package/dist/fiscal/ingestion/repository.d.ts.map +1 -0
- package/dist/fiscal/ingestion/repository.js +127 -0
- package/dist/fiscal/ingestion/repository.js.map +1 -0
- package/dist/fiscal/ingestion/synthetic-provider.d.ts +92 -0
- package/dist/fiscal/ingestion/synthetic-provider.d.ts.map +1 -0
- package/dist/fiscal/ingestion/synthetic-provider.js +99 -0
- package/dist/fiscal/ingestion/synthetic-provider.js.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.d.ts +19 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.d.ts.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.js +9 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.js.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport.d.ts +55 -0
- package/dist/fiscal/ingestion/synthetic-transport.d.ts.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport.js +57 -0
- package/dist/fiscal/ingestion/synthetic-transport.js.map +1 -0
- package/dist/fiscal/ingestion/xml-reader.d.ts +55 -0
- package/dist/fiscal/ingestion/xml-reader.d.ts.map +1 -0
- package/dist/fiscal/ingestion/xml-reader.js +112 -0
- package/dist/fiscal/ingestion/xml-reader.js.map +1 -0
- package/dist/fiscal/repository.d.ts +220 -0
- package/dist/fiscal/repository.d.ts.map +1 -0
- package/dist/fiscal/repository.js +449 -0
- package/dist/fiscal/repository.js.map +1 -0
- package/dist/fiscal/sync/circuit.d.ts +86 -0
- package/dist/fiscal/sync/circuit.d.ts.map +1 -0
- package/dist/fiscal/sync/circuit.js +118 -0
- package/dist/fiscal/sync/circuit.js.map +1 -0
- package/dist/fiscal/sync/intervention.d.ts +81 -0
- package/dist/fiscal/sync/intervention.d.ts.map +1 -0
- package/dist/fiscal/sync/intervention.js +135 -0
- package/dist/fiscal/sync/intervention.js.map +1 -0
- package/dist/fiscal/sync/lease.d.ts +118 -0
- package/dist/fiscal/sync/lease.d.ts.map +1 -0
- package/dist/fiscal/sync/lease.js +139 -0
- package/dist/fiscal/sync/lease.js.map +1 -0
- package/dist/fiscal/sync/observability.d.ts +148 -0
- package/dist/fiscal/sync/observability.d.ts.map +1 -0
- package/dist/fiscal/sync/observability.js +239 -0
- package/dist/fiscal/sync/observability.js.map +1 -0
- package/dist/fiscal/sync/orchestrator.d.ts +132 -0
- package/dist/fiscal/sync/orchestrator.d.ts.map +1 -0
- package/dist/fiscal/sync/orchestrator.js +487 -0
- package/dist/fiscal/sync/orchestrator.js.map +1 -0
- package/dist/fiscal/sync/policy.d.ts +87 -0
- package/dist/fiscal/sync/policy.d.ts.map +1 -0
- package/dist/fiscal/sync/policy.js +136 -0
- package/dist/fiscal/sync/policy.js.map +1 -0
- package/dist/fiscal/sync/reprocess.d.ts +76 -0
- package/dist/fiscal/sync/reprocess.d.ts.map +1 -0
- package/dist/fiscal/sync/reprocess.js +237 -0
- package/dist/fiscal/sync/reprocess.js.map +1 -0
- package/dist/fiscal/sync/retry.d.ts +82 -0
- package/dist/fiscal/sync/retry.d.ts.map +1 -0
- package/dist/fiscal/sync/retry.js +176 -0
- package/dist/fiscal/sync/retry.js.map +1 -0
- package/dist/fiscal/sync/secret-boundary.d.ts +169 -0
- package/dist/fiscal/sync/secret-boundary.d.ts.map +1 -0
- package/dist/fiscal/sync/secret-boundary.js +116 -0
- package/dist/fiscal/sync/secret-boundary.js.map +1 -0
- package/dist/fiscal/transport/https.d.ts +86 -0
- package/dist/fiscal/transport/https.d.ts.map +1 -0
- package/dist/fiscal/transport/https.js +303 -0
- package/dist/fiscal/transport/https.js.map +1 -0
- package/dist/fiscal/transport/synthetic-tls.d.ts +99 -0
- package/dist/fiscal/transport/synthetic-tls.d.ts.map +1 -0
- package/dist/fiscal/transport/synthetic-tls.js +374 -0
- package/dist/fiscal/transport/synthetic-tls.js.map +1 -0
- package/dist/fiscal/transport/types.d.ts +134 -0
- package/dist/fiscal/transport/types.d.ts.map +1 -0
- package/dist/fiscal/transport/types.js +88 -0
- package/dist/fiscal/transport/types.js.map +1 -0
- package/dist/import/br-documents.d.ts +26 -0
- package/dist/import/br-documents.d.ts.map +1 -0
- package/dist/import/br-documents.js +78 -0
- package/dist/import/br-documents.js.map +1 -0
- package/dist/import/clients-import.d.ts +122 -4
- package/dist/import/clients-import.d.ts.map +1 -1
- package/dist/import/clients-import.js +341 -41
- package/dist/import/clients-import.js.map +1 -1
- package/dist/index.d.ts +145 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +120 -7
- package/dist/index.js.map +1 -1
- package/dist/legal/documents.d.ts +12 -1
- package/dist/legal/documents.d.ts.map +1 -1
- package/dist/legal/documents.js +162 -18
- package/dist/legal/documents.js.map +1 -1
- package/dist/legal/index.d.ts +2 -2
- package/dist/legal/index.d.ts.map +1 -1
- package/dist/legal/index.js +1 -1
- package/dist/legal/index.js.map +1 -1
- package/dist/legal/types.d.ts +114 -2
- package/dist/legal/types.d.ts.map +1 -1
- package/dist/legal/types.js.map +1 -1
- package/dist/onboarding/persistence.d.ts +10 -1
- package/dist/onboarding/persistence.d.ts.map +1 -1
- package/dist/onboarding/persistence.js +4 -4
- package/dist/onboarding/persistence.js.map +1 -1
- package/dist/pilot/go-live-checklist.d.ts +41 -0
- package/dist/pilot/go-live-checklist.d.ts.map +1 -0
- package/dist/pilot/go-live-checklist.js +209 -0
- package/dist/pilot/go-live-checklist.js.map +1 -0
- package/dist/pilot/milestone.d.ts +56 -0
- package/dist/pilot/milestone.d.ts.map +1 -0
- package/dist/pilot/milestone.js +74 -0
- package/dist/pilot/milestone.js.map +1 -0
- package/dist/platform/capabilities.d.ts +88 -0
- package/dist/platform/capabilities.d.ts.map +1 -0
- package/dist/platform/capabilities.js +169 -0
- package/dist/platform/capabilities.js.map +1 -0
- package/dist/platform/job-contract.d.ts +232 -0
- package/dist/platform/job-contract.d.ts.map +1 -0
- package/dist/platform/job-contract.js +403 -0
- package/dist/platform/job-contract.js.map +1 -0
- package/dist/rbac/catalog.d.ts.map +1 -1
- package/dist/rbac/catalog.js +110 -0
- package/dist/rbac/catalog.js.map +1 -1
- package/dist/subscription-billing/index.d.ts +8 -5
- package/dist/subscription-billing/index.d.ts.map +1 -1
- package/dist/subscription-billing/index.js +4 -3
- package/dist/subscription-billing/index.js.map +1 -1
- package/dist/subscription-billing/platform-exemption.d.ts +89 -0
- package/dist/subscription-billing/platform-exemption.d.ts.map +1 -0
- package/dist/subscription-billing/platform-exemption.js +113 -0
- package/dist/subscription-billing/platform-exemption.js.map +1 -0
- package/dist/subscription-billing/service.d.ts +74 -0
- package/dist/subscription-billing/service.d.ts.map +1 -1
- package/dist/subscription-billing/service.js +182 -16
- package/dist/subscription-billing/service.js.map +1 -1
- package/dist/tenancy/features.d.ts +69 -0
- package/dist/tenancy/features.d.ts.map +1 -0
- package/dist/tenancy/features.js +123 -0
- package/dist/tenancy/features.js.map +1 -0
- package/dist/tenancy/settings.d.ts +63 -0
- package/dist/tenancy/settings.d.ts.map +1 -0
- package/dist/tenancy/settings.js +218 -0
- package/dist/tenancy/settings.js.map +1 -0
- package/dist/users/repository.d.ts +16 -1
- package/dist/users/repository.d.ts.map +1 -1
- package/dist/users/repository.js +24 -1
- package/dist/users/repository.js.map +1 -1
- package/dist/vault/repository.d.ts +69 -1
- package/dist/vault/repository.d.ts.map +1 -1
- package/dist/vault/repository.js +88 -5
- package/dist/vault/repository.js.map +1 -1
- package/package.json +10 -2
- package/src/db/migrations/0045_role_write_scope.sql +122 -0
- package/src/db/migrations/0046_pilot_activation_model.sql +184 -0
- package/src/db/migrations/0047_recipient_clearance.sql +89 -0
- package/src/db/migrations/0048_item_type_note.sql +16 -0
- package/src/db/migrations/0049_national_fiscal_engine.sql +279 -0
- package/src/db/migrations/0050_fiscal_vocabulary_readonly.sql +29 -0
- package/src/db/migrations/0051_seed_rules_from_catalog.sql +72 -0
- package/src/db/migrations/0052_fiscal_rule_delete_scope.sql +57 -0
- package/src/db/migrations/0053_rule_validity_lower_bound.sql +44 -0
- package/src/db/migrations/0054_tenant_profile_and_rule_source.sql +89 -0
- package/src/db/migrations/0055_job_capability_contract.sql +300 -0
- package/src/db/migrations/0056_fiscal_document_ingestion.sql +337 -0
- package/src/db/migrations/0057_fiscal_pending_event_inbox.sql +228 -0
- package/src/db/migrations/0058_fiscal_operational_engine.sql +516 -0
- package/src/db/migrations/0059_fiscal_contract_version.sql +59 -0
- package/src/db/migrations/0060_fiscal_credential_vault_and_run_authorization.sql +321 -0
- package/src/db/migrations/0061_client_official_registry_provenance.sql +193 -0
- package/src/db/migrations/0062_first_contact_and_capability_truth.sql +119 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Tx } from '../../db/client.js';
|
|
2
|
+
import type { FiscalDocumentType } from '../ingestion/provider.js';
|
|
3
|
+
/**
|
|
4
|
+
* Com que frequência — e a resposta padrão é "nenhuma".
|
|
5
|
+
*
|
|
6
|
+
* ## Duas rédeas, dois portões
|
|
7
|
+
*
|
|
8
|
+
* Elegibilidade (0055) responde QUEM pode entrar. Política responde QUANDO. São
|
|
9
|
+
* perguntas independentes, e mantê-las separadas paga em um caso concreto: no
|
|
10
|
+
* dia em que alguém inscrever a carteira inteira de uma vez — importação de
|
|
11
|
+
* clientes, um clique errado numa tela de lote — a frequência ainda será
|
|
12
|
+
* `disabled` para todos, e nenhuma consulta sai contra o ambiente nacional.
|
|
13
|
+
*
|
|
14
|
+
* Se as duas vivessem no mesmo campo, inscrever seria ligar.
|
|
15
|
+
*
|
|
16
|
+
* ## Herança com um nível, e nenhum default permissivo
|
|
17
|
+
*
|
|
18
|
+
* A linha do cliente vence a do escritório; a ausência das duas é `disabled`.
|
|
19
|
+
* Não existe "herda do produto" nem "se não disser, use diário": o padrão de
|
|
20
|
+
* fábrica de uma automação que consulta a Receita em nome de terceiros é
|
|
21
|
+
* desligada, e isso precisa valer também para quem esqueceu de configurar.
|
|
22
|
+
*/
|
|
23
|
+
export type FiscalSyncFrequency = 'disabled' | 'hourly' | 'daily' | 'business_day';
|
|
24
|
+
export interface FiscalSyncPolicy {
|
|
25
|
+
frequency: FiscalSyncFrequency;
|
|
26
|
+
/** Hora local (America/Sao_Paulo) em que a janela diária abre. */
|
|
27
|
+
windowHourLocal: number;
|
|
28
|
+
/** De onde veio a decisão. `default` = nenhuma linha, logo desligado. */
|
|
29
|
+
origin: 'client' | 'tenant' | 'default';
|
|
30
|
+
enabled: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** O que vale quando ninguém configurou nada. Desligado, sempre. */
|
|
33
|
+
export declare const FISCAL_SYNC_POLICY_DEFAULT: FiscalSyncPolicy;
|
|
34
|
+
/**
|
|
35
|
+
* Resolve a política de um cliente.
|
|
36
|
+
*
|
|
37
|
+
* Roda sob `withContext` com o tenant — a tabela tem RLS FORCE.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveFiscalSyncPolicy(tx: Tx, input: {
|
|
40
|
+
clientId: string;
|
|
41
|
+
documentType: FiscalDocumentType;
|
|
42
|
+
}): Promise<FiscalSyncPolicy>;
|
|
43
|
+
/**
|
|
44
|
+
* Quando este fluxo volta a ser elegível, pela CADÊNCIA.
|
|
45
|
+
*
|
|
46
|
+
* Distinto de `next_attempt_after`, que é espera do PROVEDOR. Desobedecer aquela
|
|
47
|
+
* bloqueia o CNPJ do cliente; antecipar esta é só desperdício. O gate efetivo é
|
|
48
|
+
* o maior dos dois, e quem os combina é `nextEffectiveRun`.
|
|
49
|
+
*
|
|
50
|
+
* `business_day` avança para segunda quando cai no fim de semana. Não é
|
|
51
|
+
* cosmético: nota emitida no sábado só é vista na segunda de qualquer forma, e
|
|
52
|
+
* uma consulta que ninguém vai olhar ainda assim consome a cota do cliente.
|
|
53
|
+
*/
|
|
54
|
+
export declare function nextRunAfter(policy: FiscalSyncPolicy, lastCompletedAt: Date | null, now: Date): Date | null;
|
|
55
|
+
/**
|
|
56
|
+
* O gate efetivo: o MAIOR entre a cadência nossa e a espera do provedor.
|
|
57
|
+
*
|
|
58
|
+
* Colapsá-los numa coluna só faria uma política diária apagar uma espera
|
|
59
|
+
* obrigatória de uma hora — e essa espera é o que separa a automação do
|
|
60
|
+
* `cStat 656`.
|
|
61
|
+
*/
|
|
62
|
+
export declare function nextEffectiveRun(cadence: Date | null, providerWait: Date | null): Date | null;
|
|
63
|
+
/**
|
|
64
|
+
* Grava a política de cadência.
|
|
65
|
+
*
|
|
66
|
+
* ## Por que existe uma função, e não um `INSERT` em cada chamador
|
|
67
|
+
*
|
|
68
|
+
* Os índices únicos da 0058 são PARCIAIS (`WHERE client_id IS NOT NULL` e
|
|
69
|
+
* `WHERE client_id IS NULL`), porque NULL não colide com NULL num índice comum
|
|
70
|
+
* e sem isso o padrão do escritório poderia ser gravado duas vezes. A
|
|
71
|
+
* consequência é que `ON CONFLICT (tenant_id, client_id, document_type)`
|
|
72
|
+
* **não encontra o índice** — o PostgreSQL exige o predicado junto.
|
|
73
|
+
*
|
|
74
|
+
* É uma armadilha que todo chamador cairia uma vez. Uma função só, que a
|
|
75
|
+
* conhece, é mais barata do que três lugares que a redescobrem.
|
|
76
|
+
*/
|
|
77
|
+
export declare function setFiscalSyncPolicy(tx: Tx, input: {
|
|
78
|
+
tenantId: string;
|
|
79
|
+
/** `null` = padrão do escritório para aquele tipo. */
|
|
80
|
+
clientId: string | null;
|
|
81
|
+
documentType: FiscalDocumentType;
|
|
82
|
+
frequency: FiscalSyncFrequency;
|
|
83
|
+
windowHourLocal?: number;
|
|
84
|
+
enabledBy?: string | null;
|
|
85
|
+
now?: Date;
|
|
86
|
+
}): Promise<void>;
|
|
87
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/fiscal/sync/policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,cAAc,CAAC;AAEnF,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,mBAAmB,CAAC;IAC/B,kEAAkE;IAClE,eAAe,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IACxC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,oEAAoE;AACpE,eAAO,MAAM,0BAA0B,EAAE,gBAKxC,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,EAAE,EACN,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,kBAAkB,CAAA;CAAE,GAC5D,OAAO,CAAC,gBAAgB,CAAC,CAsB3B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,gBAAgB,EACxB,eAAe,EAAE,IAAI,GAAG,IAAI,EAC5B,GAAG,EAAE,IAAI,GACR,IAAI,GAAG,IAAI,CA0Bb;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,IAAI,GAAG,IAAI,EAAE,YAAY,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAI7F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,EAAE,EACN,KAAK,EAAE;IACL,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,kBAAkB,CAAC;IACjC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GACA,OAAO,CAAC,IAAI,CAAC,CAkCf"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { uuidv7 } from '@baruk/shared';
|
|
2
|
+
/** O que vale quando ninguém configurou nada. Desligado, sempre. */
|
|
3
|
+
export const FISCAL_SYNC_POLICY_DEFAULT = {
|
|
4
|
+
frequency: 'disabled',
|
|
5
|
+
windowHourLocal: 8,
|
|
6
|
+
origin: 'default',
|
|
7
|
+
enabled: false,
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Resolve a política de um cliente.
|
|
11
|
+
*
|
|
12
|
+
* Roda sob `withContext` com o tenant — a tabela tem RLS FORCE.
|
|
13
|
+
*/
|
|
14
|
+
export async function resolveFiscalSyncPolicy(tx, input) {
|
|
15
|
+
const rows = await tx `
|
|
16
|
+
SELECT client_id, frequency, window_hour_local
|
|
17
|
+
FROM fiscal_sync_policy
|
|
18
|
+
WHERE document_type = ${input.documentType}
|
|
19
|
+
AND (client_id = ${input.clientId} OR client_id IS NULL)
|
|
20
|
+
-- A linha do cliente primeiro: "NULLS LAST" faz o padrão do escritório
|
|
21
|
+
-- ficar para trás sem precisar de duas consultas.
|
|
22
|
+
ORDER BY client_id NULLS LAST
|
|
23
|
+
LIMIT 1
|
|
24
|
+
`;
|
|
25
|
+
const r = rows[0];
|
|
26
|
+
if (!r)
|
|
27
|
+
return FISCAL_SYNC_POLICY_DEFAULT;
|
|
28
|
+
const frequency = r.frequency;
|
|
29
|
+
return {
|
|
30
|
+
frequency,
|
|
31
|
+
windowHourLocal: r.window_hour_local,
|
|
32
|
+
origin: r.client_id ? 'client' : 'tenant',
|
|
33
|
+
enabled: frequency !== 'disabled',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Quando este fluxo volta a ser elegível, pela CADÊNCIA.
|
|
38
|
+
*
|
|
39
|
+
* Distinto de `next_attempt_after`, que é espera do PROVEDOR. Desobedecer aquela
|
|
40
|
+
* bloqueia o CNPJ do cliente; antecipar esta é só desperdício. O gate efetivo é
|
|
41
|
+
* o maior dos dois, e quem os combina é `nextEffectiveRun`.
|
|
42
|
+
*
|
|
43
|
+
* `business_day` avança para segunda quando cai no fim de semana. Não é
|
|
44
|
+
* cosmético: nota emitida no sábado só é vista na segunda de qualquer forma, e
|
|
45
|
+
* uma consulta que ninguém vai olhar ainda assim consome a cota do cliente.
|
|
46
|
+
*/
|
|
47
|
+
export function nextRunAfter(policy, lastCompletedAt, now) {
|
|
48
|
+
if (!policy.enabled)
|
|
49
|
+
return null;
|
|
50
|
+
const base = lastCompletedAt ?? now;
|
|
51
|
+
if (policy.frequency === 'hourly') {
|
|
52
|
+
return new Date(base.getTime() + 3_600_000);
|
|
53
|
+
}
|
|
54
|
+
// A janela diária é ancorada na hora LOCAL do escritório. O deslocamento é
|
|
55
|
+
// fixo em -3 porque o Brasil não tem mais horário de verão desde 2019; se
|
|
56
|
+
// voltar, este é o ponto único a mudar — e o comentário é o que faz alguém
|
|
57
|
+
// encontrá-lo.
|
|
58
|
+
const OFFSET_HOURS = -3;
|
|
59
|
+
const alvo = new Date(base.getTime());
|
|
60
|
+
alvo.setUTCHours(policy.windowHourLocal - OFFSET_HOURS, 0, 0, 0);
|
|
61
|
+
if (alvo <= base)
|
|
62
|
+
alvo.setUTCDate(alvo.getUTCDate() + 1);
|
|
63
|
+
if (policy.frequency === 'business_day') {
|
|
64
|
+
// 0 = domingo, 6 = sábado, no fuso local.
|
|
65
|
+
for (let i = 0; i < 7; i += 1) {
|
|
66
|
+
const localDay = new Date(alvo.getTime() + OFFSET_HOURS * 3_600_000).getUTCDay();
|
|
67
|
+
if (localDay !== 0 && localDay !== 6)
|
|
68
|
+
break;
|
|
69
|
+
alvo.setUTCDate(alvo.getUTCDate() + 1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return alvo;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* O gate efetivo: o MAIOR entre a cadência nossa e a espera do provedor.
|
|
76
|
+
*
|
|
77
|
+
* Colapsá-los numa coluna só faria uma política diária apagar uma espera
|
|
78
|
+
* obrigatória de uma hora — e essa espera é o que separa a automação do
|
|
79
|
+
* `cStat 656`.
|
|
80
|
+
*/
|
|
81
|
+
export function nextEffectiveRun(cadence, providerWait) {
|
|
82
|
+
if (!cadence)
|
|
83
|
+
return providerWait;
|
|
84
|
+
if (!providerWait)
|
|
85
|
+
return cadence;
|
|
86
|
+
return cadence > providerWait ? cadence : providerWait;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Grava a política de cadência.
|
|
90
|
+
*
|
|
91
|
+
* ## Por que existe uma função, e não um `INSERT` em cada chamador
|
|
92
|
+
*
|
|
93
|
+
* Os índices únicos da 0058 são PARCIAIS (`WHERE client_id IS NOT NULL` e
|
|
94
|
+
* `WHERE client_id IS NULL`), porque NULL não colide com NULL num índice comum
|
|
95
|
+
* e sem isso o padrão do escritório poderia ser gravado duas vezes. A
|
|
96
|
+
* consequência é que `ON CONFLICT (tenant_id, client_id, document_type)`
|
|
97
|
+
* **não encontra o índice** — o PostgreSQL exige o predicado junto.
|
|
98
|
+
*
|
|
99
|
+
* É uma armadilha que todo chamador cairia uma vez. Uma função só, que a
|
|
100
|
+
* conhece, é mais barata do que três lugares que a redescobrem.
|
|
101
|
+
*/
|
|
102
|
+
export async function setFiscalSyncPolicy(tx, input) {
|
|
103
|
+
const now = input.now ?? new Date();
|
|
104
|
+
// Ligado exige registro de quem ligou e quando — o CHECK da 0058 recusa
|
|
105
|
+
// automação sem dono, e a data é gravada aqui em vez de num `DEFAULT`.
|
|
106
|
+
const enabledAt = input.frequency === 'disabled' ? null : now;
|
|
107
|
+
const hora = input.windowHourLocal ?? 8;
|
|
108
|
+
if (input.clientId) {
|
|
109
|
+
await tx `
|
|
110
|
+
INSERT INTO fiscal_sync_policy (id, tenant_id, client_id, document_type, frequency,
|
|
111
|
+
window_hour_local, enabled_at, enabled_by, updated_at)
|
|
112
|
+
VALUES (${uuidv7()}, ${input.tenantId}, ${input.clientId}, ${input.documentType},
|
|
113
|
+
${input.frequency}, ${hora}, ${enabledAt}, ${input.enabledBy ?? null}, now())
|
|
114
|
+
ON CONFLICT (tenant_id, client_id, document_type) WHERE client_id IS NOT NULL
|
|
115
|
+
DO UPDATE SET frequency = EXCLUDED.frequency,
|
|
116
|
+
window_hour_local = EXCLUDED.window_hour_local,
|
|
117
|
+
enabled_at = EXCLUDED.enabled_at,
|
|
118
|
+
enabled_by = EXCLUDED.enabled_by,
|
|
119
|
+
updated_at = now()
|
|
120
|
+
`;
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
await tx `
|
|
124
|
+
INSERT INTO fiscal_sync_policy (id, tenant_id, client_id, document_type, frequency,
|
|
125
|
+
window_hour_local, enabled_at, enabled_by, updated_at)
|
|
126
|
+
VALUES (${uuidv7()}, ${input.tenantId}, NULL, ${input.documentType},
|
|
127
|
+
${input.frequency}, ${hora}, ${enabledAt}, ${input.enabledBy ?? null}, now())
|
|
128
|
+
ON CONFLICT (tenant_id, document_type) WHERE client_id IS NULL
|
|
129
|
+
DO UPDATE SET frequency = EXCLUDED.frequency,
|
|
130
|
+
window_hour_local = EXCLUDED.window_hour_local,
|
|
131
|
+
enabled_at = EXCLUDED.enabled_at,
|
|
132
|
+
enabled_by = EXCLUDED.enabled_by,
|
|
133
|
+
updated_at = now()
|
|
134
|
+
`;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/fiscal/sync/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { Tx } from '../../db/client.js';
|
|
2
|
+
import { type IngestionDeps } from '../ingestion/pipeline.js';
|
|
3
|
+
/**
|
|
4
|
+
* A segunda chance dos itens que ficaram guardados.
|
|
5
|
+
*
|
|
6
|
+
* ## Por que os bytes foram preservados, afinal
|
|
7
|
+
*
|
|
8
|
+
* A Fase 1 guarda o XML original de todo item que não pôde ser interpretado.
|
|
9
|
+
* Isso só tem valor se houver um caminho de volta: **o parser melhora**. Um
|
|
10
|
+
* leiaute que este código não sabia ler em setembro é legível depois de um
|
|
11
|
+
* deploy, e o item guardado é a única forma de aproveitá-lo sem pedir nada ao
|
|
12
|
+
* provedor — que é a única forma que não gasta a cota do cliente.
|
|
13
|
+
*
|
|
14
|
+
* Sem reprocessamento, a caixa de entrada é um cemitério com boa intenção.
|
|
15
|
+
*
|
|
16
|
+
* ## As três garantias, e como cada uma é obtida
|
|
17
|
+
*
|
|
18
|
+
* **não duplica documento** o `INSERT` usa `ON CONFLICT DO NOTHING` sobre o
|
|
19
|
+
* índice de deduplicação. Não há `SELECT` antes,
|
|
20
|
+
* logo não há janela entre verificar e inserir.
|
|
21
|
+
* **não duplica evento** mesmo mecanismo, sobre o índice do evento.
|
|
22
|
+
* **não move o cursor** `reingestPreservedItem` simplesmente não o toca.
|
|
23
|
+
* O item já está guardado e a posição do provedor
|
|
24
|
+
* passou por ele há muito tempo; mexer aqui só
|
|
25
|
+
* poderia fazer mal, nos dois sentidos.
|
|
26
|
+
*
|
|
27
|
+
* ## A promoção do evento é feita AQUI, e não pelo pipeline
|
|
28
|
+
*
|
|
29
|
+
* Um item inválido que se revela evento poderia ser reenviado ao pipeline, que
|
|
30
|
+
* o enfileiraria como pendente — criando uma SEGUNDA linha para os MESMOS
|
|
31
|
+
* bytes, com a antiga presa em `invalid` para sempre. A linha é promovida no
|
|
32
|
+
* lugar: mesma identidade, mesmo `raw`, estado novo.
|
|
33
|
+
*/
|
|
34
|
+
export type ReprocessOutcome = 'document_created' | 'document_duplicate' | 'event_applied' | 'event_pending' | 'still_invalid' | 'already_resolved' | 'not_found';
|
|
35
|
+
export interface ReprocessResult {
|
|
36
|
+
inboxId: string;
|
|
37
|
+
outcome: ReprocessOutcome;
|
|
38
|
+
detail: string;
|
|
39
|
+
documentId: string | null;
|
|
40
|
+
reconciled: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Reprocessa um item preservado.
|
|
44
|
+
*
|
|
45
|
+
* `deps.adapter` precisa ser o adapter da MESMA fonte que guardou o item —
|
|
46
|
+
* outro leiaute produziria uma interpretação errada de bytes válidos. Quem
|
|
47
|
+
* chama confere; a rota faz isso pela `source` gravada na linha.
|
|
48
|
+
*/
|
|
49
|
+
export declare function reprocessFiscalInboxItem(tx: Tx, deps: IngestionDeps, input: {
|
|
50
|
+
tenantId: string;
|
|
51
|
+
inboxId: string;
|
|
52
|
+
actorDocument: string;
|
|
53
|
+
actorId?: string | null;
|
|
54
|
+
now?: Date;
|
|
55
|
+
}): Promise<ReprocessResult>;
|
|
56
|
+
export interface InboxItemRow {
|
|
57
|
+
id: string;
|
|
58
|
+
clientId: string;
|
|
59
|
+
clientName: string | null;
|
|
60
|
+
source: string;
|
|
61
|
+
environment: string;
|
|
62
|
+
sourceNsu: string | null;
|
|
63
|
+
state: string;
|
|
64
|
+
eventType: string | null;
|
|
65
|
+
targetAccessKey: string | null;
|
|
66
|
+
rejectReason: string | null;
|
|
67
|
+
receivedAt: string;
|
|
68
|
+
reprocessCount: number;
|
|
69
|
+
sizeBytes: number;
|
|
70
|
+
}
|
|
71
|
+
/** A caixa de entrada, para a tela. Sem o `raw` — bytes não vão em JSON de API. */
|
|
72
|
+
export declare function listFiscalInbox(tx: Tx, input?: {
|
|
73
|
+
state?: 'pending_target' | 'invalid' | 'applied' | 'any';
|
|
74
|
+
limit?: number;
|
|
75
|
+
}): Promise<InboxItemRow[]>;
|
|
76
|
+
//# sourceMappingURL=reprocess.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reprocess.d.ts","sourceRoot":"","sources":["../../../src/fiscal/sync/reprocess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,0BAA0B,CAAC;AAIlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,MAAM,gBAAgB,GACxB,kBAAkB,GAClB,oBAAoB,GACpB,eAAe,GACf,eAAe,GACf,eAAe,GACf,kBAAkB,GAClB,WAAW,CAAC;AAEhB,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAcD;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE;IACL,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GACA,OAAO,CAAC,eAAe,CAAC,CAwM1B;AA4BD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,mFAAmF;AACnF,wBAAsB,eAAe,CACnC,EAAE,EAAE,EAAE,EACN,KAAK,GAAE;IAAE,KAAK,CAAC,EAAE,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GACvF,OAAO,CAAC,YAAY,EAAE,CAAC,CA4CzB"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { appendAudit } from '../../audit/audit.js';
|
|
2
|
+
import { reingestPreservedItem, reconcileFiscalPendingEvents, } from '../ingestion/pipeline.js';
|
|
3
|
+
/**
|
|
4
|
+
* Reprocessa um item preservado.
|
|
5
|
+
*
|
|
6
|
+
* `deps.adapter` precisa ser o adapter da MESMA fonte que guardou o item —
|
|
7
|
+
* outro leiaute produziria uma interpretação errada de bytes válidos. Quem
|
|
8
|
+
* chama confere; a rota faz isso pela `source` gravada na linha.
|
|
9
|
+
*/
|
|
10
|
+
export async function reprocessFiscalInboxItem(tx, deps, input) {
|
|
11
|
+
const now = input.now ?? new Date();
|
|
12
|
+
const [row] = await tx `
|
|
13
|
+
SELECT id, client_id, source, source_environment, source_nsu, state,
|
|
14
|
+
document_type, raw, reject_reason
|
|
15
|
+
FROM fiscal_ingestion_inbox
|
|
16
|
+
WHERE id = ${input.inboxId}
|
|
17
|
+
`;
|
|
18
|
+
if (!row) {
|
|
19
|
+
return {
|
|
20
|
+
inboxId: input.inboxId,
|
|
21
|
+
outcome: 'not_found',
|
|
22
|
+
detail: 'item não encontrado',
|
|
23
|
+
documentId: null,
|
|
24
|
+
reconciled: 0,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const base = {
|
|
28
|
+
tenantId: input.tenantId,
|
|
29
|
+
clientId: row.client_id,
|
|
30
|
+
actorDocument: input.actorDocument,
|
|
31
|
+
environment: row.source_environment,
|
|
32
|
+
documentType: (row.document_type ?? 'nfse'),
|
|
33
|
+
now,
|
|
34
|
+
actorId: input.actorId ?? null,
|
|
35
|
+
};
|
|
36
|
+
// Já aplicado: reprocessar não é erro, e não faz nada. Devolver isso é melhor
|
|
37
|
+
// do que reingerir bytes que já viraram linha — seria trabalho para produzir
|
|
38
|
+
// uma duplicata que o banco recusaria de qualquer forma.
|
|
39
|
+
if (row.state === 'applied') {
|
|
40
|
+
return {
|
|
41
|
+
inboxId: row.id,
|
|
42
|
+
outcome: 'already_resolved',
|
|
43
|
+
detail: 'item já aplicado',
|
|
44
|
+
documentId: null,
|
|
45
|
+
reconciled: 0,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Pendente: o que falta não é interpretar, é o alvo existir. Reconciliar é a
|
|
49
|
+
// operação certa, e ela é idempotente por construção.
|
|
50
|
+
if (row.state === 'pending_target') {
|
|
51
|
+
const reconciled = await reconcileFiscalPendingEvents(tx, deps, {
|
|
52
|
+
tenantId: input.tenantId,
|
|
53
|
+
clientId: row.client_id,
|
|
54
|
+
});
|
|
55
|
+
await auditar(tx, input, row, reconciled > 0 ? 'event_applied' : 'event_pending', reconciled);
|
|
56
|
+
return {
|
|
57
|
+
inboxId: row.id,
|
|
58
|
+
outcome: reconciled > 0 ? 'event_applied' : 'event_pending',
|
|
59
|
+
detail: reconciled > 0
|
|
60
|
+
? 'documento-alvo encontrado; evento aplicado'
|
|
61
|
+
: 'documento-alvo ainda não chegou',
|
|
62
|
+
documentId: null,
|
|
63
|
+
reconciled,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Inválido: tenta interpretar de novo com o parser ATUAL.
|
|
67
|
+
const doc = {
|
|
68
|
+
nsu: row.source_nsu ?? '0',
|
|
69
|
+
raw: new Uint8Array(row.raw),
|
|
70
|
+
mimeType: 'application/xml',
|
|
71
|
+
};
|
|
72
|
+
let parsed;
|
|
73
|
+
try {
|
|
74
|
+
parsed = deps.adapter.parse(doc);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const reason = err ? 'parse_failed' : 'parse_failed';
|
|
78
|
+
await tx `
|
|
79
|
+
UPDATE fiscal_ingestion_inbox
|
|
80
|
+
SET reprocessed_at = ${now}, reprocess_count = reprocess_count + 1,
|
|
81
|
+
reject_reason = ${reason}
|
|
82
|
+
WHERE id = ${row.id}
|
|
83
|
+
`;
|
|
84
|
+
return {
|
|
85
|
+
inboxId: row.id,
|
|
86
|
+
outcome: 'still_invalid',
|
|
87
|
+
detail: 'o parser atual ainda não lê este item',
|
|
88
|
+
documentId: null,
|
|
89
|
+
reconciled: 0,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (parsed.event) {
|
|
93
|
+
// Promoção NO LUGAR. `dedupe_key` muda de `raw:<sha>` para a identidade
|
|
94
|
+
// real do evento, e é aí que pode haver conflito com um evento idêntico já
|
|
95
|
+
// guardado — caso em que este item é redundante e o outro já o preserva.
|
|
96
|
+
try {
|
|
97
|
+
await tx.savepoint((sp) => sp `
|
|
98
|
+
UPDATE fiscal_ingestion_inbox
|
|
99
|
+
SET state = 'pending_target',
|
|
100
|
+
document_type = ${parsed.documentType},
|
|
101
|
+
event_type = ${parsed.event.type},
|
|
102
|
+
event_code = ${parsed.event.code ?? null},
|
|
103
|
+
event_sequence = ${parsed.event.sequence ?? null},
|
|
104
|
+
occurred_at = ${parsed.event.occurredAt ?? null},
|
|
105
|
+
target_access_key = ${parsed.event.targetAccessKey},
|
|
106
|
+
dedupe_key = ${parsed.dedupeKey},
|
|
107
|
+
reject_reason = NULL,
|
|
108
|
+
reprocessed_at = ${now},
|
|
109
|
+
reprocess_count = reprocess_count + 1
|
|
110
|
+
WHERE id = ${row.id}
|
|
111
|
+
`);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
await tx `
|
|
115
|
+
UPDATE fiscal_ingestion_inbox
|
|
116
|
+
SET reprocessed_at = ${now}, reprocess_count = reprocess_count + 1,
|
|
117
|
+
reject_reason = 'duplicate_of_existing_event'
|
|
118
|
+
WHERE id = ${row.id}
|
|
119
|
+
`;
|
|
120
|
+
return {
|
|
121
|
+
inboxId: row.id,
|
|
122
|
+
outcome: 'still_invalid',
|
|
123
|
+
detail: 'evento idêntico já preservado em outro item',
|
|
124
|
+
documentId: null,
|
|
125
|
+
reconciled: 0,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const reconciled = await reconcileFiscalPendingEvents(tx, deps, {
|
|
129
|
+
tenantId: input.tenantId,
|
|
130
|
+
clientId: row.client_id,
|
|
131
|
+
});
|
|
132
|
+
await auditar(tx, input, row, reconciled > 0 ? 'event_applied' : 'event_pending', reconciled);
|
|
133
|
+
return {
|
|
134
|
+
inboxId: row.id,
|
|
135
|
+
outcome: reconciled > 0 ? 'event_applied' : 'event_pending',
|
|
136
|
+
detail: reconciled > 0
|
|
137
|
+
? 'reinterpretado como evento e aplicado'
|
|
138
|
+
: 'reinterpretado como evento; alvo ainda não existe',
|
|
139
|
+
documentId: null,
|
|
140
|
+
reconciled,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// Documento. O pipeline grava com a MESMA dedupe do caminho normal.
|
|
144
|
+
const resultado = await reingestPreservedItem(tx, deps, base, doc);
|
|
145
|
+
if (resultado.kind === 'still_invalid') {
|
|
146
|
+
await tx `
|
|
147
|
+
UPDATE fiscal_ingestion_inbox
|
|
148
|
+
SET reprocessed_at = ${now}, reprocess_count = reprocess_count + 1,
|
|
149
|
+
reject_reason = ${resultado.reason}
|
|
150
|
+
WHERE id = ${row.id}
|
|
151
|
+
`;
|
|
152
|
+
return {
|
|
153
|
+
inboxId: row.id,
|
|
154
|
+
outcome: 'still_invalid',
|
|
155
|
+
detail: resultado.reason,
|
|
156
|
+
documentId: null,
|
|
157
|
+
reconciled: 0,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
// Duplicata quer dizer que o documento JÁ existe — o item está resolvido do
|
|
161
|
+
// mesmo jeito, e apontar para a linha existente é mais útil do que apontar
|
|
162
|
+
// para nada.
|
|
163
|
+
const documentId = resultado.kind === 'document_created'
|
|
164
|
+
? resultado.documentId
|
|
165
|
+
: ((await tx `
|
|
166
|
+
SELECT id FROM fiscal_document
|
|
167
|
+
WHERE client_id = ${row.client_id} AND dedupe_key = ${parsed.dedupeKey}
|
|
168
|
+
LIMIT 1
|
|
169
|
+
`)[0]?.id ?? null);
|
|
170
|
+
await tx `
|
|
171
|
+
UPDATE fiscal_ingestion_inbox
|
|
172
|
+
SET state = 'applied', applied_at = ${now}, applied_document_id = ${documentId},
|
|
173
|
+
reject_reason = NULL, reprocessed_at = ${now},
|
|
174
|
+
reprocess_count = reprocess_count + 1
|
|
175
|
+
WHERE id = ${row.id}
|
|
176
|
+
`;
|
|
177
|
+
await auditar(tx, input, row, resultado.kind === 'document_created' ? 'document_created' : 'document_duplicate', 0);
|
|
178
|
+
return {
|
|
179
|
+
inboxId: row.id,
|
|
180
|
+
outcome: resultado.kind === 'document_created' ? 'document_created' : 'document_duplicate',
|
|
181
|
+
detail: resultado.kind === 'document_created'
|
|
182
|
+
? 'reinterpretado como documento e gravado'
|
|
183
|
+
: 'documento já existia; item marcado como resolvido',
|
|
184
|
+
documentId,
|
|
185
|
+
reconciled: 0,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/** Trilha: contadores e identificadores. Nunca XML, nunca nome, nunca valor. */
|
|
189
|
+
async function auditar(tx, input, row, outcome, reconciled) {
|
|
190
|
+
await appendAudit(tx, {
|
|
191
|
+
actorType: input.actorId ? 'user' : 'system',
|
|
192
|
+
actorId: input.actorId ?? null,
|
|
193
|
+
action: 'fiscal.inbox.reprocessed',
|
|
194
|
+
resourceType: 'fiscal_ingestion_inbox',
|
|
195
|
+
resourceId: row.id,
|
|
196
|
+
metadata: {
|
|
197
|
+
clientId: row.client_id,
|
|
198
|
+
source: row.source,
|
|
199
|
+
environment: row.source_environment,
|
|
200
|
+
previousState: row.state,
|
|
201
|
+
previousReason: row.reject_reason,
|
|
202
|
+
outcome,
|
|
203
|
+
reconciled,
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
/** A caixa de entrada, para a tela. Sem o `raw` — bytes não vão em JSON de API. */
|
|
208
|
+
export async function listFiscalInbox(tx, input = {}) {
|
|
209
|
+
const limit = Math.min(Math.max(input.limit ?? 100, 1), 500);
|
|
210
|
+
const state = input.state ?? 'any';
|
|
211
|
+
const rows = await tx `
|
|
212
|
+
SELECT i.id, i.client_id, c.display_name AS client_name, i.source, i.source_environment,
|
|
213
|
+
i.source_nsu, i.state, i.event_type, i.target_access_key, i.reject_reason,
|
|
214
|
+
i.received_at, i.reprocess_count, octet_length(i.raw) AS size_bytes
|
|
215
|
+
FROM fiscal_ingestion_inbox i
|
|
216
|
+
LEFT JOIN client c ON c.id = i.client_id
|
|
217
|
+
WHERE ${state === 'any' ? tx `true` : tx `i.state = ${state}`}
|
|
218
|
+
ORDER BY i.received_at DESC
|
|
219
|
+
LIMIT ${limit}
|
|
220
|
+
`;
|
|
221
|
+
return rows.map((r) => ({
|
|
222
|
+
id: r.id,
|
|
223
|
+
clientId: r.client_id,
|
|
224
|
+
clientName: r.client_name,
|
|
225
|
+
source: r.source,
|
|
226
|
+
environment: r.source_environment,
|
|
227
|
+
sourceNsu: r.source_nsu,
|
|
228
|
+
state: r.state,
|
|
229
|
+
eventType: r.event_type,
|
|
230
|
+
targetAccessKey: r.target_access_key,
|
|
231
|
+
rejectReason: r.reject_reason,
|
|
232
|
+
receivedAt: r.received_at.toISOString(),
|
|
233
|
+
reprocessCount: r.reprocess_count,
|
|
234
|
+
sizeBytes: r.size_bytes,
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=reprocess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reprocess.js","sourceRoot":"","sources":["../../../src/fiscal/sync/reprocess.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { FiscalProviderErrorClass } from '../ingestion/provider.js';
|
|
2
|
+
import { type FiscalTransportErrorClass } from '../transport/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* O que fazer depois de uma falha — e, sobretudo, o que NÃO fazer.
|
|
5
|
+
*
|
|
6
|
+
* ## Nem toda falha merece retentativa, e a maioria dos danos vem daí
|
|
7
|
+
*
|
|
8
|
+
* A forma óbvia de um worker é `catch { retry() }`. Aplicada ao ambiente
|
|
9
|
+
* nacional, ela produz o cenário exato que a norma pune: uma consulta recusada
|
|
10
|
+
* por espera obrigatória é reenviada em segundos, o servidor devolve
|
|
11
|
+
* `cStat 656 — Consumo Indevido`, e o CNPJ bloqueado é o do CLIENTE. Retentar
|
|
12
|
+
* uma recusa por consumo indevido é acelerar o dano, não corrigi-lo.
|
|
13
|
+
*
|
|
14
|
+
* Certificado vencido é o oposto e igualmente errado de retentar: nenhuma
|
|
15
|
+
* quantidade de tentativas renova um A1. Insistir só transforma um problema
|
|
16
|
+
* resolvível numa fila de erros que ninguém lê.
|
|
17
|
+
*
|
|
18
|
+
* ## Por que uma taxonomia própria, e não a classe do provedor
|
|
19
|
+
*
|
|
20
|
+
* `FiscalProviderErrorClass` descreve o que o PROVEDOR disse. `FiscalTransportErrorClass`
|
|
21
|
+
* descreve o que a REDE fez. Nenhuma das duas diz o que o worker deve fazer — e
|
|
22
|
+
* as duas precisam colapsar numa decisão só, porque `timeout` de socket e
|
|
23
|
+
* `cStat 108 serviço paralisado` pedem exatamente o mesmo tratamento.
|
|
24
|
+
*
|
|
25
|
+
* Esta taxonomia é a terceira, e é a única sobre a qual há decisão.
|
|
26
|
+
*/
|
|
27
|
+
export type FiscalFailureCategory = 'NETWORK_TRANSIENT' | 'PROVIDER_RATE_LIMIT' | 'PROVIDER_TEMPORARILY_UNAVAILABLE' | 'AUTHENTICATION_FAILED' | 'CERTIFICATE_INVALID' | 'CERTIFICATE_EXPIRED' | 'PERMISSION_DENIED' | 'BAD_RESPONSE' | 'MALFORMED_DOCUMENT' | 'CURSOR_CONFLICT' | 'INTERNAL_ERROR';
|
|
28
|
+
export interface FiscalRetryDecision {
|
|
29
|
+
category: FiscalFailureCategory;
|
|
30
|
+
/** `false` = nenhuma tentativa futura muda o desfecho sem ação humana. */
|
|
31
|
+
retryable: boolean;
|
|
32
|
+
/** Quando tentar de novo. `null` quando não se tenta. */
|
|
33
|
+
nextAttemptAt: Date | null;
|
|
34
|
+
/** Conta para o circuito do PROVEDOR? Falha de um cliente só, não. */
|
|
35
|
+
countsAgainstProvider: boolean;
|
|
36
|
+
/** Motivo de fila humana, quando o caso exige pessoa. */
|
|
37
|
+
interventionKind: 'auth_required' | 'certificate_expired' | 'certificate_invalid' | 'provider_access_denied' | 'repeated_failure' | null;
|
|
38
|
+
/** Código curto para trilha. Nunca a mensagem do provedor. */
|
|
39
|
+
code: string;
|
|
40
|
+
}
|
|
41
|
+
/** Classe do provedor → categoria de decisão. */
|
|
42
|
+
export declare function categorizeProviderError(cls: FiscalProviderErrorClass): FiscalFailureCategory;
|
|
43
|
+
/** Classe do transporte → categoria de decisão. */
|
|
44
|
+
export declare function categorizeTransportError(cls: FiscalTransportErrorClass): FiscalFailureCategory;
|
|
45
|
+
/** Status HTTP → categoria, para provedores REST (o ADN é um). */
|
|
46
|
+
export declare function categorizeHttpStatus(status: number): FiscalFailureCategory;
|
|
47
|
+
export interface RetryInput {
|
|
48
|
+
/** Quantas tentativas consecutivas já falharam ANTES desta. 0 na primeira. */
|
|
49
|
+
previousFailures: number;
|
|
50
|
+
now: Date;
|
|
51
|
+
/** Espera pedida pelo servidor. Quando vem, ela manda. */
|
|
52
|
+
retryAfter?: Date | null;
|
|
53
|
+
/**
|
|
54
|
+
* Fonte de aleatoriedade do jitter, em [0,1). Injetável para que o teste
|
|
55
|
+
* meça o intervalo e não a sorte.
|
|
56
|
+
*/
|
|
57
|
+
random?: () => number;
|
|
58
|
+
/** Teto de falhas consecutivas antes de o caso virar tarefa humana. */
|
|
59
|
+
humanEscalationAfter?: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Decide o que fazer com uma falha.
|
|
63
|
+
*
|
|
64
|
+
* ## Jitter é obrigatório, não enfeite
|
|
65
|
+
*
|
|
66
|
+
* Sem ele, cem clientes que falharam no mesmo minuto voltam no mesmo minuto —
|
|
67
|
+
* o rebanho que derruba o provedor de novo assim que ele levanta. O jitter é
|
|
68
|
+
* "full jitter": um sorteio em `[0, espera]`, e não `espera ± 10%`. A variante
|
|
69
|
+
* completa é a que realmente espalha; a estreita só desloca o rebanho.
|
|
70
|
+
*
|
|
71
|
+
* ## `Retry-After` vence o nosso cálculo — com piso
|
|
72
|
+
*
|
|
73
|
+
* Quando o servidor diz quando voltar, ele sabe mais do que nós. Mas um
|
|
74
|
+
* `Retry-After: 0` num 429 é o servidor se contradizendo; o piso de 60s existe
|
|
75
|
+
* para que a obediência não vire laço.
|
|
76
|
+
*/
|
|
77
|
+
export declare function decideFiscalRetry(category: FiscalFailureCategory, input: RetryInput,
|
|
78
|
+
/** Código curto do provedor/transporte. Sem ele, a categoria serve de rótulo. */
|
|
79
|
+
code?: string): FiscalRetryDecision;
|
|
80
|
+
/** Atalho: recebe o erro e devolve a decisão, sem quem chama classificar antes. */
|
|
81
|
+
export declare function decideFromError(err: unknown, input: RetryInput): FiscalRetryDecision;
|
|
82
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/fiscal/sync/retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAwB,KAAK,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAG7F;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,MAAM,qBAAqB,GAC7B,mBAAmB,GACnB,qBAAqB,GACrB,kCAAkC,GAClC,uBAAuB,GACvB,qBAAqB,GACrB,qBAAqB,GACrB,mBAAmB,GACnB,cAAc,GACd,oBAAoB,GACpB,iBAAiB,GACjB,gBAAgB,CAAC;AAErB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,qBAAqB,CAAC;IAChC,0EAA0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB,yDAAyD;IACzD,aAAa,EAAE,IAAI,GAAG,IAAI,CAAC;IAC3B,sEAAsE;IACtE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,yDAAyD;IACzD,gBAAgB,EACZ,eAAe,GACf,qBAAqB,GACrB,qBAAqB,GACrB,wBAAwB,GACxB,kBAAkB,GAClB,IAAI,CAAC;IACT,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;CACd;AAqDD,iDAAiD;AACjD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,wBAAwB,GAAG,qBAAqB,CAiB5F;AAED,mDAAmD;AACnD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,yBAAyB,GAAG,qBAAqB,CAe9F;AAED,kEAAkE;AAClE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,CAS1E;AAED,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,gBAAgB,EAAE,MAAM,CAAC;IACzB,GAAG,EAAE,IAAI,CAAC;IACV,0DAA0D;IAC1D,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,qBAAqB,EAC/B,KAAK,EAAE,UAAU;AACjB,iFAAiF;AACjF,IAAI,GAAE,MAAiB,GACtB,mBAAmB,CA+CrB;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,mBAAmB,CAkBpF"}
|