@baruk/core 0.1.0 → 0.3.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/CHANGELOG.md +59 -0
- package/dist/auth/password-reset.d.ts.map +1 -1
- package/dist/auth/password-reset.js +2 -4
- package/dist/auth/password-reset.js.map +1 -1
- package/dist/auth/password.d.ts +2 -18
- package/dist/auth/password.d.ts.map +1 -1
- package/dist/auth/password.js +12 -51
- package/dist/auth/password.js.map +1 -1
- package/dist/auth/service.d.ts +0 -12
- package/dist/auth/service.d.ts.map +1 -1
- package/dist/auth/service.js +3 -36
- package/dist/auth/service.js.map +1 -1
- package/dist/auth/session-token.d.ts +5 -2
- package/dist/auth/session-token.d.ts.map +1 -1
- package/dist/auth/session-token.js +7 -12
- package/dist/auth/session-token.js.map +1 -1
- package/dist/billing/dunning.d.ts +33 -0
- package/dist/billing/dunning.d.ts.map +1 -0
- package/dist/billing/dunning.js +49 -0
- package/dist/billing/dunning.js.map +1 -0
- package/dist/billing/provider/asaas.d.ts +15 -0
- package/dist/billing/provider/asaas.d.ts.map +1 -0
- package/dist/billing/provider/asaas.js +121 -0
- package/dist/billing/provider/asaas.js.map +1 -0
- package/dist/billing/provider/manual.d.ts +14 -0
- package/dist/billing/provider/manual.d.ts.map +1 -0
- package/dist/billing/provider/manual.js +24 -0
- package/dist/billing/provider/manual.js.map +1 -0
- package/dist/billing/provider/registry.d.ts +12 -0
- package/dist/billing/provider/registry.d.ts.map +1 -0
- package/dist/billing/provider/registry.js +22 -0
- package/dist/billing/provider/registry.js.map +1 -0
- package/dist/billing/provider/types.d.ts +76 -0
- package/dist/billing/provider/types.d.ts.map +1 -0
- package/dist/billing/provider/types.js +9 -0
- package/dist/billing/provider/types.js.map +1 -0
- package/dist/billing/receivable.d.ts +108 -0
- package/dist/billing/receivable.d.ts.map +1 -0
- package/dist/billing/receivable.js +2 -0
- package/dist/billing/receivable.js.map +1 -0
- package/dist/billing/repository.d.ts +97 -0
- package/dist/billing/repository.d.ts.map +1 -0
- package/dist/billing/repository.js +167 -0
- package/dist/billing/repository.js.map +1 -0
- package/dist/cjs/audit/audit.js +31 -0
- package/dist/cjs/audit/audit.js.map +1 -0
- package/dist/cjs/audit/repository.js +32 -0
- package/dist/cjs/audit/repository.js.map +1 -0
- package/dist/cjs/auth/password-reset.js +58 -0
- package/dist/cjs/auth/password-reset.js.map +1 -0
- package/dist/cjs/auth/password.js +32 -0
- package/dist/cjs/auth/password.js.map +1 -0
- package/dist/cjs/auth/service.js +191 -0
- package/dist/cjs/auth/service.js.map +1 -0
- package/dist/cjs/auth/session-token.js +18 -0
- package/dist/cjs/auth/session-token.js.map +1 -0
- package/dist/cjs/billing/dunning.js +54 -0
- package/dist/cjs/billing/dunning.js.map +1 -0
- package/dist/cjs/billing/provider/asaas.js +125 -0
- package/dist/cjs/billing/provider/asaas.js.map +1 -0
- package/dist/cjs/billing/provider/manual.js +28 -0
- package/dist/cjs/billing/provider/manual.js.map +1 -0
- package/dist/cjs/billing/provider/registry.js +27 -0
- package/dist/cjs/billing/provider/registry.js.map +1 -0
- package/dist/cjs/billing/provider/types.js +10 -0
- package/dist/cjs/billing/provider/types.js.map +1 -0
- package/dist/cjs/billing/receivable.js +3 -0
- package/dist/cjs/billing/receivable.js.map +1 -0
- package/dist/cjs/billing/repository.js +180 -0
- package/dist/cjs/billing/repository.js.map +1 -0
- package/dist/cjs/clients/repository.js +123 -0
- package/dist/cjs/clients/repository.js.map +1 -0
- package/dist/cjs/commercial-catalog/catalog.js +108 -0
- package/dist/cjs/commercial-catalog/catalog.js.map +1 -0
- package/dist/cjs/commercial-catalog/consumption-contracts.js +10 -0
- package/dist/cjs/commercial-catalog/consumption-contracts.js.map +1 -0
- package/dist/cjs/commercial-catalog/coupon.js +63 -0
- package/dist/cjs/commercial-catalog/coupon.js.map +1 -0
- package/dist/cjs/commercial-catalog/index.js +16 -0
- package/dist/cjs/commercial-catalog/index.js.map +1 -0
- package/dist/cjs/commercial-catalog/offer-application.js +53 -0
- package/dist/cjs/commercial-catalog/offer-application.js.map +1 -0
- package/dist/cjs/commercial-catalog/types.js +26 -0
- package/dist/cjs/commercial-catalog/types.js.map +1 -0
- package/dist/cjs/crm/repository.js +195 -0
- package/dist/cjs/crm/repository.js.map +1 -0
- package/dist/cjs/dashboard/repository.js +39 -0
- package/dist/cjs/dashboard/repository.js.map +1 -0
- package/dist/cjs/db/client.js +27 -0
- package/dist/cjs/db/client.js.map +1 -0
- package/dist/cjs/db/context.js +43 -0
- package/dist/cjs/db/context.js.map +1 -0
- package/dist/cjs/db/load-env.js +47 -0
- package/dist/cjs/db/load-env.js.map +1 -0
- package/dist/cjs/db/seed.js +69 -0
- package/dist/cjs/db/seed.js.map +1 -0
- package/dist/cjs/entitlements/decision.js +203 -0
- package/dist/cjs/entitlements/decision.js.map +1 -0
- package/dist/cjs/entitlements/derive.js +46 -0
- package/dist/cjs/entitlements/derive.js.map +1 -0
- package/dist/cjs/entitlements/index.js +23 -0
- package/dist/cjs/entitlements/index.js.map +1 -0
- package/dist/cjs/entitlements/sources.js +60 -0
- package/dist/cjs/entitlements/sources.js.map +1 -0
- package/dist/cjs/entitlements/standing.js +42 -0
- package/dist/cjs/entitlements/standing.js.map +1 -0
- package/dist/cjs/entitlements/types.js +16 -0
- package/dist/cjs/entitlements/types.js.map +1 -0
- package/dist/cjs/import/clients-import.js +147 -0
- package/dist/cjs/import/clients-import.js.map +1 -0
- package/dist/cjs/index.js +335 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/mail/dedup-store.js +56 -0
- package/dist/cjs/mail/dedup-store.js.map +1 -0
- package/dist/cjs/mail/index.js +24 -0
- package/dist/cjs/mail/index.js.map +1 -0
- package/dist/cjs/mail/provider.js +251 -0
- package/dist/cjs/mail/provider.js.map +1 -0
- package/dist/cjs/mail/resend-client.js +103 -0
- package/dist/cjs/mail/resend-client.js.map +1 -0
- package/dist/cjs/mail/resend.js +21 -0
- package/dist/cjs/mail/resend.js.map +1 -0
- package/dist/cjs/mail/sanitize.js +56 -0
- package/dist/cjs/mail/sanitize.js.map +1 -0
- package/dist/cjs/mail/sender-resolver.js +15 -0
- package/dist/cjs/mail/sender-resolver.js.map +1 -0
- package/dist/cjs/mail/template-renderer.js +21 -0
- package/dist/cjs/mail/template-renderer.js.map +1 -0
- package/dist/cjs/mail/types.js +38 -0
- package/dist/cjs/mail/types.js.map +1 -0
- package/dist/cjs/notifications/repository.js +49 -0
- package/dist/cjs/notifications/repository.js.map +1 -0
- package/dist/cjs/onboarding/domain.js +370 -0
- package/dist/cjs/onboarding/domain.js.map +1 -0
- package/dist/cjs/onboarding/interaction-review.js +425 -0
- package/dist/cjs/onboarding/interaction-review.js.map +1 -0
- package/dist/cjs/onboarding/persistence.js +444 -0
- package/dist/cjs/onboarding/persistence.js.map +1 -0
- package/dist/cjs/onboarding/portal-actions.js +157 -0
- package/dist/cjs/onboarding/portal-actions.js.map +1 -0
- package/dist/cjs/onboarding/portal.js +177 -0
- package/dist/cjs/onboarding/portal.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/portal/repository.js +37 -0
- package/dist/cjs/portal/repository.js.map +1 -0
- package/dist/cjs/pricing-engine/bundle.js +49 -0
- package/dist/cjs/pricing-engine/bundle.js.map +1 -0
- package/dist/cjs/pricing-engine/errors.js +48 -0
- package/dist/cjs/pricing-engine/errors.js.map +1 -0
- package/dist/cjs/pricing-engine/index.js +30 -0
- package/dist/cjs/pricing-engine/index.js.map +1 -0
- package/dist/cjs/pricing-engine/money.js +69 -0
- package/dist/cjs/pricing-engine/money.js.map +1 -0
- package/dist/cjs/pricing-engine/pipeline.js +330 -0
- package/dist/cjs/pricing-engine/pipeline.js.map +1 -0
- package/dist/cjs/pricing-engine/proration.js +53 -0
- package/dist/cjs/pricing-engine/proration.js.map +1 -0
- package/dist/cjs/pricing-engine/shadow.js +58 -0
- package/dist/cjs/pricing-engine/shadow.js.map +1 -0
- package/dist/cjs/pricing-engine/types.js +34 -0
- package/dist/cjs/pricing-engine/types.js.map +1 -0
- package/dist/cjs/products/catalog.js +10 -0
- package/dist/cjs/products/catalog.js.map +1 -0
- package/dist/cjs/products/repository.js +61 -0
- package/dist/cjs/products/repository.js.map +1 -0
- package/dist/cjs/rbac/authorize.js +36 -0
- package/dist/cjs/rbac/authorize.js.map +1 -0
- package/dist/cjs/rbac/catalog.js +455 -0
- package/dist/cjs/rbac/catalog.js.map +1 -0
- package/dist/cjs/requests/repository.js +114 -0
- package/dist/cjs/requests/repository.js.map +1 -0
- package/dist/cjs/subscription-billing/dunning.js +26 -0
- package/dist/cjs/subscription-billing/dunning.js.map +1 -0
- package/dist/cjs/subscription-billing/events.js +45 -0
- package/dist/cjs/subscription-billing/events.js.map +1 -0
- package/dist/cjs/subscription-billing/index.js +62 -0
- package/dist/cjs/subscription-billing/index.js.map +1 -0
- package/dist/cjs/subscription-billing/plans.js +88 -0
- package/dist/cjs/subscription-billing/plans.js.map +1 -0
- package/dist/cjs/subscription-billing/product-config.js +54 -0
- package/dist/cjs/subscription-billing/product-config.js.map +1 -0
- package/dist/cjs/subscription-billing/provider/asaas.js +233 -0
- package/dist/cjs/subscription-billing/provider/asaas.js.map +1 -0
- package/dist/cjs/subscription-billing/provider/disabled.js +46 -0
- package/dist/cjs/subscription-billing/provider/disabled.js.map +1 -0
- package/dist/cjs/subscription-billing/provider/registry.js +29 -0
- package/dist/cjs/subscription-billing/provider/registry.js.map +1 -0
- package/dist/cjs/subscription-billing/reconcile.js +198 -0
- package/dist/cjs/subscription-billing/reconcile.js.map +1 -0
- package/dist/cjs/subscription-billing/repository.js +359 -0
- package/dist/cjs/subscription-billing/repository.js.map +1 -0
- package/dist/cjs/subscription-billing/service.js +838 -0
- package/dist/cjs/subscription-billing/service.js.map +1 -0
- package/dist/cjs/subscription-billing/types.js +28 -0
- package/dist/cjs/subscription-billing/types.js.map +1 -0
- package/dist/cjs/tenancy/provisioning.js +126 -0
- package/dist/cjs/tenancy/provisioning.js.map +1 -0
- package/dist/cjs/users/repository.js +83 -0
- package/dist/cjs/users/repository.js.map +1 -0
- package/dist/cjs/vault/crypto.js +94 -0
- package/dist/cjs/vault/crypto.js.map +1 -0
- package/dist/cjs/vault/repository.js +120 -0
- package/dist/cjs/vault/repository.js.map +1 -0
- package/dist/commercial-catalog/catalog.d.ts +27 -0
- package/dist/commercial-catalog/catalog.d.ts.map +1 -0
- package/dist/commercial-catalog/catalog.js +104 -0
- package/dist/commercial-catalog/catalog.js.map +1 -0
- package/dist/commercial-catalog/consumption-contracts.d.ts +33 -0
- package/dist/commercial-catalog/consumption-contracts.d.ts.map +1 -0
- package/dist/commercial-catalog/consumption-contracts.js +9 -0
- package/dist/commercial-catalog/consumption-contracts.js.map +1 -0
- package/dist/commercial-catalog/coupon.d.ts +43 -0
- package/dist/commercial-catalog/coupon.d.ts.map +1 -0
- package/dist/commercial-catalog/coupon.js +57 -0
- package/dist/commercial-catalog/coupon.js.map +1 -0
- package/dist/commercial-catalog/index.d.ts +10 -0
- package/dist/commercial-catalog/index.d.ts.map +1 -0
- package/dist/commercial-catalog/index.js +5 -0
- package/dist/commercial-catalog/index.js.map +1 -0
- package/dist/commercial-catalog/offer-application.d.ts +39 -0
- package/dist/commercial-catalog/offer-application.d.ts.map +1 -0
- package/dist/commercial-catalog/offer-application.js +50 -0
- package/dist/commercial-catalog/offer-application.js.map +1 -0
- package/dist/commercial-catalog/types.d.ts +175 -0
- package/dist/commercial-catalog/types.d.ts.map +1 -0
- package/dist/commercial-catalog/types.js +23 -0
- package/dist/commercial-catalog/types.js.map +1 -0
- package/dist/crm/repository.d.ts +109 -0
- package/dist/crm/repository.d.ts.map +1 -0
- package/dist/crm/repository.js +181 -0
- package/dist/crm/repository.js.map +1 -0
- package/dist/db/context.d.ts +2 -0
- package/dist/db/context.d.ts.map +1 -1
- package/dist/db/context.js +3 -0
- package/dist/db/context.js.map +1 -1
- package/dist/db/migrate.js +7 -2
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/seed.js +4 -1
- package/dist/db/seed.js.map +1 -1
- package/dist/entitlements/decision.d.ts +86 -0
- package/dist/entitlements/decision.d.ts.map +1 -0
- package/dist/entitlements/decision.js +196 -0
- package/dist/entitlements/decision.js.map +1 -0
- package/dist/entitlements/derive.d.ts +30 -0
- package/dist/entitlements/derive.d.ts.map +1 -0
- package/dist/entitlements/derive.js +42 -0
- package/dist/entitlements/derive.js.map +1 -0
- package/dist/entitlements/index.d.ts +10 -0
- package/dist/entitlements/index.d.ts.map +1 -0
- package/dist/entitlements/index.js +7 -0
- package/dist/entitlements/index.js.map +1 -0
- package/dist/entitlements/sources.d.ts +30 -0
- package/dist/entitlements/sources.d.ts.map +1 -0
- package/dist/entitlements/sources.js +55 -0
- package/dist/entitlements/sources.js.map +1 -0
- package/dist/entitlements/standing.d.ts +22 -0
- package/dist/entitlements/standing.d.ts.map +1 -0
- package/dist/entitlements/standing.js +38 -0
- package/dist/entitlements/standing.js.map +1 -0
- package/dist/entitlements/types.d.ts +26 -0
- package/dist/entitlements/types.d.ts.map +1 -0
- package/dist/entitlements/types.js +15 -0
- package/dist/entitlements/types.js.map +1 -0
- package/dist/index.d.ts +74 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -4
- package/dist/index.js.map +1 -1
- package/dist/mail/dedup-store.d.ts +25 -0
- package/dist/mail/dedup-store.d.ts.map +1 -0
- package/dist/mail/dedup-store.js +51 -0
- package/dist/mail/dedup-store.js.map +1 -0
- package/dist/mail/index.d.ts +10 -0
- package/dist/mail/index.d.ts.map +1 -0
- package/dist/mail/index.js +9 -0
- package/dist/mail/index.js.map +1 -0
- package/dist/mail/provider.d.ts +31 -0
- package/dist/mail/provider.d.ts.map +1 -0
- package/dist/mail/provider.js +248 -0
- package/dist/mail/provider.js.map +1 -0
- package/dist/mail/resend-client.d.ts +16 -0
- package/dist/mail/resend-client.d.ts.map +1 -0
- package/dist/mail/resend-client.js +100 -0
- package/dist/mail/resend-client.js.map +1 -0
- package/dist/mail/resend.d.ts.map +1 -1
- package/dist/mail/resend.js +2 -0
- package/dist/mail/resend.js.map +1 -1
- package/dist/mail/sanitize.d.ts +17 -0
- package/dist/mail/sanitize.d.ts.map +1 -0
- package/dist/mail/sanitize.js +51 -0
- package/dist/mail/sanitize.js.map +1 -0
- package/dist/mail/sender-resolver.d.ts +8 -0
- package/dist/mail/sender-resolver.d.ts.map +1 -0
- package/dist/mail/sender-resolver.js +11 -0
- package/dist/mail/sender-resolver.js.map +1 -0
- package/dist/mail/template-renderer.d.ts +10 -0
- package/dist/mail/template-renderer.d.ts.map +1 -0
- package/dist/mail/template-renderer.js +17 -0
- package/dist/mail/template-renderer.js.map +1 -0
- package/dist/mail/types.d.ts +143 -0
- package/dist/mail/types.d.ts.map +1 -0
- package/dist/mail/types.js +34 -0
- package/dist/mail/types.js.map +1 -0
- package/dist/onboarding/domain.d.ts +146 -0
- package/dist/onboarding/domain.d.ts.map +1 -0
- package/dist/onboarding/domain.js +348 -0
- package/dist/onboarding/domain.js.map +1 -0
- package/dist/onboarding/interaction-review.d.ts +123 -0
- package/dist/onboarding/interaction-review.d.ts.map +1 -0
- package/dist/onboarding/interaction-review.js +413 -0
- package/dist/onboarding/interaction-review.js.map +1 -0
- package/dist/onboarding/persistence.d.ts +106 -0
- package/dist/onboarding/persistence.d.ts.map +1 -0
- package/dist/onboarding/persistence.js +430 -0
- package/dist/onboarding/persistence.js.map +1 -0
- package/dist/onboarding/portal-actions.d.ts +48 -0
- package/dist/onboarding/portal-actions.d.ts.map +1 -0
- package/dist/onboarding/portal-actions.js +153 -0
- package/dist/onboarding/portal-actions.js.map +1 -0
- package/dist/onboarding/portal.d.ts +58 -0
- package/dist/onboarding/portal.d.ts.map +1 -0
- package/dist/onboarding/portal.js +170 -0
- package/dist/onboarding/portal.js.map +1 -0
- package/dist/pricing-engine/bundle.d.ts +22 -0
- package/dist/pricing-engine/bundle.d.ts.map +1 -0
- package/dist/pricing-engine/bundle.js +44 -0
- package/dist/pricing-engine/bundle.js.map +1 -0
- package/dist/pricing-engine/errors.d.ts +32 -0
- package/dist/pricing-engine/errors.d.ts.map +1 -0
- package/dist/pricing-engine/errors.js +44 -0
- package/dist/pricing-engine/errors.js.map +1 -0
- package/dist/pricing-engine/index.d.ts +12 -0
- package/dist/pricing-engine/index.d.ts.map +1 -0
- package/dist/pricing-engine/index.js +8 -0
- package/dist/pricing-engine/index.js.map +1 -0
- package/dist/pricing-engine/money.d.ts +32 -0
- package/dist/pricing-engine/money.d.ts.map +1 -0
- package/dist/pricing-engine/money.js +58 -0
- package/dist/pricing-engine/money.js.map +1 -0
- package/dist/pricing-engine/pipeline.d.ts +3 -0
- package/dist/pricing-engine/pipeline.d.ts.map +1 -0
- package/dist/pricing-engine/pipeline.js +327 -0
- package/dist/pricing-engine/pipeline.js.map +1 -0
- package/dist/pricing-engine/proration.d.ts +3 -0
- package/dist/pricing-engine/proration.d.ts.map +1 -0
- package/dist/pricing-engine/proration.js +50 -0
- package/dist/pricing-engine/proration.js.map +1 -0
- package/dist/pricing-engine/shadow.d.ts +51 -0
- package/dist/pricing-engine/shadow.d.ts.map +1 -0
- package/dist/pricing-engine/shadow.js +54 -0
- package/dist/pricing-engine/shadow.js.map +1 -0
- package/dist/pricing-engine/types.d.ts +184 -0
- package/dist/pricing-engine/types.d.ts.map +1 -0
- package/dist/pricing-engine/types.js +31 -0
- package/dist/pricing-engine/types.js.map +1 -0
- package/dist/rbac/authorize.d.ts +3 -6
- package/dist/rbac/authorize.d.ts.map +1 -1
- package/dist/rbac/authorize.js +4 -8
- package/dist/rbac/authorize.js.map +1 -1
- package/dist/rbac/catalog.d.ts.map +1 -1
- package/dist/rbac/catalog.js +414 -21
- package/dist/rbac/catalog.js.map +1 -1
- package/dist/subscription-billing/dunning.d.ts +18 -0
- package/dist/subscription-billing/dunning.d.ts.map +1 -0
- package/dist/subscription-billing/dunning.js +28 -0
- package/dist/subscription-billing/dunning.js.map +1 -0
- package/dist/subscription-billing/events.d.ts +58 -0
- package/dist/subscription-billing/events.d.ts.map +1 -0
- package/dist/subscription-billing/events.js +38 -0
- package/dist/subscription-billing/events.js.map +1 -0
- package/dist/subscription-billing/index.d.ts +18 -0
- package/dist/subscription-billing/index.d.ts.map +1 -0
- package/dist/subscription-billing/index.js +16 -0
- package/dist/subscription-billing/index.js.map +1 -0
- package/dist/subscription-billing/plans.d.ts +34 -0
- package/dist/subscription-billing/plans.d.ts.map +1 -0
- package/dist/subscription-billing/plans.js +85 -0
- package/dist/subscription-billing/plans.js.map +1 -0
- package/dist/subscription-billing/product-config.d.ts +61 -0
- package/dist/subscription-billing/product-config.d.ts.map +1 -0
- package/dist/subscription-billing/product-config.js +50 -0
- package/dist/subscription-billing/product-config.js.map +1 -0
- package/dist/subscription-billing/provider/asaas.d.ts +26 -0
- package/dist/subscription-billing/provider/asaas.d.ts.map +1 -0
- package/dist/subscription-billing/provider/asaas.js +229 -0
- package/dist/subscription-billing/provider/asaas.js.map +1 -0
- package/dist/subscription-billing/provider/disabled.d.ts +30 -0
- package/dist/subscription-billing/provider/disabled.d.ts.map +1 -0
- package/dist/subscription-billing/provider/disabled.js +42 -0
- package/dist/subscription-billing/provider/disabled.js.map +1 -0
- package/dist/subscription-billing/provider/registry.d.ts +10 -0
- package/dist/subscription-billing/provider/registry.d.ts.map +1 -0
- package/dist/subscription-billing/provider/registry.js +26 -0
- package/dist/subscription-billing/provider/registry.js.map +1 -0
- package/dist/subscription-billing/reconcile.d.ts +45 -0
- package/dist/subscription-billing/reconcile.d.ts.map +1 -0
- package/dist/subscription-billing/reconcile.js +192 -0
- package/dist/subscription-billing/reconcile.js.map +1 -0
- package/dist/subscription-billing/repository.d.ts +168 -0
- package/dist/subscription-billing/repository.d.ts.map +1 -0
- package/dist/subscription-billing/repository.js +336 -0
- package/dist/subscription-billing/repository.js.map +1 -0
- package/dist/subscription-billing/service.d.ts +175 -0
- package/dist/subscription-billing/service.d.ts.map +1 -0
- package/dist/subscription-billing/service.js +818 -0
- package/dist/subscription-billing/service.js.map +1 -0
- package/dist/subscription-billing/types.d.ts +161 -0
- package/dist/subscription-billing/types.d.ts.map +1 -0
- package/dist/subscription-billing/types.js +24 -0
- package/dist/subscription-billing/types.js.map +1 -0
- package/dist/vault/crypto.d.ts +22 -0
- package/dist/vault/crypto.d.ts.map +1 -0
- package/dist/vault/crypto.js +88 -0
- package/dist/vault/crypto.js.map +1 -0
- package/dist/vault/repository.d.ts +45 -0
- package/dist/vault/repository.d.ts.map +1 -0
- package/dist/vault/repository.js +111 -0
- package/dist/vault/repository.js.map +1 -0
- package/package.json +23 -13
- package/src/db/migrations/0012_vault.sql +51 -0
- package/src/db/migrations/0013_crm.sql +67 -0
- package/src/db/migrations/0014_billing.sql +146 -0
- package/src/db/migrations/0015_merchant_billing_ar.sql +201 -0
- package/src/db/migrations/0016_office_onboarding.sql +162 -0
- package/src/db/migrations/0017_office_onboarding_api.sql +21 -0
- package/src/db/migrations/0018_office_onboarding_portal_actions.sql +60 -0
- package/src/db/migrations/0019_office_onboarding_interaction_review.sql +134 -0
- package/src/db/migrations/0020_saas_billing.sql +157 -0
- package/src/db/migrations/0021_saas_billing_indexes.sql +23 -0
- package/src/db/migrations/0022_saas_billing_multi_product.sql +75 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AsaasProvider = void 0;
|
|
4
|
+
const shared_1 = require("@baruk/shared");
|
|
5
|
+
/**
|
|
6
|
+
* Adapter Asaas — implementação REAL do Provider Pattern (não um mock). Mapeia os
|
|
7
|
+
* DTOs agnósticos do Billing Engine para o formato da API Asaas e vice-versa. A
|
|
8
|
+
* apiKey NUNCA é hardcoded: vem do Vault via `ProviderConfig`. `fetchImpl` é
|
|
9
|
+
* injetável, o que permite testar o mapeamento sem tocar a rede.
|
|
10
|
+
*
|
|
11
|
+
* IMPORTANTE: nenhum outro arquivo do Core importa este adapter diretamente — o
|
|
12
|
+
* acesso é sempre via `resolveBillingProvider('asaas', config)`. Assim, trocar
|
|
13
|
+
* Asaas por Stripe é trocar a string registrada, sem tocar em regra de negócio.
|
|
14
|
+
*/
|
|
15
|
+
const BILLING_TYPE = {
|
|
16
|
+
pix: 'PIX',
|
|
17
|
+
boleto: 'BOLETO',
|
|
18
|
+
card: 'CREDIT_CARD',
|
|
19
|
+
manual: 'UNDEFINED',
|
|
20
|
+
};
|
|
21
|
+
class AsaasError extends shared_1.AppError {
|
|
22
|
+
constructor(message, status = 502) {
|
|
23
|
+
super(`Asaas: ${message}`, { status, code: 'billing_provider_error' });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
class AsaasProvider {
|
|
27
|
+
key = 'asaas';
|
|
28
|
+
apiKey;
|
|
29
|
+
baseUrl;
|
|
30
|
+
fetchImpl;
|
|
31
|
+
constructor(config) {
|
|
32
|
+
if (!config.apiKey)
|
|
33
|
+
throw new AsaasError('apiKey ausente (configure no Vault).', 500);
|
|
34
|
+
this.apiKey = config.apiKey;
|
|
35
|
+
this.baseUrl = (config.baseUrl ?? 'https://api.asaas.com/v3').replace(/\/$/, '');
|
|
36
|
+
this.fetchImpl = config.fetchImpl ?? fetch;
|
|
37
|
+
}
|
|
38
|
+
async call(path, method, body) {
|
|
39
|
+
const res = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
40
|
+
method,
|
|
41
|
+
headers: { 'content-type': 'application/json', access_token: this.apiKey },
|
|
42
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
43
|
+
});
|
|
44
|
+
if (!res.ok) {
|
|
45
|
+
const text = await res.text().catch(() => '');
|
|
46
|
+
throw new AsaasError(`HTTP ${res.status} em ${method} ${path} — ${text.slice(0, 200)}`);
|
|
47
|
+
}
|
|
48
|
+
return (await res.json());
|
|
49
|
+
}
|
|
50
|
+
async createCharge(req) {
|
|
51
|
+
// Asaas exige um customer; aqui assumimos que o id do cliente Asaas veio no
|
|
52
|
+
// metadata (provisionamento fora do escopo). O mapeamento demonstra o contrato.
|
|
53
|
+
const payload = {
|
|
54
|
+
billingType: BILLING_TYPE[req.method] ?? 'UNDEFINED',
|
|
55
|
+
value: req.amount,
|
|
56
|
+
dueDate: req.dueDate,
|
|
57
|
+
description: req.description ?? undefined,
|
|
58
|
+
externalReference: req.referenceId,
|
|
59
|
+
};
|
|
60
|
+
const res = await this.call('/payments', 'POST', payload);
|
|
61
|
+
return {
|
|
62
|
+
externalId: res.id,
|
|
63
|
+
status: mapAsaasStatus(res.status),
|
|
64
|
+
payment: { boletoUrl: res.bankSlipUrl, invoiceUrl: res.invoiceUrl },
|
|
65
|
+
raw: res,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async cancelCharge(externalId) {
|
|
69
|
+
await this.call(`/payments/${externalId}`, 'DELETE');
|
|
70
|
+
}
|
|
71
|
+
async createSubscription(req) {
|
|
72
|
+
const cycle = { monthly: 'MONTHLY', quarterly: 'QUARTERLY', yearly: 'YEARLY' };
|
|
73
|
+
const res = await this.call('/subscriptions', 'POST', {
|
|
74
|
+
billingType: BILLING_TYPE[req.method] ?? 'UNDEFINED',
|
|
75
|
+
value: req.amount,
|
|
76
|
+
cycle: cycle[req.periodicity],
|
|
77
|
+
nextDueDate: req.nextDueDate,
|
|
78
|
+
description: req.description ?? undefined,
|
|
79
|
+
externalReference: req.referenceId,
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
externalId: res.id,
|
|
83
|
+
status: res.status === 'ACTIVE' ? 'active' : res.status === 'PAUSED' ? 'paused' : 'canceled',
|
|
84
|
+
nextChargeOn: res.nextDueDate ?? null,
|
|
85
|
+
raw: res,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async cancelSubscription(externalId) {
|
|
89
|
+
await this.call(`/subscriptions/${externalId}`, 'DELETE');
|
|
90
|
+
}
|
|
91
|
+
parseWebhook(payload) {
|
|
92
|
+
const p = payload;
|
|
93
|
+
const externalId = p.payment?.id ?? null;
|
|
94
|
+
switch (p.event) {
|
|
95
|
+
case 'PAYMENT_RECEIVED':
|
|
96
|
+
case 'PAYMENT_CONFIRMED':
|
|
97
|
+
return { type: 'charge.paid', externalId, paidAt: p.payment?.paymentDate ?? null, raw: payload };
|
|
98
|
+
case 'PAYMENT_OVERDUE':
|
|
99
|
+
return { type: 'charge.overdue', externalId, raw: payload };
|
|
100
|
+
case 'PAYMENT_DELETED':
|
|
101
|
+
return { type: 'charge.canceled', externalId, raw: payload };
|
|
102
|
+
case 'PAYMENT_REFUNDED':
|
|
103
|
+
return { type: 'charge.refunded', externalId, raw: payload };
|
|
104
|
+
default:
|
|
105
|
+
return { type: 'unknown', externalId, raw: payload };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.AsaasProvider = AsaasProvider;
|
|
110
|
+
function mapAsaasStatus(status) {
|
|
111
|
+
switch (status) {
|
|
112
|
+
case 'RECEIVED':
|
|
113
|
+
case 'CONFIRMED':
|
|
114
|
+
return 'paid';
|
|
115
|
+
case 'OVERDUE':
|
|
116
|
+
return 'overdue';
|
|
117
|
+
case 'REFUNDED':
|
|
118
|
+
return 'refunded';
|
|
119
|
+
case 'DELETED':
|
|
120
|
+
return 'canceled';
|
|
121
|
+
default:
|
|
122
|
+
return 'pending';
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=asaas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asaas.js","sourceRoot":"","sources":["../../../../src/billing/provider/asaas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ManualProvider = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Provider padrão — SEM gateway externo. As cobranças são controladas apenas
|
|
6
|
+
* internamente (o escritório gera PIX/boleto por fora e concilia manualmente).
|
|
7
|
+
* É o default seguro quando o tenant ainda não conectou um gateway, e o baseline
|
|
8
|
+
* para os testes: prova que o Billing Engine funciona sem NENHUM provider real.
|
|
9
|
+
*/
|
|
10
|
+
class ManualProvider {
|
|
11
|
+
key = 'manual';
|
|
12
|
+
async createCharge(req) {
|
|
13
|
+
// Nada é enviado para fora. A cobrança nasce 'pending' e é conciliada à mão.
|
|
14
|
+
return {
|
|
15
|
+
externalId: null,
|
|
16
|
+
status: 'pending',
|
|
17
|
+
payment: req.method === 'pix' ? { pixPayload: undefined } : undefined,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
async cancelCharge() {
|
|
21
|
+
// No-op — cancelamento é apenas mudança de status interno.
|
|
22
|
+
}
|
|
23
|
+
parseWebhook() {
|
|
24
|
+
return { type: 'unknown', externalId: null };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.ManualProvider = ManualProvider;
|
|
28
|
+
//# sourceMappingURL=manual.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual.js","sourceRoot":"","sources":["../../../../src/billing/provider/manual.ts"],"names":[],"mappings":";;;AAEA;;;;;GAKG;AACH,MAAa,cAAc;IAChB,GAAG,GAAG,QAAQ,CAAC;IAExB,KAAK,CAAC,YAAY,CAAC,GAAkB;QACnC,6EAA6E;QAC7E,OAAO;YACL,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,GAAG,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS;SACtE,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,2DAA2D;IAC7D,CAAC;IAED,YAAY;QACV,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAC/C,CAAC;CACF;AAnBD,wCAmBC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerBillingProvider = registerBillingProvider;
|
|
4
|
+
exports.availableProviders = availableProviders;
|
|
5
|
+
exports.resolveBillingProvider = resolveBillingProvider;
|
|
6
|
+
const shared_1 = require("@baruk/shared");
|
|
7
|
+
const manual_js_1 = require("./manual.js");
|
|
8
|
+
const asaas_js_1 = require("./asaas.js");
|
|
9
|
+
const REGISTRY = new Map([
|
|
10
|
+
['manual', () => new manual_js_1.ManualProvider()],
|
|
11
|
+
['asaas', (config) => new asaas_js_1.AsaasProvider(config)],
|
|
12
|
+
// Futuro (mesma assinatura): stripe, efi, iugu, mercadopago, inter, openfinance.
|
|
13
|
+
]);
|
|
14
|
+
function registerBillingProvider(key, factory) {
|
|
15
|
+
REGISTRY.set(key, factory);
|
|
16
|
+
}
|
|
17
|
+
function availableProviders() {
|
|
18
|
+
return [...REGISTRY.keys()];
|
|
19
|
+
}
|
|
20
|
+
function resolveBillingProvider(key, config = {}) {
|
|
21
|
+
const factory = REGISTRY.get(key);
|
|
22
|
+
if (!factory) {
|
|
23
|
+
throw new shared_1.ValidationError(`Provider de billing desconhecido: "${key}". Disponíveis: ${availableProviders().join(', ')}.`);
|
|
24
|
+
}
|
|
25
|
+
return factory(config);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../src/billing/provider/registry.ts"],"names":[],"mappings":";;AAmBA,0DAEC;AAED,gDAEC;AAED,wDAQC;AAnCD,0CAAgD;AAEhD,2CAA6C;AAC7C,yCAA2C;AAU3C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAA0B;IAChD,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,0BAAc,EAAE,CAAC;IACtC,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,wBAAa,CAAC,MAAM,CAAC,CAAC;IAChD,iFAAiF;CAClF,CAAC,CAAC;AAEH,SAAgB,uBAAuB,CAAC,GAAW,EAAE,OAAwB;IAC3E,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,SAAgB,kBAAkB;IAChC,OAAO,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,SAAgB,sBAAsB,CAAC,GAAW,EAAE,SAAyB,EAAE;IAC7E,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,wBAAe,CACvB,sCAAsC,GAAG,mBAAmB,kBAAkB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC/F,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Provider Pattern do Billing Engine. O Core (e todo módulo de negócio) fala
|
|
4
|
+
* SOMENTE com esta interface — nunca com a API de um gateway específico. Adapters
|
|
5
|
+
* concretos (Asaas, Stripe, Efí, Iugu, Mercado Pago, Inter, Open Finance) vivem
|
|
6
|
+
* em arquivos-irmãos e são resolvidos pelo `registry`. Trocar de gateway = trocar
|
|
7
|
+
* o adapter registrado, sem tocar em nenhuma regra de negócio.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/billing/provider/types.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receivable.js","sourceRoot":"","sources":["../../../src/billing/receivable.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createFeeAgreement = createFeeAgreement;
|
|
4
|
+
exports.listFeeAgreements = listFeeAgreements;
|
|
5
|
+
exports.setFeeStatus = setFeeStatus;
|
|
6
|
+
exports.createCharge = createCharge;
|
|
7
|
+
exports.listCharges = listCharges;
|
|
8
|
+
exports.getCharge = getCharge;
|
|
9
|
+
exports.markChargePaid = markChargePaid;
|
|
10
|
+
exports.markChargePaidByExternal = markChargePaidByExternal;
|
|
11
|
+
exports.setChargeStatus = setChargeStatus;
|
|
12
|
+
exports.billingSummary = billingSummary;
|
|
13
|
+
exports.listOpenCharges = listOpenCharges;
|
|
14
|
+
const shared_1 = require("@baruk/shared");
|
|
15
|
+
function mapFee(r) {
|
|
16
|
+
return {
|
|
17
|
+
id: r.id,
|
|
18
|
+
clientId: r.client_id,
|
|
19
|
+
description: r.description,
|
|
20
|
+
amount: Number(r.amount),
|
|
21
|
+
periodicity: r.periodicity,
|
|
22
|
+
dueDay: r.due_day,
|
|
23
|
+
billingMethod: r.billing_method,
|
|
24
|
+
discount: Number(r.discount),
|
|
25
|
+
finePercent: Number(r.fine_percent),
|
|
26
|
+
interestPercent: Number(r.interest_percent),
|
|
27
|
+
status: r.status,
|
|
28
|
+
startsOn: r.starts_on ? r.starts_on.toISOString().slice(0, 10) : null,
|
|
29
|
+
endsOn: r.ends_on ? r.ends_on.toISOString().slice(0, 10) : null,
|
|
30
|
+
createdAt: r.created_at.toISOString(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const FEE_COLS = `
|
|
34
|
+
id, client_id, description, amount, periodicity, due_day, billing_method,
|
|
35
|
+
discount, fine_percent, interest_percent, status, starts_on, ends_on, created_at
|
|
36
|
+
`;
|
|
37
|
+
async function createFeeAgreement(tx, input) {
|
|
38
|
+
const rows = await tx `
|
|
39
|
+
INSERT INTO fee_agreement (
|
|
40
|
+
id, tenant_id, client_id, description, amount, periodicity, due_day,
|
|
41
|
+
billing_method, discount, fine_percent, interest_percent, starts_on, created_by
|
|
42
|
+
) VALUES (
|
|
43
|
+
${(0, shared_1.uuidv7)()}, current_setting('app.current_tenant')::uuid, ${input.clientId},
|
|
44
|
+
${input.description ?? 'Honorários'}, ${input.amount}, ${input.periodicity ?? 'monthly'},
|
|
45
|
+
${input.dueDay ?? null}, ${input.billingMethod ?? 'pix'}, ${input.discount ?? 0},
|
|
46
|
+
${input.finePercent ?? 0}, ${input.interestPercent ?? 0}, ${input.startsOn ?? null}, ${input.createdBy ?? null}
|
|
47
|
+
)
|
|
48
|
+
RETURNING ${tx.unsafe(FEE_COLS)}
|
|
49
|
+
`;
|
|
50
|
+
return mapFee(rows[0]);
|
|
51
|
+
}
|
|
52
|
+
async function listFeeAgreements(tx, clientId) {
|
|
53
|
+
const rows = await tx `
|
|
54
|
+
SELECT ${tx.unsafe(FEE_COLS)} FROM fee_agreement
|
|
55
|
+
WHERE deleted_at IS NULL
|
|
56
|
+
AND (${clientId ?? null}::uuid IS NULL OR client_id = ${clientId ?? null})
|
|
57
|
+
ORDER BY created_at DESC
|
|
58
|
+
`;
|
|
59
|
+
return rows.map(mapFee);
|
|
60
|
+
}
|
|
61
|
+
async function setFeeStatus(tx, id, status) {
|
|
62
|
+
const rows = await tx `
|
|
63
|
+
UPDATE fee_agreement SET status = ${status}, updated_at = now(), version = version + 1
|
|
64
|
+
WHERE id = ${id} AND deleted_at IS NULL RETURNING id
|
|
65
|
+
`;
|
|
66
|
+
return rows.count;
|
|
67
|
+
}
|
|
68
|
+
function mapCharge(r) {
|
|
69
|
+
return {
|
|
70
|
+
id: r.id,
|
|
71
|
+
clientId: r.client_id,
|
|
72
|
+
feeAgreementId: r.fee_agreement_id,
|
|
73
|
+
provider: r.provider,
|
|
74
|
+
externalId: r.external_id,
|
|
75
|
+
method: r.method,
|
|
76
|
+
amount: Number(r.amount),
|
|
77
|
+
status: r.status,
|
|
78
|
+
description: r.description,
|
|
79
|
+
dueDate: r.due_date ? r.due_date.toISOString().slice(0, 10) : null,
|
|
80
|
+
paidAt: r.paid_at ? r.paid_at.toISOString() : null,
|
|
81
|
+
metadata: r.metadata ?? {},
|
|
82
|
+
createdAt: r.created_at.toISOString(),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const CHARGE_COLS = `
|
|
86
|
+
id, client_id, fee_agreement_id, provider, external_id, method, amount,
|
|
87
|
+
status, description, due_date, paid_at, metadata, created_at
|
|
88
|
+
`;
|
|
89
|
+
async function createCharge(tx, input) {
|
|
90
|
+
const rows = await tx `
|
|
91
|
+
INSERT INTO charge (
|
|
92
|
+
id, tenant_id, client_id, fee_agreement_id, provider, external_id, method,
|
|
93
|
+
amount, status, description, due_date, metadata, created_by
|
|
94
|
+
) VALUES (
|
|
95
|
+
${(0, shared_1.uuidv7)()}, current_setting('app.current_tenant')::uuid, ${input.clientId},
|
|
96
|
+
${input.feeAgreementId ?? null}, ${input.provider ?? 'manual'}, ${input.externalId ?? null},
|
|
97
|
+
${input.method ?? 'pix'}, ${input.amount}, ${input.status ?? 'pending'},
|
|
98
|
+
${input.description ?? null}, ${input.dueDate ?? null},
|
|
99
|
+
${tx.json((input.metadata ?? {}))}, ${input.createdBy ?? null}
|
|
100
|
+
)
|
|
101
|
+
RETURNING ${tx.unsafe(CHARGE_COLS)}
|
|
102
|
+
`;
|
|
103
|
+
return mapCharge(rows[0]);
|
|
104
|
+
}
|
|
105
|
+
async function listCharges(tx, filter = {}) {
|
|
106
|
+
const limit = Math.min(filter.limit ?? 50, 200);
|
|
107
|
+
const offset = filter.offset ?? 0;
|
|
108
|
+
const rows = await tx `
|
|
109
|
+
SELECT ${tx.unsafe(CHARGE_COLS)}, count(*) OVER() AS total
|
|
110
|
+
FROM charge
|
|
111
|
+
WHERE deleted_at IS NULL
|
|
112
|
+
AND (${filter.clientId ?? null}::uuid IS NULL OR client_id = ${filter.clientId ?? null})
|
|
113
|
+
AND (${filter.status ?? null}::text IS NULL OR status = ${filter.status ?? null})
|
|
114
|
+
ORDER BY created_at DESC
|
|
115
|
+
LIMIT ${limit} OFFSET ${offset}
|
|
116
|
+
`;
|
|
117
|
+
const total = rows[0] ? Number(rows[0].total) : 0;
|
|
118
|
+
return { items: rows.map(mapCharge), total };
|
|
119
|
+
}
|
|
120
|
+
async function getCharge(tx, id) {
|
|
121
|
+
const rows = await tx `
|
|
122
|
+
SELECT ${tx.unsafe(CHARGE_COLS)} FROM charge WHERE id = ${id} AND deleted_at IS NULL
|
|
123
|
+
`;
|
|
124
|
+
if (!rows[0])
|
|
125
|
+
throw new shared_1.NotFoundError('Cobrança não encontrada');
|
|
126
|
+
return mapCharge(rows[0]);
|
|
127
|
+
}
|
|
128
|
+
async function markChargePaid(tx, id, paidAt) {
|
|
129
|
+
const rows = await tx `
|
|
130
|
+
UPDATE charge SET status = 'paid', paid_at = COALESCE(${paidAt ?? null}::timestamptz, now()),
|
|
131
|
+
updated_at = now(), version = version + 1
|
|
132
|
+
WHERE id = ${id} AND deleted_at IS NULL AND status <> 'paid' RETURNING id
|
|
133
|
+
`;
|
|
134
|
+
return rows.count;
|
|
135
|
+
}
|
|
136
|
+
/** Reconciliação por webhook: encontra a cobrança pelo (provider, external_id) e marca paga. */
|
|
137
|
+
async function markChargePaidByExternal(tx, provider, externalId, paidAt) {
|
|
138
|
+
const rows = await tx `
|
|
139
|
+
UPDATE charge SET status = 'paid', paid_at = COALESCE(${paidAt ?? null}::timestamptz, now()),
|
|
140
|
+
updated_at = now(), version = version + 1
|
|
141
|
+
WHERE provider = ${provider} AND external_id = ${externalId}
|
|
142
|
+
AND deleted_at IS NULL AND status <> 'paid' RETURNING id
|
|
143
|
+
`;
|
|
144
|
+
return rows.count;
|
|
145
|
+
}
|
|
146
|
+
async function setChargeStatus(tx, id, status) {
|
|
147
|
+
const rows = await tx `
|
|
148
|
+
UPDATE charge SET status = ${status}, updated_at = now(), version = version + 1
|
|
149
|
+
WHERE id = ${id} AND deleted_at IS NULL RETURNING id
|
|
150
|
+
`;
|
|
151
|
+
return rows.count;
|
|
152
|
+
}
|
|
153
|
+
/** KPIs financeiros do dashboard: previsto, recebido e inadimplência. */
|
|
154
|
+
async function billingSummary(tx) {
|
|
155
|
+
const rows = await tx `
|
|
156
|
+
SELECT
|
|
157
|
+
COALESCE(sum(amount) FILTER (WHERE status IN ('pending','sent','overdue')), 0) AS expected,
|
|
158
|
+
COALESCE(sum(amount) FILTER (WHERE status = 'paid'), 0) AS received,
|
|
159
|
+
COALESCE(sum(amount) FILTER (WHERE status = 'overdue'), 0) AS overdue,
|
|
160
|
+
COALESCE(count(*) FILTER (WHERE status = 'overdue'), 0)::int AS overdue_count
|
|
161
|
+
FROM charge WHERE deleted_at IS NULL
|
|
162
|
+
`;
|
|
163
|
+
const r = rows[0];
|
|
164
|
+
return {
|
|
165
|
+
expected: Number(r.expected),
|
|
166
|
+
received: Number(r.received),
|
|
167
|
+
overdue: Number(r.overdue),
|
|
168
|
+
overdueCount: r.overdue_count,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/** Cobranças em aberto vencidas até `today` — usadas pela régua de inadimplência. */
|
|
172
|
+
async function listOpenCharges(tx) {
|
|
173
|
+
const rows = await tx `
|
|
174
|
+
SELECT ${tx.unsafe(CHARGE_COLS)} FROM charge
|
|
175
|
+
WHERE deleted_at IS NULL AND status IN ('pending','sent','overdue') AND due_date IS NOT NULL
|
|
176
|
+
ORDER BY due_date ASC
|
|
177
|
+
`;
|
|
178
|
+
return rows.map(mapCharge);
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/billing/repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createClient = createClient;
|
|
4
|
+
exports.listClients = listClients;
|
|
5
|
+
exports.getClient = getClient;
|
|
6
|
+
exports.renameClient = renameClient;
|
|
7
|
+
exports.listClientsPaged = listClientsPaged;
|
|
8
|
+
exports.updateClient = updateClient;
|
|
9
|
+
exports.softDeleteClient = softDeleteClient;
|
|
10
|
+
exports.findClientIdByDocument = findClientIdByDocument;
|
|
11
|
+
const shared_1 = require("@baruk/shared");
|
|
12
|
+
function mapRow(r) {
|
|
13
|
+
return {
|
|
14
|
+
id: r.id,
|
|
15
|
+
tenantId: r.tenant_id,
|
|
16
|
+
clientType: r.client_type,
|
|
17
|
+
displayName: r.display_name,
|
|
18
|
+
documentNumber: r.document_number,
|
|
19
|
+
status: r.status,
|
|
20
|
+
createdAt: r.created_at.toISOString(),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
async function createClient(tx, input) {
|
|
24
|
+
// tenant_id vem da GUC — nunca do input. A WITH CHECK da RLS recusa qualquer
|
|
25
|
+
// tentativa de gravar fora do tenant corrente.
|
|
26
|
+
const rows = await tx `
|
|
27
|
+
INSERT INTO client (id, tenant_id, client_type, display_name, document_number, created_by)
|
|
28
|
+
VALUES (
|
|
29
|
+
${(0, shared_1.uuidv7)()},
|
|
30
|
+
current_setting('app.current_tenant')::uuid,
|
|
31
|
+
${input.clientType ?? 'pj'},
|
|
32
|
+
${input.displayName},
|
|
33
|
+
${input.documentNumber ?? null},
|
|
34
|
+
${input.createdBy ?? null}
|
|
35
|
+
)
|
|
36
|
+
RETURNING id, tenant_id, client_type, display_name, document_number, status, created_at
|
|
37
|
+
`;
|
|
38
|
+
return mapRow(rows[0]);
|
|
39
|
+
}
|
|
40
|
+
async function listClients(tx) {
|
|
41
|
+
const rows = await tx `
|
|
42
|
+
SELECT id, tenant_id, client_type, display_name, document_number, status, created_at
|
|
43
|
+
FROM client
|
|
44
|
+
WHERE deleted_at IS NULL
|
|
45
|
+
ORDER BY created_at DESC
|
|
46
|
+
`;
|
|
47
|
+
return rows.map((r) => mapRow(r));
|
|
48
|
+
}
|
|
49
|
+
async function getClient(tx, id) {
|
|
50
|
+
const rows = await tx `
|
|
51
|
+
SELECT id, tenant_id, client_type, display_name, document_number, status, created_at
|
|
52
|
+
FROM client
|
|
53
|
+
WHERE id = ${id} AND deleted_at IS NULL
|
|
54
|
+
`;
|
|
55
|
+
if (!rows[0])
|
|
56
|
+
throw new shared_1.NotFoundError('Cliente não encontrado');
|
|
57
|
+
return mapRow(rows[0]);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Renomeia um cliente por id. Retorna a quantidade de linhas afetadas — sob RLS,
|
|
61
|
+
* uma tentativa cross-tenant afeta 0 linhas (o id "não existe" para este tenant).
|
|
62
|
+
*/
|
|
63
|
+
async function renameClient(tx, id, displayName) {
|
|
64
|
+
const rows = await tx `
|
|
65
|
+
UPDATE client
|
|
66
|
+
SET display_name = ${displayName}, updated_at = now(), version = version + 1
|
|
67
|
+
WHERE id = ${id} AND deleted_at IS NULL
|
|
68
|
+
RETURNING id
|
|
69
|
+
`;
|
|
70
|
+
return rows.count;
|
|
71
|
+
}
|
|
72
|
+
async function listClientsPaged(tx, filter = {}) {
|
|
73
|
+
const limit = Math.min(filter.limit ?? 20, 100);
|
|
74
|
+
const offset = filter.offset ?? 0;
|
|
75
|
+
const like = filter.search ? `%${filter.search}%` : null;
|
|
76
|
+
const rows = await tx `
|
|
77
|
+
SELECT id, tenant_id, client_type, display_name, document_number, status, created_at,
|
|
78
|
+
count(*) OVER() AS total
|
|
79
|
+
FROM client
|
|
80
|
+
WHERE deleted_at IS NULL
|
|
81
|
+
AND (${filter.status ?? null}::text IS NULL OR status = ${filter.status ?? null})
|
|
82
|
+
AND (${like}::text IS NULL OR display_name ILIKE ${like} OR document_number ILIKE ${like})
|
|
83
|
+
ORDER BY created_at DESC
|
|
84
|
+
LIMIT ${limit} OFFSET ${offset}
|
|
85
|
+
`;
|
|
86
|
+
const total = rows[0] ? Number(rows[0].total) : 0;
|
|
87
|
+
return { items: rows.map((r) => mapRow(r)), total };
|
|
88
|
+
}
|
|
89
|
+
async function updateClient(tx, id, input) {
|
|
90
|
+
// Casts explícitos: parâmetros NULL sem tipo quebram COALESCE ("could not
|
|
91
|
+
// determine data type of parameter") no PostgreSQL.
|
|
92
|
+
const rows = await tx `
|
|
93
|
+
UPDATE client SET
|
|
94
|
+
display_name = COALESCE(${input.displayName ?? null}::text, display_name),
|
|
95
|
+
legal_name = COALESCE(${input.legalName ?? null}::text, legal_name),
|
|
96
|
+
email = COALESCE(${input.email ?? null}::citext, email),
|
|
97
|
+
phone = COALESCE(${input.phone ?? null}::text, phone),
|
|
98
|
+
status = COALESCE(${input.status ?? null}::text, status),
|
|
99
|
+
updated_by = ${input.updatedBy ?? null}::uuid,
|
|
100
|
+
updated_at = now(),
|
|
101
|
+
version = version + 1
|
|
102
|
+
WHERE id = ${id} AND deleted_at IS NULL
|
|
103
|
+
RETURNING id
|
|
104
|
+
`;
|
|
105
|
+
return rows.count;
|
|
106
|
+
}
|
|
107
|
+
async function softDeleteClient(tx, id, deletedBy) {
|
|
108
|
+
const rows = await tx `
|
|
109
|
+
UPDATE client SET deleted_at = now(), deleted_by = ${deletedBy ?? null}
|
|
110
|
+
WHERE id = ${id} AND deleted_at IS NULL
|
|
111
|
+
RETURNING id
|
|
112
|
+
`;
|
|
113
|
+
return rows.count;
|
|
114
|
+
}
|
|
115
|
+
/** Busca por documento normalizado (dedup de importação). Retorna id ou null. */
|
|
116
|
+
async function findClientIdByDocument(tx, documentNumber) {
|
|
117
|
+
const rows = await tx `
|
|
118
|
+
SELECT id FROM client
|
|
119
|
+
WHERE document_number = ${documentNumber} AND deleted_at IS NULL LIMIT 1
|
|
120
|
+
`;
|
|
121
|
+
return rows[0]?.id ?? null;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/clients/repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateOffer = validateOffer;
|
|
4
|
+
exports.resolvePriceQuote = resolvePriceQuote;
|
|
5
|
+
/**
|
|
6
|
+
* Resolução pura do Commercial Catalog — sem DB, sem `Date.now()` interno (o
|
|
7
|
+
* instante e a `productLine` já resolvida do tenant são sempre injetados pelo
|
|
8
|
+
* consumidor). Espelha o papel de `reconcile.ts` no subscription-billing.
|
|
9
|
+
*/
|
|
10
|
+
function isEligible(eligibility, productLine) {
|
|
11
|
+
return !eligibility || eligibility.length === 0 || eligibility.includes(productLine);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Valida uma Offer contra o catálogo: elegibilidade de linha (plano/módulos),
|
|
15
|
+
* dependências reais de módulo (nunca artificiais — só o que o próprio
|
|
16
|
+
* `ModuleRecord.requiredModuleCodes` declarar), e que módulos de bundle
|
|
17
|
+
* referenciados existam entre os módulos da oferta.
|
|
18
|
+
*/
|
|
19
|
+
function validateOffer(input) {
|
|
20
|
+
const { offer, plan, modules, bundles, productLine } = input;
|
|
21
|
+
const errors = [];
|
|
22
|
+
const moduleByCode = new Map(modules.map((m) => [m.code, m]));
|
|
23
|
+
if (!isEligible(plan.productLineEligibility, productLine)) {
|
|
24
|
+
errors.push({ code: 'plan_not_eligible', message: `Plano "${plan.code}" não elegível para a linha "${productLine}".` });
|
|
25
|
+
}
|
|
26
|
+
if (!isEligible(offer.productLineEligibility, productLine)) {
|
|
27
|
+
errors.push({ code: 'offer_not_eligible', message: `Oferta "${offer.code}" não elegível para a linha "${productLine}".` });
|
|
28
|
+
}
|
|
29
|
+
for (const moduleCode of offer.moduleCodes) {
|
|
30
|
+
const mod = moduleByCode.get(moduleCode);
|
|
31
|
+
if (!mod) {
|
|
32
|
+
errors.push({ code: 'module_not_found', message: `Módulo "${moduleCode}" não existe no catálogo.` });
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (!mod.isActive) {
|
|
36
|
+
errors.push({ code: 'module_inactive', message: `Módulo "${moduleCode}" está inativo.` });
|
|
37
|
+
}
|
|
38
|
+
if (!isEligible(mod.productLineEligibility, productLine)) {
|
|
39
|
+
errors.push({ code: 'module_not_eligible', message: `Módulo "${moduleCode}" não elegível para a linha "${productLine}".` });
|
|
40
|
+
}
|
|
41
|
+
for (const req of mod.requiredModuleCodes) {
|
|
42
|
+
if (!offer.moduleCodes.includes(req)) {
|
|
43
|
+
errors.push({
|
|
44
|
+
code: 'module_dependency_missing',
|
|
45
|
+
message: `Módulo "${moduleCode}" requer "${req}", que não está na oferta.`,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const bundleCode of offer.bundleCodes) {
|
|
51
|
+
const bundle = bundles.find((b) => b.code === bundleCode);
|
|
52
|
+
if (!bundle) {
|
|
53
|
+
errors.push({ code: 'bundle_not_found', message: `Bundle "${bundleCode}" não existe no catálogo.` });
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
for (const moduleCode of bundle.moduleCodes) {
|
|
57
|
+
if (!offer.moduleCodes.includes(moduleCode)) {
|
|
58
|
+
errors.push({
|
|
59
|
+
code: 'bundle_module_missing',
|
|
60
|
+
message: `Bundle "${bundleCode}" exige o módulo "${moduleCode}", que não está na oferta.`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return errors;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Resolve o `PriceQuote` de uma Offer contra uma `CommercialPriceTable` vigente
|
|
69
|
+
* na data `now`. Não aplica cupom (isso é `coupon.ts`, sobre o quote resolvido).
|
|
70
|
+
* Precedência de escopo: maior `priority` primeiro; sem escopo casando, usa o
|
|
71
|
+
* item sem filtro de escopo (ALL implícito).
|
|
72
|
+
*/
|
|
73
|
+
function resolvePriceQuote(offer, table, now) {
|
|
74
|
+
if (table.code !== offer.priceTableCode) {
|
|
75
|
+
throw new Error(`Offer "${offer.code}" referencia a tabela "${offer.priceTableCode}", recebida "${table.code}".`);
|
|
76
|
+
}
|
|
77
|
+
if (table.status !== 'active') {
|
|
78
|
+
throw new Error(`Tabela "${table.code}" não está ativa (status="${table.status}").`);
|
|
79
|
+
}
|
|
80
|
+
if (now < table.effectiveFrom || (table.effectiveTo != null && now > table.effectiveTo)) {
|
|
81
|
+
throw new Error(`Tabela "${table.code}" fora de vigência em ${now}.`);
|
|
82
|
+
}
|
|
83
|
+
// Bundle NÃO é alvo precificável aqui (RFC §4.4: "não calcula, só declara a
|
|
84
|
+
// combinação e a intenção de desconto"). O desconto de bundle é resolvido
|
|
85
|
+
// pelo Pricing Engine (regra sobre os módulos já precificados), fora deste
|
|
86
|
+
// MVP — por isso `bundleCodes` não entra na lista de alvos obrigatórios.
|
|
87
|
+
const targets = [
|
|
88
|
+
{ targetType: 'PLAN', targetCode: offer.planCode },
|
|
89
|
+
...offer.moduleCodes.map((code) => ({ targetType: 'MODULE', targetCode: code })),
|
|
90
|
+
...offer.addonCodes.map((code) => ({ targetType: 'ADDON', targetCode: code })),
|
|
91
|
+
];
|
|
92
|
+
const items = targets.map(({ targetType, targetCode }) => {
|
|
93
|
+
const found = table.items.find((i) => i.targetType === targetType && i.targetCode === targetCode);
|
|
94
|
+
if (!found) {
|
|
95
|
+
throw new Error(`Sem preço para ${targetType}:${targetCode} na tabela "${table.code}" v${table.version}.`);
|
|
96
|
+
}
|
|
97
|
+
return { targetType, targetCode, amount: found.amount };
|
|
98
|
+
});
|
|
99
|
+
const total = items.reduce((sum, i) => sum + i.amount, 0);
|
|
100
|
+
return {
|
|
101
|
+
currency: table.currency,
|
|
102
|
+
items,
|
|
103
|
+
total,
|
|
104
|
+
priceTableCode: table.code,
|
|
105
|
+
priceTableVersion: table.version,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=catalog.js.map
|