@baruk/core 0.3.0 → 0.4.2
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 +97 -0
- package/README.md +9 -2
- 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 +39 -2
- package/dist/auth/service.d.ts.map +1 -1
- package/dist/auth/service.js +75 -10
- package/dist/auth/service.js.map +1 -1
- package/dist/billing/ar-repository.d.ts +334 -0
- package/dist/billing/ar-repository.d.ts.map +1 -0
- package/dist/billing/ar-repository.js +707 -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 +89 -0
- package/dist/billing/provider-account.d.ts.map +1 -0
- package/dist/billing/provider-account.js +161 -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 +90 -1
- package/dist/billing/repository.d.ts.map +1 -1
- package/dist/billing/repository.js +148 -19
- package/dist/billing/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 +75 -9
- package/dist/cjs/auth/service.js.map +1 -1
- package/dist/cjs/billing/ar-repository.js +728 -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 +170 -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 +150 -18
- package/dist/cjs/billing/repository.js.map +1 -1
- package/dist/cjs/clients/repository.js +96 -20
- package/dist/cjs/clients/repository.js.map +1 -1
- package/dist/cjs/collection/branding.js +140 -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/communication-bridge.js +140 -0
- package/dist/cjs/collection/communication-bridge.js.map +1 -0
- package/dist/cjs/collection/communication-runtime.js +193 -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 +414 -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 +147 -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/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 +161 -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 +483 -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/repository.js +309 -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/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/index.js +427 -48
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/legal/company.js +36 -0
- package/dist/cjs/legal/company.js.map +1 -0
- package/dist/cjs/legal/documents.js +671 -0
- package/dist/cjs/legal/documents.js.map +1 -0
- package/dist/cjs/legal/index.js +15 -0
- package/dist/cjs/legal/index.js.map +1 -0
- package/dist/cjs/legal/types.js +34 -0
- package/dist/cjs/legal/types.js.map +1 -0
- 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/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 +67 -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/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 +57 -8
- package/dist/cjs/subscription-billing/service.js.map +1 -1
- package/dist/cjs/subscription-billing/types.js.map +1 -1
- package/dist/cjs/tenancy/provisioning.js +32 -8
- package/dist/cjs/tenancy/provisioning.js.map +1 -1
- package/dist/cjs/users/repository.js +119 -2
- 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/repository.d.ts +42 -0
- package/dist/clients/repository.d.ts.map +1 -1
- package/dist/clients/repository.js +94 -21
- package/dist/clients/repository.js.map +1 -1
- package/dist/collection/branding.d.ts +72 -0
- package/dist/collection/branding.d.ts.map +1 -0
- package/dist/collection/branding.js +136 -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/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 +95 -0
- package/dist/collection/communication-runtime.d.ts.map +1 -0
- package/dist/collection/communication-runtime.js +187 -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 +177 -0
- package/dist/collection/engine.d.ts.map +1 -0
- package/dist/collection/engine.js +407 -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 +53 -0
- package/dist/collection/policy.d.ts.map +1 -0
- package/dist/collection/policy.js +141 -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/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 +158 -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 +153 -0
- package/dist/communication/engine.d.ts.map +1 -0
- package/dist/communication/engine.js +480 -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 +99 -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/repository.d.ts +147 -0
- package/dist/competence/repository.d.ts.map +1 -0
- package/dist/competence/repository.js +294 -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/db/migrate.js +17 -11
- package/dist/db/migrate.js.map +1 -1
- 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/index.d.ts +113 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +104 -8
- package/dist/index.js.map +1 -1
- package/dist/legal/company.d.ts +32 -0
- package/dist/legal/company.d.ts.map +1 -0
- package/dist/legal/company.js +33 -0
- package/dist/legal/company.js.map +1 -0
- package/dist/legal/documents.d.ts +30 -0
- package/dist/legal/documents.d.ts.map +1 -0
- package/dist/legal/documents.js +666 -0
- package/dist/legal/documents.js.map +1 -0
- package/dist/legal/index.d.ts +5 -0
- package/dist/legal/index.d.ts.map +1 -0
- package/dist/legal/index.js +4 -0
- package/dist/legal/index.js.map +1 -0
- package/dist/legal/types.d.ts +145 -0
- package/dist/legal/types.d.ts.map +1 -0
- package/dist/legal/types.js +31 -0
- package/dist/legal/types.js.map +1 -0
- 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/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 +67 -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/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 +17 -1
- package/dist/subscription-billing/service.d.ts.map +1 -1
- package/dist/subscription-billing/service.js +57 -8
- 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/provisioning.d.ts.map +1 -1
- package/dist/tenancy/provisioning.js +32 -8
- package/dist/tenancy/provisioning.js.map +1 -1
- package/dist/users/repository.d.ts +38 -0
- package/dist/users/repository.d.ts.map +1 -1
- package/dist/users/repository.js +118 -3
- 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 +19 -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/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 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-callback.d.ts","sourceRoot":"","sources":["../../src/collection/delivery-callback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,2BAA2B,CAAC;AAInC,MAAM,MAAM,eAAe;AACzB,iCAAiC;AAC/B,SAAS;AACX,oFAAoF;GAClF,yBAAyB;AAC3B,4EAA4E;GAC1E,aAAa;AACf,wEAAwE;GACtE,iBAAiB,CAAC;AAEtB,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,eAAe,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;CAC/B;AAKD;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,EAAE,EACN,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,cAAc,CAAC,CAmEzB;AA0CD,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,mBAAmB,CAAC;AAE/D;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,EAAE,EACN,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,CAsCxB"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aplicação dos callbacks de entrega ao estado do produto.
|
|
3
|
+
*
|
|
4
|
+
* `communication/webhook.ts` traduz o vocabulário do provider e decide se o
|
|
5
|
+
* evento avança o estado; este arquivo é o que ESCREVE. A separação é a mesma de
|
|
6
|
+
* sempre: o motor não conhece `dunning_event`, e a régua não conhece a Meta.
|
|
7
|
+
*
|
|
8
|
+
* Três escritas, e a ordem entre elas importa menos que o fato de estarem na
|
|
9
|
+
* MESMA transação: um callback que atualiza a etapa e falha ao gravar a trilha
|
|
10
|
+
* deixaria a tela dizendo "entregue" sem nada que explique quando nem por qual
|
|
11
|
+
* caminho.
|
|
12
|
+
*/
|
|
13
|
+
import { randomUUID } from 'node:crypto';
|
|
14
|
+
import { applyDeliveryEvent, } from '../communication/index.js';
|
|
15
|
+
import { recordConsent } from './consent-repository.js';
|
|
16
|
+
import { SC_PRODUCT } from './communication-bridge.js';
|
|
17
|
+
/** Estados de `dunning_event` que descrevem uma mensagem já entregue ao provider. */
|
|
18
|
+
const DELIVERABLE = ['sent', 'delivered', 'read', 'failed'];
|
|
19
|
+
/**
|
|
20
|
+
* Aplica um callback de entrega.
|
|
21
|
+
*
|
|
22
|
+
* A via de acesso é o `provider_ref` — é a ÚNICA coisa que o webhook traz. Sem
|
|
23
|
+
* a coluna indexada da 0038 isso exigiria varrer a tabela, e a régua de um
|
|
24
|
+
* escritório grande tornaria cada callback caro o bastante para o provider
|
|
25
|
+
* desistir de reentregar.
|
|
26
|
+
*/
|
|
27
|
+
export async function applyDeliveryCallback(tx, tenantId, event) {
|
|
28
|
+
const rows = await tx `
|
|
29
|
+
SELECT id, receivable_id, status, idempotency_key
|
|
30
|
+
FROM dunning_event
|
|
31
|
+
WHERE provider_ref = ${event.providerRef}
|
|
32
|
+
LIMIT 1
|
|
33
|
+
`;
|
|
34
|
+
const action = rows[0];
|
|
35
|
+
// Sem ação correspondente não há o que atualizar. NÃO é erro: o mesmo número
|
|
36
|
+
// pode ter mandado mensagem por outro sistema, e um 4xx aqui faria o provider
|
|
37
|
+
// reentregar para sempre um evento que nunca vai ser reconhecido.
|
|
38
|
+
if (!action) {
|
|
39
|
+
await recordCallbackEvent(tx, tenantId, event, null, null, 'unknown_message');
|
|
40
|
+
return { outcome: 'unknown_message', receivableId: null, status: null };
|
|
41
|
+
}
|
|
42
|
+
// `advanceStatus` opera sobre estados de ENTREGA. Uma ação `scheduled`,
|
|
43
|
+
// `canceled` ou `escalated` não descreve mensagem entregue, e forçá-la para
|
|
44
|
+
// `delivered` inventaria uma entrega que a régua não fez.
|
|
45
|
+
const current = (DELIVERABLE.includes(action.status) ? action.status : 'sent');
|
|
46
|
+
const decision = applyDeliveryEvent(current, event);
|
|
47
|
+
if (!decision.apply) {
|
|
48
|
+
await recordCallbackEvent(tx, tenantId, event, action.receivable_id, action.idempotency_key, decision.reason);
|
|
49
|
+
return { outcome: decision.reason, receivableId: action.receivable_id, status: null };
|
|
50
|
+
}
|
|
51
|
+
await tx `
|
|
52
|
+
UPDATE dunning_event
|
|
53
|
+
SET status = ${decision.status},
|
|
54
|
+
delivered_at = CASE
|
|
55
|
+
WHEN ${decision.status} IN ('delivered', 'read') THEN COALESCE(delivered_at, ${event.occurredAt}::timestamptz)
|
|
56
|
+
ELSE delivered_at END,
|
|
57
|
+
read_at = CASE
|
|
58
|
+
WHEN ${decision.status} = 'read' THEN COALESCE(read_at, ${event.occurredAt}::timestamptz)
|
|
59
|
+
ELSE read_at END,
|
|
60
|
+
last_error = CASE
|
|
61
|
+
WHEN ${decision.status} = 'failed' THEN ${(event.detail ?? event.code ?? 'falha reportada pelo provider').slice(0, 300)}
|
|
62
|
+
ELSE last_error END
|
|
63
|
+
WHERE id = ${action.id}
|
|
64
|
+
`;
|
|
65
|
+
await recordCallbackEvent(tx, tenantId, event, action.receivable_id, action.idempotency_key, null, decision.status);
|
|
66
|
+
return {
|
|
67
|
+
outcome: 'applied',
|
|
68
|
+
receivableId: action.receivable_id,
|
|
69
|
+
status: decision.status,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const CALLBACK_KIND = {
|
|
73
|
+
delivered: 'callback_delivered',
|
|
74
|
+
read: 'callback_read',
|
|
75
|
+
failed: 'callback_failed',
|
|
76
|
+
opted_out: 'opt_out',
|
|
77
|
+
};
|
|
78
|
+
async function recordCallbackEvent(tx, tenantId, event, subjectRef, idempotencyKey, refusal, applied) {
|
|
79
|
+
// Evento recusado também vira linha. É a diferença entre "o provider nunca
|
|
80
|
+
// avisou" e "avisou e nós descartamos" — e só a segunda tem explicação.
|
|
81
|
+
const kind = refusal ? 'dispatch_skipped' : (CALLBACK_KIND[event.status] ?? 'dispatch_skipped');
|
|
82
|
+
await tx `
|
|
83
|
+
INSERT INTO communication_event (
|
|
84
|
+
id, tenant_id, product, brand, kind, channel, event_type, subject_ref,
|
|
85
|
+
recipient_ref, idempotency_key, provider_ref, skip_reason, status, code,
|
|
86
|
+
detail, occurred_at
|
|
87
|
+
) VALUES (
|
|
88
|
+
${randomUUID()}, ${tenantId}, ${SC_PRODUCT},
|
|
89
|
+
-- A marca vem da RESERVA que produziu a mensagem. Quando não há reserva
|
|
90
|
+
-- correspondente, o evento fica sem marca — é o caso do callback sobre um
|
|
91
|
+
-- identificador que não é nosso, e inventar um valor aqui faria a trilha
|
|
92
|
+
-- atribuir a um escritório algo que ele não enviou.
|
|
93
|
+
(SELECT brand FROM communication_dispatch
|
|
94
|
+
WHERE provider_ref = ${event.providerRef} LIMIT 1),
|
|
95
|
+
${kind}, ${event.channel}, 'billing.dunning.callback', ${subjectRef},
|
|
96
|
+
NULL, ${idempotencyKey}, ${event.providerRef}, ${refusal},
|
|
97
|
+
${applied ?? event.status}, ${event.code ?? null},
|
|
98
|
+
${event.detail ? event.detail.slice(0, 300) : null}, ${event.occurredAt}::timestamptz
|
|
99
|
+
)
|
|
100
|
+
`;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Registra o opt-out que o cliente pediu respondendo no canal.
|
|
104
|
+
*
|
|
105
|
+
* `customer_reply` é a origem mais forte que existe: `recordConsent` impede que
|
|
106
|
+
* um operador a reverta pela tela. Por isso a resolução do telefone para cliente
|
|
107
|
+
* é feita pelo `phone_e164` canônico e nunca pelo campo digitado — casar por
|
|
108
|
+
* texto livre acertaria o cliente errado quando dois cadastros diferem só na
|
|
109
|
+
* pontuação, e bloquearia o canal de quem não pediu nada.
|
|
110
|
+
*/
|
|
111
|
+
export async function applyInboundOptOut(tx, tenantId, optOut) {
|
|
112
|
+
const e164 = optOut.from.startsWith('+') ? optOut.from : `+${optOut.from}`;
|
|
113
|
+
const rows = await tx `
|
|
114
|
+
SELECT id FROM client
|
|
115
|
+
WHERE phone_e164 = ${e164} AND deleted_at IS NULL
|
|
116
|
+
ORDER BY created_at
|
|
117
|
+
LIMIT 2
|
|
118
|
+
`;
|
|
119
|
+
// Dois clientes com o mesmo telefone é cadastro legítimo (marido e mulher,
|
|
120
|
+
// matriz e filial). Bloquear "o primeiro" seria escolher por sorte quem
|
|
121
|
+
// deixa de ser cobrado. Sem resolução única, nada é registrado — e o evento
|
|
122
|
+
// fica na trilha para um humano decidir.
|
|
123
|
+
if (rows.length !== 1)
|
|
124
|
+
return 'unknown_recipient';
|
|
125
|
+
await recordConsent(tx, {
|
|
126
|
+
tenantId,
|
|
127
|
+
clientId: rows[0].id,
|
|
128
|
+
channel: optOut.channel,
|
|
129
|
+
state: 'denied',
|
|
130
|
+
source: 'customer_reply',
|
|
131
|
+
note: 'opt-out recebido no canal',
|
|
132
|
+
});
|
|
133
|
+
await tx `
|
|
134
|
+
INSERT INTO communication_event (
|
|
135
|
+
id, tenant_id, product, brand, kind, channel, event_type, recipient_ref,
|
|
136
|
+
code, occurred_at
|
|
137
|
+
) VALUES (
|
|
138
|
+
-- Opt-out é do CLIENTE, e vale para todas as marcas do escritório: o
|
|
139
|
+
-- pedido de silêncio não é por linha de produto. Sem marca, portanto.
|
|
140
|
+
${randomUUID()}, ${tenantId}, ${SC_PRODUCT}, NULL, 'opt_out',
|
|
141
|
+
${optOut.channel}, 'communication.opt_out', ${rows[0].id},
|
|
142
|
+
'customer_reply', ${optOut.occurredAt}::timestamptz
|
|
143
|
+
)
|
|
144
|
+
`;
|
|
145
|
+
return 'registered';
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=delivery-callback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-callback.js","sourceRoot":"","sources":["../../src/collection/delivery-callback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { TenantBranding } from './branding.js';
|
|
2
|
+
import type { PaymentBlock } from './payment-block.js';
|
|
3
|
+
/**
|
|
4
|
+
* Shell transacional do e-mail de cobrança.
|
|
5
|
+
*
|
|
6
|
+
* Escrito com tabelas e estilo inline de propósito: Gmail remove `<style>` em
|
|
7
|
+
* boa parte dos contextos e o Outlook desktop renderiza com o motor do Word, que
|
|
8
|
+
* ignora flexbox, grid e boa parte de CSS moderno. O layout que "fica bonito no
|
|
9
|
+
* navegador" é justamente o que quebra na caixa de entrada.
|
|
10
|
+
*
|
|
11
|
+
* A única imagem é a logomarca, e o cabeçalho é construído para sobreviver ao
|
|
12
|
+
* bloqueio de imagens — padrão em muitos leitores. Nenhuma informação mora só
|
|
13
|
+
* dentro do arquivo: com as imagens desligadas, o nome do escritório continua
|
|
14
|
+
* escrito no cabeçalho.
|
|
15
|
+
*
|
|
16
|
+
* Cores e tipografia vêm do tenant (`TenantBranding`), não de constantes daqui.
|
|
17
|
+
* Nenhum escritório está no código.
|
|
18
|
+
*/
|
|
19
|
+
export interface EmailBlock {
|
|
20
|
+
greeting: string;
|
|
21
|
+
/** Parágrafos do corpo, na ordem. */
|
|
22
|
+
paragraphs: string[];
|
|
23
|
+
/** Destaque do valor/vencimento. Omitido quando não há dívida a exibir. */
|
|
24
|
+
highlight?: {
|
|
25
|
+
label: string;
|
|
26
|
+
amount: string;
|
|
27
|
+
dueLabel: string;
|
|
28
|
+
dueValue: string;
|
|
29
|
+
};
|
|
30
|
+
closing?: string;
|
|
31
|
+
/** Como pagar. Ausente quando o recebível ainda não tem cobrança emitida. */
|
|
32
|
+
payment?: PaymentBlock;
|
|
33
|
+
}
|
|
34
|
+
export declare function escapeHtml(s: string): string;
|
|
35
|
+
export declare function renderCollectionEmail(b: TenantBranding, block: EmailBlock): string;
|
|
36
|
+
/**
|
|
37
|
+
* Versão texto puro.
|
|
38
|
+
*
|
|
39
|
+
* Não é decoração: parte dos leitores prefere `text/plain`, filtros de spam
|
|
40
|
+
* penalizam mensagem só-HTML, e leitores de tela lidam melhor com o texto. O
|
|
41
|
+
* conteúdo tem de ser o MESMO — um plain text resumido faria dois clientes
|
|
42
|
+
* receberem informações diferentes.
|
|
43
|
+
*/
|
|
44
|
+
export declare function renderCollectionText(b: TenantBranding, block: EmailBlock): string;
|
|
45
|
+
//# sourceMappingURL=email-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-layout.d.ts","sourceRoot":"","sources":["../../src/collection/email-layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,2EAA2E;IAC3E,SAAS,CAAC,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAgCD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAO5C;AAsID,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CAqElF;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CAmCjF"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A cor é revalidada AQUI, e não só em `getTenantBranding`.
|
|
3
|
+
*
|
|
4
|
+
* Ela é interpolada dentro de um atributo `style`; confiar que o chamador já
|
|
5
|
+
* sanitizou é o tipo de suposição que se perde na primeira refatoração — basta
|
|
6
|
+
* alguém montar o branding à mão para injetar CSS (ou fechar o atributo e
|
|
7
|
+
* injetar markup) na mensagem que sai em nome do escritório.
|
|
8
|
+
*/
|
|
9
|
+
function safeColorForRender(v) {
|
|
10
|
+
return /^#[0-9a-fA-F]{6}$/.test(v) ? v : '#1f3a5f';
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* URL só entra no `href`/`src` se for https.
|
|
14
|
+
*
|
|
15
|
+
* O escape de HTML já impediria a fuga do atributo, mas ele não impede um
|
|
16
|
+
* `javascript:` de continuar sendo `javascript:`. E esta URL vem do metadata da
|
|
17
|
+
* cobrança, que passou por um gateway externo — validar aqui é o mesmo
|
|
18
|
+
* princípio já aplicado à cor: não confiar em quem chama.
|
|
19
|
+
*/
|
|
20
|
+
function safeUrlForRender(v) {
|
|
21
|
+
if (!v)
|
|
22
|
+
return null;
|
|
23
|
+
return /^https:\/\/[^\s"'<>]+$/i.test(v) ? v : null;
|
|
24
|
+
}
|
|
25
|
+
/** Mesma razão da cor: a stack de fontes também é interpolada num `style`. */
|
|
26
|
+
function safeFontForRender(v) {
|
|
27
|
+
return /^[A-Za-z0-9 ,.'-]+$/.test(v) ? v : `-apple-system,'Segoe UI',Helvetica,Arial,sans-serif`;
|
|
28
|
+
}
|
|
29
|
+
export function escapeHtml(s) {
|
|
30
|
+
return s
|
|
31
|
+
.replace(/&/g, '&')
|
|
32
|
+
.replace(/</g, '<')
|
|
33
|
+
.replace(/>/g, '>')
|
|
34
|
+
.replace(/"/g, '"')
|
|
35
|
+
.replace(/'/g, ''');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Cabeçalho — a assinatura visual institucional da mensagem.
|
|
39
|
+
*
|
|
40
|
+
* Três formas, conforme o que o tenant tem:
|
|
41
|
+
*
|
|
42
|
+
* | `logoUrl` | `logoKind` | Cabeçalho |
|
|
43
|
+
* |---|---|---|
|
|
44
|
+
* | ausente | — | nome + tagline em tipografia |
|
|
45
|
+
* | presente | `symbol` | símbolo à esquerda, nome + tagline à direita |
|
|
46
|
+
* | presente | `lockup` | só a imagem (o nome já está desenhada nela) + tagline |
|
|
47
|
+
*
|
|
48
|
+
* O par símbolo+texto é montado com tabela, não com flex: o Outlook desktop
|
|
49
|
+
* renderiza com o motor do Word e empilharia as duas colunas.
|
|
50
|
+
*/
|
|
51
|
+
function header(b) {
|
|
52
|
+
const name = escapeHtml(b.officeName);
|
|
53
|
+
const font = safeFontForRender(b.fontFamily);
|
|
54
|
+
const tagline = b.tagline
|
|
55
|
+
? `<div style="margin-top:6px;font-family:${font};font-size:12px;line-height:1.4;color:#ffffff;opacity:.72">${escapeHtml(b.tagline)}</div>`
|
|
56
|
+
: '';
|
|
57
|
+
const wordmark = `<span style="font-family:${font};font-size:19px;font-weight:700;color:#ffffff;letter-spacing:-.01em">${name}</span>${tagline}`;
|
|
58
|
+
if (!b.logoUrl)
|
|
59
|
+
return wordmark;
|
|
60
|
+
const src = escapeHtml(b.logoUrl);
|
|
61
|
+
if (b.logoKind === 'lockup') {
|
|
62
|
+
// O lockup já traz o nome desenhado — repetir em texto duplicaria a marca.
|
|
63
|
+
// Por isso o `alt` carrega o nome aqui: com imagens bloqueadas, é a única
|
|
64
|
+
// coisa que sobra no cabeçalho.
|
|
65
|
+
return `<img src="${src}" alt="${name}" height="36"
|
|
66
|
+
style="display:block;border:0;outline:none;text-decoration:none;height:36px;width:auto;max-width:260px" />${tagline}`;
|
|
67
|
+
}
|
|
68
|
+
// Símbolo: 40px, tamanho mínimo do manual de marca com folga, e discreto o
|
|
69
|
+
// bastante para o nome continuar sendo a primeira leitura. `alt` vazio de
|
|
70
|
+
// propósito — o nome está ao lado, e um `alt` repetido faria o leitor de tela
|
|
71
|
+
// (e o cliente com imagens bloqueadas) anunciar o escritório duas vezes.
|
|
72
|
+
return `<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse">
|
|
73
|
+
<tr>
|
|
74
|
+
<td valign="middle" style="padding-right:14px">
|
|
75
|
+
<img src="${src}" alt="" width="40" height="40"
|
|
76
|
+
style="display:block;border:0;outline:none;text-decoration:none;width:40px;height:40px" />
|
|
77
|
+
</td>
|
|
78
|
+
<td valign="middle">${wordmark}</td>
|
|
79
|
+
</tr>
|
|
80
|
+
</table>`;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Bloco de pagamento.
|
|
84
|
+
*
|
|
85
|
+
* Hierarquia deliberada: **um** botão, e o resto discreto abaixo. Dar o mesmo
|
|
86
|
+
* peso visual a PIX, boleto e link transforma a decisão de pagar numa escolha
|
|
87
|
+
* de meio — e quem hesita, adia. O botão é um `<a>` com padding, não um
|
|
88
|
+
* `<button>`: cliente de e-mail não executa formulário, e o Outlook desenha o
|
|
89
|
+
* fundo da tabela mesmo quando ignora o `border-radius`.
|
|
90
|
+
*
|
|
91
|
+
* O copia-e-cola do PIX vai em texto selecionável, sem botão de copiar — não há
|
|
92
|
+
* JavaScript em e-mail, e um botão que não copia nada é uma promessa quebrada.
|
|
93
|
+
*/
|
|
94
|
+
function renderPayment(b, t) {
|
|
95
|
+
if (!b)
|
|
96
|
+
return '';
|
|
97
|
+
const target = safeUrlForRender(b.url) ?? safeUrlForRender(b.boletoUrl);
|
|
98
|
+
const cta = target
|
|
99
|
+
? `<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;margin:0 0 18px">
|
|
100
|
+
<tr><td align="center" bgcolor="${t.primary}" style="border-radius:6px">
|
|
101
|
+
<a href="${escapeHtml(target)}"
|
|
102
|
+
style="display:inline-block;padding:14px 34px;font-family:${t.font};font-size:15px;font-weight:700;color:#ffffff;text-decoration:none;border-radius:6px">Pagar agora</a>
|
|
103
|
+
</td></tr>
|
|
104
|
+
</table>`
|
|
105
|
+
: '';
|
|
106
|
+
const alternativas = [];
|
|
107
|
+
// O QR precisa ser uma URL **https**.
|
|
108
|
+
//
|
|
109
|
+
// Um `data:` URI parece funcionar no navegador e **não funciona no Gmail**:
|
|
110
|
+
// ele serve toda imagem pelo próprio proxy, que só busca http(s). O resultado
|
|
111
|
+
// é o pior possível — um ícone quebrado onde deveria estar o meio de
|
|
112
|
+
// pagamento, exatamente como apareceu no QA.
|
|
113
|
+
//
|
|
114
|
+
// Sem URL válida, nenhuma `<img>` é emitida: o copia-e-cola abaixo continua
|
|
115
|
+
// pagando a conta, e uma imagem quebrada só faria o e-mail parecer defeituoso.
|
|
116
|
+
const qr = safeUrlForRender(b.pixQrCodeImage);
|
|
117
|
+
if (qr) {
|
|
118
|
+
alternativas.push(`<tr><td align="center" style="padding:4px 0 10px">
|
|
119
|
+
<img src="${escapeHtml(qr)}" alt="QR Code do PIX" width="150" height="150"
|
|
120
|
+
style="display:block;border:0;width:150px;height:150px" />
|
|
121
|
+
</td></tr>`);
|
|
122
|
+
}
|
|
123
|
+
if (b.pixPayload) {
|
|
124
|
+
alternativas.push(`<tr><td style="padding:0 0 10px">
|
|
125
|
+
<div style="font-family:${t.font};font-size:12px;color:${t.muted};margin-bottom:4px">PIX copia e cola</div>
|
|
126
|
+
<div style="font-family:Consolas,'Courier New',monospace;font-size:11px;line-height:1.5;color:#2b3440;word-break:break-all;background:#ffffff;border:1px solid #e3e8ee;border-radius:4px;padding:10px">${escapeHtml(b.pixPayload)}</div>
|
|
127
|
+
</td></tr>`);
|
|
128
|
+
}
|
|
129
|
+
if (b.identificationField) {
|
|
130
|
+
alternativas.push(`<tr><td style="padding:0 0 10px">
|
|
131
|
+
<div style="font-family:${t.font};font-size:12px;color:${t.muted};margin-bottom:4px">Linha digitável do boleto</div>
|
|
132
|
+
<div style="font-family:Consolas,'Courier New',monospace;font-size:12px;line-height:1.5;color:#2b3440;word-break:break-all">${escapeHtml(b.identificationField)}</div>
|
|
133
|
+
</td></tr>`);
|
|
134
|
+
}
|
|
135
|
+
if (!cta && !alternativas.length)
|
|
136
|
+
return '';
|
|
137
|
+
const alt = alternativas.length
|
|
138
|
+
? `<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%"
|
|
139
|
+
style="border-collapse:collapse;margin:0 0 20px;background:#f6f8fa;border-radius:6px">
|
|
140
|
+
<tr><td style="padding:16px 18px">
|
|
141
|
+
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-collapse:collapse">
|
|
142
|
+
${alternativas.join('')}
|
|
143
|
+
</table>
|
|
144
|
+
</td></tr>
|
|
145
|
+
</table>`
|
|
146
|
+
: '';
|
|
147
|
+
return `${cta}${alt}`;
|
|
148
|
+
}
|
|
149
|
+
export function renderCollectionEmail(b, block) {
|
|
150
|
+
const name = escapeHtml(b.officeName);
|
|
151
|
+
const primary = safeColorForRender(b.primaryColor);
|
|
152
|
+
const accent = safeColorForRender(b.accentColor);
|
|
153
|
+
const bg = safeColorForRender(b.backgroundColor);
|
|
154
|
+
const text = safeColorForRender(b.textColor);
|
|
155
|
+
const muted = safeColorForRender(b.mutedColor);
|
|
156
|
+
const font = safeFontForRender(b.fontFamily);
|
|
157
|
+
const p = (t) => `<p style="margin:0 0 16px;font-family:${font};font-size:15px;line-height:1.65;color:${text}">${escapeHtml(t)}</p>`;
|
|
158
|
+
const highlight = block.highlight
|
|
159
|
+
? `<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%"
|
|
160
|
+
style="margin:0 0 24px;border-collapse:collapse;background:#f6f8fa;border-left:3px solid ${accent};border-radius:4px">
|
|
161
|
+
<tr>
|
|
162
|
+
<td style="padding:18px 20px">
|
|
163
|
+
<div style="font-family:${font};font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:${muted};margin-bottom:6px">${escapeHtml(block.highlight.label)}</div>
|
|
164
|
+
<div style="font-family:${font};font-size:26px;font-weight:700;color:#1a2029;line-height:1.2">${escapeHtml(block.highlight.amount)}</div>
|
|
165
|
+
<div style="font-family:${font};font-size:14px;color:#4a5563;margin-top:8px">${escapeHtml(block.highlight.dueLabel)} <strong style="color:#1a2029">${escapeHtml(block.highlight.dueValue)}</strong></div>
|
|
166
|
+
</td>
|
|
167
|
+
</tr>
|
|
168
|
+
</table>`
|
|
169
|
+
: '';
|
|
170
|
+
const payment = renderPayment(block.payment, { primary, accent, muted, font });
|
|
171
|
+
const support = [
|
|
172
|
+
b.supportEmail ? escapeHtml(b.supportEmail) : null,
|
|
173
|
+
b.supportPhone ? escapeHtml(b.supportPhone) : null,
|
|
174
|
+
b.website ? escapeHtml(b.website.replace(/^https:\/\//, '')) : null,
|
|
175
|
+
].filter(Boolean);
|
|
176
|
+
return `<!doctype html>
|
|
177
|
+
<html lang="pt-BR"><head><meta charset="utf-8" />
|
|
178
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
179
|
+
<meta name="color-scheme" content="light" />
|
|
180
|
+
<title>${name}</title></head>
|
|
181
|
+
<body style="margin:0;padding:0;background:${bg};-webkit-text-size-adjust:100%">
|
|
182
|
+
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="background:${bg};border-collapse:collapse">
|
|
183
|
+
<tr><td align="center" style="padding:32px 12px">
|
|
184
|
+
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="600"
|
|
185
|
+
style="width:600px;max-width:100%;border-collapse:collapse;background:#ffffff;border-radius:8px;overflow:hidden;box-shadow:0 1px 3px rgba(16,24,40,.08)">
|
|
186
|
+
|
|
187
|
+
<tr><td style="background:${primary};padding:24px 32px">${header(b)}</td></tr>
|
|
188
|
+
|
|
189
|
+
<tr><td style="padding:32px">
|
|
190
|
+
${p(block.greeting)}
|
|
191
|
+
${block.paragraphs.map(p).join('')}
|
|
192
|
+
${highlight}
|
|
193
|
+
${payment}
|
|
194
|
+
${block.closing ? p(block.closing) : ''}
|
|
195
|
+
<p style="margin:24px 0 0;font-family:${font};font-size:15px;line-height:1.6;color:${text}">
|
|
196
|
+
Atenciosamente,<br /><strong>${escapeHtml(b.signatureName)}</strong>
|
|
197
|
+
</p>
|
|
198
|
+
</td></tr>
|
|
199
|
+
|
|
200
|
+
<tr><td style="padding:20px 32px;background:#f6f8fa;border-top:1px solid #e3e8ee">
|
|
201
|
+
<p style="margin:0;font-family:${font};font-size:12px;line-height:1.6;color:${muted}">
|
|
202
|
+
Mensagem automática enviada por ${name}.${support.length ? ` Para falar conosco: ${support.join(' · ')}.` : ''}<br />
|
|
203
|
+
Se o pagamento já foi realizado, desconsidere este aviso.
|
|
204
|
+
</p>
|
|
205
|
+
</td></tr>
|
|
206
|
+
|
|
207
|
+
</table>
|
|
208
|
+
</td></tr>
|
|
209
|
+
</table>
|
|
210
|
+
</body></html>`;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Versão texto puro.
|
|
214
|
+
*
|
|
215
|
+
* Não é decoração: parte dos leitores prefere `text/plain`, filtros de spam
|
|
216
|
+
* penalizam mensagem só-HTML, e leitores de tela lidam melhor com o texto. O
|
|
217
|
+
* conteúdo tem de ser o MESMO — um plain text resumido faria dois clientes
|
|
218
|
+
* receberem informações diferentes.
|
|
219
|
+
*/
|
|
220
|
+
export function renderCollectionText(b, block) {
|
|
221
|
+
const parts = [block.greeting, '', ...block.paragraphs];
|
|
222
|
+
if (block.highlight) {
|
|
223
|
+
parts.push('', `${block.highlight.label}: ${block.highlight.amount}`, `${block.highlight.dueLabel} ${block.highlight.dueValue}`);
|
|
224
|
+
}
|
|
225
|
+
if (block.payment) {
|
|
226
|
+
const pay = block.payment;
|
|
227
|
+
const linhas = [];
|
|
228
|
+
const alvo = pay.url ?? pay.boletoUrl;
|
|
229
|
+
if (alvo)
|
|
230
|
+
linhas.push(`Pague aqui: ${alvo}`);
|
|
231
|
+
if (pay.pixPayload)
|
|
232
|
+
linhas.push('', 'PIX copia e cola:', pay.pixPayload);
|
|
233
|
+
if (pay.identificationField)
|
|
234
|
+
linhas.push('', 'Linha digitável:', pay.identificationField);
|
|
235
|
+
if (linhas.length)
|
|
236
|
+
parts.push('', ...linhas);
|
|
237
|
+
}
|
|
238
|
+
if (block.closing)
|
|
239
|
+
parts.push('', block.closing);
|
|
240
|
+
parts.push('', 'Atenciosamente,', b.signatureName);
|
|
241
|
+
const support = [b.supportEmail, b.supportPhone, b.website?.replace(/^https:\/\//, '')]
|
|
242
|
+
.filter(Boolean)
|
|
243
|
+
.join(' · ');
|
|
244
|
+
parts.push('', '---', `Mensagem automática enviada por ${b.officeName}.${support ? ` Para falar conosco: ${support}.` : ''}`, 'Se o pagamento já foi realizado, desconsidere este aviso.');
|
|
245
|
+
return parts.join('\n');
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=email-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-layout.js","sourceRoot":"","sources":["../../src/collection/email-layout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import type { Tx } from '../db/client.js';
|
|
2
|
+
import { type CollectionPolicy, type CollectionStep } from './policy.js';
|
|
3
|
+
import type { TenantBranding } from './branding.js';
|
|
4
|
+
import type { PaymentBlock } from './payment-block.js';
|
|
5
|
+
import { type ChannelAccountStore, type ChannelPolicy, type ChannelRegistry as CommChannelRegistry, type CommunicationAuditSink, type ConsentPolicy, type ConsentStore, type DispatchClaimStore, type SenderOrigin, type TemplateStore } from '../communication/index.js';
|
|
6
|
+
import { type CollectionActionRecord } from './repository.js';
|
|
7
|
+
export interface PlanReport {
|
|
8
|
+
examined: number;
|
|
9
|
+
scheduled: number;
|
|
10
|
+
skippedAlreadyHandled: number;
|
|
11
|
+
canceledByPayment: number;
|
|
12
|
+
canceledByCancellation: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Planeja: cancela o que não deve mais sair e agenda o que a régua manda.
|
|
16
|
+
*
|
|
17
|
+
* A ordem importa. Cancelar ANTES de agendar evita a janela em que um recebível
|
|
18
|
+
* pago recebe uma etapa nova no mesmo ciclo.
|
|
19
|
+
*/
|
|
20
|
+
export declare function planCollections(tx: Tx, today: string, policyOverride?: CollectionPolicy): Promise<PlanReport>;
|
|
21
|
+
export interface ExecuteReport {
|
|
22
|
+
attempted: number;
|
|
23
|
+
sent: number;
|
|
24
|
+
failedTemporary: number;
|
|
25
|
+
failedPermanent: number;
|
|
26
|
+
skippedNoLongerDue: number;
|
|
27
|
+
skippedNoChannel: number;
|
|
28
|
+
escalated: number;
|
|
29
|
+
}
|
|
30
|
+
export interface ExecuteContext {
|
|
31
|
+
/** Identidade visual e dados de contato do escritório. */
|
|
32
|
+
branding: TenantBranding;
|
|
33
|
+
/** Resolve o destinatário lógico do cliente para o canal. */
|
|
34
|
+
resolveRecipient: (clientId: string, channel: string) => Promise<string | null>;
|
|
35
|
+
/** Descrição do recebível, para identificar a dívida sem inventar dado. */
|
|
36
|
+
describeReceivable?: (receivableId: string) => Promise<string | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Como pagar este recebível, se já houver cobrança emitida.
|
|
39
|
+
*
|
|
40
|
+
* Opcional, e resolvido no momento do envio — não no agendamento. Entre um e
|
|
41
|
+
* outro passam dias: a cobrança pode ter sido criada depois, cancelada, ou o
|
|
42
|
+
* escritório pode ter conectado a conta de pagamento no meio. Congelar o link
|
|
43
|
+
* no agendamento mandaria o cliente para uma cobrança que não existe mais.
|
|
44
|
+
*/
|
|
45
|
+
resolvePayment?: (receivableId: string) => Promise<PaymentBlock | null>;
|
|
46
|
+
/**
|
|
47
|
+
* Entrega pelo motor compartilhado do ecossistema. **Obrigatória.**
|
|
48
|
+
*
|
|
49
|
+
* Era opcional, e o opcional era o defeito. Enquanto este campo pôde faltar,
|
|
50
|
+
* havia um segundo caminho de envio — `channels` legado, HTML pronto, e-mail
|
|
51
|
+
* direto pelo Resend — com uma idempotência PRÓPRIA (`receivableId:stepKey`,
|
|
52
|
+
* que não era gravada em lugar nenhum). O cron usava um caminho, a rota
|
|
53
|
+
* manual usava o outro, e a proteção de cada um era invisível para o outro: os
|
|
54
|
+
* dois podiam enviar a mesma etapa no mesmo minuto.
|
|
55
|
+
*
|
|
56
|
+
* Sem `?`, o compilador recusa qualquer chamador que tente enviar por fora.
|
|
57
|
+
* A montagem canônica está em `communication-runtime.ts`, e ela é a única.
|
|
58
|
+
*/
|
|
59
|
+
communication: CollectionCommunication;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* O que a régua precisa fornecer para falar com o motor compartilhado.
|
|
63
|
+
*
|
|
64
|
+
* A SC não monta o `CommunicationIntent` à mão em cada etapa: ela declara uma
|
|
65
|
+
* vez de onde vêm contas, templates e consentimento, e o adaptador abaixo faz a
|
|
66
|
+
* tradução — que é o que impede o vocabulário de cobrança de vazar para o motor
|
|
67
|
+
* e o vocabulário do motor de vazar para a régua.
|
|
68
|
+
*/
|
|
69
|
+
export interface CollectionCommunication {
|
|
70
|
+
tenantId: string;
|
|
71
|
+
/** Marca do escritório. Distinta do tenant: um tenant pode operar sob mais de uma. */
|
|
72
|
+
brand: string;
|
|
73
|
+
channels: CommChannelRegistry;
|
|
74
|
+
accounts: ChannelAccountStore;
|
|
75
|
+
templates: TemplateStore;
|
|
76
|
+
consent: ConsentStore;
|
|
77
|
+
consentPolicy?: ConsentPolicy;
|
|
78
|
+
/**
|
|
79
|
+
* Canais a tentar, por etapa. Política do ESCRITÓRIO — o motor só executa.
|
|
80
|
+
*
|
|
81
|
+
* Recebe a etapa inteira, e não só a chave, para que a régua possa decidir por
|
|
82
|
+
* tom (uma etapa `reminder` pode preferir WhatsApp; uma `overdue_collection`,
|
|
83
|
+
* e-mail com trilha). Sem isto, o canal declarado no passo é o único usado.
|
|
84
|
+
*/
|
|
85
|
+
policyFor?: (step: CollectionStep) => ChannelPolicy;
|
|
86
|
+
/**
|
|
87
|
+
* Reserva atômica do direito de enviar. Substitui `alreadySent`.
|
|
88
|
+
*
|
|
89
|
+
* A consulta antiga respondia "já enviei?" e devolvia um booleano — e entre a
|
|
90
|
+
* resposta e o envio havia uma janela em que a resposta continuava valendo
|
|
91
|
+
* para todo mundo que perguntasse. A reserva não responde: ela DECIDE, uma vez
|
|
92
|
+
* só, e só um chamador ganha. Ver `communication/claim.ts`.
|
|
93
|
+
*/
|
|
94
|
+
claims: DispatchClaimStore;
|
|
95
|
+
/** Trilha estruturada do motor. Ver `communication/audit.ts`. */
|
|
96
|
+
audit: CommunicationAuditSink;
|
|
97
|
+
/**
|
|
98
|
+
* De onde veio o remetente de e-mail resolvido para este tenant.
|
|
99
|
+
*
|
|
100
|
+
* Vai para a trilha do ciclo. "Saiu pelo remetente da plataforma" tem de ser
|
|
101
|
+
* uma coisa que o escritório consegue ver, e não uma linha de código.
|
|
102
|
+
*/
|
|
103
|
+
emailSenderOrigin?: SenderOrigin | null;
|
|
104
|
+
/** Percorre tudo e relata, sem chamar adapter nenhum e sem reservar chave. */
|
|
105
|
+
dryRun?: boolean;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Executa as ações vencidas.
|
|
109
|
+
*
|
|
110
|
+
* **Revalida o estado no momento do envio.** O agendamento pode ter dias; entre
|
|
111
|
+
* ele e agora o cliente pode ter pago, o recebível pode ter sido cancelado, ou
|
|
112
|
+
* uma baixa parcial pode ter mudado o valor. Confiar no que foi agendado é como
|
|
113
|
+
* o motor manda cobrança de dívida quitada.
|
|
114
|
+
*/
|
|
115
|
+
export declare function executeCollections(tx: Tx, ctx: ExecuteContext, today: string, policyOverride?: CollectionPolicy): Promise<ExecuteReport>;
|
|
116
|
+
export interface CollectionCycleReport extends PlanReport, ExecuteReport {
|
|
117
|
+
}
|
|
118
|
+
/** Ciclo completo — o que o job roda. */
|
|
119
|
+
export declare function runCollectionCycle(tx: Tx, ctx: ExecuteContext, today: string): Promise<CollectionCycleReport>;
|
|
120
|
+
export type { CollectionActionRecord };
|
|
121
|
+
/**
|
|
122
|
+
* Desliga a régua de um recebível que acabou de ser quitado.
|
|
123
|
+
*
|
|
124
|
+
* Existe porque a baixa passou a ter dois caminhos: o job diário, que varre
|
|
125
|
+
* todos os recebíveis, e o webhook, que sabe exatamente qual foi pago. Sem esta
|
|
126
|
+
* função o webhook baixaria o valor e deixaria a comunicação agendada — o
|
|
127
|
+
* cliente pagaria e receberia a cobrança de atraso mesmo assim, que é a pior
|
|
128
|
+
* falha possível numa régua automática.
|
|
129
|
+
*
|
|
130
|
+
* Só o que ainda não saiu é cancelado. Mensagem enviada é histórico.
|
|
131
|
+
*/
|
|
132
|
+
export declare function cancelDunningForSettled(tx: Tx, receivableId: string): Promise<number>;
|
|
133
|
+
/**
|
|
134
|
+
* Religa a régua de um recebível cuja liquidação foi anulada.
|
|
135
|
+
*
|
|
136
|
+
* Sem isto, corrigir o saldo não bastaria: `planCollections` não reagenda um
|
|
137
|
+
* passo cujo `step_key` já existe na tabela — a idempotência olha a EXISTÊNCIA
|
|
138
|
+
* da linha, não o status dela. Os passos desligados pela baixa ficariam
|
|
139
|
+
* `canceled` para sempre, e o cliente voltaria a dever sem que ninguém jamais o
|
|
140
|
+
* lembrasse. O saldo estaria certo e a cobrança nunca aconteceria.
|
|
141
|
+
*
|
|
142
|
+
* Reabre **somente** o que foi fechado POR PAGAMENTO. Um passo cancelado porque
|
|
143
|
+
* o recebível foi cancelado, ou já enviado, é história e permanece intocado —
|
|
144
|
+
* reabrir tudo faria a régua reenviar mensagem que o cliente já recebeu.
|
|
145
|
+
*/
|
|
146
|
+
/**
|
|
147
|
+
* Religa etapas fechadas por FALHA DE INFRAESTRUTURA, nunca por decisão humana.
|
|
148
|
+
*
|
|
149
|
+
* Existe para o resíduo do incidente C1-PROV-R1B-C2: etapas que o motor fechou
|
|
150
|
+
* como `escalated` porque o canal ficou indisponível (cofre de credenciais fora
|
|
151
|
+
* do ar). A correção em `sendViaSharedEngine` impede que isso volte a
|
|
152
|
+
* acontecer, mas não desfaz o que já foi fechado — e nada mais no domínio
|
|
153
|
+
* consegue, porque `planCollections` não reagenda um `step_key` existente e
|
|
154
|
+
* `listActions` só enxerga `scheduled`.
|
|
155
|
+
*
|
|
156
|
+
* As guardas são deliberadamente estreitas, e cada uma exclui uma classe:
|
|
157
|
+
*
|
|
158
|
+
* - `closed_reason = 'escalated'` — deixa de fora `no_contact_data`,
|
|
159
|
+
* `opted_out`, `consent_unknown`, `paid`, `canceled`, `rule_disabled` e
|
|
160
|
+
* `permanent_failure`. Todas são decisão de negócio e permanecem terminais.
|
|
161
|
+
* - `attempts = 0` — `markEscalated` NUNCA incrementa `attempts`, enquanto
|
|
162
|
+
* `markSent` e `markFailed` sempre incrementam. Zero prova que nenhum adapter
|
|
163
|
+
* chegou a tentar.
|
|
164
|
+
* - `provider_ref IS NULL` e `sent_at IS NULL` — prova que nada saiu. Uma
|
|
165
|
+
* mensagem entregue jamais é reaberta, e o cliente nunca recebe duplicata.
|
|
166
|
+
*
|
|
167
|
+
* O `step_key` é obrigatório: recuperação é pontual e auditável, nunca
|
|
168
|
+
* "reabra tudo deste recebível".
|
|
169
|
+
*
|
|
170
|
+
* O histórico da falha NÃO é apagado. `communication_event`
|
|
171
|
+
* (`dispatch_skipped` / `no_credential`) e `communication_dispatch`
|
|
172
|
+
* (`failed_retryable`) continuam intactos — esta função move apenas o estado da
|
|
173
|
+
* régua, e `last_error` registra a origem da reabertura.
|
|
174
|
+
*/
|
|
175
|
+
export declare function rearmDunningAfterInfraFailure(tx: Tx, receivableId: string, stepKey: string, incidentRef: string): Promise<number>;
|
|
176
|
+
export declare function rearmDunningAfterReversal(tx: Tx, receivableId: string): Promise<number>;
|
|
177
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/collection/engine.ts"],"names":[],"mappings":"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"}
|