@baruk/core 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.baruk-provenance.json +4 -4
- package/CHANGELOG.md +42 -0
- package/dist/audit/repository.d.ts +33 -1
- package/dist/audit/repository.d.ts.map +1 -1
- package/dist/audit/repository.js +41 -7
- package/dist/audit/repository.js.map +1 -1
- package/dist/auth/service.d.ts +21 -0
- package/dist/auth/service.d.ts.map +1 -1
- package/dist/auth/service.js +46 -1
- package/dist/auth/service.js.map +1 -1
- package/dist/billing/ar-repository.d.ts +41 -1
- package/dist/billing/ar-repository.d.ts.map +1 -1
- package/dist/billing/ar-repository.js +82 -6
- package/dist/billing/ar-repository.js.map +1 -1
- package/dist/billing/provider-account.d.ts +38 -0
- package/dist/billing/provider-account.d.ts.map +1 -1
- package/dist/billing/provider-account.js +58 -2
- package/dist/billing/provider-account.js.map +1 -1
- package/dist/billing/repository.d.ts +44 -0
- package/dist/billing/repository.d.ts.map +1 -1
- package/dist/billing/repository.js +49 -5
- package/dist/billing/repository.js.map +1 -1
- package/dist/cjs/audit/repository.js +41 -7
- package/dist/cjs/audit/repository.js.map +1 -1
- package/dist/cjs/auth/service.js +46 -1
- package/dist/cjs/auth/service.js.map +1 -1
- package/dist/cjs/billing/ar-repository.js +82 -6
- package/dist/cjs/billing/ar-repository.js.map +1 -1
- package/dist/cjs/billing/provider-account.js +60 -1
- package/dist/cjs/billing/provider-account.js.map +1 -1
- package/dist/cjs/billing/repository.js +51 -5
- package/dist/cjs/billing/repository.js.map +1 -1
- package/dist/cjs/clients/ibge.js +117 -0
- package/dist/cjs/clients/ibge.js.map +1 -0
- package/dist/cjs/clients/registry/http.js +157 -0
- package/dist/cjs/clients/registry/http.js.map +1 -0
- package/dist/cjs/clients/registry/ibge-municipios.js +28 -0
- package/dist/cjs/clients/registry/ibge-municipios.js.map +1 -0
- package/dist/cjs/clients/registry/ibge.js +63 -0
- package/dist/cjs/clients/registry/ibge.js.map +1 -0
- package/dist/cjs/clients/registry/lookup.js +191 -0
- package/dist/cjs/clients/registry/lookup.js.map +1 -0
- package/dist/cjs/clients/registry/provider.js +34 -0
- package/dist/cjs/clients/registry/provider.js.map +1 -0
- package/dist/cjs/clients/registry/resolve.js +47 -0
- package/dist/cjs/clients/registry/resolve.js.map +1 -0
- package/dist/cjs/clients/registry/serpro.js +149 -0
- package/dist/cjs/clients/registry/serpro.js.map +1 -0
- package/dist/cjs/clients/registry/service.js +230 -0
- package/dist/cjs/clients/registry/service.js.map +1 -0
- package/dist/cjs/clients/registry/synthetic.js +165 -0
- package/dist/cjs/clients/registry/synthetic.js.map +1 -0
- package/dist/cjs/clients/repository.js +190 -9
- package/dist/cjs/clients/repository.js.map +1 -1
- package/dist/cjs/collection/branding.js +190 -0
- package/dist/cjs/collection/branding.js.map +1 -1
- package/dist/cjs/collection/clearance-store.js +74 -0
- package/dist/cjs/collection/clearance-store.js.map +1 -0
- package/dist/cjs/collection/communication-runtime.js +65 -2
- package/dist/cjs/collection/communication-runtime.js.map +1 -1
- package/dist/cjs/collection/engine.js +20 -0
- package/dist/cjs/collection/engine.js.map +1 -1
- package/dist/cjs/collection/policy.js +29 -1
- package/dist/cjs/collection/policy.js.map +1 -1
- package/dist/cjs/communication/clearance.js +18 -0
- package/dist/cjs/communication/clearance.js.map +1 -0
- package/dist/cjs/communication/dry-run-scenario.js +5 -0
- package/dist/cjs/communication/dry-run-scenario.js.map +1 -1
- package/dist/cjs/communication/engine.js +12 -0
- package/dist/cjs/communication/engine.js.map +1 -1
- package/dist/cjs/communication/policy.js.map +1 -1
- package/dist/cjs/competence/business-days.js +155 -0
- package/dist/cjs/competence/business-days.js.map +1 -0
- package/dist/cjs/competence/catalog-validation.js +174 -0
- package/dist/cjs/competence/catalog-validation.js.map +1 -0
- package/dist/cjs/competence/obligation-preview.js +190 -0
- package/dist/cjs/competence/obligation-preview.js.map +1 -0
- package/dist/cjs/competence/repository.js +330 -17
- package/dist/cjs/competence/repository.js.map +1 -1
- package/dist/cjs/dashboard/pilot-panel.js +90 -0
- package/dist/cjs/dashboard/pilot-panel.js.map +1 -0
- package/dist/cjs/dashboard/repository.js +11 -1
- package/dist/cjs/dashboard/repository.js.map +1 -1
- package/dist/cjs/db/client.js +17 -11
- package/dist/cjs/db/client.js.map +1 -1
- package/dist/cjs/db/provision-e2e-identity.js +116 -0
- package/dist/cjs/db/provision-e2e-identity.js.map +1 -0
- package/dist/cjs/fiscal/applicability.js +164 -0
- package/dist/cjs/fiscal/applicability.js.map +1 -0
- package/dist/cjs/fiscal/collection/authorization.js +186 -0
- package/dist/cjs/fiscal/collection/authorization.js.map +1 -0
- package/dist/cjs/fiscal/collection/competence.js +97 -0
- package/dist/cjs/fiscal/collection/competence.js.map +1 -0
- package/dist/cjs/fiscal/collection/first-contact.js +204 -0
- package/dist/cjs/fiscal/collection/first-contact.js.map +1 -0
- package/dist/cjs/fiscal/collection/plan.js +122 -0
- package/dist/cjs/fiscal/collection/plan.js.map +1 -0
- package/dist/cjs/fiscal/conditions.js +198 -0
- package/dist/cjs/fiscal/conditions.js.map +1 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-contract.js +390 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-contract.js.map +1 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-endpoint.js +108 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-endpoint.js.map +1 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-envelope.js +220 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-envelope.js.map +1 -0
- package/dist/cjs/fiscal/coverage/model.js +137 -0
- package/dist/cjs/fiscal/coverage/model.js.map +1 -0
- package/dist/cjs/fiscal/coverage/requests.js +99 -0
- package/dist/cjs/fiscal/coverage/requests.js.map +1 -0
- package/dist/cjs/fiscal/credentials/inspect.js +182 -0
- package/dist/cjs/fiscal/credentials/inspect.js.map +1 -0
- package/dist/cjs/fiscal/credentials/material.js +168 -0
- package/dist/cjs/fiscal/credentials/material.js.map +1 -0
- package/dist/cjs/fiscal/credentials/onboarding.js +266 -0
- package/dist/cjs/fiscal/credentials/onboarding.js.map +1 -0
- package/dist/cjs/fiscal/credentials/readiness.js +190 -0
- package/dist/cjs/fiscal/credentials/readiness.js.map +1 -0
- package/dist/cjs/fiscal/eligibility.js +199 -0
- package/dist/cjs/fiscal/eligibility.js.map +1 -0
- package/dist/cjs/fiscal/enrollment.js +134 -0
- package/dist/cjs/fiscal/enrollment.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/__fixtures__/nfse.js +128 -0
- package/dist/cjs/fiscal/ingestion/__fixtures__/nfse.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/adn-transport.js +229 -0
- package/dist/cjs/fiscal/ingestion/adn-transport.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/direction.js +36 -0
- package/dist/cjs/fiscal/ingestion/direction.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/nfse-adn.js +228 -0
- package/dist/cjs/fiscal/ingestion/nfse-adn.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/pipeline.js +704 -0
- package/dist/cjs/fiscal/ingestion/pipeline.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/provider.js +51 -0
- package/dist/cjs/fiscal/ingestion/provider.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/repository.js +132 -0
- package/dist/cjs/fiscal/ingestion/repository.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/synthetic-provider.js +103 -0
- package/dist/cjs/fiscal/ingestion/synthetic-provider.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport-types.js +13 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport-types.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport.js +61 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/xml-reader.js +121 -0
- package/dist/cjs/fiscal/ingestion/xml-reader.js.map +1 -0
- package/dist/cjs/fiscal/repository.js +470 -0
- package/dist/cjs/fiscal/repository.js.map +1 -0
- package/dist/cjs/fiscal/sync/circuit.js +124 -0
- package/dist/cjs/fiscal/sync/circuit.js.map +1 -0
- package/dist/cjs/fiscal/sync/intervention.js +140 -0
- package/dist/cjs/fiscal/sync/intervention.js.map +1 -0
- package/dist/cjs/fiscal/sync/lease.js +146 -0
- package/dist/cjs/fiscal/sync/lease.js.map +1 -0
- package/dist/cjs/fiscal/sync/observability.js +244 -0
- package/dist/cjs/fiscal/sync/observability.js.map +1 -0
- package/dist/cjs/fiscal/sync/orchestrator.js +490 -0
- package/dist/cjs/fiscal/sync/orchestrator.js.map +1 -0
- package/dist/cjs/fiscal/sync/policy.js +143 -0
- package/dist/cjs/fiscal/sync/policy.js.map +1 -0
- package/dist/cjs/fiscal/sync/reprocess.js +241 -0
- package/dist/cjs/fiscal/sync/reprocess.js.map +1 -0
- package/dist/cjs/fiscal/sync/retry.js +183 -0
- package/dist/cjs/fiscal/sync/retry.js.map +1 -0
- package/dist/cjs/fiscal/sync/secret-boundary.js +123 -0
- package/dist/cjs/fiscal/sync/secret-boundary.js.map +1 -0
- package/dist/cjs/fiscal/transport/https.js +309 -0
- package/dist/cjs/fiscal/transport/https.js.map +1 -0
- package/dist/cjs/fiscal/transport/synthetic-tls.js +380 -0
- package/dist/cjs/fiscal/transport/synthetic-tls.js.map +1 -0
- package/dist/cjs/fiscal/transport/types.js +93 -0
- package/dist/cjs/fiscal/transport/types.js.map +1 -0
- package/dist/cjs/import/br-documents.js +85 -0
- package/dist/cjs/import/br-documents.js.map +1 -0
- package/dist/cjs/import/clients-import.js +347 -40
- package/dist/cjs/import/clients-import.js.map +1 -1
- package/dist/cjs/index.js +461 -73
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/legal/documents.js +164 -19
- package/dist/cjs/legal/documents.js.map +1 -1
- package/dist/cjs/legal/index.js +3 -1
- package/dist/cjs/legal/index.js.map +1 -1
- package/dist/cjs/legal/types.js.map +1 -1
- package/dist/cjs/onboarding/persistence.js +4 -4
- package/dist/cjs/onboarding/persistence.js.map +1 -1
- package/dist/cjs/pilot/go-live-checklist.js +212 -0
- package/dist/cjs/pilot/go-live-checklist.js.map +1 -0
- package/dist/cjs/pilot/milestone.js +79 -0
- package/dist/cjs/pilot/milestone.js.map +1 -0
- package/dist/cjs/platform/capabilities.js +173 -0
- package/dist/cjs/platform/capabilities.js.map +1 -0
- package/dist/cjs/platform/job-contract.js +411 -0
- package/dist/cjs/platform/job-contract.js.map +1 -0
- package/dist/cjs/rbac/catalog.js +110 -0
- package/dist/cjs/rbac/catalog.js.map +1 -1
- package/dist/cjs/subscription-billing/index.js +9 -1
- package/dist/cjs/subscription-billing/index.js.map +1 -1
- package/dist/cjs/subscription-billing/platform-exemption.js +121 -0
- package/dist/cjs/subscription-billing/platform-exemption.js.map +1 -0
- package/dist/cjs/subscription-billing/service.js +246 -78
- package/dist/cjs/subscription-billing/service.js.map +1 -1
- package/dist/cjs/tenancy/features.js +131 -0
- package/dist/cjs/tenancy/features.js.map +1 -0
- package/dist/cjs/tenancy/settings.js +224 -0
- package/dist/cjs/tenancy/settings.js.map +1 -0
- package/dist/cjs/users/repository.js +24 -1
- package/dist/cjs/users/repository.js.map +1 -1
- package/dist/cjs/vault/repository.js +92 -5
- package/dist/cjs/vault/repository.js.map +1 -1
- package/dist/clients/ibge.d.ts +17 -0
- package/dist/clients/ibge.d.ts.map +1 -0
- package/dist/clients/ibge.js +112 -0
- package/dist/clients/ibge.js.map +1 -0
- package/dist/clients/registry/http.d.ts +61 -0
- package/dist/clients/registry/http.d.ts.map +1 -0
- package/dist/clients/registry/http.js +151 -0
- package/dist/clients/registry/http.js.map +1 -0
- package/dist/clients/registry/ibge-municipios.d.ts +25 -0
- package/dist/clients/registry/ibge-municipios.d.ts.map +1 -0
- package/dist/clients/registry/ibge-municipios.js +25 -0
- package/dist/clients/registry/ibge-municipios.js.map +1 -0
- package/dist/clients/registry/ibge.d.ts +62 -0
- package/dist/clients/registry/ibge.d.ts.map +1 -0
- package/dist/clients/registry/ibge.js +57 -0
- package/dist/clients/registry/ibge.js.map +1 -0
- package/dist/clients/registry/lookup.d.ts +94 -0
- package/dist/clients/registry/lookup.d.ts.map +1 -0
- package/dist/clients/registry/lookup.js +184 -0
- package/dist/clients/registry/lookup.js.map +1 -0
- package/dist/clients/registry/provider.d.ts +124 -0
- package/dist/clients/registry/provider.d.ts.map +1 -0
- package/dist/clients/registry/provider.js +39 -0
- package/dist/clients/registry/provider.js.map +1 -0
- package/dist/clients/registry/resolve.d.ts +36 -0
- package/dist/clients/registry/resolve.d.ts.map +1 -0
- package/dist/clients/registry/resolve.js +44 -0
- package/dist/clients/registry/resolve.js.map +1 -0
- package/dist/clients/registry/serpro.d.ts +57 -0
- package/dist/clients/registry/serpro.d.ts.map +1 -0
- package/dist/clients/registry/serpro.js +143 -0
- package/dist/clients/registry/serpro.js.map +1 -0
- package/dist/clients/registry/service.d.ts +59 -0
- package/dist/clients/registry/service.d.ts.map +1 -0
- package/dist/clients/registry/service.js +225 -0
- package/dist/clients/registry/service.js.map +1 -0
- package/dist/clients/registry/synthetic.d.ts +30 -0
- package/dist/clients/registry/synthetic.d.ts.map +1 -0
- package/dist/clients/registry/synthetic.js +161 -0
- package/dist/clients/registry/synthetic.js.map +1 -0
- package/dist/clients/repository.d.ts +158 -0
- package/dist/clients/repository.d.ts.map +1 -1
- package/dist/clients/repository.js +186 -9
- package/dist/clients/repository.js.map +1 -1
- package/dist/collection/branding.d.ts +65 -0
- package/dist/collection/branding.d.ts.map +1 -1
- package/dist/collection/branding.js +186 -0
- package/dist/collection/branding.js.map +1 -1
- package/dist/collection/clearance-store.d.ts +39 -0
- package/dist/collection/clearance-store.d.ts.map +1 -0
- package/dist/collection/clearance-store.js +69 -0
- package/dist/collection/clearance-store.js.map +1 -0
- package/dist/collection/communication-runtime.d.ts +37 -0
- package/dist/collection/communication-runtime.d.ts.map +1 -1
- package/dist/collection/communication-runtime.js +63 -1
- package/dist/collection/communication-runtime.js.map +1 -1
- package/dist/collection/engine.d.ts +23 -0
- package/dist/collection/engine.d.ts.map +1 -1
- package/dist/collection/engine.js +20 -0
- package/dist/collection/engine.js.map +1 -1
- package/dist/collection/policy.d.ts +25 -0
- package/dist/collection/policy.d.ts.map +1 -1
- package/dist/collection/policy.js +27 -0
- package/dist/collection/policy.js.map +1 -1
- package/dist/communication/clearance.d.ts +53 -0
- package/dist/communication/clearance.d.ts.map +1 -0
- package/dist/communication/clearance.js +15 -0
- package/dist/communication/clearance.js.map +1 -0
- package/dist/communication/dry-run-scenario.d.ts.map +1 -1
- package/dist/communication/dry-run-scenario.js +5 -0
- package/dist/communication/dry-run-scenario.js.map +1 -1
- package/dist/communication/engine.d.ts +10 -0
- package/dist/communication/engine.d.ts.map +1 -1
- package/dist/communication/engine.js +12 -0
- package/dist/communication/engine.js.map +1 -1
- package/dist/communication/policy.d.ts +16 -0
- package/dist/communication/policy.d.ts.map +1 -1
- package/dist/communication/policy.js.map +1 -1
- package/dist/competence/business-days.d.ts +51 -0
- package/dist/competence/business-days.d.ts.map +1 -0
- package/dist/competence/business-days.js +145 -0
- package/dist/competence/business-days.js.map +1 -0
- package/dist/competence/catalog-validation.d.ts +86 -0
- package/dist/competence/catalog-validation.d.ts.map +1 -0
- package/dist/competence/catalog-validation.js +168 -0
- package/dist/competence/catalog-validation.js.map +1 -0
- package/dist/competence/obligation-preview.d.ts +103 -0
- package/dist/competence/obligation-preview.d.ts.map +1 -0
- package/dist/competence/obligation-preview.js +184 -0
- package/dist/competence/obligation-preview.js.map +1 -0
- package/dist/competence/repository.d.ts +139 -1
- package/dist/competence/repository.d.ts.map +1 -1
- package/dist/competence/repository.js +325 -17
- package/dist/competence/repository.js.map +1 -1
- package/dist/dashboard/pilot-panel.d.ts +100 -0
- package/dist/dashboard/pilot-panel.d.ts.map +1 -0
- package/dist/dashboard/pilot-panel.js +87 -0
- package/dist/dashboard/pilot-panel.js.map +1 -0
- package/dist/dashboard/repository.d.ts.map +1 -1
- package/dist/dashboard/repository.js +11 -1
- package/dist/dashboard/repository.js.map +1 -1
- package/dist/db/client.d.ts +45 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +16 -11
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrate.d.ts +36 -1
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +199 -32
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/provision-e2e-identity.d.ts +2 -0
- package/dist/db/provision-e2e-identity.d.ts.map +1 -0
- package/dist/db/provision-e2e-identity.js +114 -0
- package/dist/db/provision-e2e-identity.js.map +1 -0
- package/dist/fiscal/applicability.d.ts +73 -0
- package/dist/fiscal/applicability.d.ts.map +1 -0
- package/dist/fiscal/applicability.js +160 -0
- package/dist/fiscal/applicability.js.map +1 -0
- package/dist/fiscal/collection/authorization.d.ts +152 -0
- package/dist/fiscal/collection/authorization.d.ts.map +1 -0
- package/dist/fiscal/collection/authorization.js +178 -0
- package/dist/fiscal/collection/authorization.js.map +1 -0
- package/dist/fiscal/collection/competence.d.ts +66 -0
- package/dist/fiscal/collection/competence.d.ts.map +1 -0
- package/dist/fiscal/collection/competence.js +90 -0
- package/dist/fiscal/collection/competence.js.map +1 -0
- package/dist/fiscal/collection/first-contact.d.ts +103 -0
- package/dist/fiscal/collection/first-contact.d.ts.map +1 -0
- package/dist/fiscal/collection/first-contact.js +201 -0
- package/dist/fiscal/collection/first-contact.js.map +1 -0
- package/dist/fiscal/collection/plan.d.ts +74 -0
- package/dist/fiscal/collection/plan.d.ts.map +1 -0
- package/dist/fiscal/collection/plan.js +119 -0
- package/dist/fiscal/collection/plan.js.map +1 -0
- package/dist/fiscal/conditions.d.ts +99 -0
- package/dist/fiscal/conditions.d.ts.map +1 -0
- package/dist/fiscal/conditions.js +190 -0
- package/dist/fiscal/conditions.js.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-contract.d.ts +315 -0
- package/dist/fiscal/contracts/nfse-adn-contract.d.ts.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-contract.js +386 -0
- package/dist/fiscal/contracts/nfse-adn-contract.js.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.d.ts +13 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.d.ts.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.js +103 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.js.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.d.ts +77 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.d.ts.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.js +215 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.js.map +1 -0
- package/dist/fiscal/coverage/model.d.ts +114 -0
- package/dist/fiscal/coverage/model.d.ts.map +1 -0
- package/dist/fiscal/coverage/model.js +130 -0
- package/dist/fiscal/coverage/model.js.map +1 -0
- package/dist/fiscal/coverage/requests.d.ts +70 -0
- package/dist/fiscal/coverage/requests.d.ts.map +1 -0
- package/dist/fiscal/coverage/requests.js +95 -0
- package/dist/fiscal/coverage/requests.js.map +1 -0
- package/dist/fiscal/credentials/inspect.d.ts +114 -0
- package/dist/fiscal/credentials/inspect.d.ts.map +1 -0
- package/dist/fiscal/credentials/inspect.js +178 -0
- package/dist/fiscal/credentials/inspect.js.map +1 -0
- package/dist/fiscal/credentials/material.d.ts +81 -0
- package/dist/fiscal/credentials/material.d.ts.map +1 -0
- package/dist/fiscal/credentials/material.js +164 -0
- package/dist/fiscal/credentials/material.js.map +1 -0
- package/dist/fiscal/credentials/onboarding.d.ts +119 -0
- package/dist/fiscal/credentials/onboarding.d.ts.map +1 -0
- package/dist/fiscal/credentials/onboarding.js +259 -0
- package/dist/fiscal/credentials/onboarding.js.map +1 -0
- package/dist/fiscal/credentials/readiness.d.ts +119 -0
- package/dist/fiscal/credentials/readiness.d.ts.map +1 -0
- package/dist/fiscal/credentials/readiness.js +186 -0
- package/dist/fiscal/credentials/readiness.js.map +1 -0
- package/dist/fiscal/eligibility.d.ts +106 -0
- package/dist/fiscal/eligibility.d.ts.map +1 -0
- package/dist/fiscal/eligibility.js +194 -0
- package/dist/fiscal/eligibility.js.map +1 -0
- package/dist/fiscal/enrollment.d.ts +91 -0
- package/dist/fiscal/enrollment.d.ts.map +1 -0
- package/dist/fiscal/enrollment.js +126 -0
- package/dist/fiscal/enrollment.js.map +1 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.d.ts +57 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.d.ts.map +1 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.js +121 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.js.map +1 -0
- package/dist/fiscal/ingestion/adn-transport.d.ts +123 -0
- package/dist/fiscal/ingestion/adn-transport.d.ts.map +1 -0
- package/dist/fiscal/ingestion/adn-transport.js +220 -0
- package/dist/fiscal/ingestion/adn-transport.js.map +1 -0
- package/dist/fiscal/ingestion/direction.d.ts +60 -0
- package/dist/fiscal/ingestion/direction.d.ts.map +1 -0
- package/dist/fiscal/ingestion/direction.js +32 -0
- package/dist/fiscal/ingestion/direction.js.map +1 -0
- package/dist/fiscal/ingestion/nfse-adn.d.ts +91 -0
- package/dist/fiscal/ingestion/nfse-adn.d.ts.map +1 -0
- package/dist/fiscal/ingestion/nfse-adn.js +222 -0
- package/dist/fiscal/ingestion/nfse-adn.js.map +1 -0
- package/dist/fiscal/ingestion/pipeline.d.ts +168 -0
- package/dist/fiscal/ingestion/pipeline.d.ts.map +1 -0
- package/dist/fiscal/ingestion/pipeline.js +699 -0
- package/dist/fiscal/ingestion/pipeline.js.map +1 -0
- package/dist/fiscal/ingestion/provider.d.ts +206 -0
- package/dist/fiscal/ingestion/provider.d.ts.map +1 -0
- package/dist/fiscal/ingestion/provider.js +47 -0
- package/dist/fiscal/ingestion/provider.js.map +1 -0
- package/dist/fiscal/ingestion/repository.d.ts +82 -0
- package/dist/fiscal/ingestion/repository.d.ts.map +1 -0
- package/dist/fiscal/ingestion/repository.js +127 -0
- package/dist/fiscal/ingestion/repository.js.map +1 -0
- package/dist/fiscal/ingestion/synthetic-provider.d.ts +92 -0
- package/dist/fiscal/ingestion/synthetic-provider.d.ts.map +1 -0
- package/dist/fiscal/ingestion/synthetic-provider.js +99 -0
- package/dist/fiscal/ingestion/synthetic-provider.js.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.d.ts +19 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.d.ts.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.js +9 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.js.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport.d.ts +55 -0
- package/dist/fiscal/ingestion/synthetic-transport.d.ts.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport.js +57 -0
- package/dist/fiscal/ingestion/synthetic-transport.js.map +1 -0
- package/dist/fiscal/ingestion/xml-reader.d.ts +55 -0
- package/dist/fiscal/ingestion/xml-reader.d.ts.map +1 -0
- package/dist/fiscal/ingestion/xml-reader.js +112 -0
- package/dist/fiscal/ingestion/xml-reader.js.map +1 -0
- package/dist/fiscal/repository.d.ts +220 -0
- package/dist/fiscal/repository.d.ts.map +1 -0
- package/dist/fiscal/repository.js +449 -0
- package/dist/fiscal/repository.js.map +1 -0
- package/dist/fiscal/sync/circuit.d.ts +86 -0
- package/dist/fiscal/sync/circuit.d.ts.map +1 -0
- package/dist/fiscal/sync/circuit.js +118 -0
- package/dist/fiscal/sync/circuit.js.map +1 -0
- package/dist/fiscal/sync/intervention.d.ts +81 -0
- package/dist/fiscal/sync/intervention.d.ts.map +1 -0
- package/dist/fiscal/sync/intervention.js +135 -0
- package/dist/fiscal/sync/intervention.js.map +1 -0
- package/dist/fiscal/sync/lease.d.ts +118 -0
- package/dist/fiscal/sync/lease.d.ts.map +1 -0
- package/dist/fiscal/sync/lease.js +139 -0
- package/dist/fiscal/sync/lease.js.map +1 -0
- package/dist/fiscal/sync/observability.d.ts +148 -0
- package/dist/fiscal/sync/observability.d.ts.map +1 -0
- package/dist/fiscal/sync/observability.js +239 -0
- package/dist/fiscal/sync/observability.js.map +1 -0
- package/dist/fiscal/sync/orchestrator.d.ts +132 -0
- package/dist/fiscal/sync/orchestrator.d.ts.map +1 -0
- package/dist/fiscal/sync/orchestrator.js +487 -0
- package/dist/fiscal/sync/orchestrator.js.map +1 -0
- package/dist/fiscal/sync/policy.d.ts +87 -0
- package/dist/fiscal/sync/policy.d.ts.map +1 -0
- package/dist/fiscal/sync/policy.js +136 -0
- package/dist/fiscal/sync/policy.js.map +1 -0
- package/dist/fiscal/sync/reprocess.d.ts +76 -0
- package/dist/fiscal/sync/reprocess.d.ts.map +1 -0
- package/dist/fiscal/sync/reprocess.js +237 -0
- package/dist/fiscal/sync/reprocess.js.map +1 -0
- package/dist/fiscal/sync/retry.d.ts +82 -0
- package/dist/fiscal/sync/retry.d.ts.map +1 -0
- package/dist/fiscal/sync/retry.js +176 -0
- package/dist/fiscal/sync/retry.js.map +1 -0
- package/dist/fiscal/sync/secret-boundary.d.ts +169 -0
- package/dist/fiscal/sync/secret-boundary.d.ts.map +1 -0
- package/dist/fiscal/sync/secret-boundary.js +116 -0
- package/dist/fiscal/sync/secret-boundary.js.map +1 -0
- package/dist/fiscal/transport/https.d.ts +86 -0
- package/dist/fiscal/transport/https.d.ts.map +1 -0
- package/dist/fiscal/transport/https.js +303 -0
- package/dist/fiscal/transport/https.js.map +1 -0
- package/dist/fiscal/transport/synthetic-tls.d.ts +99 -0
- package/dist/fiscal/transport/synthetic-tls.d.ts.map +1 -0
- package/dist/fiscal/transport/synthetic-tls.js +374 -0
- package/dist/fiscal/transport/synthetic-tls.js.map +1 -0
- package/dist/fiscal/transport/types.d.ts +134 -0
- package/dist/fiscal/transport/types.d.ts.map +1 -0
- package/dist/fiscal/transport/types.js +88 -0
- package/dist/fiscal/transport/types.js.map +1 -0
- package/dist/import/br-documents.d.ts +26 -0
- package/dist/import/br-documents.d.ts.map +1 -0
- package/dist/import/br-documents.js +78 -0
- package/dist/import/br-documents.js.map +1 -0
- package/dist/import/clients-import.d.ts +122 -4
- package/dist/import/clients-import.d.ts.map +1 -1
- package/dist/import/clients-import.js +341 -41
- package/dist/import/clients-import.js.map +1 -1
- package/dist/index.d.ts +145 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +120 -7
- package/dist/index.js.map +1 -1
- package/dist/legal/documents.d.ts +12 -1
- package/dist/legal/documents.d.ts.map +1 -1
- package/dist/legal/documents.js +162 -18
- package/dist/legal/documents.js.map +1 -1
- package/dist/legal/index.d.ts +2 -2
- package/dist/legal/index.d.ts.map +1 -1
- package/dist/legal/index.js +1 -1
- package/dist/legal/index.js.map +1 -1
- package/dist/legal/types.d.ts +114 -2
- package/dist/legal/types.d.ts.map +1 -1
- package/dist/legal/types.js.map +1 -1
- package/dist/onboarding/persistence.d.ts +10 -1
- package/dist/onboarding/persistence.d.ts.map +1 -1
- package/dist/onboarding/persistence.js +4 -4
- package/dist/onboarding/persistence.js.map +1 -1
- package/dist/pilot/go-live-checklist.d.ts +41 -0
- package/dist/pilot/go-live-checklist.d.ts.map +1 -0
- package/dist/pilot/go-live-checklist.js +209 -0
- package/dist/pilot/go-live-checklist.js.map +1 -0
- package/dist/pilot/milestone.d.ts +56 -0
- package/dist/pilot/milestone.d.ts.map +1 -0
- package/dist/pilot/milestone.js +74 -0
- package/dist/pilot/milestone.js.map +1 -0
- package/dist/platform/capabilities.d.ts +88 -0
- package/dist/platform/capabilities.d.ts.map +1 -0
- package/dist/platform/capabilities.js +169 -0
- package/dist/platform/capabilities.js.map +1 -0
- package/dist/platform/job-contract.d.ts +232 -0
- package/dist/platform/job-contract.d.ts.map +1 -0
- package/dist/platform/job-contract.js +403 -0
- package/dist/platform/job-contract.js.map +1 -0
- package/dist/rbac/catalog.d.ts.map +1 -1
- package/dist/rbac/catalog.js +110 -0
- package/dist/rbac/catalog.js.map +1 -1
- package/dist/subscription-billing/index.d.ts +8 -5
- package/dist/subscription-billing/index.d.ts.map +1 -1
- package/dist/subscription-billing/index.js +4 -3
- package/dist/subscription-billing/index.js.map +1 -1
- package/dist/subscription-billing/platform-exemption.d.ts +89 -0
- package/dist/subscription-billing/platform-exemption.d.ts.map +1 -0
- package/dist/subscription-billing/platform-exemption.js +113 -0
- package/dist/subscription-billing/platform-exemption.js.map +1 -0
- package/dist/subscription-billing/service.d.ts +74 -0
- package/dist/subscription-billing/service.d.ts.map +1 -1
- package/dist/subscription-billing/service.js +182 -16
- package/dist/subscription-billing/service.js.map +1 -1
- package/dist/tenancy/features.d.ts +69 -0
- package/dist/tenancy/features.d.ts.map +1 -0
- package/dist/tenancy/features.js +123 -0
- package/dist/tenancy/features.js.map +1 -0
- package/dist/tenancy/settings.d.ts +63 -0
- package/dist/tenancy/settings.d.ts.map +1 -0
- package/dist/tenancy/settings.js +218 -0
- package/dist/tenancy/settings.js.map +1 -0
- package/dist/users/repository.d.ts +16 -1
- package/dist/users/repository.d.ts.map +1 -1
- package/dist/users/repository.js +24 -1
- package/dist/users/repository.js.map +1 -1
- package/dist/vault/repository.d.ts +69 -1
- package/dist/vault/repository.d.ts.map +1 -1
- package/dist/vault/repository.js +88 -5
- package/dist/vault/repository.js.map +1 -1
- package/package.json +10 -2
- package/src/db/migrations/0045_role_write_scope.sql +122 -0
- package/src/db/migrations/0046_pilot_activation_model.sql +184 -0
- package/src/db/migrations/0047_recipient_clearance.sql +89 -0
- package/src/db/migrations/0048_item_type_note.sql +16 -0
- package/src/db/migrations/0049_national_fiscal_engine.sql +279 -0
- package/src/db/migrations/0050_fiscal_vocabulary_readonly.sql +29 -0
- package/src/db/migrations/0051_seed_rules_from_catalog.sql +72 -0
- package/src/db/migrations/0052_fiscal_rule_delete_scope.sql +57 -0
- package/src/db/migrations/0053_rule_validity_lower_bound.sql +44 -0
- package/src/db/migrations/0054_tenant_profile_and_rule_source.sql +89 -0
- package/src/db/migrations/0055_job_capability_contract.sql +300 -0
- package/src/db/migrations/0056_fiscal_document_ingestion.sql +337 -0
- package/src/db/migrations/0057_fiscal_pending_event_inbox.sql +228 -0
- package/src/db/migrations/0058_fiscal_operational_engine.sql +516 -0
- package/src/db/migrations/0059_fiscal_contract_version.sql +59 -0
- package/src/db/migrations/0060_fiscal_credential_vault_and_run_authorization.sql +321 -0
- package/src/db/migrations/0061_client_official_registry_provenance.sql +193 -0
- package/src/db/migrations/0062_first_contact_and_capability_truth.sql +119 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
-- 0046 — o modelo de dados que falta para ativar um cliente real.
|
|
2
|
+
--
|
|
3
|
+
-- A Fase 5 começou mapeando, contra o schema, exatamente quais dados um
|
|
4
|
+
-- escritório precisa para ativar um cliente. Quatro ausências apareceram, e
|
|
5
|
+
-- todas bloqueiam algo concreto do piloto:
|
|
6
|
+
--
|
|
7
|
+
-- 1. **Não há onde guardar município e UF.** Três obrigações do catálogo são
|
|
8
|
+
-- estaduais ou municipais e têm prazo que varia por localidade. Sem UF e
|
|
9
|
+
-- município no cliente, marcar essas obrigações como "depende da localidade"
|
|
10
|
+
-- é honesto mas inútil: não há o dado com que decidir.
|
|
11
|
+
--
|
|
12
|
+
-- 2. **Não há responsável pelo cliente.** `recurring_instance` e
|
|
13
|
+
-- `service_request` têm `responsible_user_id`; o cliente não tem. Então a
|
|
14
|
+
-- carteira não pode ser dividida entre as pessoas do escritório — só as
|
|
15
|
+
-- tarefas podem, uma a uma, depois de criadas.
|
|
16
|
+
--
|
|
17
|
+
-- 3. **A importação não deixa rastro reversível.** `commitImport` cria
|
|
18
|
+
-- clientes e devolve uma contagem. Não há como responder "quais linhas
|
|
19
|
+
-- entraram naquela importação" nem desfazer uma importação inteira.
|
|
20
|
+
--
|
|
21
|
+
-- 4. **A validação humana do catálogo não tem onde ser gravada.** O catálogo
|
|
22
|
+
-- fiscal foi semeado tecnicamente e não foi conferido contra os serviços que
|
|
23
|
+
-- a SC presta. Marcar "conferido" é por escritório, não global — o mesmo
|
|
24
|
+
-- template de sistema pode ser válido para um escritório e não se aplicar a
|
|
25
|
+
-- outro. Por isso é tabela própria, e não coluna em `recurring_item_type`:
|
|
26
|
+
-- aquela linha é COMPARTILHADA entre todos os tenants, e uma coluna nela
|
|
27
|
+
-- faria um escritório carimbar a validação do outro.
|
|
28
|
+
--
|
|
29
|
+
-- Nada aqui liga cobrança, obrigação ou envio. É só onde o dado passa a caber.
|
|
30
|
+
|
|
31
|
+
-- ── 1 · Localidade e responsável do cliente ────────────────────────────────
|
|
32
|
+
--
|
|
33
|
+
-- Os campos de endereço são deliberadamente poucos: os que o produto usa hoje.
|
|
34
|
+
-- `state_uf` tem CHECK de duas maiúsculas porque é ele que vai selecionar regra
|
|
35
|
+
-- estadual — um "Goias" digitado no lugar de "GO" faria a regra não casar em
|
|
36
|
+
-- silêncio, e silêncio é o modo de falha que esta fase existe para eliminar.
|
|
37
|
+
|
|
38
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS address_line text;
|
|
39
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS municipality text;
|
|
40
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS state_uf text;
|
|
41
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS postal_code text;
|
|
42
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS notes text;
|
|
43
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS responsible_user_id uuid REFERENCES "user"(id);
|
|
44
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS contract_started_on date;
|
|
45
|
+
|
|
46
|
+
DO $$
|
|
47
|
+
BEGIN
|
|
48
|
+
IF NOT EXISTS (
|
|
49
|
+
SELECT FROM pg_constraint WHERE conname = 'client_state_uf_format'
|
|
50
|
+
) THEN
|
|
51
|
+
ALTER TABLE client ADD CONSTRAINT client_state_uf_format
|
|
52
|
+
CHECK (state_uf IS NULL OR state_uf ~ '^[A-Z]{2}$');
|
|
53
|
+
END IF;
|
|
54
|
+
END $$;
|
|
55
|
+
|
|
56
|
+
CREATE INDEX IF NOT EXISTS client_responsible_idx
|
|
57
|
+
ON client (tenant_id, responsible_user_id) WHERE deleted_at IS NULL;
|
|
58
|
+
CREATE INDEX IF NOT EXISTS client_locality_idx
|
|
59
|
+
ON client (tenant_id, state_uf, municipality) WHERE deleted_at IS NULL;
|
|
60
|
+
|
|
61
|
+
COMMENT ON COLUMN client.state_uf IS
|
|
62
|
+
'UF em duas maiúsculas. Seleciona regra estadual de vencimento; formato livre faria a regra não casar em silêncio.';
|
|
63
|
+
COMMENT ON COLUMN client.responsible_user_id IS
|
|
64
|
+
'Responsável pela carteira deste cliente. Toda troca passa por audit_log — ver assignClientResponsible.';
|
|
65
|
+
|
|
66
|
+
-- ── 2 · Lote de importação ─────────────────────────────────────────────────
|
|
67
|
+
--
|
|
68
|
+
-- Existe para duas perguntas que hoje não têm resposta: "o que entrou naquela
|
|
69
|
+
-- importação?" e "como desfaço?". O desfazer é lógico (soft-delete dos clientes
|
|
70
|
+
-- do lote que ninguém tocou desde então), nunca físico: apagar linha real é
|
|
71
|
+
-- proibido, e um cliente que já ganhou honorário ou obrigação não é mais "só uma
|
|
72
|
+
-- linha importada".
|
|
73
|
+
--
|
|
74
|
+
-- `source_digest` é o sha256 do CSV. É ele que amarra plano e commit: o commit
|
|
75
|
+
-- recusa aplicar um conteúdo diferente do que foi previsto, em vez de reparsear
|
|
76
|
+
-- e produzir um resultado que ninguém viu.
|
|
77
|
+
|
|
78
|
+
CREATE TABLE IF NOT EXISTS client_import_batch (
|
|
79
|
+
id uuid PRIMARY KEY,
|
|
80
|
+
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
|
81
|
+
source_digest text NOT NULL,
|
|
82
|
+
source_name text,
|
|
83
|
+
row_total int NOT NULL DEFAULT 0,
|
|
84
|
+
created_count int NOT NULL DEFAULT 0,
|
|
85
|
+
skipped_count int NOT NULL DEFAULT 0,
|
|
86
|
+
error_count int NOT NULL DEFAULT 0,
|
|
87
|
+
status text NOT NULL DEFAULT 'applied'
|
|
88
|
+
CHECK (status IN ('applied', 'rolled_back')),
|
|
89
|
+
created_by uuid REFERENCES "user"(id),
|
|
90
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
91
|
+
rolled_back_at timestamptz,
|
|
92
|
+
rolled_back_by uuid REFERENCES "user"(id),
|
|
93
|
+
CONSTRAINT client_import_batch_tenant_id_uq UNIQUE (tenant_id, id),
|
|
94
|
+
CHECK ((status <> 'rolled_back') OR rolled_back_at IS NOT NULL)
|
|
95
|
+
);
|
|
96
|
+
CREATE INDEX IF NOT EXISTS client_import_batch_tenant_idx
|
|
97
|
+
ON client_import_batch (tenant_id, created_at DESC);
|
|
98
|
+
|
|
99
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS import_batch_id uuid;
|
|
100
|
+
|
|
101
|
+
DO $$
|
|
102
|
+
BEGIN
|
|
103
|
+
IF NOT EXISTS (SELECT FROM pg_constraint WHERE conname = 'client_import_batch_fk') THEN
|
|
104
|
+
ALTER TABLE client ADD CONSTRAINT client_import_batch_fk
|
|
105
|
+
FOREIGN KEY (tenant_id, import_batch_id)
|
|
106
|
+
REFERENCES client_import_batch (tenant_id, id);
|
|
107
|
+
END IF;
|
|
108
|
+
END $$;
|
|
109
|
+
|
|
110
|
+
CREATE INDEX IF NOT EXISTS client_import_batch_idx
|
|
111
|
+
ON client (tenant_id, import_batch_id) WHERE import_batch_id IS NOT NULL;
|
|
112
|
+
|
|
113
|
+
ALTER TABLE client_import_batch ENABLE ROW LEVEL SECURITY;
|
|
114
|
+
ALTER TABLE client_import_batch FORCE ROW LEVEL SECURITY;
|
|
115
|
+
CREATE POLICY client_import_batch_tenant_isolation ON client_import_batch
|
|
116
|
+
USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
|
|
117
|
+
WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
|
|
118
|
+
|
|
119
|
+
-- ── 3 · Validação humana do catálogo, por escritório ───────────────────────
|
|
120
|
+
--
|
|
121
|
+
-- Um item do catálogo, para um escritório, está em um de quatro estados. O
|
|
122
|
+
-- padrão é `pending_validation` e ele é o ponto inteiro: enquanto ninguém
|
|
123
|
+
-- conferiu, o produto deve DIZER que ninguém conferiu, em vez de deixar o seed
|
|
124
|
+
-- passar por verdade operacional.
|
|
125
|
+
--
|
|
126
|
+
-- `depends_on_locality` marca os itens cujo prazo muda por UF ou município. Não
|
|
127
|
+
-- é um prazo inventado — é a ausência de prazo, declarada.
|
|
128
|
+
|
|
129
|
+
CREATE TABLE IF NOT EXISTS recurring_item_type_validation (
|
|
130
|
+
id uuid PRIMARY KEY,
|
|
131
|
+
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
|
132
|
+
item_type_id uuid NOT NULL REFERENCES recurring_item_type(id),
|
|
133
|
+
status text NOT NULL DEFAULT 'pending_validation'
|
|
134
|
+
CHECK (status IN ('validated', 'pending_validation', 'not_applicable', 'disabled')),
|
|
135
|
+
depends_on_locality boolean NOT NULL DEFAULT false,
|
|
136
|
+
note text,
|
|
137
|
+
validated_by uuid REFERENCES "user"(id),
|
|
138
|
+
validated_at timestamptz,
|
|
139
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
140
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
141
|
+
CONSTRAINT recurring_item_type_validation_tenant_id_uq UNIQUE (tenant_id, id),
|
|
142
|
+
CHECK ((status <> 'validated') OR validated_at IS NOT NULL)
|
|
143
|
+
);
|
|
144
|
+
CREATE UNIQUE INDEX IF NOT EXISTS recurring_item_type_validation_uq
|
|
145
|
+
ON recurring_item_type_validation (tenant_id, item_type_id);
|
|
146
|
+
|
|
147
|
+
ALTER TABLE recurring_item_type_validation ENABLE ROW LEVEL SECURITY;
|
|
148
|
+
ALTER TABLE recurring_item_type_validation FORCE ROW LEVEL SECURITY;
|
|
149
|
+
CREATE POLICY recurring_item_type_validation_tenant_isolation ON recurring_item_type_validation
|
|
150
|
+
USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
|
|
151
|
+
WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
|
|
152
|
+
|
|
153
|
+
COMMENT ON TABLE recurring_item_type_validation IS
|
|
154
|
+
'Conferência humana do catálogo, POR ESCRITÓRIO. Tabela própria porque recurring_item_type com tenant_id NULL é linha compartilhada: coluna nela faria um escritório carimbar a validação do outro.';
|
|
155
|
+
|
|
156
|
+
-- ── 4 · O serviço contratado ganha responsável e vínculo com obrigação ─────
|
|
157
|
+
--
|
|
158
|
+
-- `fee_agreement` já era a entidade de serviço contratado: tem descrição, valor,
|
|
159
|
+
-- periodicidade, vencimento, início, fim e status, e um cliente pode ter
|
|
160
|
+
-- vários. Não se cria entidade nova para o que já existe. Faltavam duas coisas.
|
|
161
|
+
--
|
|
162
|
+
-- O vínculo é tabela de ligação porque a relação é N-para-N de verdade: um
|
|
163
|
+
-- serviço de folha cobre eSocial, FGTS e a própria folha; e a mesma obrigação
|
|
164
|
+
-- pode estar coberta por mais de um contrato ao longo do tempo.
|
|
165
|
+
|
|
166
|
+
ALTER TABLE fee_agreement ADD COLUMN IF NOT EXISTS responsible_user_id uuid REFERENCES "user"(id);
|
|
167
|
+
|
|
168
|
+
CREATE TABLE IF NOT EXISTS fee_agreement_obligation (
|
|
169
|
+
id uuid PRIMARY KEY,
|
|
170
|
+
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
|
171
|
+
fee_agreement_id uuid NOT NULL,
|
|
172
|
+
item_type_id uuid NOT NULL REFERENCES recurring_item_type(id),
|
|
173
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
174
|
+
CONSTRAINT fee_agreement_obligation_tenant_id_uq UNIQUE (tenant_id, id),
|
|
175
|
+
FOREIGN KEY (tenant_id, fee_agreement_id) REFERENCES fee_agreement (tenant_id, id)
|
|
176
|
+
);
|
|
177
|
+
CREATE UNIQUE INDEX IF NOT EXISTS fee_agreement_obligation_uq
|
|
178
|
+
ON fee_agreement_obligation (tenant_id, fee_agreement_id, item_type_id);
|
|
179
|
+
|
|
180
|
+
ALTER TABLE fee_agreement_obligation ENABLE ROW LEVEL SECURITY;
|
|
181
|
+
ALTER TABLE fee_agreement_obligation FORCE ROW LEVEL SECURITY;
|
|
182
|
+
CREATE POLICY fee_agreement_obligation_tenant_isolation ON fee_agreement_obligation
|
|
183
|
+
USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
|
|
184
|
+
WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
-- 0047 — liberação do destinatário para comunicação externa.
|
|
2
|
+
--
|
|
3
|
+
-- ── O que foi medido em produção ────────────────────────────────────────────
|
|
4
|
+
--
|
|
5
|
+
-- Em 2026-09-05, às 12:00, o cron de cobrança enviou 5 e-mails no tenant `sc`.
|
|
6
|
+
-- Hoje isso é inofensivo: o único cliente com e-mail cadastrado é o do próprio
|
|
7
|
+
-- titular, e os recebíveis são sintéticos.
|
|
8
|
+
--
|
|
9
|
+
-- O problema aparece no dia seguinte à importação da carteira real. A régua
|
|
10
|
+
-- percorre todo cliente com e-mail e recebível vencido, e **nada no caminho
|
|
11
|
+
-- pergunta se alguém conferiu aquele endereço**. Trezentos clientes importados
|
|
12
|
+
-- de manhã recebem cobrança automática à tarde, sobre dados que ninguém
|
|
13
|
+
-- validou. Foi exatamente assim que 81 e-mails saíram sobre a carteira de QA.
|
|
14
|
+
--
|
|
15
|
+
-- ── Por que não é consentimento ─────────────────────────────────────────────
|
|
16
|
+
--
|
|
17
|
+
-- O motor já tem consentimento, e ele está certo do jeito que está: a política
|
|
18
|
+
-- do produto trata `unknown` como permitido no e-mail porque cobrança
|
|
19
|
+
-- transacional se apoia na relação contratual. Mudar isso travaria a cobrança
|
|
20
|
+
-- de toda carteira legada que nunca teve o campo preenchido — o próprio código
|
|
21
|
+
-- do consentimento avisa disso.
|
|
22
|
+
--
|
|
23
|
+
-- São perguntas diferentes:
|
|
24
|
+
--
|
|
25
|
+
-- consentimento → "esta pessoa aceita ser contatada?" (vontade do DESTINATÁRIO)
|
|
26
|
+
-- liberação → "alguém daqui conferiu este endereço?" (conferência do REMETENTE)
|
|
27
|
+
--
|
|
28
|
+
-- Elas se separam exatamente no caso que importa: o cliente recém-importado tem
|
|
29
|
+
-- relação contratual e nenhuma conferência.
|
|
30
|
+
--
|
|
31
|
+
-- ── Por que a ausência bloqueia ─────────────────────────────────────────────
|
|
32
|
+
--
|
|
33
|
+
-- O padrão é NÃO liberado, e não existe configuração que inverta isso. Um
|
|
34
|
+
-- default "libera se ninguém disse nada" transformaria a omissão em
|
|
35
|
+
-- autorização — e omissão é o estado natural de todo cliente que acabou de
|
|
36
|
+
-- entrar. O cliente não some da operação: ele aparece com pulo nomeado
|
|
37
|
+
-- (`recipient_not_confirmed`) na trilha e contado no painel.
|
|
38
|
+
|
|
39
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS communication_cleared_at timestamptz;
|
|
40
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS communication_cleared_by uuid REFERENCES "user"(id);
|
|
41
|
+
|
|
42
|
+
DO $$
|
|
43
|
+
BEGIN
|
|
44
|
+
IF NOT EXISTS (SELECT FROM pg_constraint WHERE conname = 'client_clearance_coherent') THEN
|
|
45
|
+
-- Data e autor andam juntos: uma liberação sem autor não responde "quem
|
|
46
|
+
-- conferiu?", que é a única pergunta que ela existe para responder.
|
|
47
|
+
ALTER TABLE client ADD CONSTRAINT client_clearance_coherent
|
|
48
|
+
CHECK ((communication_cleared_at IS NULL) = (communication_cleared_by IS NULL));
|
|
49
|
+
END IF;
|
|
50
|
+
END $$;
|
|
51
|
+
|
|
52
|
+
CREATE INDEX IF NOT EXISTS client_clearance_idx
|
|
53
|
+
ON client (tenant_id, communication_cleared_at) WHERE deleted_at IS NULL;
|
|
54
|
+
|
|
55
|
+
COMMENT ON COLUMN client.communication_cleared_at IS
|
|
56
|
+
'Quando alguém do escritório conferiu o contato e liberou este cliente para comunicação externa. NULL = não liberado, e a régua pula com motivo nomeado.';
|
|
57
|
+
|
|
58
|
+
-- ── Marco de início do piloto real ──────────────────────────────────────────
|
|
59
|
+
--
|
|
60
|
+
-- Os registros hoje no tenant `sc` são de desenvolvimento, QA, homologação e
|
|
61
|
+
-- demonstração — inclusive os do App Review da Meta. Nenhum é carteira real.
|
|
62
|
+
--
|
|
63
|
+
-- Sem um marco explícito, daqui a três meses ninguém distingue "cliente de
|
|
64
|
+
-- teste de agosto" de "cliente real de setembro", e todo indicador do painel
|
|
65
|
+
-- passa a misturar os dois. A tabela existe para que a fronteira seja um FATO
|
|
66
|
+
-- gravado, com autor e data, e não uma lembrança.
|
|
67
|
+
|
|
68
|
+
CREATE TABLE IF NOT EXISTS tenant_pilot_milestone (
|
|
69
|
+
id uuid PRIMARY KEY,
|
|
70
|
+
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
|
71
|
+
milestone text NOT NULL CHECK (milestone IN ('real_pilot_start')),
|
|
72
|
+
occurred_at timestamptz NOT NULL DEFAULT now(),
|
|
73
|
+
declared_by uuid REFERENCES "user"(id),
|
|
74
|
+
note text,
|
|
75
|
+
CONSTRAINT tenant_pilot_milestone_tenant_id_uq UNIQUE (tenant_id, id)
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
-- Um marco por tenant: "quando começou de verdade" não admite duas respostas.
|
|
79
|
+
CREATE UNIQUE INDEX IF NOT EXISTS tenant_pilot_milestone_uq
|
|
80
|
+
ON tenant_pilot_milestone (tenant_id, milestone);
|
|
81
|
+
|
|
82
|
+
ALTER TABLE tenant_pilot_milestone ENABLE ROW LEVEL SECURITY;
|
|
83
|
+
ALTER TABLE tenant_pilot_milestone FORCE ROW LEVEL SECURITY;
|
|
84
|
+
CREATE POLICY tenant_pilot_milestone_tenant_isolation ON tenant_pilot_milestone
|
|
85
|
+
USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
|
|
86
|
+
WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
|
|
87
|
+
|
|
88
|
+
COMMENT ON TABLE tenant_pilot_milestone IS
|
|
89
|
+
'Fronteira gravada entre dado pré-produtivo (QA, demo, Meta App Review) e carteira real. Sem ela, os indicadores do painel misturam os dois e ninguém consegue separar depois.';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
-- 0048 — a observação do catálogo passa a chegar a quem confere.
|
|
2
|
+
--
|
|
3
|
+
-- `FiscalCatalogEntry.note` existe na vertical desde a Fase 3, com o comentário
|
|
4
|
+
-- "Aparece na UI para o operador saber o que ajustar". Ela nunca apareceu:
|
|
5
|
+
-- não havia coluna, o seed não a escrevia, e a tela não tinha o que mostrar.
|
|
6
|
+
--
|
|
7
|
+
-- Nove das dezessete entradas têm nota, e são exatamente as que o escritório
|
|
8
|
+
-- precisa ler para decidir — as de esfera estadual e municipal, cujo prazo
|
|
9
|
+
-- muda por localidade, e as que dependem do segmento atendido. A conferência
|
|
10
|
+
-- humana do catálogo é o bloqueio desta fase, e ela estava sendo pedida sem a
|
|
11
|
+
-- informação que a torna possível.
|
|
12
|
+
|
|
13
|
+
ALTER TABLE recurring_item_type ADD COLUMN IF NOT EXISTS note text;
|
|
14
|
+
|
|
15
|
+
COMMENT ON COLUMN recurring_item_type.note IS
|
|
16
|
+
'Observação para quem confere: o que este item exige de decisão local (UF, município, segmento). Não é regra — é o que o operador precisa saber para decidir.';
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
-- 0049 — a fundação nacional do motor fiscal.
|
|
2
|
+
--
|
|
3
|
+
-- ═══ A decisão de modelagem que organiza tudo ═══════════════════════════════
|
|
4
|
+
--
|
|
5
|
+
-- Hoje `recurring_item_type` responde duas perguntas diferentes na mesma linha:
|
|
6
|
+
--
|
|
7
|
+
-- "o que é esta obrigação?" → DAS, ISS, eSocial. Nacional e estável.
|
|
8
|
+
-- "para quem, quando e como vence?" → varia por UF, por município e no tempo.
|
|
9
|
+
--
|
|
10
|
+
-- Enquanto as duas moram juntas, o índice único em `(key)` permite UMA linha
|
|
11
|
+
-- por chave, e daí saem as três limitações que a auditoria mediu: o ISS de
|
|
12
|
+
-- Goiânia e o de São Paulo não coexistem, duas versões da mesma regra não
|
|
13
|
+
-- coexistem, e a aplicabilidade só sabe olhar regime.
|
|
14
|
+
--
|
|
15
|
+
-- Esta migration separa as duas perguntas:
|
|
16
|
+
--
|
|
17
|
+
-- `recurring_item_type` → a IDENTIDADE. Continua como está. Nada quebra.
|
|
18
|
+
-- `fiscal_rule` → a REGRA: jurisdição + vigência + versão +
|
|
19
|
+
-- condições + vencimento.
|
|
20
|
+
--
|
|
21
|
+
-- Um tipo de item passa a ter N regras: uma federal, uma por UF, uma por
|
|
22
|
+
-- município, e mais de uma no tempo. É o que abrangência nacional exige, e é
|
|
23
|
+
-- aditivo — nenhuma linha existente é reescrita.
|
|
24
|
+
--
|
|
25
|
+
-- ═══ O que esta migration NÃO faz ══════════════════════════════════════════
|
|
26
|
+
--
|
|
27
|
+
-- Não cataloga regra nenhuma do Brasil. Ela cria a capacidade; o conteúdo
|
|
28
|
+
-- entra depois, com governança. Os 17 seeds atuais são migrados na 0050 SEM
|
|
29
|
+
-- ganhar precisão que não têm.
|
|
30
|
+
|
|
31
|
+
-- ── 1 · Vocabulário do perfil fiscal ───────────────────────────────────────
|
|
32
|
+
--
|
|
33
|
+
-- Registro de atributos, e não colunas em `client`.
|
|
34
|
+
--
|
|
35
|
+
-- A alternativa seria `has_employees`, `icms_taxpayer`, `iss_taxpayer`,
|
|
36
|
+
-- `ipi_taxpayer`… uma coluna por pergunta fiscal. Isso não escala: cada UF e
|
|
37
|
+
-- cada segmento acrescenta perguntas, e a tabela de cliente viraria uma
|
|
38
|
+
-- estrutura rígida impossível de evoluir — exatamente o que a premissa pede
|
|
39
|
+
-- para evitar.
|
|
40
|
+
--
|
|
41
|
+
-- Com um REGISTRO, acrescentar um atributo é INSERT, não migration. E a FK
|
|
42
|
+
-- impede erro de digitação virar atributo novo em silêncio.
|
|
43
|
+
|
|
44
|
+
CREATE TABLE IF NOT EXISTS fiscal_attribute_definition (
|
|
45
|
+
key text PRIMARY KEY,
|
|
46
|
+
label text NOT NULL,
|
|
47
|
+
description text,
|
|
48
|
+
value_type text NOT NULL CHECK (value_type IN ('boolean', 'text', 'enum')),
|
|
49
|
+
-- Para `enum`: os valores aceitos. Para os demais, `null`.
|
|
50
|
+
allowed_values jsonb,
|
|
51
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
52
|
+
CHECK ((value_type = 'enum') = (allowed_values IS NOT NULL))
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
COMMENT ON TABLE fiscal_attribute_definition IS
|
|
56
|
+
'Vocabulário GLOBAL do perfil fiscal. Acrescentar atributo é INSERT, não migration — é o que permite o modelo evoluir sem alterar a tabela de cliente.';
|
|
57
|
+
|
|
58
|
+
INSERT INTO fiscal_attribute_definition (key, label, description, value_type, allowed_values) VALUES
|
|
59
|
+
('has_employees', 'Possui empregados',
|
|
60
|
+
'Decide a aplicabilidade das obrigações trabalhistas. A AUSÊNCIA deste dado não é "não": é desconhecido, e o motor devolve INSUFFICIENT_DATA.',
|
|
61
|
+
'boolean', NULL),
|
|
62
|
+
('icms_taxpayer', 'Contribuinte de ICMS', NULL, 'boolean', NULL),
|
|
63
|
+
('ipi_taxpayer', 'Contribuinte de IPI', NULL, 'boolean', NULL),
|
|
64
|
+
('iss_taxpayer', 'Contribuinte de ISS', NULL, 'boolean', NULL),
|
|
65
|
+
('activity_segment', 'Segmento de atividade', NULL,
|
|
66
|
+
'enum', '["comercio","industria","servicos","misto"]'::jsonb),
|
|
67
|
+
('cnae_primary', 'CNAE principal', 'Código, sem interpretação pelo motor nesta fase.', 'text', NULL),
|
|
68
|
+
('state_registration', 'Inscrição estadual', NULL, 'text', NULL),
|
|
69
|
+
('municipal_registration', 'Inscrição municipal', NULL, 'text', NULL)
|
|
70
|
+
ON CONFLICT (key) DO NOTHING;
|
|
71
|
+
|
|
72
|
+
-- ── 2 · Perfil fiscal do cliente ───────────────────────────────────────────
|
|
73
|
+
--
|
|
74
|
+
-- Ausência de linha = atributo DESCONHECIDO, e é distinto de `false`. É a
|
|
75
|
+
-- distinção que sustenta o `INSUFFICIENT_DATA` do motor: um cliente sobre o
|
|
76
|
+
-- qual ninguém disse se tem empregados não pode receber eSocial nem ser
|
|
77
|
+
-- declarado isento dele.
|
|
78
|
+
|
|
79
|
+
CREATE TABLE IF NOT EXISTS client_fiscal_attribute (
|
|
80
|
+
id uuid PRIMARY KEY,
|
|
81
|
+
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
|
82
|
+
client_id uuid NOT NULL,
|
|
83
|
+
attribute_key text NOT NULL REFERENCES fiscal_attribute_definition(key),
|
|
84
|
+
value_bool boolean,
|
|
85
|
+
value_text text,
|
|
86
|
+
source text,
|
|
87
|
+
updated_by uuid REFERENCES "user"(id),
|
|
88
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
89
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
90
|
+
CONSTRAINT client_fiscal_attribute_tenant_id_uq UNIQUE (tenant_id, id),
|
|
91
|
+
FOREIGN KEY (tenant_id, client_id) REFERENCES client (tenant_id, id),
|
|
92
|
+
-- Exatamente um valor. Nenhum seria linha sem informação; dois seriam duas
|
|
93
|
+
-- respostas para a mesma pergunta.
|
|
94
|
+
CHECK ((value_bool IS NOT NULL)::int + (value_text IS NOT NULL)::int = 1)
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
CREATE UNIQUE INDEX IF NOT EXISTS client_fiscal_attribute_uq
|
|
98
|
+
ON client_fiscal_attribute (tenant_id, client_id, attribute_key);
|
|
99
|
+
|
|
100
|
+
ALTER TABLE client_fiscal_attribute ENABLE ROW LEVEL SECURITY;
|
|
101
|
+
ALTER TABLE client_fiscal_attribute FORCE ROW LEVEL SECURITY;
|
|
102
|
+
CREATE POLICY client_fiscal_attribute_tenant_isolation ON client_fiscal_attribute
|
|
103
|
+
USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
|
|
104
|
+
WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
|
|
105
|
+
|
|
106
|
+
-- Código IBGE do município: o identificador canônico.
|
|
107
|
+
--
|
|
108
|
+
-- `client.municipality` é texto livre e serve para a tela. Casar regra
|
|
109
|
+
-- municipal por texto livre falharia no primeiro "Goiania" sem acento. O
|
|
110
|
+
-- código é opcional: sem ele, regra municipal devolve INSUFFICIENT_DATA em vez
|
|
111
|
+
-- de casar por aproximação.
|
|
112
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS municipality_ibge_code text;
|
|
113
|
+
|
|
114
|
+
DO $$
|
|
115
|
+
BEGIN
|
|
116
|
+
IF NOT EXISTS (SELECT FROM pg_constraint WHERE conname = 'client_ibge_format') THEN
|
|
117
|
+
ALTER TABLE client ADD CONSTRAINT client_ibge_format
|
|
118
|
+
CHECK (municipality_ibge_code IS NULL OR municipality_ibge_code ~ '^[0-9]{7}$');
|
|
119
|
+
END IF;
|
|
120
|
+
END $$;
|
|
121
|
+
|
|
122
|
+
-- ── 3 · A regra fiscal versionada ──────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
CREATE TABLE IF NOT EXISTS fiscal_rule (
|
|
125
|
+
id uuid PRIMARY KEY,
|
|
126
|
+
-- NULL = regra GLOBAL do produto. NOT NULL = regra do próprio escritório.
|
|
127
|
+
-- Mesmo padrão de `recurring_item_type` e `role`: ler o global é direito de
|
|
128
|
+
-- todos; escrevê-lo, de ninguém que opere como tenant.
|
|
129
|
+
tenant_id uuid REFERENCES tenant(id),
|
|
130
|
+
item_type_id uuid NOT NULL REFERENCES recurring_item_type(id),
|
|
131
|
+
|
|
132
|
+
-- ── jurisdição ──────────────────────────────────────────────────────────
|
|
133
|
+
jurisdiction_scope text NOT NULL CHECK (jurisdiction_scope IN ('federal', 'state', 'municipal')),
|
|
134
|
+
jurisdiction_uf text CHECK (jurisdiction_uf IS NULL OR jurisdiction_uf ~ '^[A-Z]{2}$'),
|
|
135
|
+
jurisdiction_city_ibge text CHECK (jurisdiction_city_ibge IS NULL OR jurisdiction_city_ibge ~ '^[0-9]{7}$'),
|
|
136
|
+
-- A jurisdição precisa ser COMPLETA para o seu nível. Uma regra "estadual"
|
|
137
|
+
-- sem UF não é uma regra: é um marcador que casaria com o país inteiro.
|
|
138
|
+
CHECK (
|
|
139
|
+
(jurisdiction_scope = 'federal' AND jurisdiction_uf IS NULL AND jurisdiction_city_ibge IS NULL) OR
|
|
140
|
+
(jurisdiction_scope = 'state' AND jurisdiction_uf IS NOT NULL AND jurisdiction_city_ibge IS NULL) OR
|
|
141
|
+
(jurisdiction_scope = 'municipal' AND jurisdiction_uf IS NOT NULL AND jurisdiction_city_ibge IS NOT NULL)
|
|
142
|
+
),
|
|
143
|
+
|
|
144
|
+
-- ── vigência e versão ───────────────────────────────────────────────────
|
|
145
|
+
version int NOT NULL DEFAULT 1 CHECK (version > 0),
|
|
146
|
+
valid_from date NOT NULL,
|
|
147
|
+
valid_until date,
|
|
148
|
+
CHECK (valid_until IS NULL OR valid_until >= valid_from),
|
|
149
|
+
|
|
150
|
+
status text NOT NULL DEFAULT 'pending_validation'
|
|
151
|
+
CHECK (status IN ('not_configured', 'pending_validation', 'validated', 'expired', 'disabled')),
|
|
152
|
+
|
|
153
|
+
-- ── conteúdo ────────────────────────────────────────────────────────────
|
|
154
|
+
-- AST declarativa. Interpretada por código tipado, NUNCA avaliada como
|
|
155
|
+
-- expressão: nada aqui vira `eval`, SQL ou função.
|
|
156
|
+
conditions jsonb NOT NULL DEFAULT '{"op":"always"}'::jsonb,
|
|
157
|
+
due_rule jsonb,
|
|
158
|
+
|
|
159
|
+
-- ── procedência ─────────────────────────────────────────────────────────
|
|
160
|
+
source_reference text,
|
|
161
|
+
validated_by uuid REFERENCES "user"(id),
|
|
162
|
+
validated_at timestamptz,
|
|
163
|
+
note text,
|
|
164
|
+
|
|
165
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
166
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
167
|
+
deleted_at timestamptz,
|
|
168
|
+
|
|
169
|
+
CONSTRAINT fiscal_rule_tenant_id_uq UNIQUE (tenant_id, id),
|
|
170
|
+
-- Uma regra `validated` sem quem validou é uma afirmação sem autor.
|
|
171
|
+
CHECK ((status <> 'validated') OR (validated_at IS NOT NULL AND validated_by IS NOT NULL)),
|
|
172
|
+
-- `not_configured` é o estado honesto de quem não tem vencimento definido.
|
|
173
|
+
-- Uma regra validada SEM vencimento produziria obrigação sem data.
|
|
174
|
+
CHECK ((status <> 'validated') OR due_rule IS NOT NULL)
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
-- Versões da mesma regra não se sobrepõem: uma só vigente por jurisdição.
|
|
178
|
+
-- Mesmo padrão que `accounting_regime` já provou para o regime do cliente.
|
|
179
|
+
CREATE UNIQUE INDEX IF NOT EXISTS fiscal_rule_current_uq
|
|
180
|
+
ON fiscal_rule (
|
|
181
|
+
coalesce(tenant_id::text, '-'), item_type_id, jurisdiction_scope,
|
|
182
|
+
coalesce(jurisdiction_uf, '-'), coalesce(jurisdiction_city_ibge, '-')
|
|
183
|
+
)
|
|
184
|
+
WHERE valid_until IS NULL AND deleted_at IS NULL;
|
|
185
|
+
|
|
186
|
+
CREATE UNIQUE INDEX IF NOT EXISTS fiscal_rule_version_uq
|
|
187
|
+
ON fiscal_rule (
|
|
188
|
+
coalesce(tenant_id::text, '-'), item_type_id, jurisdiction_scope,
|
|
189
|
+
coalesce(jurisdiction_uf, '-'), coalesce(jurisdiction_city_ibge, '-'), version
|
|
190
|
+
)
|
|
191
|
+
WHERE deleted_at IS NULL;
|
|
192
|
+
|
|
193
|
+
-- Pré-filtragem: a engine busca por jurisdição + vigência antes de avaliar
|
|
194
|
+
-- condição nenhuma. Sem este índice, avaliar a carteira exigiria varrer o
|
|
195
|
+
-- catálogo inteiro por cliente.
|
|
196
|
+
CREATE INDEX IF NOT EXISTS fiscal_rule_lookup_idx
|
|
197
|
+
ON fiscal_rule (jurisdiction_scope, jurisdiction_uf, jurisdiction_city_ibge, valid_from)
|
|
198
|
+
WHERE deleted_at IS NULL;
|
|
199
|
+
CREATE INDEX IF NOT EXISTS fiscal_rule_item_idx
|
|
200
|
+
ON fiscal_rule (item_type_id, valid_from) WHERE deleted_at IS NULL;
|
|
201
|
+
|
|
202
|
+
ALTER TABLE fiscal_rule ENABLE ROW LEVEL SECURITY;
|
|
203
|
+
ALTER TABLE fiscal_rule FORCE ROW LEVEL SECURITY;
|
|
204
|
+
|
|
205
|
+
-- Leitura: a regra global e as do próprio escritório.
|
|
206
|
+
-- Escrita: SOMENTE as do próprio escritório.
|
|
207
|
+
--
|
|
208
|
+
-- O `WITH CHECK` sem o ramo `IS NULL` é a lição da 0045: com ele, qualquer
|
|
209
|
+
-- tenant forjaria regra fiscal GLOBAL — que vale para todos os escritórios do
|
|
210
|
+
-- país. É a escalada mais cara que este schema comporta.
|
|
211
|
+
CREATE POLICY fiscal_rule_visibility ON fiscal_rule
|
|
212
|
+
USING (tenant_id IS NULL OR tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
|
|
213
|
+
WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
|
|
214
|
+
|
|
215
|
+
DO $$
|
|
216
|
+
DECLARE owner_role text;
|
|
217
|
+
BEGIN
|
|
218
|
+
SELECT tableowner INTO owner_role FROM pg_tables
|
|
219
|
+
WHERE schemaname = 'public' AND tablename = 'fiscal_rule';
|
|
220
|
+
IF owner_role IS NULL THEN
|
|
221
|
+
RAISE EXCEPTION 'fiscal_rule sem dono identificável — abortando';
|
|
222
|
+
END IF;
|
|
223
|
+
-- FORCE RLS vale para o dono; o provisionamento do catálogo global roda sem
|
|
224
|
+
-- tenant no contexto e precisa de política nominal. Padrão da 0042/0045.
|
|
225
|
+
EXECUTE format(
|
|
226
|
+
'CREATE POLICY fiscal_rule_system_provisioning ON fiscal_rule FOR ALL TO %I USING (true) WITH CHECK (true)',
|
|
227
|
+
owner_role);
|
|
228
|
+
END $$;
|
|
229
|
+
|
|
230
|
+
COMMENT ON POLICY fiscal_rule_visibility ON fiscal_rule IS
|
|
231
|
+
'Leitura: regra global + as do tenant. Escrita: SOMENTE do tenant. O ramo IS NULL fora do WITH CHECK impede forjar regra fiscal nacional (lição do P0-A, Fase 4).';
|
|
232
|
+
|
|
233
|
+
-- ── 4 · Política operacional do escritório ─────────────────────────────────
|
|
234
|
+
--
|
|
235
|
+
-- Separa REGRA LEGAL de PROCEDIMENTO DO ESCRITÓRIO.
|
|
236
|
+
--
|
|
237
|
+
-- O prazo legal do DAS é do país. O prazo em que o escritório quer os
|
|
238
|
+
-- documentos do cliente na mão é dele. Enquanto os dois moram no mesmo campo,
|
|
239
|
+
-- ajustar o procedimento interno reescreve a regra legal — em silêncio, e para
|
|
240
|
+
-- todo mundo que enxerga aquela linha.
|
|
241
|
+
|
|
242
|
+
CREATE TABLE IF NOT EXISTS tenant_rule_policy (
|
|
243
|
+
id uuid PRIMARY KEY,
|
|
244
|
+
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
|
245
|
+
item_type_id uuid NOT NULL REFERENCES recurring_item_type(id),
|
|
246
|
+
-- Dias ANTES do vencimento legal em que o escritório quer a coisa pronta.
|
|
247
|
+
-- Não altera o vencimento legal: acrescenta um prazo interno ao lado dele.
|
|
248
|
+
internal_lead_days int CHECK (internal_lead_days IS NULL OR internal_lead_days BETWEEN 0 AND 90),
|
|
249
|
+
enabled boolean NOT NULL DEFAULT true,
|
|
250
|
+
note text,
|
|
251
|
+
updated_by uuid REFERENCES "user"(id),
|
|
252
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
253
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
254
|
+
CONSTRAINT tenant_rule_policy_tenant_id_uq UNIQUE (tenant_id, id)
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
CREATE UNIQUE INDEX IF NOT EXISTS tenant_rule_policy_uq
|
|
258
|
+
ON tenant_rule_policy (tenant_id, item_type_id);
|
|
259
|
+
|
|
260
|
+
ALTER TABLE tenant_rule_policy ENABLE ROW LEVEL SECURITY;
|
|
261
|
+
ALTER TABLE tenant_rule_policy FORCE ROW LEVEL SECURITY;
|
|
262
|
+
CREATE POLICY tenant_rule_policy_tenant_isolation ON tenant_rule_policy
|
|
263
|
+
USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
|
|
264
|
+
WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
|
|
265
|
+
|
|
266
|
+
COMMENT ON TABLE tenant_rule_policy IS
|
|
267
|
+
'Procedimento do escritório, ao LADO da regra legal e nunca por cima dela. Prazo interno não é prazo legal.';
|
|
268
|
+
|
|
269
|
+
-- ── 5 · Preservação histórica ──────────────────────────────────────────────
|
|
270
|
+
--
|
|
271
|
+
-- A instância já congela `label` e `due_date`. Falta saber QUAL versão da
|
|
272
|
+
-- regra produziu aquela data — sem isso, uma V2 publicada amanhã faz a
|
|
273
|
+
-- obrigação de ontem parecer ter nascido de uma regra que não existia.
|
|
274
|
+
|
|
275
|
+
ALTER TABLE recurring_instance ADD COLUMN IF NOT EXISTS fiscal_rule_id uuid REFERENCES fiscal_rule(id);
|
|
276
|
+
ALTER TABLE recurring_instance ADD COLUMN IF NOT EXISTS fiscal_rule_version int;
|
|
277
|
+
|
|
278
|
+
COMMENT ON COLUMN recurring_instance.fiscal_rule_id IS
|
|
279
|
+
'Versão EXATA da regra que gerou esta obrigação. Publicar uma V2 não altera o que já foi gerado sob a V1.';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
-- 0050 — o vocabulário do perfil fiscal é lido pelo runtime, nunca escrito.
|
|
2
|
+
--
|
|
3
|
+
-- Esta migration existe separada da 0049 por uma razão de processo, e vale
|
|
4
|
+
-- registrar: eu havia acrescentado este bloco ao fim da 0049 depois de ela já
|
|
5
|
+
-- ter sido aplicada. O runner recusou — migrations são imutáveis, e a checagem
|
|
6
|
+
-- de hash existe exatamente para impedir que o que rodou num ambiente seja
|
|
7
|
+
-- diferente do que roda no próximo.
|
|
8
|
+
--
|
|
9
|
+
-- ── A barreira ─────────────────────────────────────────────────────────────
|
|
10
|
+
--
|
|
11
|
+
-- `fiscal_attribute_definition` é catálogo GLOBAL, sem `tenant_id`. Não há RLS
|
|
12
|
+
-- que o proteja, porque não há linha de ninguém: a barreira só pode ser o
|
|
13
|
+
-- privilégio.
|
|
14
|
+
--
|
|
15
|
+
-- O runtime lê o vocabulário a cada avaliação de aplicabilidade e nunca o
|
|
16
|
+
-- escreve. Um tenant capaz de inserir atributo aqui poderia criar um atributo
|
|
17
|
+
-- que nenhuma regra usa (inócuo) ou — pior — apagar um que as regras de todos
|
|
18
|
+
-- os escritórios usam, derrubando a avaliação do país inteiro por FK.
|
|
19
|
+
--
|
|
20
|
+
-- Repetido em `migrate.ts` no mesmo bloco de `role` e `audit_log`: o GRANT da
|
|
21
|
+
-- allowlist é amplo por construção e devolveria a escrita no deploy seguinte.
|
|
22
|
+
-- Foi o defeito que a Fase 3 encontrou ao separar GRANT de hardening.
|
|
23
|
+
|
|
24
|
+
DO $$
|
|
25
|
+
BEGIN
|
|
26
|
+
IF EXISTS (SELECT FROM pg_roles WHERE rolname = 'baruk_app') THEN
|
|
27
|
+
EXECUTE 'REVOKE INSERT, UPDATE, DELETE ON fiscal_attribute_definition FROM baruk_app';
|
|
28
|
+
END IF;
|
|
29
|
+
END $$;
|