@baruk/core 0.4.2 → 0.5.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 +103 -0
- package/dist/cjs/clients/ibge.js.map +1 -0
- package/dist/cjs/clients/repository.js +186 -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 +111 -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/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 +127 -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/material.js +168 -0
- package/dist/cjs/fiscal/credentials/material.js.map +1 -0
- package/dist/cjs/fiscal/credentials/readiness.js +163 -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/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 +328 -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 +316 -11
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/legal/documents.js +100 -15
- 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 +144 -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 +34 -0
- package/dist/cjs/rbac/catalog.js.map +1 -1
- package/dist/cjs/subscription-billing/index.js +2 -1
- package/dist/cjs/subscription-billing/index.js.map +1 -1
- package/dist/cjs/subscription-billing/service.js +153 -77
- 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/clients/ibge.d.ts +17 -0
- package/dist/clients/ibge.d.ts.map +1 -0
- package/dist/clients/ibge.js +98 -0
- package/dist/clients/ibge.js.map +1 -0
- package/dist/clients/repository.d.ts +154 -0
- package/dist/clients/repository.d.ts.map +1 -1
- package/dist/clients/repository.js +182 -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 +109 -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/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 +86 -0
- package/dist/fiscal/coverage/model.d.ts.map +1 -0
- package/dist/fiscal/coverage/model.js +120 -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/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/readiness.d.ts +92 -0
- package/dist/fiscal/credentials/readiness.d.ts.map +1 -0
- package/dist/fiscal/credentials/readiness.js +159 -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/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 +80 -0
- package/dist/fiscal/transport/synthetic-tls.d.ts.map +1 -0
- package/dist/fiscal/transport/synthetic-tls.js +323 -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 +115 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +100 -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 +98 -14
- package/dist/legal/documents.js.map +1 -1
- package/dist/legal/index.d.ts +1 -1
- 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 +37 -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 +140 -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 +34 -0
- package/dist/rbac/catalog.js.map +1 -1
- package/dist/subscription-billing/index.d.ts +6 -5
- package/dist/subscription-billing/index.d.ts.map +1 -1
- package/dist/subscription-billing/index.js +3 -3
- package/dist/subscription-billing/index.js.map +1 -1
- package/dist/subscription-billing/service.d.ts +21 -0
- package/dist/subscription-billing/service.d.ts.map +1 -1
- package/dist/subscription-billing/service.js +90 -15
- 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/package.json +9 -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
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { ValidationError } from '@baruk/shared';
|
|
2
|
+
/**
|
|
3
|
+
* Coerência do código IBGE do município — SEM catálogo de municípios.
|
|
4
|
+
*
|
|
5
|
+
* O problema real: a validação anterior era `^[0-9]{7}$` e só. Um operador
|
|
6
|
+
* podia digitar 3550308 para um cliente declarado em Goiás, e o motor fiscal
|
|
7
|
+
* passaria a casar esse cliente com regra municipal de São Paulo. Nada no
|
|
8
|
+
* sistema contradizia o dado.
|
|
9
|
+
*
|
|
10
|
+
* O que este módulo faz é o pedaço da verificação que NÃO depende de fonte
|
|
11
|
+
* externa: os dois primeiros dígitos de todo código de município são o código
|
|
12
|
+
* da UF, e essa tabela é fechada em 27 valores desde 1988. Com ela dá para
|
|
13
|
+
* recusar (a) prefixo que não é UF nenhuma e (b) município de um estado
|
|
14
|
+
* atribuído a cliente de outro — que é o erro de digitação e de copiar-colar
|
|
15
|
+
* que produz jurisdição errada.
|
|
16
|
+
*
|
|
17
|
+
* O que este módulo deliberadamente NÃO faz:
|
|
18
|
+
*
|
|
19
|
+
* - Não confere o dígito verificador. O algoritmo circula publicamente, mas
|
|
20
|
+
* não temos aqui a lista dos 5.570 códigos reais para provar que todos
|
|
21
|
+
* fecham por ele. Um falso negativo recusaria o cadastro de um município
|
|
22
|
+
* legítimo — pior que a dívida que estamos fechando, porque quebra a
|
|
23
|
+
* operação do escritório em vez de apenas deixar passar um dado errado.
|
|
24
|
+
* - Não afirma que o município existe. 5299999 tem prefixo de Goiás e passa
|
|
25
|
+
* daqui; só um catálogo oficial recusaria. Continua dívida documentada.
|
|
26
|
+
*
|
|
27
|
+
* Ou seja: o que passa daqui é COERENTE, não é VERIFICADO. A distinção está
|
|
28
|
+
* na mensagem de erro e no relatório da fase, e não deve ser apagada.
|
|
29
|
+
*/
|
|
30
|
+
/** Os 27 prefixos oficiais. Tabela fechada — não é fonte de dados externa. */
|
|
31
|
+
const UF_BY_PREFIX = Object.freeze({
|
|
32
|
+
'11': 'RO',
|
|
33
|
+
'12': 'AC',
|
|
34
|
+
'13': 'AM',
|
|
35
|
+
'14': 'RR',
|
|
36
|
+
'15': 'PA',
|
|
37
|
+
'16': 'AP',
|
|
38
|
+
'17': 'TO',
|
|
39
|
+
'21': 'MA',
|
|
40
|
+
'22': 'PI',
|
|
41
|
+
'23': 'CE',
|
|
42
|
+
'24': 'RN',
|
|
43
|
+
'25': 'PB',
|
|
44
|
+
'26': 'PE',
|
|
45
|
+
'27': 'AL',
|
|
46
|
+
'28': 'SE',
|
|
47
|
+
'29': 'BA',
|
|
48
|
+
'31': 'MG',
|
|
49
|
+
'32': 'ES',
|
|
50
|
+
'33': 'RJ',
|
|
51
|
+
'35': 'SP',
|
|
52
|
+
'41': 'PR',
|
|
53
|
+
'42': 'SC',
|
|
54
|
+
'43': 'RS',
|
|
55
|
+
'50': 'MS',
|
|
56
|
+
'51': 'MT',
|
|
57
|
+
'52': 'GO',
|
|
58
|
+
'53': 'DF',
|
|
59
|
+
});
|
|
60
|
+
/** A UF que o próprio código declara, ou `null` se o prefixo não é de UF alguma. */
|
|
61
|
+
export function ufOfIbgeCode(code) {
|
|
62
|
+
const t = code?.trim();
|
|
63
|
+
if (!t || !/^[0-9]{7}$/.test(t))
|
|
64
|
+
return null;
|
|
65
|
+
return UF_BY_PREFIX[t.slice(0, 2)] ?? null;
|
|
66
|
+
}
|
|
67
|
+
/** Só para o teste de equivalência e para a tela: as UFs que o motor reconhece. */
|
|
68
|
+
export function knownUfs() {
|
|
69
|
+
return Object.values(UF_BY_PREFIX).slice().sort();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Recusa o par (código, UF) quando ele se contradiz.
|
|
73
|
+
*
|
|
74
|
+
* Recebe o ESTADO RESULTANTE, nunca o corpo da requisição: num PATCH que muda
|
|
75
|
+
* só a UF, o código incoerente é o que já estava gravado. Validar o payload
|
|
76
|
+
* deixaria passar exatamente a metade dos casos.
|
|
77
|
+
*
|
|
78
|
+
* UF ausente não é contradição — é dado faltando, e o cliente pode ficar sem
|
|
79
|
+
* UF de propósito enquanto o escritório confere. O código sozinho já carrega a
|
|
80
|
+
* jurisdição estadual.
|
|
81
|
+
*/
|
|
82
|
+
export function assertIbgeCoherent(code, uf) {
|
|
83
|
+
if (!code)
|
|
84
|
+
return;
|
|
85
|
+
if (!/^[0-9]{7}$/.test(code)) {
|
|
86
|
+
throw new ValidationError('Código IBGE do município tem 7 dígitos.', {
|
|
87
|
+
field: 'municipalityIbgeCode',
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const declared = ufOfIbgeCode(code);
|
|
91
|
+
if (declared === null) {
|
|
92
|
+
throw new ValidationError(`Código IBGE ${code} não começa com um código de UF válido — os dois primeiros dígitos identificam o estado.`, { field: 'municipalityIbgeCode' });
|
|
93
|
+
}
|
|
94
|
+
if (uf && declared !== uf) {
|
|
95
|
+
throw new ValidationError(`Código IBGE ${code} é de município de ${declared}, mas o cliente está em ${uf}. Corrija o código ou a UF.`, { field: 'municipalityIbgeCode', declaredUf: declared, clientUf: uf });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=ibge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ibge.js","sourceRoot":"","sources":["../../src/clients/ibge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,8EAA8E;AAC9E,MAAM,YAAY,GAAqC,MAAM,CAAC,MAAM,CAAC;IACnE,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;CACX,CAAC,CAAC;AAEH,oFAAoF;AACpF,MAAM,UAAU,YAAY,CAAC,IAA+B;IAC1D,MAAM,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC;IACvB,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,OAAO,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC7C,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,QAAQ;IACtB,OAAO,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;AACpD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAmB,EAAE,EAAiB;IACvE,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,eAAe,CAAC,yCAAyC,EAAE;YACnE,KAAK,EAAE,sBAAsB;SAC9B,CAAC,CAAC;IACL,CAAC;IACD,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,eAAe,CACvB,eAAe,IAAI,0FAA0F,EAC7G,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAClC,CAAC;IACJ,CAAC;IACD,IAAI,EAAE,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,eAAe,CACvB,eAAe,IAAI,sBAAsB,QAAQ,2BAA2B,EAAE,6BAA6B,EAC3G,EAAE,KAAK,EAAE,sBAAsB,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -15,6 +15,21 @@ export interface ClientRecord {
|
|
|
15
15
|
phone: string | null;
|
|
16
16
|
status: string;
|
|
17
17
|
createdAt: string;
|
|
18
|
+
/** Quem, no escritório, responde por este cliente. `null` = carteira sem dono. */
|
|
19
|
+
responsibleUserId: string | null;
|
|
20
|
+
municipality: string | null;
|
|
21
|
+
stateUf: string | null;
|
|
22
|
+
legalName: string | null;
|
|
23
|
+
addressLine: string | null;
|
|
24
|
+
postalCode: string | null;
|
|
25
|
+
notes: string | null;
|
|
26
|
+
/** Sete dígitos do IBGE. Sem ele, nenhuma regra municipal alcança o cliente. */
|
|
27
|
+
municipalityIbgeCode: string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Quando alguém do escritório conferiu o contato e liberou a comunicação
|
|
30
|
+
* externa. `null` = a régua não alcança este cliente.
|
|
31
|
+
*/
|
|
32
|
+
communicationClearedAt: string | null;
|
|
18
33
|
/**
|
|
19
34
|
* Por quais canais dá para falar com este cliente.
|
|
20
35
|
*
|
|
@@ -31,10 +46,46 @@ export interface Contactability {
|
|
|
31
46
|
phone: ContactChannelState;
|
|
32
47
|
/** Nenhum canal utilizável — o caso que exige atualização cadastral. */
|
|
33
48
|
reachable: boolean;
|
|
49
|
+
/** Situação em uma palavra, para a tela e para o relatório de carga. */
|
|
50
|
+
status: ContactabilityStatus;
|
|
51
|
+
/**
|
|
52
|
+
* A automação alcança este cliente?
|
|
53
|
+
*
|
|
54
|
+
* Distinto de `reachable`: um cliente com telefone e sem e-mail tem contato
|
|
55
|
+
* cadastrado (`reachable`) e mesmo assim não recebe nada, enquanto o canal de
|
|
56
|
+
* telefone do escritório não estiver ligado.
|
|
57
|
+
*/
|
|
58
|
+
automated: boolean;
|
|
34
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Situação de contato do cliente, em uma palavra.
|
|
62
|
+
*
|
|
63
|
+
* `reachable` responde "tem algum contato?", que não é a mesma pergunta que o
|
|
64
|
+
* escritório faz. A pergunta dele é **"a régua de cobrança e o pedido de
|
|
65
|
+
* documento vão alcançar este cliente?"** — e a resposta depende também de quais
|
|
66
|
+
* canais o escritório tem LIGADOS.
|
|
67
|
+
*
|
|
68
|
+
* Um cliente com telefone e sem e-mail parece contactável e não é, enquanto o
|
|
69
|
+
* WhatsApp do escritório não estiver operacional. Foi exatamente o caso que a
|
|
70
|
+
* Fase 3 identificou como silencioso: o cliente entra na carteira e fica
|
|
71
|
+
* invisível para os dois motores, sem ninguém ser avisado.
|
|
72
|
+
*
|
|
73
|
+
* `phone_only` e `phone_no_channel` são separados de propósito. O primeiro é uma
|
|
74
|
+
* situação normal — o escritório fala com esse cliente por WhatsApp. O segundo é
|
|
75
|
+
* uma pendência operacional, e confundi-los faria a tela mostrar tranquilidade
|
|
76
|
+
* onde há trabalho a fazer.
|
|
77
|
+
*/
|
|
78
|
+
export type ContactabilityStatus = 'email_ready' | 'phone_only' | 'phone_no_channel' | 'no_channel';
|
|
35
79
|
export declare function contactabilityOf(input: {
|
|
36
80
|
email?: string | null;
|
|
37
81
|
phone?: string | null;
|
|
82
|
+
},
|
|
83
|
+
/**
|
|
84
|
+
* Canais que o ESCRITÓRIO tem operacionais. Omitido = só e-mail, que é o
|
|
85
|
+
* estado de quem ainda não conectou telefone — e é o padrão hoje.
|
|
86
|
+
*/
|
|
87
|
+
channels?: {
|
|
88
|
+
phone?: boolean;
|
|
38
89
|
}): Contactability;
|
|
39
90
|
/**
|
|
40
91
|
* Normalização de contato.
|
|
@@ -54,7 +105,28 @@ export interface CreateClientInput {
|
|
|
54
105
|
email?: string | null;
|
|
55
106
|
phone?: string | null;
|
|
56
107
|
createdBy?: string | null;
|
|
108
|
+
/** Razão social, quando difere do nome pelo qual o escritório chama o cliente. */
|
|
109
|
+
legalName?: string | null;
|
|
110
|
+
addressLine?: string | null;
|
|
111
|
+
municipality?: string | null;
|
|
112
|
+
/** UF em duas maiúsculas — o CHECK do banco recusa qualquer outra forma. */
|
|
113
|
+
stateUf?: string | null;
|
|
114
|
+
/**
|
|
115
|
+
* Código IBGE de sete dígitos do município.
|
|
116
|
+
*
|
|
117
|
+
* A coluna nasceu na 0049 e nenhum caminho de escrita a alcançava — só um
|
|
118
|
+
* `UPDATE` cru dentro de um teste. Sem ela, regra municipal nenhuma casa.
|
|
119
|
+
*/
|
|
120
|
+
municipalityIbgeCode?: string | null;
|
|
121
|
+
postalCode?: string | null;
|
|
122
|
+
notes?: string | null;
|
|
123
|
+
responsibleUserId?: string | null;
|
|
124
|
+
contractStartedOn?: string | null;
|
|
125
|
+
/** Lote de importação que originou a linha. Só o importador preenche. */
|
|
126
|
+
importBatchId?: string | null;
|
|
57
127
|
}
|
|
128
|
+
/** UF só entra em caixa alta; o banco recusa o resto, e recusar cedo dá erro melhor. */
|
|
129
|
+
export declare function normalizeUf(v: string | null | undefined): string | null;
|
|
58
130
|
export declare function createClient(tx: Tx, input: CreateClientInput): Promise<ClientRecord>;
|
|
59
131
|
export declare function listClients(tx: Tx): Promise<ClientRecord[]>;
|
|
60
132
|
export declare function getClient(tx: Tx, id: string): Promise<ClientRecord>;
|
|
@@ -68,17 +140,63 @@ export interface ListClientsFilter {
|
|
|
68
140
|
status?: string;
|
|
69
141
|
limit?: number;
|
|
70
142
|
offset?: number;
|
|
143
|
+
/**
|
|
144
|
+
* Filtra a carteira por responsável.
|
|
145
|
+
*
|
|
146
|
+
* `'unassigned'` é um valor de primeira classe e não um acaso: "quem não tem
|
|
147
|
+
* dono" é a pergunta que o escritório mais precisa fazer numa importação
|
|
148
|
+
* recém-concluída, e ela não é expressável passando um id.
|
|
149
|
+
*/
|
|
150
|
+
responsibleUserId?: string | 'unassigned';
|
|
71
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* O escritório tem canal de telefone operacional?
|
|
154
|
+
*
|
|
155
|
+
* Decide se um cliente que só tem telefone é `phone_only` (situação normal) ou
|
|
156
|
+
* `phone_no_channel` (pendência). A consulta roda sob RLS, então enxerga só o
|
|
157
|
+
* `channel_binding` do tenant do contexto.
|
|
158
|
+
*
|
|
159
|
+
* Uma consulta por listagem, não uma por linha: a resposta é a mesma para todos
|
|
160
|
+
* os clientes do escritório.
|
|
161
|
+
*/
|
|
162
|
+
export declare function tenantHasPhoneChannel(tx: Tx): Promise<boolean>;
|
|
72
163
|
export declare function listClientsPaged(tx: Tx, filter?: ListClientsFilter): Promise<{
|
|
73
164
|
items: ClientRecord[];
|
|
74
165
|
total: number;
|
|
75
166
|
}>;
|
|
167
|
+
/**
|
|
168
|
+
* Campo cuja AUSÊNCIA e cujo `null` significam coisas diferentes.
|
|
169
|
+
*
|
|
170
|
+
* `undefined` preserva o que está gravado; `null` apaga. A distinção existe
|
|
171
|
+
* porque endereço e jurisdição são corrigíveis: quem digitou a UF errada
|
|
172
|
+
* precisa conseguir voltar ao desconhecido, e não só sobrescrever com outro
|
|
173
|
+
* palpite. O padrão `COALESCE` dos campos antigos não sabe fazer isso — nele,
|
|
174
|
+
* `null` é indistinguível de "não mandei".
|
|
175
|
+
*/
|
|
176
|
+
type Erasable<T> = T | null | undefined;
|
|
76
177
|
export interface UpdateClientInput {
|
|
77
178
|
displayName?: string;
|
|
78
179
|
legalName?: string | null;
|
|
79
180
|
email?: string | null;
|
|
80
181
|
phone?: string | null;
|
|
81
182
|
status?: string;
|
|
183
|
+
/**
|
|
184
|
+
* Endereço e jurisdição.
|
|
185
|
+
*
|
|
186
|
+
* Chegaram tarde de propósito? Não: chegaram tarde por omissão. O importador
|
|
187
|
+
* de CSV gravava `state_uf` desde a Fase 5, mas nem a criação avulsa nem a
|
|
188
|
+
* edição tinham onde recebê-lo — um cliente cadastrado pela tela nascia sem
|
|
189
|
+
* jurisdição e NÃO HAVIA COMO CORRIGIR sem SQL. Toda regra estadual ou
|
|
190
|
+
* municipal respondia `INSUFFICIENT_DATA` para sempre.
|
|
191
|
+
*/
|
|
192
|
+
addressLine?: Erasable<string>;
|
|
193
|
+
municipality?: Erasable<string>;
|
|
194
|
+
/** Sete dígitos do IBGE. É o que casa o cliente com uma regra municipal. */
|
|
195
|
+
municipalityIbgeCode?: Erasable<string>;
|
|
196
|
+
/** UF em duas maiúsculas. Casa o cliente com uma regra estadual. */
|
|
197
|
+
stateUf?: Erasable<string>;
|
|
198
|
+
postalCode?: Erasable<string>;
|
|
199
|
+
notes?: Erasable<string>;
|
|
82
200
|
/**
|
|
83
201
|
* CPF/CNPJ. Faltava aqui: o cliente nascia com documento e nunca podia
|
|
84
202
|
* corrigi-lo — e é justamente o campo que todo gateway de pagamento exige
|
|
@@ -92,4 +210,40 @@ export declare function updateClient(tx: Tx, id: string, input: UpdateClientInpu
|
|
|
92
210
|
export declare function softDeleteClient(tx: Tx, id: string, deletedBy?: string | null): Promise<number>;
|
|
93
211
|
/** Busca por documento normalizado (dedup de importação). Retorna id ou null. */
|
|
94
212
|
export declare function findClientIdByDocument(tx: Tx, documentNumber: string): Promise<string | null>;
|
|
213
|
+
/**
|
|
214
|
+
* Troca o responsável pela carteira de um cliente.
|
|
215
|
+
*
|
|
216
|
+
* Devolve quem era e quem passou a ser, para que a auditoria registre a
|
|
217
|
+
* TRANSIÇÃO e não apenas o destino. "Passou a ser da Ana" não responde a
|
|
218
|
+
* pergunta que se faz meses depois — "saiu de quem?" — e é essa que importa
|
|
219
|
+
* quando um cliente deixa de ser atendido.
|
|
220
|
+
*
|
|
221
|
+
* O usuário precisa ser membro ativo do escritório. Sem essa checagem, a FK
|
|
222
|
+
* aceitaria qualquer `user.id` do banco inteiro, inclusive de outro tenant:
|
|
223
|
+
* FKs ignoram RLS, então a barreira tem de ser explícita aqui.
|
|
224
|
+
*/
|
|
225
|
+
export declare function assignClientResponsible(tx: Tx, input: {
|
|
226
|
+
clientId: string;
|
|
227
|
+
responsibleUserId: string | null;
|
|
228
|
+
}): Promise<{
|
|
229
|
+
clientId: string;
|
|
230
|
+
from: string | null;
|
|
231
|
+
to: string | null;
|
|
232
|
+
}>;
|
|
233
|
+
export interface PortfolioBucket {
|
|
234
|
+
responsibleUserId: string | null;
|
|
235
|
+
responsibleName: string | null;
|
|
236
|
+
clients: number;
|
|
237
|
+
semCanalAutomatico: number;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* A carteira dividida por responsável.
|
|
241
|
+
*
|
|
242
|
+
* O balde `null` — clientes sem dono — vem junto, e vem por último, em vez de
|
|
243
|
+
* ser omitido. Uma carteira recém-importada é inteiramente desse balde, e uma
|
|
244
|
+
* tela que só lista responsáveis existentes mostraria zero clientes num
|
|
245
|
+
* escritório com trezentos.
|
|
246
|
+
*/
|
|
247
|
+
export declare function portfolioByResponsible(tx: Tx): Promise<PortfolioBucket[]>;
|
|
248
|
+
export {};
|
|
95
249
|
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/clients/repository.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/clients/repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,32 @@
|
|
|
1
1
|
import { ConflictError, NotFoundError, uuidv7 } from '@baruk/shared';
|
|
2
2
|
import { toE164OrNull } from '../contacts/phone.js';
|
|
3
|
-
|
|
3
|
+
import { assertIbgeCoherent } from './ibge.js';
|
|
4
|
+
export function contactabilityOf(input,
|
|
5
|
+
/**
|
|
6
|
+
* Canais que o ESCRITÓRIO tem operacionais. Omitido = só e-mail, que é o
|
|
7
|
+
* estado de quem ainda não conectou telefone — e é o padrão hoje.
|
|
8
|
+
*/
|
|
9
|
+
channels = {}) {
|
|
4
10
|
const email = input.email?.trim() ? 'ready' : 'missing';
|
|
5
11
|
const phone = input.phone?.trim() ? 'ready' : 'missing';
|
|
6
|
-
|
|
12
|
+
const phoneChannelLigado = channels.phone === true;
|
|
13
|
+
const status = email === 'ready'
|
|
14
|
+
? 'email_ready'
|
|
15
|
+
: phone === 'ready'
|
|
16
|
+
? phoneChannelLigado
|
|
17
|
+
? 'phone_only'
|
|
18
|
+
: 'phone_no_channel'
|
|
19
|
+
: 'no_channel';
|
|
20
|
+
return {
|
|
21
|
+
email,
|
|
22
|
+
phone,
|
|
23
|
+
// `reachable` mantém o significado antigo — "tem contato cadastrado" — para
|
|
24
|
+
// não mudar o comportamento de quem já o consulta. Quem quer saber se a
|
|
25
|
+
// automação alcança usa `automated`.
|
|
26
|
+
reachable: email === 'ready' || phone === 'ready',
|
|
27
|
+
status,
|
|
28
|
+
automated: status === 'email_ready' || status === 'phone_only',
|
|
29
|
+
};
|
|
7
30
|
}
|
|
8
31
|
/**
|
|
9
32
|
* Normalização de contato.
|
|
@@ -28,7 +51,12 @@ export function normalizePhone(v) {
|
|
|
28
51
|
return null;
|
|
29
52
|
return plus ? `+${digits}` : digits;
|
|
30
53
|
}
|
|
31
|
-
|
|
54
|
+
/** UF só entra em caixa alta; o banco recusa o resto, e recusar cedo dá erro melhor. */
|
|
55
|
+
export function normalizeUf(v) {
|
|
56
|
+
const t = v?.trim().toUpperCase();
|
|
57
|
+
return t && /^[A-Z]{2}$/.test(t) ? t : null;
|
|
58
|
+
}
|
|
59
|
+
function mapRow(r, channels = {}) {
|
|
32
60
|
return {
|
|
33
61
|
id: r.id,
|
|
34
62
|
tenantId: r.tenant_id,
|
|
@@ -39,7 +67,16 @@ function mapRow(r) {
|
|
|
39
67
|
phone: r.phone ?? null,
|
|
40
68
|
status: r.status,
|
|
41
69
|
createdAt: r.created_at.toISOString(),
|
|
42
|
-
|
|
70
|
+
responsibleUserId: r.responsible_user_id ?? null,
|
|
71
|
+
municipality: r.municipality ?? null,
|
|
72
|
+
stateUf: r.state_uf ?? null,
|
|
73
|
+
legalName: r.legal_name ?? null,
|
|
74
|
+
addressLine: r.address_line ?? null,
|
|
75
|
+
postalCode: r.postal_code ?? null,
|
|
76
|
+
notes: r.notes ?? null,
|
|
77
|
+
municipalityIbgeCode: r.municipality_ibge_code ?? null,
|
|
78
|
+
communicationClearedAt: r.communication_cleared_at?.toISOString() ?? null,
|
|
79
|
+
contactability: contactabilityOf({ email: r.email, phone: r.phone }, channels),
|
|
43
80
|
};
|
|
44
81
|
}
|
|
45
82
|
/**
|
|
@@ -57,21 +94,37 @@ function asDuplicateDocument(err) {
|
|
|
57
94
|
}
|
|
58
95
|
}
|
|
59
96
|
export async function createClient(tx, input) {
|
|
97
|
+
// Antes de gravar: o código IBGE não pode contradizer a UF. Aqui o estado
|
|
98
|
+
// resultante é o próprio input — não há linha anterior com que se misturar.
|
|
99
|
+
assertIbgeCoherent(input.municipalityIbgeCode?.trim() || null, normalizeUf(input.stateUf));
|
|
60
100
|
// tenant_id vem da GUC — nunca do input. A WITH CHECK da RLS recusa qualquer
|
|
61
101
|
// tentativa de gravar fora do tenant corrente.
|
|
62
102
|
try {
|
|
63
103
|
const rows = await tx `
|
|
64
|
-
INSERT INTO client (id, tenant_id, client_type, display_name, document_number,
|
|
65
|
-
email, phone, phone_e164,
|
|
104
|
+
INSERT INTO client (id, tenant_id, client_type, display_name, legal_name, document_number,
|
|
105
|
+
email, phone, phone_e164, address_line, municipality, state_uf,
|
|
106
|
+
municipality_ibge_code,
|
|
107
|
+
postal_code, notes, responsible_user_id, contract_started_on,
|
|
108
|
+
import_batch_id, created_by)
|
|
66
109
|
VALUES (
|
|
67
110
|
${uuidv7()},
|
|
68
111
|
current_setting('app.current_tenant')::uuid,
|
|
69
112
|
${input.clientType ?? 'pj'},
|
|
70
113
|
${input.displayName},
|
|
114
|
+
${input.legalName?.trim() || null},
|
|
71
115
|
${input.documentNumber ?? null},
|
|
72
116
|
${normalizeEmail(input.email)},
|
|
73
117
|
${normalizePhone(input.phone)},
|
|
74
118
|
${toE164OrNull(input.phone)},
|
|
119
|
+
${input.addressLine?.trim() || null},
|
|
120
|
+
${input.municipality?.trim() || null},
|
|
121
|
+
${normalizeUf(input.stateUf)},
|
|
122
|
+
${input.municipalityIbgeCode?.trim() || null},
|
|
123
|
+
${input.postalCode?.trim() || null},
|
|
124
|
+
${input.notes?.trim() || null},
|
|
125
|
+
${input.responsibleUserId ?? null},
|
|
126
|
+
${input.contractStartedOn ?? null},
|
|
127
|
+
${input.importBatchId ?? null},
|
|
75
128
|
${input.createdBy ?? null}
|
|
76
129
|
)
|
|
77
130
|
RETURNING id, tenant_id, client_type, display_name, document_number, email, phone,
|
|
@@ -95,7 +148,9 @@ export async function listClients(tx) {
|
|
|
95
148
|
}
|
|
96
149
|
export async function getClient(tx, id) {
|
|
97
150
|
const rows = await tx `
|
|
98
|
-
SELECT id, tenant_id, client_type, display_name, document_number, email, phone,
|
|
151
|
+
SELECT id, tenant_id, client_type, display_name, legal_name, document_number, email, phone,
|
|
152
|
+
status, created_at, responsible_user_id, address_line, municipality, state_uf,
|
|
153
|
+
municipality_ibge_code, postal_code, notes
|
|
99
154
|
FROM client
|
|
100
155
|
WHERE id = ${id} AND deleted_at IS NULL
|
|
101
156
|
`;
|
|
@@ -116,24 +171,68 @@ export async function renameClient(tx, id, displayName) {
|
|
|
116
171
|
`;
|
|
117
172
|
return rows.count;
|
|
118
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* O escritório tem canal de telefone operacional?
|
|
176
|
+
*
|
|
177
|
+
* Decide se um cliente que só tem telefone é `phone_only` (situação normal) ou
|
|
178
|
+
* `phone_no_channel` (pendência). A consulta roda sob RLS, então enxerga só o
|
|
179
|
+
* `channel_binding` do tenant do contexto.
|
|
180
|
+
*
|
|
181
|
+
* Uma consulta por listagem, não uma por linha: a resposta é a mesma para todos
|
|
182
|
+
* os clientes do escritório.
|
|
183
|
+
*/
|
|
184
|
+
export async function tenantHasPhoneChannel(tx) {
|
|
185
|
+
const rows = await tx `
|
|
186
|
+
SELECT count(*)::int AS n FROM channel_binding
|
|
187
|
+
WHERE channel IN ('whatsapp', 'sms') AND revoked_at IS NULL
|
|
188
|
+
`;
|
|
189
|
+
return (rows[0]?.n ?? 0) > 0;
|
|
190
|
+
}
|
|
119
191
|
export async function listClientsPaged(tx, filter = {}) {
|
|
120
192
|
const limit = Math.min(filter.limit ?? 20, 100);
|
|
121
193
|
const offset = filter.offset ?? 0;
|
|
122
194
|
const like = filter.search ? `%${filter.search}%` : null;
|
|
123
195
|
const rows = await tx `
|
|
124
196
|
SELECT id, tenant_id, client_type, display_name, document_number, email, phone, status, created_at,
|
|
197
|
+
responsible_user_id, municipality, state_uf, communication_cleared_at,
|
|
125
198
|
count(*) OVER() AS total
|
|
126
199
|
FROM client
|
|
127
200
|
WHERE deleted_at IS NULL
|
|
128
201
|
AND (${filter.status ?? null}::text IS NULL OR status = ${filter.status ?? null})
|
|
129
202
|
AND (${like}::text IS NULL OR display_name ILIKE ${like} OR document_number ILIKE ${like})
|
|
203
|
+
AND (${filter.responsibleUserId ?? null}::text IS NULL
|
|
204
|
+
OR (${filter.responsibleUserId ?? null} = 'unassigned' AND responsible_user_id IS NULL)
|
|
205
|
+
OR responsible_user_id::text = ${filter.responsibleUserId ?? null})
|
|
130
206
|
ORDER BY created_at DESC
|
|
131
207
|
LIMIT ${limit} OFFSET ${offset}
|
|
132
208
|
`;
|
|
133
209
|
const total = rows[0] ? Number(rows[0].total) : 0;
|
|
134
|
-
|
|
210
|
+
const phone = await tenantHasPhoneChannel(tx);
|
|
211
|
+
return { items: rows.map((r) => mapRow(r, { phone })), total };
|
|
135
212
|
}
|
|
136
213
|
export async function updateClient(tx, id, input) {
|
|
214
|
+
// Coerência IBGE↔UF do ESTADO RESULTANTE, não do corpo da requisição.
|
|
215
|
+
//
|
|
216
|
+
// Um PATCH que manda só `stateUf` deixa no banco o código IBGE de antes;
|
|
217
|
+
// validar apenas o payload aprovaria trocar a UF de GO para SP mantendo o
|
|
218
|
+
// município goiano gravado. Por isso lemos a linha e mesclamos antes.
|
|
219
|
+
//
|
|
220
|
+
// O SELECT só acontece quando um dos dois campos está no corpo: o PATCH
|
|
221
|
+
// comum (nome, telefone, status) continua sendo uma única query.
|
|
222
|
+
if ('municipalityIbgeCode' in input || 'stateUf' in input) {
|
|
223
|
+
const [atual] = await tx `
|
|
224
|
+
SELECT state_uf, municipality_ibge_code FROM client WHERE id = ${id} AND deleted_at IS NULL
|
|
225
|
+
`;
|
|
226
|
+
// Sem linha, quem responde é o UPDATE abaixo com 0 afetadas (404). Recusar
|
|
227
|
+
// aqui por validação transformaria "cliente não existe" em "dado inválido".
|
|
228
|
+
if (atual) {
|
|
229
|
+
const code = 'municipalityIbgeCode' in input
|
|
230
|
+
? input.municipalityIbgeCode?.trim() || null
|
|
231
|
+
: atual.municipality_ibge_code;
|
|
232
|
+
const uf = 'stateUf' in input ? normalizeUf(input.stateUf) : atual.state_uf;
|
|
233
|
+
assertIbgeCoherent(code, uf);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
137
236
|
// Corrigir um documento para um que já existe cai na mesma violação — e o
|
|
138
237
|
// escritório precisa da mesma explicação, não de um 500.
|
|
139
238
|
// Casts explícitos: parâmetros NULL sem tipo quebram COALESCE ("could not
|
|
@@ -142,7 +241,7 @@ export async function updateClient(tx, id, input) {
|
|
|
142
241
|
const rows = await tx `
|
|
143
242
|
UPDATE client SET
|
|
144
243
|
display_name = COALESCE(${input.displayName ?? null}::text, display_name),
|
|
145
|
-
legal_name =
|
|
244
|
+
legal_name = CASE WHEN ${'legalName' in input} THEN ${input.legalName?.trim() || null}::text ELSE legal_name END,
|
|
146
245
|
document_number = COALESCE(${input.documentNumber ?? null}::text, document_number),
|
|
147
246
|
email = COALESCE(${normalizeEmail(input.email)}::citext, email),
|
|
148
247
|
phone = COALESCE(${normalizePhone(input.phone)}::text, phone),
|
|
@@ -154,6 +253,14 @@ export async function updateClient(tx, id, input) {
|
|
|
154
253
|
phone_e164 = CASE WHEN ${input.phone ?? null}::text IS NULL THEN phone_e164
|
|
155
254
|
ELSE ${toE164OrNull(input.phone)}::text END,
|
|
156
255
|
status = COALESCE(${input.status ?? null}::text, status),
|
|
256
|
+
-- Presença, nao valor: ausente preserva, null apaga. Um COALESCE aqui
|
|
257
|
+
-- tornaria a UF errada permanente -- so daria para troca-la por outra.
|
|
258
|
+
address_line = CASE WHEN ${'addressLine' in input} THEN ${input.addressLine?.trim() || null}::text ELSE address_line END,
|
|
259
|
+
municipality = CASE WHEN ${'municipality' in input} THEN ${input.municipality?.trim() || null}::text ELSE municipality END,
|
|
260
|
+
municipality_ibge_code = CASE WHEN ${'municipalityIbgeCode' in input} THEN ${input.municipalityIbgeCode?.trim() || null}::text ELSE municipality_ibge_code END,
|
|
261
|
+
state_uf = CASE WHEN ${'stateUf' in input} THEN ${normalizeUf(input.stateUf)}::text ELSE state_uf END,
|
|
262
|
+
postal_code = CASE WHEN ${'postalCode' in input} THEN ${input.postalCode?.trim() || null}::text ELSE postal_code END,
|
|
263
|
+
notes = CASE WHEN ${'notes' in input} THEN ${input.notes?.trim() || null}::text ELSE notes END,
|
|
157
264
|
updated_by = ${input.updatedBy ?? null}::uuid,
|
|
158
265
|
updated_at = now(),
|
|
159
266
|
version = version + 1
|
|
@@ -183,4 +290,70 @@ export async function findClientIdByDocument(tx, documentNumber) {
|
|
|
183
290
|
`;
|
|
184
291
|
return rows[0]?.id ?? null;
|
|
185
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Troca o responsável pela carteira de um cliente.
|
|
295
|
+
*
|
|
296
|
+
* Devolve quem era e quem passou a ser, para que a auditoria registre a
|
|
297
|
+
* TRANSIÇÃO e não apenas o destino. "Passou a ser da Ana" não responde a
|
|
298
|
+
* pergunta que se faz meses depois — "saiu de quem?" — e é essa que importa
|
|
299
|
+
* quando um cliente deixa de ser atendido.
|
|
300
|
+
*
|
|
301
|
+
* O usuário precisa ser membro ativo do escritório. Sem essa checagem, a FK
|
|
302
|
+
* aceitaria qualquer `user.id` do banco inteiro, inclusive de outro tenant:
|
|
303
|
+
* FKs ignoram RLS, então a barreira tem de ser explícita aqui.
|
|
304
|
+
*/
|
|
305
|
+
export async function assignClientResponsible(tx, input) {
|
|
306
|
+
if (input.responsibleUserId) {
|
|
307
|
+
const [m] = await tx `
|
|
308
|
+
SELECT count(*)::int AS n FROM membership
|
|
309
|
+
WHERE user_id = ${input.responsibleUserId}
|
|
310
|
+
AND status = 'active' AND deleted_at IS NULL
|
|
311
|
+
`;
|
|
312
|
+
if ((m?.n ?? 0) === 0) {
|
|
313
|
+
throw new NotFoundError('Usuário não é membro ativo deste escritório.');
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
const [before] = await tx `
|
|
317
|
+
SELECT responsible_user_id FROM client WHERE id = ${input.clientId} AND deleted_at IS NULL
|
|
318
|
+
`;
|
|
319
|
+
if (!before)
|
|
320
|
+
throw new NotFoundError('Cliente não encontrado.');
|
|
321
|
+
await tx `
|
|
322
|
+
UPDATE client
|
|
323
|
+
SET responsible_user_id = ${input.responsibleUserId}, updated_at = now()
|
|
324
|
+
WHERE id = ${input.clientId} AND deleted_at IS NULL
|
|
325
|
+
`;
|
|
326
|
+
return {
|
|
327
|
+
clientId: input.clientId,
|
|
328
|
+
from: before.responsible_user_id,
|
|
329
|
+
to: input.responsibleUserId,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* A carteira dividida por responsável.
|
|
334
|
+
*
|
|
335
|
+
* O balde `null` — clientes sem dono — vem junto, e vem por último, em vez de
|
|
336
|
+
* ser omitido. Uma carteira recém-importada é inteiramente desse balde, e uma
|
|
337
|
+
* tela que só lista responsáveis existentes mostraria zero clientes num
|
|
338
|
+
* escritório com trezentos.
|
|
339
|
+
*/
|
|
340
|
+
export async function portfolioByResponsible(tx) {
|
|
341
|
+
const rows = await tx `
|
|
342
|
+
SELECT c.responsible_user_id,
|
|
343
|
+
u.full_name,
|
|
344
|
+
count(*)::int AS clients,
|
|
345
|
+
count(*) FILTER (WHERE c.email IS NULL)::int AS sem_canal
|
|
346
|
+
FROM client c
|
|
347
|
+
LEFT JOIN "user" u ON u.id = c.responsible_user_id
|
|
348
|
+
WHERE c.deleted_at IS NULL
|
|
349
|
+
GROUP BY c.responsible_user_id, u.full_name
|
|
350
|
+
ORDER BY (c.responsible_user_id IS NULL), u.full_name NULLS LAST
|
|
351
|
+
`;
|
|
352
|
+
return rows.map((r) => ({
|
|
353
|
+
responsibleUserId: r.responsible_user_id,
|
|
354
|
+
responsibleName: r.full_name,
|
|
355
|
+
clients: r.clients,
|
|
356
|
+
semCanalAutomatico: r.sem_canal,
|
|
357
|
+
}));
|
|
358
|
+
}
|
|
186
359
|
//# sourceMappingURL=repository.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/clients/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/clients/repository.ts"],"names":[],"mappings":"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"}
|