@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
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ensureSaasPlanCatalog = exports.getPlan = exports.listPublicPlans = void 0;
|
|
4
4
|
exports.seedSaasPlans = seedSaasPlans;
|
|
5
|
+
exports.provisionAccountingOffice = provisionAccountingOffice;
|
|
5
6
|
exports.signupSelfService = signupSelfService;
|
|
6
7
|
exports.standingFor = standingFor;
|
|
7
8
|
exports.entitlementsForPlan = entitlementsForPlan;
|
|
@@ -21,18 +22,19 @@ const shared_1 = require("@baruk/shared");
|
|
|
21
22
|
const context_js_1 = require("../db/context.js");
|
|
22
23
|
const audit_js_1 = require("../audit/audit.js");
|
|
23
24
|
const password_js_1 = require("../auth/password.js");
|
|
25
|
+
const repository_js_1 = require("../users/repository.js");
|
|
24
26
|
const provisioning_js_1 = require("../tenancy/provisioning.js");
|
|
25
|
-
const
|
|
27
|
+
const repository_js_2 = require("../products/repository.js");
|
|
26
28
|
const derive_js_1 = require("../entitlements/derive.js");
|
|
27
29
|
const transactional_outbound_js_1 = require("../mail/transactional-outbound.js");
|
|
28
30
|
const reconcile_js_1 = require("./reconcile.js");
|
|
29
31
|
const dunning_js_1 = require("./dunning.js");
|
|
30
32
|
const live_guard_js_1 = require("../billing/live-guard.js");
|
|
31
33
|
const registry_js_1 = require("./provider/registry.js");
|
|
32
|
-
const
|
|
33
|
-
Object.defineProperty(exports, "ensureSaasPlanCatalog", { enumerable: true, get: function () { return
|
|
34
|
-
Object.defineProperty(exports, "getPlan", { enumerable: true, get: function () { return
|
|
35
|
-
Object.defineProperty(exports, "listPublicPlans", { enumerable: true, get: function () { return
|
|
34
|
+
const repository_js_3 = require("./repository.js");
|
|
35
|
+
Object.defineProperty(exports, "ensureSaasPlanCatalog", { enumerable: true, get: function () { return repository_js_3.ensureSaasPlanCatalog; } });
|
|
36
|
+
Object.defineProperty(exports, "getPlan", { enumerable: true, get: function () { return repository_js_3.getPlan; } });
|
|
37
|
+
Object.defineProperty(exports, "listPublicPlans", { enumerable: true, get: function () { return repository_js_3.listPublicPlans; } });
|
|
36
38
|
const plans_js_1 = require("./plans.js");
|
|
37
39
|
const product_config_js_1 = require("./product-config.js");
|
|
38
40
|
function asRegistry(source) {
|
|
@@ -87,8 +89,70 @@ async function syncTenantStatus(tx, tenantId, status) {
|
|
|
87
89
|
}
|
|
88
90
|
/** Seed do catálogo padrão (chamado pelo seed do core). */
|
|
89
91
|
async function seedSaasPlans(db) {
|
|
90
|
-
await (0,
|
|
91
|
-
await (0,
|
|
92
|
+
await (0, repository_js_2.ensureProductCatalog)(db);
|
|
93
|
+
await (0, repository_js_3.ensureSaasPlanCatalog)(db, plans_js_1.SAAS_PLANS);
|
|
94
|
+
}
|
|
95
|
+
async function provisionAccountingOffice(db, input, nowIso) {
|
|
96
|
+
const email = input.ownerEmail.trim().toLowerCase();
|
|
97
|
+
if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email))
|
|
98
|
+
throw new shared_1.ValidationError('E-mail inválido');
|
|
99
|
+
if (!input.companyName.trim())
|
|
100
|
+
throw new shared_1.ValidationError('Nome do escritório é obrigatório');
|
|
101
|
+
if (!input.ownerFullName.trim())
|
|
102
|
+
throw new shared_1.ValidationError('Nome do responsável é obrigatório');
|
|
103
|
+
const planKey = input.planKey ?? plans_js_1.SAAS_PLANS.find((p) => p.isActive && p.isPublic)?.key;
|
|
104
|
+
if (!planKey)
|
|
105
|
+
throw new shared_1.ValidationError('Nenhum plano ativo disponível');
|
|
106
|
+
const plan = await (0, repository_js_3.getPlan)(db, planKey);
|
|
107
|
+
if (!plan || !plan.isActive)
|
|
108
|
+
throw new shared_1.ValidationError(`Plano indisponível: ${planKey}`);
|
|
109
|
+
const code = await uniqueTenantCode(db, input.companyName);
|
|
110
|
+
const tenantId = await (0, provisioning_js_1.ensureTenant)(db, {
|
|
111
|
+
code,
|
|
112
|
+
displayName: input.companyName.trim(),
|
|
113
|
+
status: 'trial',
|
|
114
|
+
primaryProduct: plans_js_1.DEFAULT_PRODUCT_KEY,
|
|
115
|
+
});
|
|
116
|
+
await (0, provisioning_js_1.ensureOrganization)(db, tenantId, input.companyName.trim());
|
|
117
|
+
await (0, repository_js_2.ensureProductCatalog)(db);
|
|
118
|
+
await (0, repository_js_2.ensureTenantProduct)(db, tenantId, plans_js_1.DEFAULT_PRODUCT_KEY);
|
|
119
|
+
const trialEndsAt = addDays(nowIso, plan.trialDays > 0 ? plan.trialDays : plans_js_1.DEFAULT_TRIAL_DAYS);
|
|
120
|
+
const { subscription, domainEvents } = (0, reconcile_js_1.startTrial)(tenantId, plan.key, trialEndsAt, nowIso);
|
|
121
|
+
/*
|
|
122
|
+
* Contexto do TENANT NOVO com o usuário da OPERADORA.
|
|
123
|
+
*
|
|
124
|
+
* O operador não é membro deste escritório e nunca será — ele abre o contexto
|
|
125
|
+
* para criar o convite e sai. O `invited_by` aponta para ele, que é a
|
|
126
|
+
* resposta honesta a "quem colocou esta pessoa aqui".
|
|
127
|
+
*/
|
|
128
|
+
return (0, context_js_1.withContext)(db, { tenantId, userId: input.operatorUserId }, async (tx) => {
|
|
129
|
+
const invited = await (0, repository_js_1.inviteUser)(tx, {
|
|
130
|
+
email,
|
|
131
|
+
fullName: input.ownerFullName.trim(),
|
|
132
|
+
roleKey: 'owner',
|
|
133
|
+
invitedBy: input.operatorUserId,
|
|
134
|
+
});
|
|
135
|
+
const row = await (0, repository_js_3.upsertSubscription)(tx, { tenantId, planKey: plan.key, subscription });
|
|
136
|
+
await (0, repository_js_3.appendDomainEvents)(tx, row.rowId, domainEvents);
|
|
137
|
+
await (0, audit_js_1.appendAudit)(tx, {
|
|
138
|
+
actorId: input.operatorUserId,
|
|
139
|
+
action: 'tenant.provisioned_by_operator',
|
|
140
|
+
resourceType: 'tenant',
|
|
141
|
+
resourceId: tenantId,
|
|
142
|
+
metadata: { planKey: plan.key, trialEndsAt, tenantCode: code, ownerEmail: email },
|
|
143
|
+
ip: input.ip ?? null,
|
|
144
|
+
userAgent: input.userAgent ?? null,
|
|
145
|
+
});
|
|
146
|
+
return {
|
|
147
|
+
tenantId,
|
|
148
|
+
tenantCode: code,
|
|
149
|
+
ownerUserId: invited.userId,
|
|
150
|
+
ownerEmail: invited.email,
|
|
151
|
+
planKey: plan.key,
|
|
152
|
+
trialEndsAt,
|
|
153
|
+
activationToken: invited.activationToken,
|
|
154
|
+
};
|
|
155
|
+
});
|
|
92
156
|
}
|
|
93
157
|
function slugify(name) {
|
|
94
158
|
return name
|
|
@@ -99,6 +163,31 @@ function slugify(name) {
|
|
|
99
163
|
.replace(/^-+|-+$/g, '')
|
|
100
164
|
.slice(0, 40);
|
|
101
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Código do escritório a partir do nome, único na base.
|
|
168
|
+
*
|
|
169
|
+
* Extraído do signup quando o provisionamento pela operadora passou a precisar
|
|
170
|
+
* do mesmo cálculo. Duas cópias da regra de colisão renderiam dois códigos
|
|
171
|
+
* diferentes para o mesmo nome dependendo de por qual porta o escritório
|
|
172
|
+
* entrou — e o código aparece em referência de cobrança já emitida.
|
|
173
|
+
*/
|
|
174
|
+
async function uniqueTenantCode(db, companyName) {
|
|
175
|
+
const base = slugify(companyName) || 'escritorio';
|
|
176
|
+
let code = base;
|
|
177
|
+
for (let i = 2;; i += 1) {
|
|
178
|
+
const clash = await db `
|
|
179
|
+
SELECT id FROM tenant WHERE lower(code) = lower(${code}) AND deleted_at IS NULL
|
|
180
|
+
`;
|
|
181
|
+
if (!clash[0])
|
|
182
|
+
break;
|
|
183
|
+
code = `${base}-${i}`;
|
|
184
|
+
if (i > 50) {
|
|
185
|
+
code = `${base}-${(0, shared_1.uuidv7)().slice(-6)}`;
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return code;
|
|
190
|
+
}
|
|
102
191
|
/**
|
|
103
192
|
* Cadastro self-service (Fase 17): cria usuário + tenant em TRIAL + organização +
|
|
104
193
|
* membership com papel `owner` + entitlement do produto + assinatura `trialing`.
|
|
@@ -112,7 +201,7 @@ async function signupSelfService(db, input, nowIso) {
|
|
|
112
201
|
throw new shared_1.ValidationError('Senha deve ter ao menos 8 caracteres');
|
|
113
202
|
if (!input.companyName.trim())
|
|
114
203
|
throw new shared_1.ValidationError('Nome da empresa é obrigatório');
|
|
115
|
-
const plan = await (0,
|
|
204
|
+
const plan = await (0, repository_js_3.getPlan)(db, input.planKey);
|
|
116
205
|
if (!plan || !plan.isActive || !plan.isPublic) {
|
|
117
206
|
throw new shared_1.ValidationError(`Plano indisponível: ${input.planKey}`);
|
|
118
207
|
}
|
|
@@ -123,20 +212,7 @@ async function signupSelfService(db, input, nowIso) {
|
|
|
123
212
|
throw new shared_1.ConflictError('Já existe uma conta com este e-mail. Faça login para continuar.');
|
|
124
213
|
}
|
|
125
214
|
// Código único do tenant a partir do nome (sufixo em caso de colisão).
|
|
126
|
-
const
|
|
127
|
-
let code = base;
|
|
128
|
-
for (let i = 2;; i += 1) {
|
|
129
|
-
const clash = await db `
|
|
130
|
-
SELECT id FROM tenant WHERE lower(code) = lower(${code}) AND deleted_at IS NULL
|
|
131
|
-
`;
|
|
132
|
-
if (!clash[0])
|
|
133
|
-
break;
|
|
134
|
-
code = `${base}-${i}`;
|
|
135
|
-
if (i > 50) {
|
|
136
|
-
code = `${base}-${(0, shared_1.uuidv7)().slice(-6)}`;
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
215
|
+
const code = await uniqueTenantCode(db, input.companyName);
|
|
140
216
|
// INSERT puro (não upsert): o papel de app pode CRIAR credencial, nunca
|
|
141
217
|
// sobrescrever (REVOKE UPDATE em user_credential — anti account-takeover).
|
|
142
218
|
// A checagem de e-mail acima já garante que o usuário é novo.
|
|
@@ -159,13 +235,13 @@ async function signupSelfService(db, input, nowIso) {
|
|
|
159
235
|
await (0, provisioning_js_1.ensureOrganization)(db, tenantId, input.companyName.trim());
|
|
160
236
|
await (0, provisioning_js_1.ensureMembership)(db, tenantId, user.id);
|
|
161
237
|
await (0, provisioning_js_1.assignSystemRole)(db, tenantId, user.id, 'owner');
|
|
162
|
-
await (0,
|
|
163
|
-
await (0,
|
|
238
|
+
await (0, repository_js_2.ensureProductCatalog)(db);
|
|
239
|
+
await (0, repository_js_2.ensureTenantProduct)(db, tenantId, 'contabil');
|
|
164
240
|
const trialEndsAt = addDays(nowIso, plan.trialDays > 0 ? plan.trialDays : 14);
|
|
165
241
|
const { subscription, domainEvents } = (0, reconcile_js_1.startTrial)(tenantId, plan.key, trialEndsAt, nowIso);
|
|
166
242
|
await (0, context_js_1.withContext)(db, { tenantId, userId: user.id }, async (tx) => {
|
|
167
|
-
const row = await (0,
|
|
168
|
-
await (0,
|
|
243
|
+
const row = await (0, repository_js_3.upsertSubscription)(tx, { tenantId, planKey: plan.key, subscription });
|
|
244
|
+
await (0, repository_js_3.appendDomainEvents)(tx, row.rowId, domainEvents);
|
|
169
245
|
await (0, audit_js_1.appendAudit)(tx, {
|
|
170
246
|
actorId: user.id,
|
|
171
247
|
action: 'signup',
|
|
@@ -212,16 +288,16 @@ function entitlementsForPlan(sub, plan, nowIso) {
|
|
|
212
288
|
}
|
|
213
289
|
async function subscriptionOverview(db, ctx, nowIso) {
|
|
214
290
|
const { sub, invoices, events } = await (0, context_js_1.withContext)(db, ctx, async (tx) => {
|
|
215
|
-
const sub0 = await (0,
|
|
291
|
+
const sub0 = await (0, repository_js_3.getSubscription)(tx);
|
|
216
292
|
return {
|
|
217
293
|
sub: sub0,
|
|
218
|
-
invoices: sub0 ? await (0,
|
|
219
|
-
events: sub0 ? await (0,
|
|
294
|
+
invoices: sub0 ? await (0, repository_js_3.listInvoices)(tx) : [],
|
|
295
|
+
events: sub0 ? await (0, repository_js_3.listBillingEvents)(tx, 20) : [],
|
|
220
296
|
};
|
|
221
297
|
});
|
|
222
298
|
// Fora da transação: getPlan usa outra conexão do pool — dentro dela seria
|
|
223
299
|
// um segundo checkout de conexão com transação aberta (deadlock de pool).
|
|
224
|
-
const plan = sub ? await (0,
|
|
300
|
+
const plan = sub ? await (0, repository_js_3.getPlan)(db, sub.planKey) : null;
|
|
225
301
|
return {
|
|
226
302
|
subscription: sub,
|
|
227
303
|
plan,
|
|
@@ -238,7 +314,7 @@ async function subscriptionOverview(db, ctx, nowIso) {
|
|
|
238
314
|
* manual (backoffice) — nunca cobra por falta de configuração.
|
|
239
315
|
*/
|
|
240
316
|
async function startCheckout(db, ctx, source, planKey, _nowIso, productKey = plans_js_1.DEFAULT_PRODUCT_KEY) {
|
|
241
|
-
const plan = await (0,
|
|
317
|
+
const plan = await (0, repository_js_3.getPlan)(db, planKey, productKey);
|
|
242
318
|
if (!plan || !plan.isActive || !plan.isPublic) {
|
|
243
319
|
throw new shared_1.ValidationError(`Plano indisponível: ${planKey}`);
|
|
244
320
|
}
|
|
@@ -270,7 +346,7 @@ async function startCheckout(db, ctx, source, planKey, _nowIso, productKey = pla
|
|
|
270
346
|
const userRows = await tx `
|
|
271
347
|
SELECT email FROM "user" WHERE id = ${ctx.userId}
|
|
272
348
|
`;
|
|
273
|
-
const sub = await (0,
|
|
349
|
+
const sub = await (0, repository_js_3.getSubscription)(tx);
|
|
274
350
|
return {
|
|
275
351
|
tenantName: tenantRows[0]?.display_name ?? 'Tenant Baruk',
|
|
276
352
|
email: userRows[0]?.email ?? null,
|
|
@@ -297,8 +373,8 @@ async function startCheckout(db, ctx, source, planKey, _nowIso, productKey = pla
|
|
|
297
373
|
// 3) Persistência curta: SOMENTE as referências de provider (nunca o estado
|
|
298
374
|
// da assinatura — um webhook pode tê-la mudado durante a chamada de rede).
|
|
299
375
|
await (0, context_js_1.withContext)(db, ctx, async (tx) => {
|
|
300
|
-
await (0,
|
|
301
|
-
await (0,
|
|
376
|
+
await (0, repository_js_3.lockTenantBilling)(tx, ctx.tenantId);
|
|
377
|
+
await (0, repository_js_3.setSubscriptionProviderRefs)(tx, ctx.tenantId, provider.name, customer.externalId);
|
|
302
378
|
await (0, audit_js_1.appendAudit)(tx, {
|
|
303
379
|
actorId: ctx.userId,
|
|
304
380
|
action: 'checkout_started',
|
|
@@ -355,7 +431,7 @@ async function processWebhook(db, source, headers, rawBody, payload, nowIso, pro
|
|
|
355
431
|
const event = provider.parseWebhookEvent(payload);
|
|
356
432
|
if (!event)
|
|
357
433
|
return { outcome: 'ignored' };
|
|
358
|
-
const webhookId = await (0,
|
|
434
|
+
const webhookId = await (0, repository_js_3.insertWebhookEvent)(db, {
|
|
359
435
|
provider: provider.name,
|
|
360
436
|
externalEventId: event.externalEventId,
|
|
361
437
|
eventType: event.eventType,
|
|
@@ -372,7 +448,7 @@ async function processWebhook(db, source, headers, rawBody, payload, nowIso, pro
|
|
|
372
448
|
async function reconcileStoredWebhookEvent(db, provider, event, webhookId, nowIso, expectedProductKey = plans_js_1.DEFAULT_PRODUCT_KEY) {
|
|
373
449
|
const attribution = parseAttribution(event);
|
|
374
450
|
if (!attribution) {
|
|
375
|
-
await (0,
|
|
451
|
+
await (0, repository_js_3.markWebhookEvent)(db, webhookId, 'ignored', null, 'externalReference ausente/inválida');
|
|
376
452
|
return { outcome: 'ignored' };
|
|
377
453
|
}
|
|
378
454
|
// ISOLAMENTO FINANCEIRO: a conta que assinou o webhook é a conta de UM
|
|
@@ -380,15 +456,15 @@ async function reconcileStoredWebhookEvent(db, provider, event, webhookId, nowIs
|
|
|
380
456
|
// errada no gateway — ou é tentativa de mover dinheiro entre produtos.
|
|
381
457
|
// Recusar é obrigatório: reconciliar aqui escreveria na assinatura errada.
|
|
382
458
|
if (attribution.productKey !== expectedProductKey) {
|
|
383
|
-
await (0,
|
|
459
|
+
await (0, repository_js_3.markWebhookEvent)(db, webhookId, 'ignored', null, `produto divergente: evento=${attribution.productKey} conta=${expectedProductKey}`);
|
|
384
460
|
return { outcome: 'ignored' };
|
|
385
461
|
}
|
|
386
462
|
try {
|
|
387
|
-
const plan = await (0,
|
|
463
|
+
const plan = await (0, repository_js_3.getPlan)(db, attribution.planKey, attribution.productKey);
|
|
388
464
|
const { tenantId } = attribution;
|
|
389
465
|
const applied = await (0, context_js_1.withContext)(db, { tenantId }, async (tx) => {
|
|
390
|
-
await (0,
|
|
391
|
-
const current = await (0,
|
|
466
|
+
await (0, repository_js_3.lockTenantBilling)(tx, tenantId);
|
|
467
|
+
const current = await (0, repository_js_3.getSubscription)(tx);
|
|
392
468
|
// Guarda de ordenação (webhook atrasado): um OVERDUE que chega DEPOIS do
|
|
393
469
|
// pagamento do mesmo ciclo (período corrente ainda vigente) é obsoleto —
|
|
394
470
|
// aplicá-lo marcaria past_due uma assinatura em dia. Política de
|
|
@@ -448,7 +524,7 @@ async function reconcileStoredWebhookEvent(db, provider, event, webhookId, nowIs
|
|
|
448
524
|
currentPeriodEnd: addMonths(nowIso, plan.periodicity === 'yearly' ? 12 : 3),
|
|
449
525
|
};
|
|
450
526
|
}
|
|
451
|
-
const row = await (0,
|
|
527
|
+
const row = await (0, repository_js_3.upsertSubscription)(tx, {
|
|
452
528
|
tenantId,
|
|
453
529
|
planKey: effectivePlanKey ?? current?.planKey ?? next.items[0]?.planKey ?? 'starter',
|
|
454
530
|
subscription: next,
|
|
@@ -456,9 +532,9 @@ async function reconcileStoredWebhookEvent(db, provider, event, webhookId, nowIs
|
|
|
456
532
|
providerCustomerId: event.externalCustomerId ?? null,
|
|
457
533
|
providerSubscriptionId: event.subscription?.externalId ?? null,
|
|
458
534
|
});
|
|
459
|
-
await (0,
|
|
535
|
+
await (0, repository_js_3.appendDomainEvents)(tx, row.rowId, domainEvents);
|
|
460
536
|
if (event.invoice) {
|
|
461
|
-
await (0,
|
|
537
|
+
await (0, repository_js_3.upsertInvoice)(tx, {
|
|
462
538
|
tenantId,
|
|
463
539
|
subscriptionRowId: row.rowId,
|
|
464
540
|
provider: provider.name,
|
|
@@ -486,25 +562,25 @@ async function reconcileStoredWebhookEvent(db, provider, event, webhookId, nowIs
|
|
|
486
562
|
return null;
|
|
487
563
|
});
|
|
488
564
|
if (applied !== null) {
|
|
489
|
-
await (0,
|
|
565
|
+
await (0, repository_js_3.markWebhookEvent)(db, webhookId, 'ignored', attribution.tenantId, applied);
|
|
490
566
|
return { outcome: 'ignored', tenantId: attribution.tenantId };
|
|
491
567
|
}
|
|
492
|
-
await (0,
|
|
568
|
+
await (0, repository_js_3.markWebhookEvent)(db, webhookId, 'processed', attribution.tenantId);
|
|
493
569
|
return { outcome: 'processed', tenantId: attribution.tenantId };
|
|
494
570
|
}
|
|
495
571
|
catch (err) {
|
|
496
|
-
await (0,
|
|
572
|
+
await (0, repository_js_3.markWebhookEvent)(db, webhookId, 'failed', attribution.tenantId, err instanceof Error ? err.message : String(err));
|
|
497
573
|
return { outcome: 'failed', tenantId: attribution.tenantId };
|
|
498
574
|
}
|
|
499
575
|
}
|
|
500
576
|
// ── Gestão da assinatura (tenant) ────────────────────────────────────────────
|
|
501
577
|
async function changePlanForTenant(db, ctx, newPlanKey, nowIso) {
|
|
502
|
-
const plan = await (0,
|
|
578
|
+
const plan = await (0, repository_js_3.getPlan)(db, newPlanKey);
|
|
503
579
|
if (!plan || !plan.isActive)
|
|
504
580
|
throw new shared_1.ValidationError(`Plano desconhecido: ${newPlanKey}`);
|
|
505
581
|
return (0, context_js_1.withContext)(db, ctx, async (tx) => {
|
|
506
|
-
await (0,
|
|
507
|
-
const current = await (0,
|
|
582
|
+
await (0, repository_js_3.lockTenantBilling)(tx, ctx.tenantId);
|
|
583
|
+
const current = await (0, repository_js_3.getSubscription)(tx);
|
|
508
584
|
if (!current)
|
|
509
585
|
throw new shared_1.NotFoundError('Nenhuma assinatura para este tenant');
|
|
510
586
|
if (current.status === 'canceled') {
|
|
@@ -513,12 +589,12 @@ async function changePlanForTenant(db, ctx, newPlanKey, nowIso) {
|
|
|
513
589
|
if (current.planKey === plan.key)
|
|
514
590
|
return current;
|
|
515
591
|
const { subscription, domainEvents } = (0, reconcile_js_1.changePlan)(current, plan.key, nowIso);
|
|
516
|
-
const row = await (0,
|
|
592
|
+
const row = await (0, repository_js_3.upsertSubscription)(tx, {
|
|
517
593
|
tenantId: ctx.tenantId,
|
|
518
594
|
planKey: plan.key,
|
|
519
595
|
subscription,
|
|
520
596
|
});
|
|
521
|
-
await (0,
|
|
597
|
+
await (0, repository_js_3.appendDomainEvents)(tx, row.rowId, domainEvents);
|
|
522
598
|
await (0, audit_js_1.appendAudit)(tx, {
|
|
523
599
|
actorId: ctx.userId,
|
|
524
600
|
action: 'plan_changed',
|
|
@@ -547,7 +623,7 @@ async function changePlanForTenant(db, ctx, newPlanKey, nowIso) {
|
|
|
547
623
|
*/
|
|
548
624
|
async function cancelForTenant(db, ctx, source, nowIso, productKey = plans_js_1.DEFAULT_PRODUCT_KEY) {
|
|
549
625
|
// Fora da transação: chamada de rede não pode segurar o lock do tenant.
|
|
550
|
-
const existing = await (0, context_js_1.withContext)(db, ctx, (tx) => (0,
|
|
626
|
+
const existing = await (0, context_js_1.withContext)(db, ctx, (tx) => (0, repository_js_3.getSubscription)(tx, productKey));
|
|
551
627
|
if (!existing)
|
|
552
628
|
throw new shared_1.NotFoundError('Nenhuma assinatura para este tenant');
|
|
553
629
|
let providerOutcome = 'skipped_no_provider_id';
|
|
@@ -563,8 +639,8 @@ async function cancelForTenant(db, ctx, source, nowIso, productKey = plans_js_1.
|
|
|
563
639
|
}
|
|
564
640
|
}
|
|
565
641
|
return (0, context_js_1.withContext)(db, ctx, async (tx) => {
|
|
566
|
-
await (0,
|
|
567
|
-
const current = await (0,
|
|
642
|
+
await (0, repository_js_3.lockTenantBilling)(tx, ctx.tenantId);
|
|
643
|
+
const current = await (0, repository_js_3.getSubscription)(tx, productKey);
|
|
568
644
|
if (!current)
|
|
569
645
|
throw new shared_1.NotFoundError('Nenhuma assinatura para este tenant');
|
|
570
646
|
// Idempotência: cancelar o que já está cancelado devolve o estado, sem erro
|
|
@@ -572,12 +648,12 @@ async function cancelForTenant(db, ctx, source, nowIso, productKey = plans_js_1.
|
|
|
572
648
|
if (current.status === 'canceled')
|
|
573
649
|
return current;
|
|
574
650
|
const { subscription, domainEvents } = (0, reconcile_js_1.cancelSubscription)(current, nowIso);
|
|
575
|
-
const row = await (0,
|
|
651
|
+
const row = await (0, repository_js_3.upsertSubscription)(tx, {
|
|
576
652
|
tenantId: ctx.tenantId,
|
|
577
653
|
planKey: current.planKey,
|
|
578
654
|
subscription,
|
|
579
655
|
});
|
|
580
|
-
await (0,
|
|
656
|
+
await (0, repository_js_3.appendDomainEvents)(tx, row.rowId, domainEvents);
|
|
581
657
|
await syncTenantStatus(tx, ctx.tenantId, subscription.status);
|
|
582
658
|
await (0, audit_js_1.appendAudit)(tx, {
|
|
583
659
|
actorId: ctx.userId,
|
|
@@ -597,7 +673,7 @@ async function cancelForTenant(db, ctx, source, nowIso, productKey = plans_js_1.
|
|
|
597
673
|
* devolve o checkout; em modo 'disabled' a reativação é manual (backoffice).
|
|
598
674
|
*/
|
|
599
675
|
async function reactivateForTenant(db, ctx, source, nowIso, productKey = plans_js_1.DEFAULT_PRODUCT_KEY) {
|
|
600
|
-
const sub = await (0, context_js_1.withContext)(db, ctx, (tx) => (0,
|
|
676
|
+
const sub = await (0, context_js_1.withContext)(db, ctx, (tx) => (0, repository_js_3.getSubscription)(tx, productKey));
|
|
601
677
|
if (!sub)
|
|
602
678
|
throw new shared_1.NotFoundError('Nenhuma assinatura para este tenant');
|
|
603
679
|
if (sub.status === 'active' || sub.status === 'trialing') {
|
|
@@ -607,10 +683,10 @@ async function reactivateForTenant(db, ctx, source, nowIso, productKey = plans_j
|
|
|
607
683
|
}
|
|
608
684
|
// ── Backoffice (operadora) ───────────────────────────────────────────────────
|
|
609
685
|
async function backofficeListSubscriptions(db, filter = {}) {
|
|
610
|
-
return (0,
|
|
686
|
+
return (0, repository_js_3.withOperatorContext)(db, (tx) => (0, repository_js_3.listAllSubscriptions)(tx, filter));
|
|
611
687
|
}
|
|
612
688
|
async function backofficeOverview(db) {
|
|
613
|
-
return (0,
|
|
689
|
+
return (0, repository_js_3.withOperatorContext)(db, (tx) => (0, repository_js_3.backofficeSummary)(tx));
|
|
614
690
|
}
|
|
615
691
|
async function backofficeListWebhookEvents(db, limit = 100) {
|
|
616
692
|
const rows = await db `
|
|
@@ -635,12 +711,12 @@ async function backofficeListWebhookEvents(db, limit = 100) {
|
|
|
635
711
|
* nenhuma transição de estado fora do domínio puro.
|
|
636
712
|
*/
|
|
637
713
|
async function backofficeActivateSubscription(db, operatorEmail, tenantId, planKey, nowIso) {
|
|
638
|
-
const plan = await (0,
|
|
714
|
+
const plan = await (0, repository_js_3.getPlan)(db, planKey);
|
|
639
715
|
if (!plan)
|
|
640
716
|
throw new shared_1.ValidationError(`Plano desconhecido: ${planKey}`);
|
|
641
717
|
return (0, context_js_1.withContext)(db, { tenantId }, async (tx) => {
|
|
642
|
-
await (0,
|
|
643
|
-
const current = await (0,
|
|
718
|
+
await (0, repository_js_3.lockTenantBilling)(tx, tenantId);
|
|
719
|
+
const current = await (0, repository_js_3.getSubscription)(tx);
|
|
644
720
|
const manualEvent = {
|
|
645
721
|
externalEventId: `manual_${(0, shared_1.uuidv7)()}`,
|
|
646
722
|
eventType: 'manual.activation',
|
|
@@ -661,14 +737,14 @@ async function backofficeActivateSubscription(db, operatorEmail, tenantId, planK
|
|
|
661
737
|
event: manualEvent,
|
|
662
738
|
now: nowIso,
|
|
663
739
|
});
|
|
664
|
-
const row = await (0,
|
|
740
|
+
const row = await (0, repository_js_3.upsertSubscription)(tx, {
|
|
665
741
|
tenantId,
|
|
666
742
|
planKey: plan.key,
|
|
667
743
|
subscription,
|
|
668
744
|
provider: 'manual',
|
|
669
745
|
});
|
|
670
|
-
await (0,
|
|
671
|
-
await (0,
|
|
746
|
+
await (0, repository_js_3.appendDomainEvents)(tx, row.rowId, domainEvents);
|
|
747
|
+
await (0, repository_js_3.upsertInvoice)(tx, {
|
|
672
748
|
tenantId,
|
|
673
749
|
subscriptionRowId: row.rowId,
|
|
674
750
|
provider: 'manual',
|
|
@@ -697,14 +773,14 @@ async function backofficeActivateSubscription(db, operatorEmail, tenantId, planK
|
|
|
697
773
|
async function retryFailedWebhookEvents(db, source, nowIso, limit = 25, productKey = plans_js_1.DEFAULT_PRODUCT_KEY) {
|
|
698
774
|
const cfg = asRegistry(source).resolve({ productKey });
|
|
699
775
|
const provider = providerFor(cfg);
|
|
700
|
-
const failed = await (0,
|
|
776
|
+
const failed = await (0, repository_js_3.listFailedWebhookEvents)(db, limit);
|
|
701
777
|
let recovered = 0;
|
|
702
778
|
for (const row of failed) {
|
|
703
779
|
if (row.provider !== provider.name)
|
|
704
780
|
continue;
|
|
705
781
|
const event = provider.parseWebhookEvent(row.payload);
|
|
706
782
|
if (!event) {
|
|
707
|
-
await (0,
|
|
783
|
+
await (0, repository_js_3.markWebhookEvent)(db, row.id, 'ignored', null, 'payload não parseável no reprocessamento');
|
|
708
784
|
continue;
|
|
709
785
|
}
|
|
710
786
|
const result = await reconcileStoredWebhookEvent(db, provider, event, row.id, nowIso, productKey);
|
|
@@ -748,7 +824,7 @@ async function runBillingCron(db, source, nowIso) {
|
|
|
748
824
|
report.webhooksRetried += retry.retried;
|
|
749
825
|
report.webhooksRecovered += retry.recovered;
|
|
750
826
|
}
|
|
751
|
-
const subs = await (0,
|
|
827
|
+
const subs = await (0, repository_js_3.withOperatorContext)(db, (tx) => (0, repository_js_3.listSubscriptionsForCron)(tx, today));
|
|
752
828
|
report.examined = subs.length;
|
|
753
829
|
for (const sub of subs) {
|
|
754
830
|
// Isolamento de falha: um tenant quebrado não pode derrubar a régua dos demais.
|
|
@@ -758,8 +834,8 @@ async function runBillingCron(db, source, nowIso) {
|
|
|
758
834
|
// assinatura — nunca de uma configuração global compartilhada.
|
|
759
835
|
const cfg = registry.resolve({ productKey: sub.productKey, tenantId: sub.tenantId });
|
|
760
836
|
await (0, context_js_1.withContext)(db, { tenantId: sub.tenantId }, async (tx) => {
|
|
761
|
-
await (0,
|
|
762
|
-
const loaded = await (0,
|
|
837
|
+
await (0, repository_js_3.lockTenantBilling)(tx, sub.tenantId);
|
|
838
|
+
const loaded = await (0, repository_js_3.getSubscription)(tx, sub.productKey);
|
|
763
839
|
if (!loaded)
|
|
764
840
|
return; // sumiu entre o scan e o lock (ex.: tenant removido)
|
|
765
841
|
let current = loaded;
|
|
@@ -801,30 +877,30 @@ async function runBillingCron(db, source, nowIso) {
|
|
|
801
877
|
...subscription,
|
|
802
878
|
currentPeriodEnd: subscription.currentPeriodEnd ?? reference,
|
|
803
879
|
};
|
|
804
|
-
const row = await (0,
|
|
880
|
+
const row = await (0, repository_js_3.upsertSubscription)(tx, {
|
|
805
881
|
tenantId: current.tenantId,
|
|
806
882
|
planKey: current.planKey,
|
|
807
883
|
subscription: next,
|
|
808
884
|
});
|
|
809
|
-
await (0,
|
|
885
|
+
await (0, repository_js_3.appendDomainEvents)(tx, row.rowId, domainEvents);
|
|
810
886
|
await (0, audit_js_1.appendAudit)(tx, {
|
|
811
887
|
actorType: 'automation',
|
|
812
888
|
action: trialExpired ? 'trial_expired' : 'period_expired',
|
|
813
889
|
resourceType: 'saas_subscription',
|
|
814
890
|
resourceId: row.rowId,
|
|
815
891
|
});
|
|
816
|
-
current = (await (0,
|
|
892
|
+
current = (await (0, repository_js_3.getSubscription)(tx));
|
|
817
893
|
}
|
|
818
894
|
}
|
|
819
895
|
// 2. Régua de inadimplência (idempotente por stepKey + reference_date).
|
|
820
896
|
if (current.status === 'past_due') {
|
|
821
897
|
const reference = current.currentPeriodEnd ?? current.trialEndsAt ?? today;
|
|
822
|
-
const executed = await (0,
|
|
898
|
+
const executed = await (0, repository_js_3.listExecutedDunningSteps)(tx, current.rowId, reference);
|
|
823
899
|
const events = (0, dunning_js_1.dunningStepsAsEvents)({ ...current, currentPeriodEnd: reference }, today, executed);
|
|
824
900
|
for (const ev of events) {
|
|
825
901
|
const stepKey = ev.data.dunningStep?.stepKey ??
|
|
826
902
|
`step_${ev.sequence}`;
|
|
827
|
-
await (0,
|
|
903
|
+
await (0, repository_js_3.recordDunningStep)(tx, {
|
|
828
904
|
tenantId: current.tenantId,
|
|
829
905
|
subscriptionRowId: current.rowId,
|
|
830
906
|
stepKey,
|
|
@@ -833,9 +909,9 @@ async function runBillingCron(db, source, nowIso) {
|
|
|
833
909
|
report.dunningStepsExecuted += 1;
|
|
834
910
|
}
|
|
835
911
|
if (events.length > 0) {
|
|
836
|
-
await (0,
|
|
912
|
+
await (0, repository_js_3.appendDomainEvents)(tx, current.rowId, events);
|
|
837
913
|
dunningEmailTo = await ownerEmailForTenant(tx, current.tenantId);
|
|
838
|
-
await (0,
|
|
914
|
+
await (0, repository_js_3.upsertSubscription)(tx, {
|
|
839
915
|
tenantId: current.tenantId,
|
|
840
916
|
planKey: current.planKey,
|
|
841
917
|
subscription: { ...current, sequence: current.sequence + events.length },
|