@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,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AdnContractMismatchError = void 0;
|
|
4
|
+
exports.readAdnEnvelope = readAdnEnvelope;
|
|
5
|
+
const node_zlib_1 = require("node:zlib");
|
|
6
|
+
const provider_js_1 = require("../ingestion/provider.js");
|
|
7
|
+
const nfse_adn_contract_js_1 = require("./nfse-adn-contract.js");
|
|
8
|
+
/**
|
|
9
|
+
* A resposta não corresponde ao contrato declarado.
|
|
10
|
+
*
|
|
11
|
+
* Classe `invalid` porque retentar não resolve: o formato não muda entre
|
|
12
|
+
* tentativas. `providerCode` é SEMPRE `PROTOCOL_CONTRACT_MISMATCH` — um código
|
|
13
|
+
* único é o que permite ao painel perguntar "o contrato quebrou?" com uma
|
|
14
|
+
* comparação de igualdade. O detalhe fica em `reason`, que é enumerado e não
|
|
15
|
+
* carrega um byte do corpo recebido: um corpo hostil não escreve na nossa trilha.
|
|
16
|
+
*/
|
|
17
|
+
class AdnContractMismatchError extends provider_js_1.FiscalProviderError {
|
|
18
|
+
reason;
|
|
19
|
+
profileId;
|
|
20
|
+
constructor(reason, profileId) {
|
|
21
|
+
super('invalid', `resposta do ADN não corresponde ao perfil ${profileId} (${reason})`, 'PROTOCOL_CONTRACT_MISMATCH');
|
|
22
|
+
this.reason = reason;
|
|
23
|
+
this.profileId = profileId;
|
|
24
|
+
this.name = 'AdnContractMismatchError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.AdnContractMismatchError = AdnContractMismatchError;
|
|
28
|
+
/** Base64 canônico. `Buffer.from(x,'base64')` ignora lixo em silêncio — este não. */
|
|
29
|
+
const BASE64 = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
30
|
+
/** Assinatura do gzip (RFC 1952 §2.3.1): `1f 8b`. Dois bytes, sem ambiguidade. */
|
|
31
|
+
const GZIP_MAGIC = [0x1f, 0x8b];
|
|
32
|
+
/**
|
|
33
|
+
* Lê o envelope. Devolve lote (possivelmente vazio e RECONHECIDO), ou lança.
|
|
34
|
+
*
|
|
35
|
+
* Nunca devolve `documents: []` para uma resposta que não entendeu. Essa é a
|
|
36
|
+
* invariante, e o teste de mutação da Fase 3 a exercita reintroduzindo o
|
|
37
|
+
* comportamento antigo e exigindo que a suíte fique vermelha.
|
|
38
|
+
*/
|
|
39
|
+
function readAdnEnvelope(body, options) {
|
|
40
|
+
const { profile, fromNsu } = options;
|
|
41
|
+
const maxBytes = options.maxResponseBytes ?? nfse_adn_contract_js_1.NFSE_ADN_LIMITS.maxResponseBytes.value;
|
|
42
|
+
const maxDoc = options.maxDecompressedBytesPerDocument ??
|
|
43
|
+
nfse_adn_contract_js_1.NFSE_ADN_LIMITS.maxDecompressedBytesPerDocument.value;
|
|
44
|
+
const maxLote = options.maxDecompressedBytesPerBatch ?? nfse_adn_contract_js_1.NFSE_ADN_LIMITS.maxDecompressedBytesPerBatch.value;
|
|
45
|
+
const maxItens = options.maxDocumentsPerBatch ?? nfse_adn_contract_js_1.NFSE_ADN_LIMITS.maxDocumentsPerBatch.value;
|
|
46
|
+
// A anotação de tipo explícita não é decoração: sem ela o TypeScript não
|
|
47
|
+
// propaga o `never` de uma arrow function, e todo `if (...) recusa(...)`
|
|
48
|
+
// deixaria de estreitar o tipo depois — obrigando a um `return` ou a um `!`
|
|
49
|
+
// em cada ponto, que é exatamente onde um dia alguém erra.
|
|
50
|
+
const recusa = (r) => {
|
|
51
|
+
throw new AdnContractMismatchError(r, profile.id);
|
|
52
|
+
};
|
|
53
|
+
if (body.byteLength > maxBytes)
|
|
54
|
+
recusa('RESPONSE_TOO_LARGE');
|
|
55
|
+
if (body.byteLength === 0)
|
|
56
|
+
recusa('BODY_EMPTY');
|
|
57
|
+
const texto = Buffer.from(body).toString('utf8').trim();
|
|
58
|
+
// Página de erro de proxy, portal de captura, HTML de WAF. Todos começam com
|
|
59
|
+
// `<`, e todos seriam "JSON inválido" — um diagnóstico que manda a pessoa
|
|
60
|
+
// olhar o lugar errado. Nomear o caso aponta para a rede, não para o parser.
|
|
61
|
+
if (texto.startsWith('<'))
|
|
62
|
+
recusa('MARKUP_INSTEAD_OF_JSON');
|
|
63
|
+
let json;
|
|
64
|
+
try {
|
|
65
|
+
json = JSON.parse(texto);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
recusa('NOT_JSON');
|
|
69
|
+
}
|
|
70
|
+
if (json === null || typeof json !== 'object' || Array.isArray(json))
|
|
71
|
+
recusa('NOT_OBJECT');
|
|
72
|
+
const raiz = json;
|
|
73
|
+
// ── Rejeição RECONHECIDA ────────────────────────────────────────────────
|
|
74
|
+
//
|
|
75
|
+
// Antes de exigir o lote: uma rejeição legítima do ADN não traz lote nenhum,
|
|
76
|
+
// e cobrá-lo dela transformaria "seu cliente não teve nota" em "o contrato
|
|
77
|
+
// quebrou" — o alarme mais caro que este produto poderia dar.
|
|
78
|
+
const codigo = leiaCodigo(raiz[profile.codeField]);
|
|
79
|
+
if (codigo) {
|
|
80
|
+
const oficial = nfse_adn_contract_js_1.NFSE_ADN_OFFICIAL_CODES[codigo];
|
|
81
|
+
if (oficial?.outcome === 'no_documents') {
|
|
82
|
+
return {
|
|
83
|
+
documents: [],
|
|
84
|
+
// A posição de quem não achou nada é a de onde partiu. Ver o comentário
|
|
85
|
+
// de `fromNsu` acima: `null` aqui faria a próxima execução recomeçar.
|
|
86
|
+
lastNsu: fromNsu,
|
|
87
|
+
maxNsu: null,
|
|
88
|
+
// Esgotado: o Manual dos Municípios §1.4.2.b manda esperar uma hora
|
|
89
|
+
// "caso receba a indicação que não existem mais documentos".
|
|
90
|
+
exhausted: true,
|
|
91
|
+
providerStatus: codigo,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
if (oficial) {
|
|
95
|
+
throw new provider_js_1.FiscalProviderError(oficial.errorClass ?? 'unknown', `ADN recusou: ${oficial.meaning}`, codigo);
|
|
96
|
+
}
|
|
97
|
+
// Código do ADN que não está no nosso mapa. NÃO é lote vazio, e NÃO é
|
|
98
|
+
// `invalid`: o governo pode ter acrescentado um código sem mudar o
|
|
99
|
+
// envelope. `unknown` é tratado como transitório com teto pelo motor —
|
|
100
|
+
// errar para "tente de novo com espera" custa latência; errar para "está
|
|
101
|
+
// tudo bem, zero documentos" custa uma fiscalização.
|
|
102
|
+
throw new provider_js_1.FiscalProviderError('unknown', 'ADN devolveu código não catalogado', codigo);
|
|
103
|
+
}
|
|
104
|
+
// ── Lote ────────────────────────────────────────────────────────────────
|
|
105
|
+
if (!(profile.batchField in raiz))
|
|
106
|
+
recusa('BATCH_FIELD_MISSING');
|
|
107
|
+
const lote = raiz[profile.batchField];
|
|
108
|
+
if (!Array.isArray(lote))
|
|
109
|
+
recusa('BATCH_NOT_ARRAY');
|
|
110
|
+
const itens = lote;
|
|
111
|
+
// O teto de 50 é oficial. Um lote maior significa que estamos falando com
|
|
112
|
+
// algo que não é o ADN — ou que o contrato mudou. Nos dois casos, parar.
|
|
113
|
+
if (itens.length > maxItens)
|
|
114
|
+
recusa('BATCH_OVER_OFFICIAL_LIMIT');
|
|
115
|
+
const documents = [];
|
|
116
|
+
let descompactadoNoLote = 0;
|
|
117
|
+
for (const item of itens) {
|
|
118
|
+
if (item === null || typeof item !== 'object' || Array.isArray(item))
|
|
119
|
+
recusa('ITEM_NOT_OBJECT');
|
|
120
|
+
const linha = item;
|
|
121
|
+
const nsu = leiaNsu(linha[profile.itemNsuField]);
|
|
122
|
+
if (nsu === null)
|
|
123
|
+
recusa('ITEM_NSU_INVALID');
|
|
124
|
+
const conteudo = linha[profile.itemContentField];
|
|
125
|
+
if (typeof conteudo !== 'string' || conteudo.length === 0)
|
|
126
|
+
recusa('ITEM_CONTENT_MISSING');
|
|
127
|
+
if (!BASE64.test(conteudo))
|
|
128
|
+
recusa('ITEM_CONTENT_NOT_BASE64');
|
|
129
|
+
const bytes = Buffer.from(conteudo, 'base64');
|
|
130
|
+
let raw;
|
|
131
|
+
if (profile.contentEncoding === 'gzip+base64') {
|
|
132
|
+
// A verificação da assinatura vem ANTES da descompressão, e substitui o
|
|
133
|
+
// `try/catch` que virava fallback. Sem ela, "não é gzip" e "é gzip
|
|
134
|
+
// corrompido" chegam pelo mesmo caminho — e o antigo `catch` respondia
|
|
135
|
+
// aos dois tratando os bytes como XML.
|
|
136
|
+
if (bytes.length < 2 || bytes[0] !== GZIP_MAGIC[0] || bytes[1] !== GZIP_MAGIC[1]) {
|
|
137
|
+
recusa('ITEM_CONTENT_NOT_GZIP');
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
// `maxOutputLength` é a defesa contra bomba de descompressão: o zlib
|
|
141
|
+
// aborta ao ultrapassar, em vez de alocar até o processo morrer.
|
|
142
|
+
raw = new Uint8Array((0, node_zlib_1.gunzipSync)(bytes, { maxOutputLength: maxDoc }));
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
// O zlib distingue os dois casos, e a distinção importa: "grande demais"
|
|
146
|
+
// é possivelmente hostil e "corrompido" é possivelmente rede.
|
|
147
|
+
const code = err?.code;
|
|
148
|
+
if (code === 'ERR_BUFFER_TOO_LARGE')
|
|
149
|
+
recusa('ITEM_CONTENT_TOO_LARGE');
|
|
150
|
+
recusa('ITEM_CONTENT_DECOMPRESSION_FAILED');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
if (bytes.length > maxDoc)
|
|
155
|
+
recusa('ITEM_CONTENT_TOO_LARGE');
|
|
156
|
+
raw = new Uint8Array(bytes);
|
|
157
|
+
}
|
|
158
|
+
descompactadoNoLote += raw.byteLength;
|
|
159
|
+
// O teto do LOTE existe porque o produto dos tetos individuais não é um
|
|
160
|
+
// teto: 50 documentos de 8 MiB seriam 400 MiB perfeitamente "válidos".
|
|
161
|
+
if (descompactadoNoLote > maxLote)
|
|
162
|
+
recusa('BATCH_DECOMPRESSED_TOO_LARGE');
|
|
163
|
+
documents.push({ nsu, raw, mimeType: 'application/xml' });
|
|
164
|
+
}
|
|
165
|
+
const ultimo = leiaPosicao(raiz, profile.lastNsuField, recusa);
|
|
166
|
+
const maximo = leiaPosicao(raiz, profile.maxNsuField, recusa);
|
|
167
|
+
// Sem `ultNSU` declarado, a posição é a do último item — e, se nem item houve,
|
|
168
|
+
// é de onde partimos. Jamais `null`: ver o comentário de `fromNsu`.
|
|
169
|
+
const lastNsu = ultimo ?? documents.at(-1)?.nsu ?? fromNsu;
|
|
170
|
+
return {
|
|
171
|
+
documents,
|
|
172
|
+
lastNsu,
|
|
173
|
+
maxNsu: maximo,
|
|
174
|
+
// Esgotado é o servidor DECLARANDO que a posição alcançou o máximo
|
|
175
|
+
// (Manual dos Municípios §1.4.2.b: "Se o NSU informado (ultNSU) for igual ao
|
|
176
|
+
// maior NSU do Ambiente Nacional (maxNSU), então não existem mais
|
|
177
|
+
// documentos"). Nunca por lote vazio: um lote vazio no meio da faixa não
|
|
178
|
+
// autoriza a espera de uma hora, e tratá-lo assim atrasaria o cliente à toa.
|
|
179
|
+
exhausted: lastNsu !== null && maximo !== null && lastNsu === maximo,
|
|
180
|
+
providerStatus: null,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* NSU como o contrato o define: dígitos, sem sinal, sem separador.
|
|
185
|
+
*
|
|
186
|
+
* Número JSON é aceito e normalizado para texto — o ADN pode enviá-lo como
|
|
187
|
+
* número, e recusá-lo seria rigor sem propósito. O que não é aceito é qualquer
|
|
188
|
+
* coisa que não seja uma posição: `null`, negativo, decimal, texto com letra.
|
|
189
|
+
* Um NSU que não é posição não pode governar cursor.
|
|
190
|
+
*/
|
|
191
|
+
function leiaNsu(v) {
|
|
192
|
+
if (typeof v === 'number') {
|
|
193
|
+
return Number.isSafeInteger(v) && v >= 0 ? String(v) : null;
|
|
194
|
+
}
|
|
195
|
+
if (typeof v === 'string' && /^\d{1,20}$/.test(v))
|
|
196
|
+
return v;
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
/** `ultNSU`/`maxNSU`: ausente é legítimo; presente e inválido, não. */
|
|
200
|
+
function leiaPosicao(raiz, campo, recusa) {
|
|
201
|
+
if (!(campo in raiz))
|
|
202
|
+
return null;
|
|
203
|
+
const bruto = raiz[campo];
|
|
204
|
+
if (bruto === null || bruto === undefined)
|
|
205
|
+
return null;
|
|
206
|
+
const nsu = leiaNsu(bruto);
|
|
207
|
+
// Presente e ilegível é diferente de ausente: o primeiro é contrato quebrado,
|
|
208
|
+
// o segundo é campo opcional. Tratá-los igual perderia a quebra.
|
|
209
|
+
if (nsu === null)
|
|
210
|
+
recusa('NSU_POSITION_INVALID');
|
|
211
|
+
return nsu;
|
|
212
|
+
}
|
|
213
|
+
/** O código do ADN, quando a resposta é uma rejeição. `E` seguido de dígitos. */
|
|
214
|
+
function leiaCodigo(v) {
|
|
215
|
+
if (typeof v !== 'string')
|
|
216
|
+
return null;
|
|
217
|
+
const t = v.trim().toUpperCase();
|
|
218
|
+
return /^E\d{4}$/.test(t) ? t : null;
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=nfse-adn-envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nfse-adn-envelope.js","sourceRoot":"","sources":["../../../../src/fiscal/contracts/nfse-adn-envelope.ts"],"names":[],"mappings":";;;AAuHA,0CAuJC;AA9QD,yCAAuC;AACvC,0DAIkC;AAClC,iEAIgC;AAyDhC;;;;;;;;GAQG;AACH,MAAa,wBAAyB,SAAQ,iCAAmB;IAEpD;IACA;IAFX,YACW,MAAyB,EACzB,SAAiB;QAE1B,KAAK,CACH,SAAS,EACT,6CAA6C,SAAS,KAAK,MAAM,GAAG,EACpE,4BAA4B,CAC7B,CAAC;QAPO,WAAM,GAAN,MAAM,CAAmB;QACzB,cAAS,GAAT,SAAS,CAAQ;QAO1B,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AAZD,4DAYC;AAmBD,qFAAqF;AACrF,MAAM,MAAM,GAAG,wBAAwB,CAAC;AACxC,kFAAkF;AAClF,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,IAAI,CAAU,CAAC;AAEzC;;;;;;GAMG;AACH,SAAgB,eAAe,CAC7B,IAAgB,EAChB,OAA+B;IAE/B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,IAAI,sCAAe,CAAC,gBAAgB,CAAC,KAAK,CAAC;IACpF,MAAM,MAAM,GACV,OAAO,CAAC,+BAA+B;QACvC,sCAAe,CAAC,+BAA+B,CAAC,KAAK,CAAC;IACxD,MAAM,OAAO,GACX,OAAO,CAAC,4BAA4B,IAAI,sCAAe,CAAC,4BAA4B,CAAC,KAAK,CAAC;IAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,oBAAoB,IAAI,sCAAe,CAAC,oBAAoB,CAAC,KAAK,CAAC;IAC5F,yEAAyE;IACzE,yEAAyE;IACzE,4EAA4E;IAC5E,2DAA2D;IAC3D,MAAM,MAAM,GAAoC,CAAC,CAAC,EAAE,EAAE;QACpD,MAAM,IAAI,wBAAwB,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC;IAEF,IAAI,IAAI,CAAC,UAAU,GAAG,QAAQ;QAAE,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC7D,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC;QAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IAEhD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACxD,6EAA6E;IAC7E,0EAA0E;IAC1E,6EAA6E;IAC7E,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,MAAM,CAAC,wBAAwB,CAAC,CAAC;IAE5D,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,UAAU,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IAC3F,MAAM,IAAI,GAAG,IAA+B,CAAC;IAE7C,2EAA2E;IAC3E,EAAE;IACF,6EAA6E;IAC7E,2EAA2E;IAC3E,8DAA8D;IAC9D,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IACnD,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,8CAAuB,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,OAAO,EAAE,OAAO,KAAK,cAAc,EAAE,CAAC;YACxC,OAAO;gBACL,SAAS,EAAE,EAAE;gBACb,wEAAwE;gBACxE,sEAAsE;gBACtE,OAAO,EAAE,OAAO;gBAChB,MAAM,EAAE,IAAI;gBACZ,oEAAoE;gBACpE,6DAA6D;gBAC7D,SAAS,EAAE,IAAI;gBACf,cAAc,EAAE,MAAM;aACvB,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,iCAAmB,CAC3B,OAAO,CAAC,UAAU,IAAI,SAAS,EAC/B,gBAAgB,OAAO,CAAC,OAAO,EAAE,EACjC,MAAM,CACP,CAAC;QACJ,CAAC;QACD,sEAAsE;QACtE,mEAAmE;QACnE,uEAAuE;QACvE,yEAAyE;QACzE,qDAAqD;QACrD,MAAM,IAAI,iCAAmB,CAAC,SAAS,EAAE,oCAAoC,EAAE,MAAM,CAAC,CAAC;IACzF,CAAC;IAED,2EAA2E;IAC3E,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC;QAAE,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,IAAiB,CAAC;IAChC,0EAA0E;IAC1E,yEAAyE;IACzE,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ;QAAE,MAAM,CAAC,2BAA2B,CAAC,CAAC;IAEjE,MAAM,SAAS,GAAwB,EAAE,CAAC;IAC1C,IAAI,mBAAmB,GAAG,CAAC,CAAC;IAE5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAChG,MAAM,KAAK,GAAG,IAA+B,CAAC;QAE9C,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;QACjD,IAAI,GAAG,KAAK,IAAI;YAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAE7C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACjD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC1F,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,MAAM,CAAC,yBAAyB,CAAC,CAAC;QAE9D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC9C,IAAI,GAAe,CAAC;QAEpB,IAAI,OAAO,CAAC,eAAe,KAAK,aAAa,EAAE,CAAC;YAC9C,wEAAwE;YACxE,mEAAmE;YACnE,uEAAuE;YACvE,uCAAuC;YACvC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjF,MAAM,CAAC,uBAAuB,CAAC,CAAC;YAClC,CAAC;YACD,IAAI,CAAC;gBACH,qEAAqE;gBACrE,iEAAiE;gBACjE,GAAG,GAAG,IAAI,UAAU,CAAC,IAAA,sBAAU,EAAC,KAAK,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YACvE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,yEAAyE;gBACzE,8DAA8D;gBAC9D,MAAM,IAAI,GAAI,GAAiC,EAAE,IAAI,CAAC;gBACtD,IAAI,IAAI,KAAK,sBAAsB;oBAAE,MAAM,CAAC,wBAAwB,CAAC,CAAC;gBACtE,MAAM,CAAC,mCAAmC,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM;gBAAE,MAAM,CAAC,wBAAwB,CAAC,CAAC;YAC5D,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QAED,mBAAmB,IAAI,GAAG,CAAC,UAAU,CAAC;QACtC,wEAAwE;QACxE,uEAAuE;QACvE,IAAI,mBAAmB,GAAG,OAAO;YAAE,MAAM,CAAC,8BAA8B,CAAC,CAAC;QAE1E,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAE9D,+EAA+E;IAC/E,oEAAoE;IACpE,MAAM,OAAO,GAAG,MAAM,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,OAAO,CAAC;IAE3D,OAAO;QACL,SAAS;QACT,OAAO;QACP,MAAM,EAAE,MAAM;QACd,mEAAmE;QACnE,6EAA6E;QAC7E,kEAAkE;QAClE,yEAAyE;QACzE,6EAA6E;QAC7E,SAAS,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,KAAK,MAAM;QACpE,cAAc,EAAE,IAAI;KACrB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,OAAO,CAAC,CAAU;IACzB,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,uEAAuE;AACvE,SAAS,WAAW,CAClB,IAA6B,EAC7B,KAAa,EACb,MAAuC;IAEvC,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACvD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3B,8EAA8E;IAC9E,iEAAiE;IACjE,IAAI,GAAG,KAAK,IAAI;QAAE,MAAM,CAAC,sBAAsB,CAAC,CAAC;IACjD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iFAAiF;AACjF,SAAS,UAAU,CAAC,CAAU;IAC5B,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unknownCoverage = unknownCoverage;
|
|
4
|
+
exports.resolveFiscalCoverage = resolveFiscalCoverage;
|
|
5
|
+
exports.coverageForClient = coverageForClient;
|
|
6
|
+
exports.listFiscalCoverage = listFiscalCoverage;
|
|
7
|
+
exports.assumesUniversalNfseCoverage = assumesUniversalNfseCoverage;
|
|
8
|
+
const repository_js_1 = require("../repository.js");
|
|
9
|
+
/** A resposta quando nem a linha padrão existe. Desconhecida, nunca coberta. */
|
|
10
|
+
function unknownCoverage(documentType, scope, code) {
|
|
11
|
+
return {
|
|
12
|
+
id: 'unknown',
|
|
13
|
+
documentType,
|
|
14
|
+
jurisdictionScope: scope,
|
|
15
|
+
jurisdictionCode: code,
|
|
16
|
+
provider: 'desconhecido',
|
|
17
|
+
coverageStatus: 'UNKNOWN',
|
|
18
|
+
automationMethod: null,
|
|
19
|
+
credentialRequirement: 'unknown',
|
|
20
|
+
environments: [],
|
|
21
|
+
fallbackType: 'manual_upload',
|
|
22
|
+
officialApiAvailable: 'unknown',
|
|
23
|
+
connectorImplemented: false,
|
|
24
|
+
protocolVerified: false,
|
|
25
|
+
supportedOperations: [],
|
|
26
|
+
lastVerifiedAt: null,
|
|
27
|
+
sourceReference: null,
|
|
28
|
+
notes: 'Nenhuma linha de cobertura para esta combinação. Ninguém mediu.',
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const map = (r) => ({
|
|
32
|
+
id: r.id,
|
|
33
|
+
documentType: r.document_type,
|
|
34
|
+
jurisdictionScope: r.jurisdiction_scope,
|
|
35
|
+
jurisdictionCode: r.jurisdiction_code,
|
|
36
|
+
provider: r.provider,
|
|
37
|
+
coverageStatus: r.coverage_status,
|
|
38
|
+
automationMethod: r.automation_method,
|
|
39
|
+
credentialRequirement: r.credential_requirement,
|
|
40
|
+
environments: r.environments ?? [],
|
|
41
|
+
fallbackType: r.fallback_type,
|
|
42
|
+
officialApiAvailable: r.official_api_available ?? 'unknown',
|
|
43
|
+
connectorImplemented: r.connector_implemented ?? false,
|
|
44
|
+
protocolVerified: r.protocol_verified ?? false,
|
|
45
|
+
supportedOperations: r.supported_operations ?? [],
|
|
46
|
+
lastVerifiedAt: r.last_verified_at ? r.last_verified_at.toISOString().slice(0, 10) : null,
|
|
47
|
+
sourceReference: r.source_reference,
|
|
48
|
+
notes: r.notes,
|
|
49
|
+
});
|
|
50
|
+
const COLUMNS = `id, document_type, jurisdiction_scope, jurisdiction_code, provider,
|
|
51
|
+
coverage_status, automation_method, credential_requirement, environments,
|
|
52
|
+
fallback_type, official_api_available, connector_implemented,
|
|
53
|
+
protocol_verified, supported_operations,
|
|
54
|
+
last_verified_at, source_reference, notes`;
|
|
55
|
+
/**
|
|
56
|
+
* Resolve a cobertura de uma pergunta específica.
|
|
57
|
+
*
|
|
58
|
+
* Duas etapas, e a segunda NUNCA sobe de escopo: a linha exata do código, e
|
|
59
|
+
* depois a linha padrão do MESMO escopo. Não há terceira etapa.
|
|
60
|
+
*/
|
|
61
|
+
async function resolveFiscalCoverage(tx, input) {
|
|
62
|
+
const code = input.jurisdictionCode ?? null;
|
|
63
|
+
if (code) {
|
|
64
|
+
const exact = await tx `
|
|
65
|
+
SELECT ${tx.unsafe(COLUMNS)} FROM fiscal_coverage
|
|
66
|
+
WHERE document_type = ${input.documentType}
|
|
67
|
+
AND jurisdiction_scope = ${input.jurisdictionScope}
|
|
68
|
+
AND jurisdiction_code = ${code}
|
|
69
|
+
LIMIT 1
|
|
70
|
+
`;
|
|
71
|
+
if (exact[0])
|
|
72
|
+
return map(exact[0]);
|
|
73
|
+
}
|
|
74
|
+
const fallback = await tx `
|
|
75
|
+
SELECT ${tx.unsafe(COLUMNS)} FROM fiscal_coverage
|
|
76
|
+
WHERE document_type = ${input.documentType}
|
|
77
|
+
AND jurisdiction_scope = ${input.jurisdictionScope}
|
|
78
|
+
AND jurisdiction_code IS NULL
|
|
79
|
+
LIMIT 1
|
|
80
|
+
`;
|
|
81
|
+
if (fallback[0])
|
|
82
|
+
return { ...map(fallback[0]), jurisdictionCode: code };
|
|
83
|
+
return unknownCoverage(input.documentType, input.jurisdictionScope, code);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A cobertura que vale para um CLIENTE — a pergunta que a tela realmente faz.
|
|
87
|
+
*
|
|
88
|
+
* NFS-e é municipal por natureza: quem recolhe ISS é a prefeitura. Por isso a
|
|
89
|
+
* pergunta pelo cliente vai ao escopo municipal, e é ali que ela encontra
|
|
90
|
+
* `UNKNOWN` enquanto ninguém tiver medido a adesão daquele município. NF-e e
|
|
91
|
+
* CT-e são de distribuição nacional, e a pergunta é nacional.
|
|
92
|
+
*/
|
|
93
|
+
async function coverageForClient(tx, input) {
|
|
94
|
+
const jurisdiction = await (0, repository_js_1.loadClientJurisdiction)(tx, input.clientId);
|
|
95
|
+
if (input.documentType === 'nfse') {
|
|
96
|
+
const coverage = await resolveFiscalCoverage(tx, {
|
|
97
|
+
documentType: 'nfse',
|
|
98
|
+
jurisdictionScope: 'municipal',
|
|
99
|
+
jurisdictionCode: jurisdiction.cityIbge,
|
|
100
|
+
});
|
|
101
|
+
// Sem o IBGE do cliente não dá para nem PERGUNTAR pelo município certo. É um
|
|
102
|
+
// dado que falta, e dizer isso é diferente de dizer que não há cobertura.
|
|
103
|
+
return { ...coverage, jurisdictionKnown: jurisdiction.cityIbge !== null };
|
|
104
|
+
}
|
|
105
|
+
const coverage = await resolveFiscalCoverage(tx, {
|
|
106
|
+
documentType: input.documentType,
|
|
107
|
+
jurisdictionScope: 'national',
|
|
108
|
+
jurisdictionCode: null,
|
|
109
|
+
});
|
|
110
|
+
return { ...coverage, jurisdictionKnown: true };
|
|
111
|
+
}
|
|
112
|
+
/** O catálogo inteiro, para a tela de cobertura. */
|
|
113
|
+
async function listFiscalCoverage(tx) {
|
|
114
|
+
const rows = await tx `
|
|
115
|
+
SELECT ${tx.unsafe(COLUMNS)} FROM fiscal_coverage
|
|
116
|
+
ORDER BY document_type, jurisdiction_scope, jurisdiction_code NULLS FIRST
|
|
117
|
+
`;
|
|
118
|
+
return rows.map(map);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Existe alguma afirmação de cobertura NACIONAL para NFS-e municipal?
|
|
122
|
+
*
|
|
123
|
+
* A pergunta parece estranha e é o oráculo de `UNIVERSAL_NFSE_COVERAGE_ASSUMED`:
|
|
124
|
+
* o modelo passa se, e somente se, uma pergunta municipal sem medição não
|
|
125
|
+
* devolver "coberto". Um teste que só verificasse a linha nacional passaria com
|
|
126
|
+
* o defeito presente.
|
|
127
|
+
*/
|
|
128
|
+
async function assumesUniversalNfseCoverage(tx) {
|
|
129
|
+
const resolved = await resolveFiscalCoverage(tx, {
|
|
130
|
+
documentType: 'nfse',
|
|
131
|
+
jurisdictionScope: 'municipal',
|
|
132
|
+
// Um IBGE que ninguém mediu. É o caso da esmagadora maioria dos 5.570.
|
|
133
|
+
jurisdictionCode: '9999999',
|
|
134
|
+
});
|
|
135
|
+
return resolved.coverageStatus !== 'UNKNOWN';
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../src/fiscal/coverage/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assessRequestCoverage = assessRequestCoverage;
|
|
4
|
+
exports.listRequestCoverage = listRequestCoverage;
|
|
5
|
+
/**
|
|
6
|
+
* Classifica a cobertura da solicitação de uma competência.
|
|
7
|
+
*
|
|
8
|
+
* `FULLY_COVERED_BY_AUTOMATION` exige as DUAS condições, e não uma:
|
|
9
|
+
* cobertura oficial declarada para a jurisdição E documentos de entrada e saída
|
|
10
|
+
* presentes. Com só uma delas, o máximo é `PARTIALLY_COVERED` — porque só uma
|
|
11
|
+
* delas é, literalmente, cobertura parcial.
|
|
12
|
+
*/
|
|
13
|
+
async function assessRequestCoverage(tx, input) {
|
|
14
|
+
const documentType = input.documentType ?? 'nfse';
|
|
15
|
+
const [doc] = await tx `
|
|
16
|
+
SELECT count(*)::int AS total,
|
|
17
|
+
coalesce(array_agg(DISTINCT direction), '{}') AS direcoes
|
|
18
|
+
FROM fiscal_document
|
|
19
|
+
WHERE client_id = ${input.clientId}
|
|
20
|
+
AND competence_label = ${input.competenceLabel}
|
|
21
|
+
AND source <> 'manual'
|
|
22
|
+
`;
|
|
23
|
+
const [cov] = await tx `
|
|
24
|
+
SELECT fc.coverage_status
|
|
25
|
+
FROM client c
|
|
26
|
+
LEFT JOIN fiscal_coverage fc
|
|
27
|
+
ON fc.document_type = ${documentType}
|
|
28
|
+
AND fc.jurisdiction_scope = ${documentType === 'nfse' ? 'municipal' : 'national'}
|
|
29
|
+
AND (fc.jurisdiction_code = c.municipality_ibge_code OR fc.jurisdiction_code IS NULL)
|
|
30
|
+
WHERE c.id = ${input.clientId}
|
|
31
|
+
ORDER BY fc.jurisdiction_code NULLS LAST
|
|
32
|
+
LIMIT 1
|
|
33
|
+
`;
|
|
34
|
+
const coverageStatus = cov?.coverage_status ?? 'UNKNOWN';
|
|
35
|
+
const total = doc?.total ?? 0;
|
|
36
|
+
const direcoes = doc?.direcoes ?? [];
|
|
37
|
+
const oficial = coverageStatus === 'SUPPORTED_OFFICIAL' || coverageStatus === 'SUPPORTED_PROVIDER';
|
|
38
|
+
const temEntradaESaida = direcoes.includes('received') && direcoes.includes('issued');
|
|
39
|
+
const level = total === 0
|
|
40
|
+
? 'NOT_COVERED'
|
|
41
|
+
: oficial && temEntradaESaida
|
|
42
|
+
? 'FULLY_COVERED_BY_AUTOMATION'
|
|
43
|
+
: 'PARTIALLY_COVERED';
|
|
44
|
+
return {
|
|
45
|
+
clientId: input.clientId,
|
|
46
|
+
competenceLabel: input.competenceLabel,
|
|
47
|
+
level,
|
|
48
|
+
automaticDocuments: total,
|
|
49
|
+
directions: direcoes,
|
|
50
|
+
coverageStatus,
|
|
51
|
+
autoClosed: false,
|
|
52
|
+
detail: level === 'NOT_COVERED'
|
|
53
|
+
? 'Nenhum documento coletado automaticamente nesta competência.'
|
|
54
|
+
: level === 'FULLY_COVERED_BY_AUTOMATION'
|
|
55
|
+
? `${total} documentos coletados, com entrada e saída, em jurisdição com cobertura oficial.`
|
|
56
|
+
: oficial
|
|
57
|
+
? `${total} documentos coletados, mas falta ${direcoes.includes('issued') ? 'documento de entrada' : 'documento de saída'}.`
|
|
58
|
+
: `${total} documentos coletados, porém a cobertura desta jurisdição é ${coverageStatus}.`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* As solicitações de "Documentos fiscais do mês" com sua classificação.
|
|
63
|
+
*
|
|
64
|
+
* Leitura pura. Nenhuma linha de `recurring_instance` é tocada — e um teste
|
|
65
|
+
* confere isso comparando o `updated_at` das solicitações antes e depois, porque
|
|
66
|
+
* "eu não escrevi nada" é uma afirmação que precisa de oráculo.
|
|
67
|
+
*/
|
|
68
|
+
async function listRequestCoverage(tx, input = {}) {
|
|
69
|
+
const limit = Math.min(Math.max(input.limit ?? 100, 1), 500);
|
|
70
|
+
const rows = await tx `
|
|
71
|
+
SELECT ri.id AS request_id, ri.client_id, c.display_name AS client_name,
|
|
72
|
+
ri.status, ri.due_date, comp.label AS competence_label
|
|
73
|
+
FROM recurring_instance ri
|
|
74
|
+
JOIN recurring_item_type rit ON rit.id = ri.item_type_id
|
|
75
|
+
JOIN competence comp ON comp.id = ri.competence_id
|
|
76
|
+
JOIN client c ON c.id = ri.client_id
|
|
77
|
+
WHERE rit.key = 'docs_fiscais_mes'
|
|
78
|
+
AND ri.deleted_at IS NULL
|
|
79
|
+
AND ${input.competenceLabel ? tx `comp.label = ${input.competenceLabel}` : tx `true`}
|
|
80
|
+
ORDER BY comp.label DESC, c.display_name
|
|
81
|
+
LIMIT ${limit}
|
|
82
|
+
`;
|
|
83
|
+
const out = [];
|
|
84
|
+
for (const r of rows) {
|
|
85
|
+
const assessment = await assessRequestCoverage(tx, {
|
|
86
|
+
clientId: r.client_id,
|
|
87
|
+
competenceLabel: r.competence_label,
|
|
88
|
+
});
|
|
89
|
+
out.push({
|
|
90
|
+
...assessment,
|
|
91
|
+
requestId: r.request_id,
|
|
92
|
+
clientName: r.client_name,
|
|
93
|
+
status: r.status,
|
|
94
|
+
dueDate: r.due_date ? r.due_date.toISOString().slice(0, 10) : null,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=requests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requests.js","sourceRoot":"","sources":["../../../../src/fiscal/coverage/requests.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.inspectPkcs12 = inspectPkcs12;
|
|
4
|
+
exports.matchIdentity = matchIdentity;
|
|
5
|
+
const node_tls_1 = require("node:tls");
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
7
|
+
/**
|
|
8
|
+
* OID 2.16.76.1.3.3 — o CNPJ da pessoa jurídica no `otherName` do
|
|
9
|
+
* `subjectAltName`, na forma que a ICP-Brasil padronizou (DOC-ICP-04).
|
|
10
|
+
*
|
|
11
|
+
* Em DER: tag `06`, comprimento `05`, e os componentes `2.16` colapsados em
|
|
12
|
+
* `0x60`. Procurar a sequência de bytes é mais confiável que ler
|
|
13
|
+
* `x509.subjectAltName`, que em várias versões do Node devolve `undefined` ou
|
|
14
|
+
* `othername:<unsupported>` justamente para os `otherName` do ICP-Brasil.
|
|
15
|
+
*/
|
|
16
|
+
const OID_CNPJ_ICP_BRASIL = Buffer.from([0x06, 0x05, 0x60, 0x4c, 0x01, 0x03, 0x03]);
|
|
17
|
+
/** Janela de busca depois do OID: o valor vem logo em seguida, dentro do mesmo `otherName`. */
|
|
18
|
+
const OID_VALUE_WINDOW = 48;
|
|
19
|
+
/**
|
|
20
|
+
* Inspeciona o material, sem rede e sem disco.
|
|
21
|
+
*
|
|
22
|
+
* NUNCA lança: toda falha vira uma classe. Quem chama é uma rota de upload, e
|
|
23
|
+
* uma exceção com texto de OpenSSL atravessando até o handler é exatamente como
|
|
24
|
+
* o sujeito de um certificado acaba num log.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Inspeciona o material, sem rede e sem disco.
|
|
28
|
+
*
|
|
29
|
+
* NUNCA lança: toda falha vira uma classe. Quem chama é uma rota de upload, e
|
|
30
|
+
* uma exceção com texto de OpenSSL atravessando até o handler é exatamente como
|
|
31
|
+
* o sujeito de um certificado acaba num log.
|
|
32
|
+
*
|
|
33
|
+
* `async` sem `await` é deliberado: o contrato é assíncrono porque a primeira
|
|
34
|
+
* implementação precisava de um handshake, e porque uma leitura de material
|
|
35
|
+
* criptográfico é o tipo de operação que pode voltar a precisar. Mudar a
|
|
36
|
+
* assinatura para síncrona obrigaria todo chamador a mudar junto, por nenhum
|
|
37
|
+
* ganho.
|
|
38
|
+
*/
|
|
39
|
+
async function inspectPkcs12(pfx, passphrase) {
|
|
40
|
+
if (pfx.byteLength === 0)
|
|
41
|
+
return { status: 'failed', reason: 'malformed_material' };
|
|
42
|
+
// Primeiro portão: o contexto abre? Isto é a checagem de senha, e ela lança
|
|
43
|
+
// aqui — antes de existir qualquer outra coisa.
|
|
44
|
+
let context;
|
|
45
|
+
try {
|
|
46
|
+
context = (0, node_tls_1.createSecureContext)({ pfx, passphrase, minVersion: 'TLSv1.2' });
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
return { status: 'failed', reason: classify(err) };
|
|
50
|
+
}
|
|
51
|
+
let der;
|
|
52
|
+
try {
|
|
53
|
+
der = certificateDerFrom(context);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
return { status: 'failed', reason: classify(err) };
|
|
57
|
+
}
|
|
58
|
+
if (!der || der.byteLength === 0)
|
|
59
|
+
return { status: 'failed', reason: 'inspection_failed' };
|
|
60
|
+
try {
|
|
61
|
+
return { status: 'ok', facts: factsFrom(new node_crypto_1.X509Certificate(der)) };
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
return { status: 'failed', reason: classify(err) };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* O DER do certificado carregado no contexto.
|
|
69
|
+
*
|
|
70
|
+
* `context.getCertificate()` é o handle NATIVO do `SecureContext`, não a API
|
|
71
|
+
* pública documentada do Node. Por isso o acesso é defensivo em vez de direto: o
|
|
72
|
+
* dia em que uma versão do Node o renomear, o produto deve responder
|
|
73
|
+
* `inspection_failed` — e a suíte, que lê um PKCS#12 sintético de verdade, vai
|
|
74
|
+
* ficar vermelha na atualização, que é quando alguém pode agir.
|
|
75
|
+
*
|
|
76
|
+
* A alternativa — depender do binário `openssl` na imagem — troca este risco por
|
|
77
|
+
* um pior: uma falha que só aparece em produção, num contêiner onde ninguém
|
|
78
|
+
* conferiu o que está instalado.
|
|
79
|
+
*/
|
|
80
|
+
function certificateDerFrom(context) {
|
|
81
|
+
const handle = context.context;
|
|
82
|
+
const der = handle?.getCertificate?.();
|
|
83
|
+
return Buffer.isBuffer(der) ? der : null;
|
|
84
|
+
}
|
|
85
|
+
function factsFrom(cert) {
|
|
86
|
+
const validTo = new Date(cert.validTo);
|
|
87
|
+
return {
|
|
88
|
+
fingerprintSha256: cert.fingerprint256.replace(/:/g, '').toLowerCase(),
|
|
89
|
+
subjectCommonName: commonName(cert.subject),
|
|
90
|
+
issuerCommonName: commonName(cert.issuer),
|
|
91
|
+
serialTail: cert.serialNumber ? cert.serialNumber.slice(-8) : null,
|
|
92
|
+
validFrom: new Date(cert.validFrom).toISOString(),
|
|
93
|
+
validTo: validTo.toISOString(),
|
|
94
|
+
expired: validTo.getTime() <= Date.now(),
|
|
95
|
+
document: documentFrom(cert),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/** `CN=` do DN multilinha que o Node devolve. `null` quando não há. */
|
|
99
|
+
function commonName(dn) {
|
|
100
|
+
if (!dn)
|
|
101
|
+
return null;
|
|
102
|
+
for (const line of dn.split('\n')) {
|
|
103
|
+
const m = /^\s*CN\s*=\s*(.+?)\s*$/.exec(line);
|
|
104
|
+
if (m?.[1])
|
|
105
|
+
return m[1];
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* O documento do titular, do material.
|
|
111
|
+
*
|
|
112
|
+
* Duas fontes, nesta ordem — e a ordem importa:
|
|
113
|
+
*
|
|
114
|
+
* 1. O `otherName` do OID da ICP-Brasil, varrido no DER. É onde a norma manda
|
|
115
|
+
* escrever, é o que a Receita valida, e é o único lugar que não depende de
|
|
116
|
+
* convenção de quem emitiu.
|
|
117
|
+
* 2. O sufixo `:<14 dígitos>` do `CN`, convenção quase universal dos e-CNPJ.
|
|
118
|
+
*
|
|
119
|
+
* Não há terceira fonte. Procurar "14 dígitos em qualquer lugar do sujeito"
|
|
120
|
+
* casaria com um CEP colado a um telefone e devolveria um CNPJ inventado — que
|
|
121
|
+
* é pior que `null`, porque `null` deixa a comparação `indeterminate` e essa é
|
|
122
|
+
* a resposta honesta.
|
|
123
|
+
*/
|
|
124
|
+
function documentFrom(cert) {
|
|
125
|
+
const fromOid = documentFromDer(cert.raw);
|
|
126
|
+
if (fromOid)
|
|
127
|
+
return fromOid;
|
|
128
|
+
const cn = commonName(cert.subject);
|
|
129
|
+
const m = cn ? /:(\d{11}|\d{14})\s*$/.exec(cn) : null;
|
|
130
|
+
return m?.[1] ?? null;
|
|
131
|
+
}
|
|
132
|
+
function documentFromDer(der) {
|
|
133
|
+
let from = 0;
|
|
134
|
+
for (;;) {
|
|
135
|
+
const at = der.indexOf(OID_CNPJ_ICP_BRASIL, from);
|
|
136
|
+
if (at < 0)
|
|
137
|
+
return null;
|
|
138
|
+
const window = der
|
|
139
|
+
.subarray(at + OID_CNPJ_ICP_BRASIL.length, at + OID_CNPJ_ICP_BRASIL.length + OID_VALUE_WINDOW)
|
|
140
|
+
.toString('latin1');
|
|
141
|
+
const digits = /(\d{14})/.exec(window);
|
|
142
|
+
if (digits?.[1])
|
|
143
|
+
return digits[1];
|
|
144
|
+
from = at + 1;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Traduz a falha do OpenSSL em classe, olhando SÓ os fragmentos conhecidos.
|
|
149
|
+
*
|
|
150
|
+
* A mensagem inteira nunca é propagada nem registrada. `mac verify failure` é a
|
|
151
|
+
* resposta do PKCS#12 a uma senha que não abre o MAC — é o único caso em que se
|
|
152
|
+
* pode dizer ao operador "a senha está errada" com alguma confiança.
|
|
153
|
+
*/
|
|
154
|
+
function classify(err) {
|
|
155
|
+
const raw = err instanceof Error ? err.message : '';
|
|
156
|
+
const message = raw.toLowerCase();
|
|
157
|
+
if (message.includes('mac verify failure') || message.includes('invalid password')) {
|
|
158
|
+
return 'wrong_password';
|
|
159
|
+
}
|
|
160
|
+
if (message.includes('not enough data') ||
|
|
161
|
+
message.includes('wrong tag') ||
|
|
162
|
+
message.includes('header too long') ||
|
|
163
|
+
message.includes('nested asn1') ||
|
|
164
|
+
message.includes('asn1')) {
|
|
165
|
+
return 'malformed_material';
|
|
166
|
+
}
|
|
167
|
+
if (message.includes('unsupported') || message.includes('unknown cipher')) {
|
|
168
|
+
return 'unsupported_material';
|
|
169
|
+
}
|
|
170
|
+
return 'inspection_failed';
|
|
171
|
+
}
|
|
172
|
+
function matchIdentity(certificateDocument, clientDocument) {
|
|
173
|
+
const a = digitsOnly(certificateDocument);
|
|
174
|
+
const b = digitsOnly(clientDocument);
|
|
175
|
+
if (!a || !b)
|
|
176
|
+
return 'indeterminate';
|
|
177
|
+
return a === b ? 'match' : 'mismatch';
|
|
178
|
+
}
|
|
179
|
+
function digitsOnly(v) {
|
|
180
|
+
return (v ?? '').replace(/\D/g, '');
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=inspect.js.map
|