@baruk/core 0.3.1 → 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 +10 -0
- package/CHANGELOG.md +127 -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/password-reset.d.ts +30 -1
- package/dist/auth/password-reset.d.ts.map +1 -1
- package/dist/auth/password-reset.js +139 -11
- package/dist/auth/password-reset.js.map +1 -1
- package/dist/auth/service.d.ts +60 -2
- package/dist/auth/service.d.ts.map +1 -1
- package/dist/auth/service.js +121 -11
- package/dist/auth/service.js.map +1 -1
- package/dist/billing/ar-repository.d.ts +374 -0
- package/dist/billing/ar-repository.d.ts.map +1 -0
- package/dist/billing/ar-repository.js +783 -0
- package/dist/billing/ar-repository.js.map +1 -0
- package/dist/billing/auto-generation.d.ts +87 -0
- package/dist/billing/auto-generation.d.ts.map +1 -0
- package/dist/billing/auto-generation.js +181 -0
- package/dist/billing/auto-generation.js.map +1 -0
- package/dist/billing/live-guard.d.ts +64 -0
- package/dist/billing/live-guard.d.ts.map +1 -0
- package/dist/billing/live-guard.js +68 -0
- package/dist/billing/live-guard.js.map +1 -0
- package/dist/billing/payment-means-catalog.d.ts +17 -0
- package/dist/billing/payment-means-catalog.d.ts.map +1 -0
- package/dist/billing/payment-means-catalog.js +21 -0
- package/dist/billing/payment-means-catalog.js.map +1 -0
- package/dist/billing/payment-means.d.ts +38 -0
- package/dist/billing/payment-means.d.ts.map +1 -0
- package/dist/billing/payment-means.js +29 -0
- package/dist/billing/payment-means.js.map +1 -0
- package/dist/billing/payment-rail.d.ts +118 -0
- package/dist/billing/payment-rail.d.ts.map +1 -0
- package/dist/billing/payment-rail.js +295 -0
- package/dist/billing/payment-rail.js.map +1 -0
- package/dist/billing/provider/asaas.d.ts +46 -1
- package/dist/billing/provider/asaas.d.ts.map +1 -1
- package/dist/billing/provider/asaas.js +194 -14
- package/dist/billing/provider/asaas.js.map +1 -1
- package/dist/billing/provider/manual.js +1 -1
- package/dist/billing/provider/manual.js.map +1 -1
- package/dist/billing/provider/types.d.ts +115 -8
- package/dist/billing/provider/types.d.ts.map +1 -1
- package/dist/billing/provider-account.d.ts +127 -0
- package/dist/billing/provider-account.d.ts.map +1 -0
- package/dist/billing/provider-account.js +217 -0
- package/dist/billing/provider-account.js.map +1 -0
- package/dist/billing/provider-onboarding.d.ts +67 -0
- package/dist/billing/provider-onboarding.d.ts.map +1 -0
- package/dist/billing/provider-onboarding.js +234 -0
- package/dist/billing/provider-onboarding.js.map +1 -0
- package/dist/billing/receivable.d.ts +5 -1
- package/dist/billing/receivable.d.ts.map +1 -1
- package/dist/billing/reconcile.d.ts +58 -0
- package/dist/billing/reconcile.d.ts.map +1 -0
- package/dist/billing/reconcile.js +138 -0
- package/dist/billing/reconcile.js.map +1 -0
- package/dist/billing/repository.d.ts +134 -1
- package/dist/billing/repository.d.ts.map +1 -1
- package/dist/billing/repository.js +193 -20
- 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/password-reset.js +141 -11
- package/dist/cjs/auth/password-reset.js.map +1 -1
- package/dist/cjs/auth/service.js +121 -10
- package/dist/cjs/auth/service.js.map +1 -1
- package/dist/cjs/billing/ar-repository.js +804 -0
- package/dist/cjs/billing/ar-repository.js.map +1 -0
- package/dist/cjs/billing/auto-generation.js +186 -0
- package/dist/cjs/billing/auto-generation.js.map +1 -0
- package/dist/cjs/billing/live-guard.js +72 -0
- package/dist/cjs/billing/live-guard.js.map +1 -0
- package/dist/cjs/billing/payment-means-catalog.js +25 -0
- package/dist/cjs/billing/payment-means-catalog.js.map +1 -0
- package/dist/cjs/billing/payment-means.js +33 -0
- package/dist/cjs/billing/payment-means.js.map +1 -0
- package/dist/cjs/billing/payment-rail.js +301 -0
- package/dist/cjs/billing/payment-rail.js.map +1 -0
- package/dist/cjs/billing/provider/asaas.js +194 -14
- package/dist/cjs/billing/provider/asaas.js.map +1 -1
- package/dist/cjs/billing/provider/manual.js +1 -1
- package/dist/cjs/billing/provider/manual.js.map +1 -1
- package/dist/cjs/billing/provider-account.js +229 -0
- package/dist/cjs/billing/provider-account.js.map +1 -0
- package/dist/cjs/billing/provider-onboarding.js +239 -0
- package/dist/cjs/billing/provider-onboarding.js.map +1 -0
- package/dist/cjs/billing/reconcile.js +143 -0
- package/dist/cjs/billing/reconcile.js.map +1 -0
- package/dist/cjs/billing/repository.js +197 -19
- 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 +276 -23
- package/dist/cjs/clients/repository.js.map +1 -1
- package/dist/cjs/collection/branding.js +330 -0
- package/dist/cjs/collection/branding.js.map +1 -0
- package/dist/cjs/collection/channel-accounts.js +137 -0
- package/dist/cjs/collection/channel-accounts.js.map +1 -0
- package/dist/cjs/collection/channel.js +17 -0
- package/dist/cjs/collection/channel.js.map +1 -0
- package/dist/cjs/collection/clearance-store.js +74 -0
- package/dist/cjs/collection/clearance-store.js.map +1 -0
- package/dist/cjs/collection/communication-bridge.js +140 -0
- package/dist/cjs/collection/communication-bridge.js.map +1 -0
- package/dist/cjs/collection/communication-runtime.js +256 -0
- package/dist/cjs/collection/communication-runtime.js.map +1 -0
- package/dist/cjs/collection/consent-repository.js +84 -0
- package/dist/cjs/collection/consent-repository.js.map +1 -0
- package/dist/cjs/collection/copy.js +125 -0
- package/dist/cjs/collection/copy.js.map +1 -0
- package/dist/cjs/collection/delivery-callback.js +151 -0
- package/dist/cjs/collection/delivery-callback.js.map +1 -0
- package/dist/cjs/collection/email-layout.js +252 -0
- package/dist/cjs/collection/email-layout.js.map +1 -0
- package/dist/cjs/collection/engine.js +434 -0
- package/dist/cjs/collection/engine.js.map +1 -0
- package/dist/cjs/collection/format.js +76 -0
- package/dist/cjs/collection/format.js.map +1 -0
- package/dist/cjs/collection/payment-block.js +3 -0
- package/dist/cjs/collection/payment-block.js.map +1 -0
- package/dist/cjs/collection/policy.js +175 -0
- package/dist/cjs/collection/policy.js.map +1 -0
- package/dist/cjs/collection/repository.js +260 -0
- package/dist/cjs/collection/repository.js.map +1 -0
- package/dist/cjs/collection/subject.js +104 -0
- package/dist/cjs/collection/subject.js.map +1 -0
- package/dist/cjs/collection/template-catalog.js +165 -0
- package/dist/cjs/collection/template-catalog.js.map +1 -0
- package/dist/cjs/collection/template.js +78 -0
- package/dist/cjs/collection/template.js.map +1 -0
- package/dist/cjs/communication/adapters/email.js +132 -0
- package/dist/cjs/communication/adapters/email.js.map +1 -0
- package/dist/cjs/communication/adapters/sms.js +127 -0
- package/dist/cjs/communication/adapters/sms.js.map +1 -0
- package/dist/cjs/communication/adapters/whatsapp-language.js +39 -0
- package/dist/cjs/communication/adapters/whatsapp-language.js.map +1 -0
- package/dist/cjs/communication/adapters/whatsapp-templates.js +100 -0
- package/dist/cjs/communication/adapters/whatsapp-templates.js.map +1 -0
- package/dist/cjs/communication/adapters/whatsapp.js +213 -0
- package/dist/cjs/communication/adapters/whatsapp.js.map +1 -0
- package/dist/cjs/communication/audit.js +61 -0
- package/dist/cjs/communication/audit.js.map +1 -0
- package/dist/cjs/communication/capabilities.js +76 -0
- package/dist/cjs/communication/capabilities.js.map +1 -0
- package/dist/cjs/communication/channel.js +53 -0
- package/dist/cjs/communication/channel.js.map +1 -0
- package/dist/cjs/communication/claim.js +228 -0
- package/dist/cjs/communication/claim.js.map +1 -0
- package/dist/cjs/communication/clearance.js +18 -0
- package/dist/cjs/communication/clearance.js.map +1 -0
- package/dist/cjs/communication/consent.js +43 -0
- package/dist/cjs/communication/consent.js.map +1 -0
- package/dist/cjs/communication/context.js +45 -0
- package/dist/cjs/communication/context.js.map +1 -0
- package/dist/cjs/communication/credentials.js +121 -0
- package/dist/cjs/communication/credentials.js.map +1 -0
- package/dist/cjs/communication/dry-run-scenario.js +166 -0
- package/dist/cjs/communication/dry-run-scenario.js.map +1 -0
- package/dist/cjs/communication/dry-run.js +97 -0
- package/dist/cjs/communication/dry-run.js.map +1 -0
- package/dist/cjs/communication/engine.js +495 -0
- package/dist/cjs/communication/engine.js.map +1 -0
- package/dist/cjs/communication/graph.js +50 -0
- package/dist/cjs/communication/graph.js.map +1 -0
- package/dist/cjs/communication/idempotency.js +26 -0
- package/dist/cjs/communication/idempotency.js.map +1 -0
- package/dist/cjs/communication/identity.js +110 -0
- package/dist/cjs/communication/identity.js.map +1 -0
- package/dist/cjs/communication/index.js +135 -0
- package/dist/cjs/communication/index.js.map +1 -0
- package/dist/cjs/communication/onboarding.js +297 -0
- package/dist/cjs/communication/onboarding.js.map +1 -0
- package/dist/cjs/communication/policy.js +16 -0
- package/dist/cjs/communication/policy.js.map +1 -0
- package/dist/cjs/communication/routing.js +77 -0
- package/dist/cjs/communication/routing.js.map +1 -0
- package/dist/cjs/communication/sender-profile.js +128 -0
- package/dist/cjs/communication/sender-profile.js.map +1 -0
- package/dist/cjs/communication/status.js +86 -0
- package/dist/cjs/communication/status.js.map +1 -0
- package/dist/cjs/communication/stores/onboarding.js +135 -0
- package/dist/cjs/communication/stores/onboarding.js.map +1 -0
- package/dist/cjs/communication/stores/postgres.js +458 -0
- package/dist/cjs/communication/stores/postgres.js.map +1 -0
- package/dist/cjs/communication/stores/routing.js +334 -0
- package/dist/cjs/communication/stores/routing.js.map +1 -0
- package/dist/cjs/communication/stores/secrets.js +126 -0
- package/dist/cjs/communication/stores/secrets.js.map +1 -0
- package/dist/cjs/communication/template-provider.js +22 -0
- package/dist/cjs/communication/template-provider.js.map +1 -0
- package/dist/cjs/communication/template.js +63 -0
- package/dist/cjs/communication/template.js.map +1 -0
- package/dist/cjs/communication/webhook-subscription.js +258 -0
- package/dist/cjs/communication/webhook-subscription.js.map +1 -0
- package/dist/cjs/communication/webhook.js +292 -0
- package/dist/cjs/communication/webhook.js.map +1 -0
- 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 +622 -0
- package/dist/cjs/competence/repository.js.map +1 -0
- package/dist/cjs/contacts/phone.js +192 -0
- package/dist/cjs/contacts/phone.js.map +1 -0
- 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/db/seed-catalog.js +48 -0
- package/dist/cjs/db/seed-catalog.js.map +1 -0
- package/dist/cjs/db/seed.js +15 -7
- package/dist/cjs/db/seed.js.map +1 -1
- package/dist/cjs/documents/repository.js +244 -0
- package/dist/cjs/documents/repository.js.map +1 -0
- package/dist/cjs/documents/requests.js +136 -0
- package/dist/cjs/documents/requests.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 +711 -39
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/legal/documents.js +224 -17
- 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 +1 -0
- package/dist/cjs/legal/types.js.map +1 -1
- package/dist/cjs/mail/auth-templates.js +29 -0
- package/dist/cjs/mail/auth-templates.js.map +1 -0
- package/dist/cjs/mail/dedup-store.js +12 -51
- package/dist/cjs/mail/dedup-store.js.map +1 -1
- package/dist/cjs/mail/index.js +16 -4
- package/dist/cjs/mail/index.js.map +1 -1
- package/dist/cjs/mail/provider.js +12 -247
- package/dist/cjs/mail/provider.js.map +1 -1
- package/dist/cjs/mail/resend.js +14 -18
- package/dist/cjs/mail/resend.js.map +1 -1
- package/dist/cjs/mail/sender-resolver.js +12 -11
- package/dist/cjs/mail/sender-resolver.js.map +1 -1
- package/dist/cjs/mail/template-renderer.js +11 -16
- package/dist/cjs/mail/template-renderer.js.map +1 -1
- package/dist/cjs/mail/transactional-outbound.js +117 -0
- package/dist/cjs/mail/transactional-outbound.js.map +1 -0
- package/dist/cjs/mail/types.js +8 -35
- package/dist/cjs/mail/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/portal/provisioning.js +144 -0
- package/dist/cjs/portal/provisioning.js.map +1 -0
- package/dist/cjs/pricing-engine/canonical.js +42 -0
- package/dist/cjs/pricing-engine/canonical.js.map +1 -0
- package/dist/cjs/pricing-engine/errors.js +6 -1
- package/dist/cjs/pricing-engine/errors.js.map +1 -1
- package/dist/cjs/pricing-engine/index.js +12 -1
- package/dist/cjs/pricing-engine/index.js.map +1 -1
- package/dist/cjs/pricing-engine/pipeline.js +200 -26
- package/dist/cjs/pricing-engine/pipeline.js.map +1 -1
- package/dist/cjs/pricing-engine/shadow-adapter.js +79 -0
- package/dist/cjs/pricing-engine/shadow-adapter.js.map +1 -0
- package/dist/cjs/pricing-engine/shadow-diff.js +55 -0
- package/dist/cjs/pricing-engine/shadow-diff.js.map +1 -0
- package/dist/cjs/pricing-engine/shadow-facade.js +85 -0
- package/dist/cjs/pricing-engine/shadow-facade.js.map +1 -0
- package/dist/cjs/pricing-engine/shadow-legacy-types.js +19 -0
- package/dist/cjs/pricing-engine/shadow-legacy-types.js.map +1 -0
- package/dist/cjs/pricing-engine/shadow-metrics.js +34 -0
- package/dist/cjs/pricing-engine/shadow-metrics.js.map +1 -0
- package/dist/cjs/pricing-engine/shadow-normalizer.js +42 -0
- package/dist/cjs/pricing-engine/shadow-normalizer.js.map +1 -0
- package/dist/cjs/rbac/authorize.js +28 -0
- package/dist/cjs/rbac/authorize.js.map +1 -1
- package/dist/cjs/rbac/catalog.js +101 -1
- package/dist/cjs/rbac/catalog.js.map +1 -1
- package/dist/cjs/rbac/workload-provisioning.js +160 -0
- package/dist/cjs/rbac/workload-provisioning.js.map +1 -0
- package/dist/cjs/rbac/workload.js +191 -0
- package/dist/cjs/rbac/workload.js.map +1 -0
- package/dist/cjs/storage/checksum.js +15 -0
- package/dist/cjs/storage/checksum.js.map +1 -0
- package/dist/cjs/storage/key.js +72 -0
- package/dist/cjs/storage/key.js.map +1 -0
- package/dist/cjs/storage/local.js +100 -0
- package/dist/cjs/storage/local.js.map +1 -0
- package/dist/cjs/storage/r2.js +181 -0
- package/dist/cjs/storage/r2.js.map +1 -0
- package/dist/cjs/storage/registry.js +41 -0
- package/dist/cjs/storage/registry.js.map +1 -0
- package/dist/cjs/storage/types.js +50 -0
- package/dist/cjs/storage/types.js.map +1 -0
- package/dist/cjs/subscription-billing/index.js +2 -1
- package/dist/cjs/subscription-billing/index.js.map +1 -1
- package/dist/cjs/subscription-billing/provider/asaas.js +32 -7
- package/dist/cjs/subscription-billing/provider/asaas.js.map +1 -1
- package/dist/cjs/subscription-billing/provider/disabled.js +8 -0
- package/dist/cjs/subscription-billing/provider/disabled.js.map +1 -1
- package/dist/cjs/subscription-billing/provider/registry.js +17 -0
- package/dist/cjs/subscription-billing/provider/registry.js.map +1 -1
- package/dist/cjs/subscription-billing/service.js +208 -83
- package/dist/cjs/subscription-billing/service.js.map +1 -1
- package/dist/cjs/subscription-billing/types.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/provisioning.js +32 -8
- package/dist/cjs/tenancy/provisioning.js.map +1 -1
- package/dist/cjs/tenancy/settings.js +224 -0
- package/dist/cjs/tenancy/settings.js.map +1 -0
- package/dist/cjs/users/repository.js +143 -3
- package/dist/cjs/users/repository.js.map +1 -1
- package/dist/cjs/vault/repository.js +81 -0
- 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 +98 -0
- package/dist/clients/ibge.js.map +1 -0
- package/dist/clients/repository.d.ts +196 -0
- package/dist/clients/repository.d.ts.map +1 -1
- package/dist/clients/repository.js +270 -24
- package/dist/clients/repository.js.map +1 -1
- package/dist/collection/branding.d.ts +137 -0
- package/dist/collection/branding.d.ts.map +1 -0
- package/dist/collection/branding.js +322 -0
- package/dist/collection/branding.js.map +1 -0
- package/dist/collection/channel-accounts.d.ts +57 -0
- package/dist/collection/channel-accounts.d.ts.map +1 -0
- package/dist/collection/channel-accounts.js +133 -0
- package/dist/collection/channel-accounts.js.map +1 -0
- package/dist/collection/channel.d.ts +24 -0
- package/dist/collection/channel.d.ts.map +1 -0
- package/dist/collection/channel.js +16 -0
- package/dist/collection/channel.js.map +1 -0
- 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-bridge.d.ts +66 -0
- package/dist/collection/communication-bridge.d.ts.map +1 -0
- package/dist/collection/communication-bridge.js +134 -0
- package/dist/collection/communication-bridge.js.map +1 -0
- package/dist/collection/communication-runtime.d.ts +132 -0
- package/dist/collection/communication-runtime.d.ts.map +1 -0
- package/dist/collection/communication-runtime.js +249 -0
- package/dist/collection/communication-runtime.js.map +1 -0
- package/dist/collection/consent-repository.d.ts +32 -0
- package/dist/collection/consent-repository.d.ts.map +1 -0
- package/dist/collection/consent-repository.js +79 -0
- package/dist/collection/consent-repository.js.map +1 -0
- package/dist/collection/copy.d.ts +50 -0
- package/dist/collection/copy.d.ts.map +1 -0
- package/dist/collection/copy.js +122 -0
- package/dist/collection/copy.js.map +1 -0
- package/dist/collection/delivery-callback.d.ts +49 -0
- package/dist/collection/delivery-callback.d.ts.map +1 -0
- package/dist/collection/delivery-callback.js +147 -0
- package/dist/collection/delivery-callback.js.map +1 -0
- package/dist/collection/email-layout.d.ts +45 -0
- package/dist/collection/email-layout.d.ts.map +1 -0
- package/dist/collection/email-layout.js +247 -0
- package/dist/collection/email-layout.js.map +1 -0
- package/dist/collection/engine.d.ts +200 -0
- package/dist/collection/engine.d.ts.map +1 -0
- package/dist/collection/engine.js +427 -0
- package/dist/collection/engine.js.map +1 -0
- package/dist/collection/format.d.ts +32 -0
- package/dist/collection/format.d.ts.map +1 -0
- package/dist/collection/format.js +70 -0
- package/dist/collection/format.js.map +1 -0
- package/dist/collection/payment-block.d.ts +24 -0
- package/dist/collection/payment-block.d.ts.map +1 -0
- package/dist/collection/payment-block.js +2 -0
- package/dist/collection/payment-block.js.map +1 -0
- package/dist/collection/policy.d.ts +78 -0
- package/dist/collection/policy.d.ts.map +1 -0
- package/dist/collection/policy.js +168 -0
- package/dist/collection/policy.js.map +1 -0
- package/dist/collection/repository.d.ts +129 -0
- package/dist/collection/repository.d.ts.map +1 -0
- package/dist/collection/repository.js +246 -0
- package/dist/collection/repository.js.map +1 -0
- package/dist/collection/subject.d.ts +66 -0
- package/dist/collection/subject.d.ts.map +1 -0
- package/dist/collection/subject.js +99 -0
- package/dist/collection/subject.js.map +1 -0
- package/dist/collection/template-catalog.d.ts +16 -0
- package/dist/collection/template-catalog.d.ts.map +1 -0
- package/dist/collection/template-catalog.js +162 -0
- package/dist/collection/template-catalog.js.map +1 -0
- package/dist/collection/template.d.ts +37 -0
- package/dist/collection/template.d.ts.map +1 -0
- package/dist/collection/template.js +73 -0
- package/dist/collection/template.js.map +1 -0
- package/dist/communication/adapters/email.d.ts +28 -0
- package/dist/communication/adapters/email.d.ts.map +1 -0
- package/dist/communication/adapters/email.js +129 -0
- package/dist/communication/adapters/email.js.map +1 -0
- package/dist/communication/adapters/sms.d.ts +95 -0
- package/dist/communication/adapters/sms.d.ts.map +1 -0
- package/dist/communication/adapters/sms.js +121 -0
- package/dist/communication/adapters/sms.js.map +1 -0
- package/dist/communication/adapters/whatsapp-language.d.ts +34 -0
- package/dist/communication/adapters/whatsapp-language.d.ts.map +1 -0
- package/dist/communication/adapters/whatsapp-language.js +36 -0
- package/dist/communication/adapters/whatsapp-language.js.map +1 -0
- package/dist/communication/adapters/whatsapp-templates.d.ts +18 -0
- package/dist/communication/adapters/whatsapp-templates.d.ts.map +1 -0
- package/dist/communication/adapters/whatsapp-templates.js +97 -0
- package/dist/communication/adapters/whatsapp-templates.js.map +1 -0
- package/dist/communication/adapters/whatsapp.d.ts +29 -0
- package/dist/communication/adapters/whatsapp.d.ts.map +1 -0
- package/dist/communication/adapters/whatsapp.js +210 -0
- package/dist/communication/adapters/whatsapp.js.map +1 -0
- package/dist/communication/audit.d.ts +105 -0
- package/dist/communication/audit.d.ts.map +1 -0
- package/dist/communication/audit.js +56 -0
- package/dist/communication/audit.js.map +1 -0
- package/dist/communication/capabilities.d.ts +88 -0
- package/dist/communication/capabilities.d.ts.map +1 -0
- package/dist/communication/capabilities.js +72 -0
- package/dist/communication/capabilities.js.map +1 -0
- package/dist/communication/channel.d.ts +125 -0
- package/dist/communication/channel.d.ts.map +1 -0
- package/dist/communication/channel.js +47 -0
- package/dist/communication/channel.js.map +1 -0
- package/dist/communication/claim.d.ts +368 -0
- package/dist/communication/claim.d.ts.map +1 -0
- package/dist/communication/claim.js +224 -0
- package/dist/communication/claim.js.map +1 -0
- 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/consent.d.ts +65 -0
- package/dist/communication/consent.d.ts.map +1 -0
- package/dist/communication/consent.js +40 -0
- package/dist/communication/consent.js.map +1 -0
- package/dist/communication/context.d.ts +48 -0
- package/dist/communication/context.d.ts.map +1 -0
- package/dist/communication/context.js +41 -0
- package/dist/communication/context.js.map +1 -0
- package/dist/communication/credentials.d.ts +74 -0
- package/dist/communication/credentials.d.ts.map +1 -0
- package/dist/communication/credentials.js +115 -0
- package/dist/communication/credentials.js.map +1 -0
- package/dist/communication/dry-run-scenario.d.ts +37 -0
- package/dist/communication/dry-run-scenario.d.ts.map +1 -0
- package/dist/communication/dry-run-scenario.js +163 -0
- package/dist/communication/dry-run-scenario.js.map +1 -0
- package/dist/communication/dry-run.d.ts +40 -0
- package/dist/communication/dry-run.d.ts.map +1 -0
- package/dist/communication/dry-run.js +92 -0
- package/dist/communication/dry-run.js.map +1 -0
- package/dist/communication/engine.d.ts +163 -0
- package/dist/communication/engine.d.ts.map +1 -0
- package/dist/communication/engine.js +492 -0
- package/dist/communication/engine.js.map +1 -0
- package/dist/communication/graph.d.ts +38 -0
- package/dist/communication/graph.d.ts.map +1 -0
- package/dist/communication/graph.js +45 -0
- package/dist/communication/graph.js.map +1 -0
- package/dist/communication/idempotency.d.ts +33 -0
- package/dist/communication/idempotency.d.ts.map +1 -0
- package/dist/communication/idempotency.js +23 -0
- package/dist/communication/idempotency.js.map +1 -0
- package/dist/communication/identity.d.ts +127 -0
- package/dist/communication/identity.d.ts.map +1 -0
- package/dist/communication/identity.js +105 -0
- package/dist/communication/identity.js.map +1 -0
- package/dist/communication/index.d.ts +66 -0
- package/dist/communication/index.d.ts.map +1 -0
- package/dist/communication/index.js +42 -0
- package/dist/communication/index.js.map +1 -0
- package/dist/communication/onboarding.d.ts +223 -0
- package/dist/communication/onboarding.d.ts.map +1 -0
- package/dist/communication/onboarding.js +287 -0
- package/dist/communication/onboarding.js.map +1 -0
- package/dist/communication/policy.d.ts +115 -0
- package/dist/communication/policy.d.ts.map +1 -0
- package/dist/communication/policy.js +13 -0
- package/dist/communication/policy.js.map +1 -0
- package/dist/communication/routing.d.ts +99 -0
- package/dist/communication/routing.d.ts.map +1 -0
- package/dist/communication/routing.js +73 -0
- package/dist/communication/routing.js.map +1 -0
- package/dist/communication/sender-profile.d.ts +100 -0
- package/dist/communication/sender-profile.d.ts.map +1 -0
- package/dist/communication/sender-profile.js +123 -0
- package/dist/communication/sender-profile.js.map +1 -0
- package/dist/communication/status.d.ts +48 -0
- package/dist/communication/status.d.ts.map +1 -0
- package/dist/communication/status.js +79 -0
- package/dist/communication/status.js.map +1 -0
- package/dist/communication/stores/onboarding.d.ts +88 -0
- package/dist/communication/stores/onboarding.d.ts.map +1 -0
- package/dist/communication/stores/onboarding.js +127 -0
- package/dist/communication/stores/onboarding.js.map +1 -0
- package/dist/communication/stores/postgres.d.ts +81 -0
- package/dist/communication/stores/postgres.d.ts.map +1 -0
- package/dist/communication/stores/postgres.js +453 -0
- package/dist/communication/stores/postgres.js.map +1 -0
- package/dist/communication/stores/routing.d.ts +169 -0
- package/dist/communication/stores/routing.d.ts.map +1 -0
- package/dist/communication/stores/routing.js +324 -0
- package/dist/communication/stores/routing.js.map +1 -0
- package/dist/communication/stores/secrets.d.ts +89 -0
- package/dist/communication/stores/secrets.d.ts.map +1 -0
- package/dist/communication/stores/secrets.js +122 -0
- package/dist/communication/stores/secrets.js.map +1 -0
- package/dist/communication/template-provider.d.ts +85 -0
- package/dist/communication/template-provider.d.ts.map +1 -0
- package/dist/communication/template-provider.js +21 -0
- package/dist/communication/template-provider.js.map +1 -0
- package/dist/communication/template.d.ts +87 -0
- package/dist/communication/template.d.ts.map +1 -0
- package/dist/communication/template.js +59 -0
- package/dist/communication/template.js.map +1 -0
- package/dist/communication/webhook-subscription.d.ts +156 -0
- package/dist/communication/webhook-subscription.d.ts.map +1 -0
- package/dist/communication/webhook-subscription.js +252 -0
- package/dist/communication/webhook-subscription.js.map +1 -0
- package/dist/communication/webhook.d.ts +121 -0
- package/dist/communication/webhook.d.ts.map +1 -0
- package/dist/communication/webhook.js +283 -0
- package/dist/communication/webhook.js.map +1 -0
- 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 +285 -0
- package/dist/competence/repository.d.ts.map +1 -0
- package/dist/competence/repository.js +602 -0
- package/dist/competence/repository.js.map +1 -0
- package/dist/contacts/phone.d.ts +70 -0
- package/dist/contacts/phone.d.ts.map +1 -0
- package/dist/contacts/phone.js +186 -0
- package/dist/contacts/phone.js.map +1 -0
- 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 +208 -35
- 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/db/seed-catalog.d.ts +18 -0
- package/dist/db/seed-catalog.d.ts.map +1 -0
- package/dist/db/seed-catalog.js +45 -0
- package/dist/db/seed-catalog.js.map +1 -0
- package/dist/db/seed.js +16 -8
- package/dist/db/seed.js.map +1 -1
- package/dist/documents/repository.d.ts +97 -0
- package/dist/documents/repository.d.ts.map +1 -0
- package/dist/documents/repository.js +236 -0
- package/dist/documents/repository.js.map +1 -0
- package/dist/documents/requests.d.ts +73 -0
- package/dist/documents/requests.d.ts.map +1 -0
- package/dist/documents/requests.js +127 -0
- package/dist/documents/requests.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 +217 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +196 -11
- 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 +222 -16
- 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 +69 -3
- package/dist/legal/types.d.ts.map +1 -1
- package/dist/legal/types.js +1 -0
- package/dist/legal/types.js.map +1 -1
- package/dist/mail/auth-templates.d.ts +15 -0
- package/dist/mail/auth-templates.d.ts.map +1 -0
- package/dist/mail/auth-templates.js +26 -0
- package/dist/mail/auth-templates.js.map +1 -0
- package/dist/mail/dedup-store.d.ts +1 -24
- package/dist/mail/dedup-store.d.ts.map +1 -1
- package/dist/mail/dedup-store.js +9 -48
- package/dist/mail/dedup-store.js.map +1 -1
- package/dist/mail/index.d.ts +2 -1
- package/dist/mail/index.d.ts.map +1 -1
- package/dist/mail/index.js +13 -2
- package/dist/mail/index.js.map +1 -1
- package/dist/mail/provider.d.ts +2 -30
- package/dist/mail/provider.d.ts.map +1 -1
- package/dist/mail/provider.js +10 -246
- package/dist/mail/provider.js.map +1 -1
- package/dist/mail/resend.d.ts +2 -12
- package/dist/mail/resend.d.ts.map +1 -1
- package/dist/mail/resend.js +11 -17
- package/dist/mail/resend.js.map +1 -1
- package/dist/mail/sender-resolver.d.ts +1 -7
- package/dist/mail/sender-resolver.d.ts.map +1 -1
- package/dist/mail/sender-resolver.js +11 -10
- package/dist/mail/sender-resolver.js.map +1 -1
- package/dist/mail/template-renderer.d.ts +1 -9
- package/dist/mail/template-renderer.d.ts.map +1 -1
- package/dist/mail/template-renderer.js +10 -15
- package/dist/mail/template-renderer.js.map +1 -1
- package/dist/mail/transactional-outbound.d.ts +115 -0
- package/dist/mail/transactional-outbound.d.ts.map +1 -0
- package/dist/mail/transactional-outbound.js +113 -0
- package/dist/mail/transactional-outbound.js.map +1 -0
- package/dist/mail/types.d.ts +2 -142
- package/dist/mail/types.d.ts.map +1 -1
- package/dist/mail/types.js +1 -33
- package/dist/mail/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/portal/provisioning.d.ts +58 -0
- package/dist/portal/provisioning.d.ts.map +1 -0
- package/dist/portal/provisioning.js +139 -0
- package/dist/portal/provisioning.js.map +1 -0
- package/dist/pricing-engine/canonical.d.ts +14 -0
- package/dist/pricing-engine/canonical.d.ts.map +1 -0
- package/dist/pricing-engine/canonical.js +39 -0
- package/dist/pricing-engine/canonical.js.map +1 -0
- package/dist/pricing-engine/errors.d.ts.map +1 -1
- package/dist/pricing-engine/errors.js +6 -1
- package/dist/pricing-engine/errors.js.map +1 -1
- package/dist/pricing-engine/index.d.ts +12 -2
- package/dist/pricing-engine/index.d.ts.map +1 -1
- package/dist/pricing-engine/index.js +6 -1
- package/dist/pricing-engine/index.js.map +1 -1
- package/dist/pricing-engine/pipeline.d.ts.map +1 -1
- package/dist/pricing-engine/pipeline.js +202 -28
- package/dist/pricing-engine/pipeline.js.map +1 -1
- package/dist/pricing-engine/shadow-adapter.d.ts +37 -0
- package/dist/pricing-engine/shadow-adapter.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-adapter.js +75 -0
- package/dist/pricing-engine/shadow-adapter.js.map +1 -0
- package/dist/pricing-engine/shadow-diff.d.ts +26 -0
- package/dist/pricing-engine/shadow-diff.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-diff.js +52 -0
- package/dist/pricing-engine/shadow-diff.js.map +1 -0
- package/dist/pricing-engine/shadow-facade.d.ts +42 -0
- package/dist/pricing-engine/shadow-facade.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-facade.js +82 -0
- package/dist/pricing-engine/shadow-facade.js.map +1 -0
- package/dist/pricing-engine/shadow-legacy-types.d.ts +64 -0
- package/dist/pricing-engine/shadow-legacy-types.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-legacy-types.js +18 -0
- package/dist/pricing-engine/shadow-legacy-types.js.map +1 -0
- package/dist/pricing-engine/shadow-metrics.d.ts +33 -0
- package/dist/pricing-engine/shadow-metrics.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-metrics.js +31 -0
- package/dist/pricing-engine/shadow-metrics.js.map +1 -0
- package/dist/pricing-engine/shadow-normalizer.d.ts +17 -0
- package/dist/pricing-engine/shadow-normalizer.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-normalizer.js +39 -0
- package/dist/pricing-engine/shadow-normalizer.js.map +1 -0
- package/dist/pricing-engine/types.d.ts +2 -0
- package/dist/pricing-engine/types.d.ts.map +1 -1
- package/dist/rbac/authorize.d.ts +12 -0
- package/dist/rbac/authorize.d.ts.map +1 -1
- package/dist/rbac/authorize.js +27 -0
- package/dist/rbac/authorize.js.map +1 -1
- package/dist/rbac/catalog.d.ts.map +1 -1
- package/dist/rbac/catalog.js +101 -1
- package/dist/rbac/catalog.js.map +1 -1
- package/dist/rbac/workload-provisioning.d.ts +66 -0
- package/dist/rbac/workload-provisioning.d.ts.map +1 -0
- package/dist/rbac/workload-provisioning.js +153 -0
- package/dist/rbac/workload-provisioning.js.map +1 -0
- package/dist/rbac/workload.d.ts +124 -0
- package/dist/rbac/workload.d.ts.map +1 -0
- package/dist/rbac/workload.js +184 -0
- package/dist/rbac/workload.js.map +1 -0
- package/dist/storage/checksum.d.ts +9 -0
- package/dist/storage/checksum.d.ts.map +1 -0
- package/dist/storage/checksum.js +12 -0
- package/dist/storage/checksum.js.map +1 -0
- package/dist/storage/key.d.ts +37 -0
- package/dist/storage/key.d.ts.map +1 -0
- package/dist/storage/key.js +67 -0
- package/dist/storage/key.js.map +1 -0
- package/dist/storage/local.d.ts +40 -0
- package/dist/storage/local.d.ts.map +1 -0
- package/dist/storage/local.js +96 -0
- package/dist/storage/local.js.map +1 -0
- package/dist/storage/r2.d.ts +43 -0
- package/dist/storage/r2.d.ts.map +1 -0
- package/dist/storage/r2.js +177 -0
- package/dist/storage/r2.js.map +1 -0
- package/dist/storage/registry.d.ts +23 -0
- package/dist/storage/registry.d.ts.map +1 -0
- package/dist/storage/registry.js +37 -0
- package/dist/storage/registry.js.map +1 -0
- package/dist/storage/types.d.ts +67 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +45 -0
- package/dist/storage/types.js.map +1 -0
- 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/provider/asaas.d.ts +14 -0
- package/dist/subscription-billing/provider/asaas.d.ts.map +1 -1
- package/dist/subscription-billing/provider/asaas.js +32 -7
- package/dist/subscription-billing/provider/asaas.js.map +1 -1
- package/dist/subscription-billing/provider/disabled.d.ts +9 -0
- package/dist/subscription-billing/provider/disabled.d.ts.map +1 -1
- package/dist/subscription-billing/provider/disabled.js +8 -0
- package/dist/subscription-billing/provider/disabled.js.map +1 -1
- package/dist/subscription-billing/provider/registry.d.ts +10 -0
- package/dist/subscription-billing/provider/registry.d.ts.map +1 -1
- package/dist/subscription-billing/provider/registry.js +17 -0
- package/dist/subscription-billing/provider/registry.js.map +1 -1
- package/dist/subscription-billing/service.d.ts +38 -1
- package/dist/subscription-billing/service.d.ts.map +1 -1
- package/dist/subscription-billing/service.js +147 -23
- package/dist/subscription-billing/service.js.map +1 -1
- package/dist/subscription-billing/types.d.ts +13 -0
- package/dist/subscription-billing/types.d.ts.map +1 -1
- package/dist/subscription-billing/types.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/provisioning.d.ts.map +1 -1
- package/dist/tenancy/provisioning.js +32 -8
- package/dist/tenancy/provisioning.js.map +1 -1
- 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 +54 -1
- package/dist/users/repository.d.ts.map +1 -1
- package/dist/users/repository.js +142 -4
- package/dist/users/repository.js.map +1 -1
- package/dist/vault/repository.d.ts +67 -0
- package/dist/vault/repository.d.ts.map +1 -1
- package/dist/vault/repository.js +78 -0
- package/dist/vault/repository.js.map +1 -1
- package/package.json +20 -4
- package/src/db/migrations/0023_user_invite_activation.sql +15 -0
- package/src/db/migrations/0024_set_user_password_function.sql +32 -0
- package/src/db/migrations/0025_revoke_user_session_function.sql +28 -0
- package/src/db/migrations/0026_documents_and_competence.sql +353 -0
- package/src/db/migrations/0027_receivable_client_isolation.sql +58 -0
- package/src/db/migrations/0028_collection_engine.sql +94 -0
- package/src/db/migrations/0029_payment_rail.sql +107 -0
- package/src/db/migrations/0030_provider_account_uniqueness.sql +22 -0
- package/src/db/migrations/0031_provider_account_environment_scope.sql +21 -0
- package/src/db/migrations/0032_settlement_reversal.sql +76 -0
- package/src/db/migrations/0033_receivable_idempotency.sql +28 -0
- package/src/db/migrations/0034_payment_customer_reconcile.sql +30 -0
- package/src/db/migrations/0035_payment_account_environments.sql +61 -0
- package/src/db/migrations/0036_primary_backfill_under_force_rls.sql +41 -0
- package/src/db/migrations/0037_receivable_generation_source.sql +29 -0
- package/src/db/migrations/0038_notification_channels.sql +175 -0
- package/src/db/migrations/0039_communication_dispatch_claim.sql +193 -0
- package/src/db/migrations/0040_communication_unknown_outcome.sql +99 -0
- package/src/db/migrations/0041_channel_binding_routing.sql +146 -0
- package/src/db/migrations/0042_channel_route_read_isolation.sql +165 -0
- package/src/db/migrations/0043_workload_identity.sql +105 -0
- package/src/db/migrations/0044_channel_onboarding_session.sql +96 -0
- 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/dist/cjs/mail/resend-client.js +0 -103
- package/dist/cjs/mail/resend-client.js.map +0 -1
- package/dist/mail/resend-client.d.ts +0 -16
- package/dist/mail/resend-client.d.ts.map +0 -1
- package/dist/mail/resend-client.js +0 -100
- package/dist/mail/resend-client.js.map +0 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
-- 0032 — Reversão de liquidação (dívida L da Onda 1B.4.2)
|
|
2
|
+
--
|
|
3
|
+
-- O gateway pode desfazer uma baixa que ele próprio registrou: o caso concreto é
|
|
4
|
+
-- o "recebimento em dinheiro" informado à mão no painel e depois cancelado. Até
|
|
5
|
+
-- aqui o sistema não tinha como representar isso. A cobrança continuava `paid`,
|
|
6
|
+
-- o `payment` continuava `confirmed`, o recebível continuava quitado — e a régua
|
|
7
|
+
-- de cobrança ficava desligada para sempre. Um dinheiro que nunca entrou saía do
|
|
8
|
+
-- sistema como recebido.
|
|
9
|
+
--
|
|
10
|
+
-- A distinção que este schema passa a suportar é financeira, não cosmética:
|
|
11
|
+
--
|
|
12
|
+
-- `refunded` — o dinheiro ENTROU e depois SAIU. Dois fatos, duas linhas na
|
|
13
|
+
-- história do caixa. A dívida foi quitada; o estorno é evento
|
|
14
|
+
-- novo, e não desfaz a quitação.
|
|
15
|
+
-- `reversed` — o dinheiro NUNCA ENTROU. O registro de liquidação estava
|
|
16
|
+
-- errado e foi anulado na origem. Não há fato novo de caixa: há
|
|
17
|
+
-- um fato anterior que deixou de valer.
|
|
18
|
+
--
|
|
19
|
+
-- Reaproveitar `refunded` para o segundo caso poria no extrato do escritório uma
|
|
20
|
+
-- devolução que nunca aconteceu.
|
|
21
|
+
--
|
|
22
|
+
-- NADA é apagado. A linha de `payment` permanece, com o valor, o método e a data
|
|
23
|
+
-- em que se acreditou ter recebido; ela apenas deixa de contar no saldo, e passa
|
|
24
|
+
-- a carregar quando e por que foi anulada. `charge.paid_at` também permanece: é
|
|
25
|
+
-- o registro de quando a cobrança esteve liquidada.
|
|
26
|
+
|
|
27
|
+
-- ── payment ────────────────────────────────────────────────────────────────
|
|
28
|
+
ALTER TABLE payment DROP CONSTRAINT IF EXISTS payment_status_check;
|
|
29
|
+
ALTER TABLE payment ADD CONSTRAINT payment_status_check
|
|
30
|
+
CHECK (status IN ('detected', 'confirmed', 'refunded', 'reversed'));
|
|
31
|
+
|
|
32
|
+
ALTER TABLE payment ADD COLUMN IF NOT EXISTS reversed_at timestamptz;
|
|
33
|
+
-- Motivo em texto curto e estável (`settlement_undone`, …), não prosa livre:
|
|
34
|
+
-- quem for auditar precisa agrupar, e não ler.
|
|
35
|
+
ALTER TABLE payment ADD COLUMN IF NOT EXISTS reversal_reason text;
|
|
36
|
+
|
|
37
|
+
-- Um pagamento revertido tem de dizer QUANDO. Sem isto a anulação vira um
|
|
38
|
+
-- status sem data, e a pergunta "desde quando este dinheiro deixou de contar?"
|
|
39
|
+
-- deixa de ter resposta.
|
|
40
|
+
ALTER TABLE payment DROP CONSTRAINT IF EXISTS payment_reversed_at_check;
|
|
41
|
+
ALTER TABLE payment ADD CONSTRAINT payment_reversed_at_check
|
|
42
|
+
CHECK ((status = 'reversed') = (reversed_at IS NOT NULL));
|
|
43
|
+
|
|
44
|
+
-- ── charge ─────────────────────────────────────────────────────────────────
|
|
45
|
+
ALTER TABLE charge DROP CONSTRAINT IF EXISTS charge_status_check;
|
|
46
|
+
ALTER TABLE charge ADD CONSTRAINT charge_status_check
|
|
47
|
+
CHECK (status IN ('pending', 'sent', 'paid', 'overdue', 'canceled', 'refunded', 'reversed'));
|
|
48
|
+
|
|
49
|
+
ALTER TABLE charge ADD COLUMN IF NOT EXISTS reversed_at timestamptz;
|
|
50
|
+
|
|
51
|
+
-- `reversed` NÃO entra na lista de cobranças mortas do índice único parcial de
|
|
52
|
+
-- `charge (tenant_id, receivable_id)`, e isso é deliberado: o boleto ou o PIX
|
|
53
|
+
-- continuam válidos no gateway e continuam pagáveis. A cobrança revertida segue
|
|
54
|
+
-- sendo A cobrança viva do recebível — emitir uma segunda para a mesma dívida é
|
|
55
|
+
-- que produziria duplicidade. Pela mesma razão, a régua de cobrança volta a
|
|
56
|
+
-- alcançá-la: `dunning` só ignora `paid`, `canceled` e `refunded`.
|
|
57
|
+
|
|
58
|
+
-- ── Unicidade do id de pagamento no provider ───────────────────────────────
|
|
59
|
+
--
|
|
60
|
+
-- O índice da 0029 impede que o MESMO pagamento do gateway vire duas baixas —
|
|
61
|
+
-- webhook duplicado é a regra, não a exceção. Ele continua valendo.
|
|
62
|
+
--
|
|
63
|
+
-- O que muda é o alcance: uma linha ANULADA deixa de ocupar o id. A cobrança
|
|
64
|
+
-- revertida continua pagável, e quando o cliente de fato paga, o gateway usa o
|
|
65
|
+
-- mesmo `pay_…`. Com o índice cobrindo linhas anuladas, essa baixa legítima
|
|
66
|
+
-- estouraria unicidade, a transação inteira do webhook falharia, e o gateway
|
|
67
|
+
-- reenviaria para sempre um pagamento que o sistema nunca conseguiria registrar.
|
|
68
|
+
-- Dinheiro real entrando e não sendo baixado — o defeito que esta onda existe
|
|
69
|
+
-- para eliminar, reaparecendo pela porta oposta.
|
|
70
|
+
--
|
|
71
|
+
-- Duas linhas CONFIRMADAS com o mesmo id continuam impossíveis, que é o que o
|
|
72
|
+
-- índice protege.
|
|
73
|
+
DROP INDEX IF EXISTS payment_provider_payment_uq;
|
|
74
|
+
CREATE UNIQUE INDEX payment_provider_payment_uq
|
|
75
|
+
ON payment (tenant_id, provider, provider_payment_id)
|
|
76
|
+
WHERE provider_payment_id IS NOT NULL AND status <> 'reversed';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-- 0033 — Idempotência do lançamento avulso
|
|
2
|
+
--
|
|
3
|
+
-- A emissão da COBRANÇA já era idempotente: o índice único parcial de
|
|
4
|
+
-- `charge (tenant_id, receivable_id)` garante uma cobrança viva por recebível.
|
|
5
|
+
-- O RECEBÍVEL não era. Um duplo clique no formulário, um retry de HTTP ou um
|
|
6
|
+
-- refresh depois do POST criavam dois recebíveis para o mesmo serviço — e, com
|
|
7
|
+
-- dois recebíveis, duas cobranças legítimas, cada uma com o seu PIX. O cliente
|
|
8
|
+
-- receberia dois pedidos de pagamento do mesmo trabalho.
|
|
9
|
+
--
|
|
10
|
+
-- O fluxo por competência nunca teve esse problema porque a idempotência dele é
|
|
11
|
+
-- semântica: o único `(tenant, fee_agreement, competence)` diz "esta dívida já
|
|
12
|
+
-- existe". No avulso não há chave semântica — dois honorários avulsos de mesmo
|
|
13
|
+
-- valor, mesma descrição e mesmo vencimento podem ser dois serviços de verdade,
|
|
14
|
+
-- e recusar o segundo seria um defeito pior.
|
|
15
|
+
--
|
|
16
|
+
-- Daí a chave vir de FORA: quem inicia a operação declara um identificador da
|
|
17
|
+
-- TENTATIVA. Reenviar a mesma tentativa devolve o mesmo recebível; um novo
|
|
18
|
+
-- lançamento tem chave nova e é criado normalmente. A distinção entre "de novo" e
|
|
19
|
+
-- "outra vez" passa a ser do chamador, que é quem realmente sabe.
|
|
20
|
+
ALTER TABLE receivable ADD COLUMN IF NOT EXISTS idempotency_key text;
|
|
21
|
+
|
|
22
|
+
-- Parcial: só as linhas que declararam chave participam. Sem o `WHERE`, todo
|
|
23
|
+
-- recebível gerado por competência (chave nula) colidiria com o primeiro —
|
|
24
|
+
-- porque em índice único comum `NULL` não colide, mas a intenção aqui é explícita
|
|
25
|
+
-- e vale registrá-la.
|
|
26
|
+
CREATE UNIQUE INDEX IF NOT EXISTS receivable_idempotency_uq
|
|
27
|
+
ON receivable (tenant_id, idempotency_key)
|
|
28
|
+
WHERE idempotency_key IS NOT NULL;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
-- 0034 — Reconciliação cadastral do pagador no provedor (dívida R)
|
|
2
|
+
--
|
|
3
|
+
-- `payment_customer` guardava o id do pagador no gateway e nada mais. O efeito
|
|
4
|
+
-- prático era uma afirmação que o schema nunca fez, mas o código assumia:
|
|
5
|
+
-- *"este cliente já existe lá, logo os dados dele estão corretos para sempre"*.
|
|
6
|
+
--
|
|
7
|
+
-- Não estão. Um cliente cadastrado no Office SEM CPF/CNPJ produzia um pagador
|
|
8
|
+
-- sem documento no gateway. Corrigir o documento no Office não mudava nada lá —
|
|
9
|
+
-- o cache devolvia o id e o adapter sequer era chamado — e a emissão continuava
|
|
10
|
+
-- sendo recusada pelo provedor. O escritório corrigia no lugar certo e o sistema
|
|
11
|
+
-- seguia dizendo não.
|
|
12
|
+
--
|
|
13
|
+
-- A coluna nova responde outra pergunta: não "existe?", mas **"o que está lá
|
|
14
|
+
-- corresponde ao que temos aqui?"**.
|
|
15
|
+
ALTER TABLE payment_customer ADD COLUMN IF NOT EXISTS synced_fingerprint text;
|
|
16
|
+
ALTER TABLE payment_customer ADD COLUMN IF NOT EXISTS synced_at timestamptz;
|
|
17
|
+
|
|
18
|
+
-- É um DIGEST, nunca os dados.
|
|
19
|
+
--
|
|
20
|
+
-- Guardar nome, documento, e-mail e telefone aqui duplicaria dado pessoal que já
|
|
21
|
+
-- vive em `client`, com uma segunda cópia para manter em dia e vazar. O digest
|
|
22
|
+
-- responde exatamente a pergunta que interessa — "mudou desde a última
|
|
23
|
+
-- sincronização?" — e não responde nenhuma outra.
|
|
24
|
+
COMMENT ON COLUMN payment_customer.synced_fingerprint IS
|
|
25
|
+
'sha256 dos campos cadastrais enviados ao provedor. Digest, nunca os valores.';
|
|
26
|
+
|
|
27
|
+
-- Linhas antigas ficam com `NULL` de propósito: nulo significa "nunca
|
|
28
|
+
-- reconciliado", e a primeira emissão de cada cliente existente vai reconciliar.
|
|
29
|
+
-- É assim que a dívida R se cura sozinha na base atual, sem backfill adivinhando
|
|
30
|
+
-- o que o gateway tem.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
-- 0035 — Sandbox e produção deixam de ser excludentes (dívida U)
|
|
2
|
+
--
|
|
3
|
+
-- O único por `(tenant_id, provider)` dizia, na prática: *um escritório tem UMA
|
|
4
|
+
-- conta Asaas*. Ambiente não fazia parte da identidade lógica, então ativar
|
|
5
|
+
-- produção exigia **revogar o laboratório** — e a decisão "vou cobrar de
|
|
6
|
+
-- verdade" ficava amarrada a "vou perder onde ensaio".
|
|
7
|
+
--
|
|
8
|
+
-- Duas contas do mesmo provedor em ambientes diferentes não são a mesma conta.
|
|
9
|
+
-- Elas têm credencial distinta, endpoint distinto, dinheiro distinto — e a 0031
|
|
10
|
+
-- já reconhecia isso ao pôr `environment` na unicidade da referência externa. O
|
|
11
|
+
-- que faltava era reconhecer o mesmo no único por tenant.
|
|
12
|
+
ALTER TABLE payment_provider_account
|
|
13
|
+
ADD COLUMN IF NOT EXISTS is_primary boolean NOT NULL DEFAULT false;
|
|
14
|
+
|
|
15
|
+
-- ── 1. Uma conta por (tenant, provider, AMBIENTE) ──────────────────────────
|
|
16
|
+
DROP INDEX IF EXISTS payment_provider_account_provider_uq;
|
|
17
|
+
CREATE UNIQUE INDEX IF NOT EXISTS payment_provider_account_env_uq
|
|
18
|
+
ON payment_provider_account (tenant_id, provider, environment)
|
|
19
|
+
WHERE status <> 'revoked';
|
|
20
|
+
|
|
21
|
+
-- ── 2. Exatamente UMA conta operacional por (tenant, provider) ─────────────
|
|
22
|
+
--
|
|
23
|
+
-- Coexistir não pode virar ambiguidade. Sem esta trava, "qual conta emite?"
|
|
24
|
+
-- passaria a depender de ordem de criação ou de um `LIMIT 1` — que é
|
|
25
|
+
-- exatamente a escolha implícita que não se pode ter quando o assunto é
|
|
26
|
+
-- para onde vai o dinheiro.
|
|
27
|
+
--
|
|
28
|
+
-- A promoção desta marca é o ato de "entrar em produção": explícito, auditável
|
|
29
|
+
-- e reversível, em vez de um efeito colateral de revogar o sandbox.
|
|
30
|
+
CREATE UNIQUE INDEX IF NOT EXISTS payment_provider_account_primary_uq
|
|
31
|
+
ON payment_provider_account (tenant_id, provider)
|
|
32
|
+
WHERE is_primary AND status <> 'revoked';
|
|
33
|
+
|
|
34
|
+
-- ── 3. Classificação dos registros existentes ──────────────────────────────
|
|
35
|
+
--
|
|
36
|
+
-- Toda conta viva hoje É a conta operacional do seu escritório — era a única
|
|
37
|
+
-- que podia existir. Marcá-la mantém o comportamento atual EXATAMENTE como
|
|
38
|
+
-- está: quem já emitia pelo sandbox continua emitindo pelo sandbox.
|
|
39
|
+
--
|
|
40
|
+
-- Nada é reinterpretado: nenhum `sandbox` vira `live`, nenhum ambiente é
|
|
41
|
+
-- adivinhado. `environment` já existia preenchido e NOT NULL desde a 0015.
|
|
42
|
+
UPDATE payment_provider_account SET is_primary = true WHERE status <> 'revoked';
|
|
43
|
+
|
|
44
|
+
-- ── 4. Isolamento do identificador externo da cobrança ─────────────────────
|
|
45
|
+
--
|
|
46
|
+
-- `charge_external_uq` era `(tenant_id, provider, external_id)` — cego ao
|
|
47
|
+
-- ambiente. Com as duas contas coexistindo, um `pay_…` de sandbox e um de
|
|
48
|
+
-- produção que coincidissem colidiriam, e a emissão legítima seria recusada.
|
|
49
|
+
--
|
|
50
|
+
-- Passa a incluir a CONTA. Cobrança anterior ao Payment Rail não tem conta;
|
|
51
|
+
-- `COALESCE` para o uuid nulo preserva a proteção dessas linhas entre si, em
|
|
52
|
+
-- vez de deixá-las fora do índice como `NULL` faria.
|
|
53
|
+
DROP INDEX IF EXISTS charge_external_uq;
|
|
54
|
+
CREATE UNIQUE INDEX IF NOT EXISTS charge_external_uq
|
|
55
|
+
ON charge (tenant_id, provider,
|
|
56
|
+
COALESCE(provider_account_id, '00000000-0000-0000-0000-000000000000'::uuid),
|
|
57
|
+
external_id)
|
|
58
|
+
WHERE external_id IS NOT NULL AND deleted_at IS NULL;
|
|
59
|
+
|
|
60
|
+
COMMENT ON COLUMN payment_provider_account.is_primary IS
|
|
61
|
+
'A conta que o escritório OPERA. Exatamente uma por (tenant, provider). Promover é o ato de entrar em produção.';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- 0036 — refazer o backfill de `is_primary` que a 0035 não conseguiu aplicar.
|
|
2
|
+
--
|
|
3
|
+
-- `payment_provider_account` tem FORCE ROW LEVEL SECURITY: a política vale
|
|
4
|
+
-- inclusive para o DONO da tabela, que é quem roda as migrations. O UPDATE da
|
|
5
|
+
-- 0035 rodou sem `app.current_tenant` definida, a política não casou com linha
|
|
6
|
+
-- nenhuma e o comando afetou ZERO linhas — sem erro, sem aviso, com a migration
|
|
7
|
+
-- registrada como aplicada.
|
|
8
|
+
--
|
|
9
|
+
-- A consequência não é cosmética. `getActiveProviderAccount` passou a exigir
|
|
10
|
+
-- `is_primary`; com o backfill vazio, um escritório que já tinha conta conectada
|
|
11
|
+
-- ficava sem conta operacional e simplesmente não conseguia emitir — um sistema
|
|
12
|
+
-- financeiro mudo por causa de um UPDATE que "deu certo".
|
|
13
|
+
--
|
|
14
|
+
-- A 0035 é imutável (o migrador confere checksum), então a correção vem adiante.
|
|
15
|
+
-- `NO FORCE` só vale dentro desta transação; se qualquer passo falhar, o ALTER
|
|
16
|
+
-- volta atrás junto com o resto.
|
|
17
|
+
|
|
18
|
+
ALTER TABLE payment_provider_account NO FORCE ROW LEVEL SECURITY;
|
|
19
|
+
|
|
20
|
+
-- Uma primária por (tenant, provider). `created_at` decide: a conta mais antiga
|
|
21
|
+
-- é a que o escritório vinha usando, e promover a mais nova trocaria silen-
|
|
22
|
+
-- ciosamente para onde o dinheiro vai — exatamente o que esta migration não
|
|
23
|
+
-- pode fazer. Tenant que já tem primária não é tocado.
|
|
24
|
+
WITH escolhida AS (
|
|
25
|
+
SELECT DISTINCT ON (tenant_id, provider) id
|
|
26
|
+
FROM payment_provider_account
|
|
27
|
+
WHERE status <> 'revoked'
|
|
28
|
+
AND NOT EXISTS (
|
|
29
|
+
SELECT 1 FROM payment_provider_account outra
|
|
30
|
+
WHERE outra.tenant_id = payment_provider_account.tenant_id
|
|
31
|
+
AND outra.provider = payment_provider_account.provider
|
|
32
|
+
AND outra.is_primary
|
|
33
|
+
AND outra.status <> 'revoked')
|
|
34
|
+
ORDER BY tenant_id, provider, created_at
|
|
35
|
+
)
|
|
36
|
+
UPDATE payment_provider_account
|
|
37
|
+
SET is_primary = true, updated_at = now()
|
|
38
|
+
FROM escolhida
|
|
39
|
+
WHERE payment_provider_account.id = escolhida.id;
|
|
40
|
+
|
|
41
|
+
ALTER TABLE payment_provider_account FORCE ROW LEVEL SECURITY;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
-- 0037 — Quem criou o recebível: a pessoa ou o relógio
|
|
2
|
+
--
|
|
3
|
+
-- A geração por competência passa a acontecer sozinha, todo dia, para todo
|
|
4
|
+
-- honorário ativo (AUTO_RECURRING_RECEIVABLE_GENERATION). O motor é o MESMO da
|
|
5
|
+
-- ação "Gerar competência manualmente" — deliberadamente, para que não existam
|
|
6
|
+
-- duas regras discordando sobre quanto o cliente deve. O que muda é só quem
|
|
7
|
+
-- puxou o gatilho.
|
|
8
|
+
--
|
|
9
|
+
-- E é essa distinção que precisa sobreviver na linha. Sem ela, "por que este
|
|
10
|
+
-- cliente tem recebível de agosto se ninguém gerou agosto?" não tem resposta
|
|
11
|
+
-- consultável: `created_by` fica nulo tanto no automático quanto num script, e
|
|
12
|
+
-- a trilha de auditoria responde por LOTE, não por recebível. Quando alguém
|
|
13
|
+
-- contestar uma dívida — e alguém vai —, a pergunta será sobre UMA linha.
|
|
14
|
+
--
|
|
15
|
+
-- `generated_by` NÃO é natureza financeira. Um recebível automático e um manual
|
|
16
|
+
-- da mesma competência são a mesma dívida, com o mesmo valor, o mesmo
|
|
17
|
+
-- vencimento e a mesma régua. A coluna é procedência, não classificação: nada
|
|
18
|
+
-- no domínio pode decidir cobrar diferente por causa dela.
|
|
19
|
+
ALTER TABLE receivable
|
|
20
|
+
ADD COLUMN IF NOT EXISTS generated_by text NOT NULL DEFAULT 'manual'
|
|
21
|
+
CHECK (generated_by IN ('manual', 'automatic'));
|
|
22
|
+
|
|
23
|
+
-- Default 'manual' e não 'unknown': tudo que existe hoje foi criado por uma
|
|
24
|
+
-- pessoa apertando um botão ou por um script que uma pessoa rodou. Marcar o
|
|
25
|
+
-- acervo como desconhecido descreveria pior a realidade do que descrevê-lo como
|
|
26
|
+
-- manual, e obrigaria toda leitura futura a tratar um terceiro caso que só
|
|
27
|
+
-- existiria por causa desta migração.
|
|
28
|
+
COMMENT ON COLUMN receivable.generated_by IS
|
|
29
|
+
'Procedência: manual (operador/rota) ou automatic (scheduler). Nunca altera a natureza financeira.';
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
-- 0038 — Canais de cobrança além do e-mail: WhatsApp e SMS
|
|
2
|
+
--
|
|
3
|
+
-- O motor de cobrança (0028) já era agnóstico de canal: a política declara o
|
|
4
|
+
-- canal por etapa, o adapter entrega, o desfecho volta normalizado. O que não
|
|
5
|
+
-- existia era o que um canal de TELEFONE exige e o e-mail não: um número em
|
|
6
|
+
-- formato canônico, permissão para usá-lo, e correlação com o identificador que
|
|
7
|
+
-- o provider devolve.
|
|
8
|
+
--
|
|
9
|
+
-- Esta migração acrescenta só isso. Nenhuma regra financeira muda.
|
|
10
|
+
|
|
11
|
+
-- ── Telefone canônico do cliente ────────────────────────────────────────────
|
|
12
|
+
--
|
|
13
|
+
-- `client.phone` continua sendo o que o operador digitou — "(62) 99999-8888",
|
|
14
|
+
-- "62 9 9999 8888", "+55 62 99999-8888". Deliberadamente: é o que ele reconhece
|
|
15
|
+
-- na tela, e reescrever o campo do usuário para caber num provider é o tipo de
|
|
16
|
+
-- "melhoria" que faz alguém perder o ramal anotado no fim da linha.
|
|
17
|
+
--
|
|
18
|
+
-- O que os providers exigem é E.164, e essa é uma DERIVAÇÃO. Guardá-la separada
|
|
19
|
+
-- permite responder três perguntas que hoje não têm resposta: este cliente tem
|
|
20
|
+
-- número utilizável? é celular (WhatsApp/SMS) ou fixo? e o que exatamente foi
|
|
21
|
+
-- enviado ao provider, seis meses depois, quando o cadastro já mudou.
|
|
22
|
+
ALTER TABLE client ADD COLUMN IF NOT EXISTS phone_e164 text;
|
|
23
|
+
|
|
24
|
+
-- Parcial e não único: dois clientes do mesmo escritório podem legitimamente
|
|
25
|
+
-- compartilhar um telefone (marido e mulher, matriz e filial, o contador da
|
|
26
|
+
-- empresa). Unicidade aqui recusaria cadastro válido.
|
|
27
|
+
CREATE INDEX IF NOT EXISTS client_phone_e164_idx
|
|
28
|
+
ON client (tenant_id, phone_e164)
|
|
29
|
+
WHERE phone_e164 IS NOT NULL AND deleted_at IS NULL;
|
|
30
|
+
|
|
31
|
+
-- ── Permissão de canal ──────────────────────────────────────────────────────
|
|
32
|
+
--
|
|
33
|
+
-- Uma linha por (cliente, canal). A AUSÊNCIA de linha não é "pode": é
|
|
34
|
+
-- "ninguém decidiu ainda", e quem decide o que fazer com a ausência é a
|
|
35
|
+
-- política do tenant, não esta tabela.
|
|
36
|
+
--
|
|
37
|
+
-- Por que uma tabela e não uma coluna booleana em `client`: opt-out precisa
|
|
38
|
+
-- registrar QUANDO e POR QUEM. "Este cliente pediu para não receber WhatsApp"
|
|
39
|
+
-- vira uma discussão desagradável no dia em que ele recebe assim mesmo, e uma
|
|
40
|
+
-- coluna `whatsapp_ok = false` não tem como responder quando ele pediu, se
|
|
41
|
+
-- pediu ou se alguém desmarcou por engano.
|
|
42
|
+
CREATE TABLE IF NOT EXISTS client_channel_consent (
|
|
43
|
+
id uuid PRIMARY KEY,
|
|
44
|
+
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
|
45
|
+
client_id uuid NOT NULL,
|
|
46
|
+
channel text NOT NULL CHECK (channel IN ('email', 'whatsapp', 'sms')),
|
|
47
|
+
-- `granted` = pode enviar (consentimento registrado ou relação contratual)
|
|
48
|
+
-- `denied` = opt-out. NUNCA enviar, por nenhuma via — nem manual.
|
|
49
|
+
-- `unknown` = registro existe mas ninguém decidiu; a política resolve.
|
|
50
|
+
state text NOT NULL DEFAULT 'unknown'
|
|
51
|
+
CHECK (state IN ('granted', 'denied', 'unknown')),
|
|
52
|
+
-- Como a decisão chegou. `customer_reply` é o opt-out que o próprio cliente
|
|
53
|
+
-- pediu (responder SAIR no WhatsApp, por exemplo) e é o mais forte de todos:
|
|
54
|
+
-- ninguém no escritório deveria poder reverter isso por engano na tela.
|
|
55
|
+
source text NOT NULL DEFAULT 'staff'
|
|
56
|
+
CHECK (source IN ('staff', 'customer_reply', 'import', 'contract', 'provider')),
|
|
57
|
+
-- Texto curto do operador. Nunca conteúdo de mensagem, nunca PII extra.
|
|
58
|
+
note text,
|
|
59
|
+
decided_at timestamptz NOT NULL DEFAULT now(),
|
|
60
|
+
decided_by uuid REFERENCES "user"(id),
|
|
61
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
62
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
63
|
+
CONSTRAINT client_channel_consent_tenant_id_uq UNIQUE (tenant_id, id),
|
|
64
|
+
FOREIGN KEY (tenant_id, client_id) REFERENCES client (tenant_id, id)
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
-- Uma decisão viva por (cliente, canal). Sem isto, dois opt-outs concorrentes
|
|
68
|
+
-- criariam duas linhas e a leitura teria de escolher uma — e escolher errado
|
|
69
|
+
-- significa enviar para quem pediu para não receber.
|
|
70
|
+
CREATE UNIQUE INDEX IF NOT EXISTS client_channel_consent_uq
|
|
71
|
+
ON client_channel_consent (tenant_id, client_id, channel);
|
|
72
|
+
|
|
73
|
+
CREATE INDEX IF NOT EXISTS client_channel_consent_denied_idx
|
|
74
|
+
ON client_channel_consent (tenant_id, channel)
|
|
75
|
+
WHERE state = 'denied';
|
|
76
|
+
|
|
77
|
+
-- ── RLS: tenant E cliente ───────────────────────────────────────────────────
|
|
78
|
+
--
|
|
79
|
+
-- Mesmo padrão das tabelas client-scoped (0026/0027). Sem isto a tabela seria a
|
|
80
|
+
-- única com `tenant_id` do schema sem política — e não falharia em teste
|
|
81
|
+
-- nenhum, porque não existe guard que varra cobertura de RLS. Passaria verde,
|
|
82
|
+
-- e a permissão de contato de um escritório ficaria legível por outro.
|
|
83
|
+
--
|
|
84
|
+
-- FORCE porque a política precisa valer inclusive para o dono da tabela: é o
|
|
85
|
+
-- papel que roda migration, e é exatamente onde a armadilha da 0035/0036 mora.
|
|
86
|
+
ALTER TABLE client_channel_consent ENABLE ROW LEVEL SECURITY;
|
|
87
|
+
ALTER TABLE client_channel_consent FORCE ROW LEVEL SECURITY;
|
|
88
|
+
|
|
89
|
+
CREATE POLICY client_channel_consent_tenant_client_isolation ON client_channel_consent
|
|
90
|
+
USING (
|
|
91
|
+
tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid
|
|
92
|
+
AND (
|
|
93
|
+
NULLIF(current_setting('app.current_client', true), '') IS NULL
|
|
94
|
+
OR client_id = NULLIF(current_setting('app.current_client', true), '')::uuid
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
WITH CHECK (
|
|
98
|
+
tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid
|
|
99
|
+
AND (
|
|
100
|
+
NULLIF(current_setting('app.current_client', true), '') IS NULL
|
|
101
|
+
OR client_id = NULLIF(current_setting('app.current_client', true), '')::uuid
|
|
102
|
+
)
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
-- ── Correlação com o provider ───────────────────────────────────────────────
|
|
106
|
+
--
|
|
107
|
+
-- CORREÇÃO DE DEFEITO. `markSent` gravava o identificador do provider em
|
|
108
|
+
-- `template`, com `COALESCE(template, provider_ref)` — ou seja, quando o
|
|
109
|
+
-- template já estava preenchido (sempre, pois `scheduleAction` o grava), o id
|
|
110
|
+
-- do provider era descartado em silêncio; e se estivesse nulo, o id ocuparia o
|
|
111
|
+
-- lugar do nome do template e corromperia o relatório da régua.
|
|
112
|
+
--
|
|
113
|
+
-- Nunca deu problema porque o adapter de e-mail não devolve identificador.
|
|
114
|
+
-- WhatsApp e SMS devolvem sempre, e o webhook de entrega chega trazendo APENAS
|
|
115
|
+
-- esse id — sem uma coluna própria e indexada, não há como achar a ação que ele
|
|
116
|
+
-- descreve, e todo status de entrega se perderia.
|
|
117
|
+
ALTER TABLE dunning_event ADD COLUMN IF NOT EXISTS provider_ref text;
|
|
118
|
+
|
|
119
|
+
-- O webhook chega com o id do provider e nada mais. Esta é a via de acesso.
|
|
120
|
+
CREATE INDEX IF NOT EXISTS dunning_event_provider_ref_idx
|
|
121
|
+
ON dunning_event (tenant_id, provider_ref)
|
|
122
|
+
WHERE provider_ref IS NOT NULL;
|
|
123
|
+
|
|
124
|
+
-- ── Estados de entrega ──────────────────────────────────────────────────────
|
|
125
|
+
--
|
|
126
|
+
-- `sent` significa "o provider aceitou", que é o único desfecho que o e-mail
|
|
127
|
+
-- consegue afirmar. WhatsApp e SMS informam depois, por webhook, se a mensagem
|
|
128
|
+
-- chegou ao aparelho (`delivered`) e — só o WhatsApp — se foi aberta (`read`).
|
|
129
|
+
--
|
|
130
|
+
-- São estados NOVOS, não uma renomeação: `sent` continua querendo dizer
|
|
131
|
+
-- exatamente o que dizia, e nenhuma linha existente muda de valor. Colapsar
|
|
132
|
+
-- "aceito pelo provider" e "chegou ao cliente" faria a tela afirmar entrega que
|
|
133
|
+
-- ninguém confirmou — que é precisamente a pergunta que o escritório faz quando
|
|
134
|
+
-- o cliente diz "não recebi nada".
|
|
135
|
+
--
|
|
136
|
+
-- Não há `read` para SMS, e não se inventa: o canal simplesmente nunca alcança
|
|
137
|
+
-- esse estado. Ver a nota sobre equivalência falsa no adapter.
|
|
138
|
+
ALTER TABLE dunning_event DROP CONSTRAINT IF EXISTS dunning_event_status_check;
|
|
139
|
+
ALTER TABLE dunning_event ADD CONSTRAINT dunning_event_status_check
|
|
140
|
+
CHECK (status IN ('scheduled', 'sent', 'delivered', 'read', 'failed', 'canceled', 'escalated'));
|
|
141
|
+
|
|
142
|
+
-- Quando o provider confirmou a entrega no aparelho. Separado de `sent_at`
|
|
143
|
+
-- porque a distância entre os dois é a informação útil: aceito às 9h e entregue
|
|
144
|
+
-- às 14h significa aparelho desligado, não falha.
|
|
145
|
+
ALTER TABLE dunning_event ADD COLUMN IF NOT EXISTS delivered_at timestamptz;
|
|
146
|
+
ALTER TABLE dunning_event ADD COLUMN IF NOT EXISTS read_at timestamptz;
|
|
147
|
+
|
|
148
|
+
COMMENT ON COLUMN dunning_event.provider_ref IS
|
|
149
|
+
'Identificador da mensagem no provider. Nunca uma credencial. Via de acesso do webhook de entrega.';
|
|
150
|
+
COMMENT ON TABLE client_channel_consent IS
|
|
151
|
+
'Permissão de contato por canal. Ausência de linha = indefinido; a política do tenant decide.';
|
|
152
|
+
|
|
153
|
+
-- ── Idempotência com contexto ───────────────────────────────────────────────
|
|
154
|
+
--
|
|
155
|
+
-- A chave de `(receivable, step_key)` protege o AGENDAMENTO: o índice único de
|
|
156
|
+
-- `dunning_event` já impede duas ações para a mesma etapa do mesmo recebível.
|
|
157
|
+
-- O que ela não protege é o ENVIO feito pelo motor compartilhado, cuja chave
|
|
158
|
+
-- carrega tenant, produto, marca, canal, evento e versão de template — porque
|
|
159
|
+
-- lá o mesmo aviso pode sair legitimamente por dois canais, e um template
|
|
160
|
+
-- corrigido é um envio novo.
|
|
161
|
+
--
|
|
162
|
+
-- Sem esta coluna, "já enviei isto?" só teria como ser respondido por
|
|
163
|
+
-- aproximação, e aproximação numa régua de cobrança erra para os dois lados:
|
|
164
|
+
-- cala um aviso devido, ou repete um que já saiu.
|
|
165
|
+
ALTER TABLE dunning_event ADD COLUMN IF NOT EXISTS idempotency_key text;
|
|
166
|
+
|
|
167
|
+
-- Único por tenant. Parcial porque as ações do caminho legado (e todas as
|
|
168
|
+
-- criadas antes desta migração) não têm chave — e NULL não deve colidir com
|
|
169
|
+
-- NULL.
|
|
170
|
+
CREATE UNIQUE INDEX IF NOT EXISTS dunning_event_idempotency_key_uq
|
|
171
|
+
ON dunning_event (tenant_id, idempotency_key)
|
|
172
|
+
WHERE idempotency_key IS NOT NULL;
|
|
173
|
+
|
|
174
|
+
COMMENT ON COLUMN dunning_event.idempotency_key IS
|
|
175
|
+
'Chave do motor compartilhado (sha256 de tenant/produto/marca/canal/evento/assunto/versão). NULL no caminho legado.';
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
-- 0039 — Reserva atômica de envio e trilha do motor de comunicação
|
|
2
|
+
--
|
|
3
|
+
-- CORREÇÃO DE DEFEITO ESTRUTURAL. A 0038 entregou a chave de idempotência
|
|
4
|
+
-- (`dunning_event.idempotency_key`) e o motor a consultava assim:
|
|
5
|
+
--
|
|
6
|
+
-- alreadySent(key) → adapter.send() → markSent(key)
|
|
7
|
+
--
|
|
8
|
+
-- Três passos. Entre o primeiro e o terceiro há uma janela em que dois workers
|
|
9
|
+
-- concorrentes — cron e envio manual, duas instâncias durante um redeploy, um
|
|
10
|
+
-- retry sobreposto ao original — recebem os DOIS a resposta "ainda não enviei",
|
|
11
|
+
-- e os dois chamam o provider. O cliente recebe a mesma cobrança duas vezes, e
|
|
12
|
+
-- a coluna de idempotência registra fielmente que houve um envio.
|
|
13
|
+
--
|
|
14
|
+
-- O índice único da 0038 não protege isso: ele impede duas LINHAS com a mesma
|
|
15
|
+
-- chave, e o envio duplo acontece antes de qualquer linha ser escrita. Um índice
|
|
16
|
+
-- é uma restrição sobre o registro; o que faltava é uma restrição sobre o
|
|
17
|
+
-- DIREITO DE AGIR.
|
|
18
|
+
--
|
|
19
|
+
-- Estas duas tabelas são isso. Nenhuma regra financeira muda; `dunning_event`
|
|
20
|
+
-- continua sendo o estado da etapa da régua.
|
|
21
|
+
|
|
22
|
+
-- ── Reserva de envio ────────────────────────────────────────────────────────
|
|
23
|
+
--
|
|
24
|
+
-- Uma linha por chave de idempotência. A linha É a reserva: quem consegue
|
|
25
|
+
-- gravá-la (ou retomá-la de um titular vencido) tem o direito de chamar o
|
|
26
|
+
-- provider, e mais ninguém.
|
|
27
|
+
--
|
|
28
|
+
-- Tabela do MOTOR, não da cobrança. Um segundo consumidor (Dental, Manga Verde)
|
|
29
|
+
-- reserva aqui sem nenhuma coluna nova — `product` e `brand` já estão na chave,
|
|
30
|
+
-- e é por isso que ela não mora dentro de `dunning_event`: amarrar a reserva à
|
|
31
|
+
-- tabela de uma régua de honorários obrigaria o próximo produto a ter uma régua
|
|
32
|
+
-- de honorários.
|
|
33
|
+
CREATE TABLE IF NOT EXISTS communication_dispatch (
|
|
34
|
+
id uuid PRIMARY KEY,
|
|
35
|
+
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
|
36
|
+
product text NOT NULL,
|
|
37
|
+
brand text NOT NULL,
|
|
38
|
+
channel text NOT NULL CHECK (channel IN ('email', 'whatsapp', 'sms', 'notification')),
|
|
39
|
+
event_type text NOT NULL,
|
|
40
|
+
-- Referência do assunto no domínio do consumidor (recebível, fatura, pedido).
|
|
41
|
+
-- Nunca PII.
|
|
42
|
+
subject_ref text NOT NULL,
|
|
43
|
+
-- sha256 composto pelo motor a partir de tenant/produto/marca/canal/evento/
|
|
44
|
+
-- assunto/versão de template. Ver `communication/idempotency.ts`.
|
|
45
|
+
idempotency_key text NOT NULL,
|
|
46
|
+
|
|
47
|
+
-- in_flight alguém tem a reserva AGORA e pode estar chamando o provider
|
|
48
|
+
-- sent o provider aceitou. Terminal para esta chave.
|
|
49
|
+
-- failed_retryable falhou de um jeito que vale tentar de novo; a chave volta a ser reservável
|
|
50
|
+
-- failed_permanent falhou de um jeito que não vale; só ação humana muda isto
|
|
51
|
+
--
|
|
52
|
+
-- `sent` NÃO é "entregue": quem afirma entrega é o webhook, e o estado de
|
|
53
|
+
-- entrega mora em `communication_event`/`dunning_event`. Colapsar os dois
|
|
54
|
+
-- faria a reserva virar uma segunda fonte de verdade sobre entrega, que
|
|
55
|
+
-- divergiria da primeira no primeiro callback fora de ordem.
|
|
56
|
+
status text NOT NULL DEFAULT 'in_flight'
|
|
57
|
+
CHECK (status IN ('in_flight', 'sent', 'failed_retryable', 'failed_permanent')),
|
|
58
|
+
|
|
59
|
+
-- Identidade do TITULAR atual da reserva. Sem isto, um processo que ressuscita
|
|
60
|
+
-- depois do prazo vencido assentaria o desfecho por cima de quem está
|
|
61
|
+
-- enviando agora — e marcaria como enviada uma mensagem que o titular novo
|
|
62
|
+
-- ainda não mandou.
|
|
63
|
+
claim_id uuid,
|
|
64
|
+
claimed_at timestamptz,
|
|
65
|
+
-- Prazo. Existe porque processo morre: sem ele, um worker que cai segurando a
|
|
66
|
+
-- reserva calaria a etapa para sempre, e o silêncio de uma régua de cobrança
|
|
67
|
+
-- é indistinguível de "o cliente não devia nada".
|
|
68
|
+
claim_expires_at timestamptz,
|
|
69
|
+
-- A reserva atual foi TOMADA de um titular vencido. Significa risco real de
|
|
70
|
+
-- duplicata (o anterior pode ter enviado e morrido antes de assentar), e é o
|
|
71
|
+
-- que permite a um humano explicar "por que chegou duas vezes".
|
|
72
|
+
recovered_from_expired boolean NOT NULL DEFAULT false,
|
|
73
|
+
|
|
74
|
+
attempts integer NOT NULL DEFAULT 0,
|
|
75
|
+
provider_ref text,
|
|
76
|
+
-- Rótulo curto e estável para métrica. snake_case. Nunca PII, nunca segredo.
|
|
77
|
+
last_code text,
|
|
78
|
+
last_detail text,
|
|
79
|
+
sent_at timestamptz,
|
|
80
|
+
settled_at timestamptz,
|
|
81
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
82
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
83
|
+
|
|
84
|
+
CONSTRAINT communication_dispatch_tenant_id_uq UNIQUE (tenant_id, id)
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
-- A restrição que faz a reserva existir. Sem ela, `ON CONFLICT` não tem alvo e
|
|
88
|
+
-- todo `claim` viraria um INSERT novo — ou seja, todo mundo ganharia a reserva.
|
|
89
|
+
CREATE UNIQUE INDEX IF NOT EXISTS communication_dispatch_key_uq
|
|
90
|
+
ON communication_dispatch (tenant_id, idempotency_key);
|
|
91
|
+
|
|
92
|
+
-- Via de acesso do webhook de entrega: ele chega com o id do provider e nada mais.
|
|
93
|
+
CREATE INDEX IF NOT EXISTS communication_dispatch_provider_ref_idx
|
|
94
|
+
ON communication_dispatch (tenant_id, provider_ref)
|
|
95
|
+
WHERE provider_ref IS NOT NULL;
|
|
96
|
+
|
|
97
|
+
-- Reservas penduradas, para diagnóstico operacional.
|
|
98
|
+
CREATE INDEX IF NOT EXISTS communication_dispatch_in_flight_idx
|
|
99
|
+
ON communication_dispatch (tenant_id, claim_expires_at)
|
|
100
|
+
WHERE status = 'in_flight';
|
|
101
|
+
|
|
102
|
+
CREATE INDEX IF NOT EXISTS communication_dispatch_subject_idx
|
|
103
|
+
ON communication_dispatch (tenant_id, subject_ref, event_type);
|
|
104
|
+
|
|
105
|
+
-- FORCE porque a política precisa valer inclusive para o dono da tabela — é o
|
|
106
|
+
-- papel que roda migration, e é onde a armadilha da 0035/0036 morava.
|
|
107
|
+
ALTER TABLE communication_dispatch ENABLE ROW LEVEL SECURITY;
|
|
108
|
+
ALTER TABLE communication_dispatch FORCE ROW LEVEL SECURITY;
|
|
109
|
+
|
|
110
|
+
CREATE POLICY communication_dispatch_tenant_isolation ON communication_dispatch
|
|
111
|
+
USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
|
|
112
|
+
WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
|
|
113
|
+
|
|
114
|
+
-- ── Trilha do motor ─────────────────────────────────────────────────────────
|
|
115
|
+
--
|
|
116
|
+
-- Registro estruturado do que o motor decidiu. NÃO é log: log é texto que
|
|
117
|
+
-- alguém talvez leia, isto responde "por que este cliente não recebeu?" seis
|
|
118
|
+
-- meses depois, com filtro por motivo.
|
|
119
|
+
--
|
|
120
|
+
-- Separada de `audit_log` de propósito. `audit_log` registra ATOS DE USUÁRIO —
|
|
121
|
+
-- tem ator, IP, user-agent, e é lida por auditoria de acesso. A maioria dos
|
|
122
|
+
-- eventos daqui não tem ator humano nenhum (cron, webhook), tem volume de outra
|
|
123
|
+
-- ordem de grandeza, e é consultada por chave de idempotência e referência do
|
|
124
|
+
-- provider. Misturá-las tornaria a auditoria de acesso ilegível e esta consulta
|
|
125
|
+
-- lenta.
|
|
126
|
+
--
|
|
127
|
+
-- Também separada de `dunning_event`: lá mora o estado da ETAPA da régua, um por
|
|
128
|
+
-- (recebível, passo). Aqui mora o histórico da INTENÇÃO — várias por etapa,
|
|
129
|
+
-- porque uma etapa pode ter um canal recusado por consentimento, outro por
|
|
130
|
+
-- telefone inválido, e um terceiro entregue.
|
|
131
|
+
CREATE TABLE IF NOT EXISTS communication_event (
|
|
132
|
+
id uuid PRIMARY KEY,
|
|
133
|
+
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
|
134
|
+
product text NOT NULL,
|
|
135
|
+
-- NULLABLE, e a exceção é real: um callback que chega com um identificador de
|
|
136
|
+
-- provider que não corresponde a nenhuma mensagem nossa não pertence a marca
|
|
137
|
+
-- nenhuma. Forçar um valor ali inventaria uma marca — e a trilha passaria a
|
|
138
|
+
-- afirmar que o escritório X mandou algo que ele não mandou.
|
|
139
|
+
brand text,
|
|
140
|
+
-- Vocabulário FECHADO. Um `text` livre viraria dez grafias do mesmo evento e
|
|
141
|
+
-- nenhuma métrica agregável.
|
|
142
|
+
kind text NOT NULL CHECK (kind IN (
|
|
143
|
+
'intent_created', 'dispatch_claimed', 'dispatch_skipped',
|
|
144
|
+
'dispatch_sent', 'dispatch_failed', 'consent_blocked',
|
|
145
|
+
'invalid_contact', 'callback_delivered', 'callback_read',
|
|
146
|
+
'callback_failed', 'opt_out')),
|
|
147
|
+
channel text CHECK (channel IS NULL OR channel IN ('email', 'whatsapp', 'sms', 'notification')),
|
|
148
|
+
event_type text NOT NULL,
|
|
149
|
+
subject_ref text,
|
|
150
|
+
-- Referência LÓGICA do destinatário (id do cliente). NUNCA telefone, NUNCA
|
|
151
|
+
-- e-mail: a trilha é consultada por quem opera, e uma trilha que carrega o
|
|
152
|
+
-- contato transforma toda consulta operacional numa exportação de PII.
|
|
153
|
+
recipient_ref text,
|
|
154
|
+
idempotency_key text,
|
|
155
|
+
provider_ref text,
|
|
156
|
+
skip_reason text,
|
|
157
|
+
status text,
|
|
158
|
+
code text,
|
|
159
|
+
-- Truncado na escrita. Nunca corpo de mensagem, nunca credencial.
|
|
160
|
+
detail text,
|
|
161
|
+
attempt integer,
|
|
162
|
+
occurred_at timestamptz NOT NULL DEFAULT now(),
|
|
163
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
164
|
+
|
|
165
|
+
CONSTRAINT communication_event_tenant_id_uq UNIQUE (tenant_id, id)
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
CREATE INDEX IF NOT EXISTS communication_event_key_idx
|
|
169
|
+
ON communication_event (tenant_id, idempotency_key, occurred_at DESC)
|
|
170
|
+
WHERE idempotency_key IS NOT NULL;
|
|
171
|
+
|
|
172
|
+
CREATE INDEX IF NOT EXISTS communication_event_subject_idx
|
|
173
|
+
ON communication_event (tenant_id, subject_ref, occurred_at DESC);
|
|
174
|
+
|
|
175
|
+
CREATE INDEX IF NOT EXISTS communication_event_recipient_idx
|
|
176
|
+
ON communication_event (tenant_id, recipient_ref, occurred_at DESC);
|
|
177
|
+
|
|
178
|
+
CREATE INDEX IF NOT EXISTS communication_event_kind_idx
|
|
179
|
+
ON communication_event (tenant_id, kind, occurred_at DESC);
|
|
180
|
+
|
|
181
|
+
ALTER TABLE communication_event ENABLE ROW LEVEL SECURITY;
|
|
182
|
+
ALTER TABLE communication_event FORCE ROW LEVEL SECURITY;
|
|
183
|
+
|
|
184
|
+
CREATE POLICY communication_event_tenant_isolation ON communication_event
|
|
185
|
+
USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
|
|
186
|
+
WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
|
|
187
|
+
|
|
188
|
+
COMMENT ON TABLE communication_dispatch IS
|
|
189
|
+
'Reserva atômica do direito de enviar, por chave de idempotência. A linha É a reserva.';
|
|
190
|
+
COMMENT ON TABLE communication_event IS
|
|
191
|
+
'Trilha estruturada do motor de comunicação. Sem PII de contato, sem credencial, sem corpo de mensagem.';
|
|
192
|
+
COMMENT ON COLUMN communication_dispatch.recovered_from_expired IS
|
|
193
|
+
'A reserva foi tomada de um titular vencido — há risco real de o anterior ter enviado antes de morrer.';
|