@baruk/core 0.1.0 → 0.2.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 +53 -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 +27 -0
- package/dist/commercial-catalog/coupon.d.ts.map +1 -0
- package/dist/commercial-catalog/coupon.js +47 -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 +155 -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,198 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applySubscriptionEvent = applySubscriptionEvent;
|
|
4
|
+
exports.changePlan = changePlan;
|
|
5
|
+
exports.cancelSubscription = cancelSubscription;
|
|
6
|
+
exports.startTrial = startTrial;
|
|
7
|
+
const events_js_1 = require("./events.js");
|
|
8
|
+
function newSubscriptionId(tenantId) {
|
|
9
|
+
return `sub_${tenantId}`;
|
|
10
|
+
}
|
|
11
|
+
function itemsFor(planKey) {
|
|
12
|
+
return [{ planKey, quantity: 1 }];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Guard defensivo (Design Review pos-implementacao, achado pre-Golden-Project): v0.1
|
|
16
|
+
* so suporta exatamente 1 item por assinatura, apesar de `items[]` ja ter a forma
|
|
17
|
+
* preparada para o futuro (RFC §12.5/§13, ver `types.ts`). Falha alto e cedo em vez
|
|
18
|
+
* de reconciliar silenciosamente um estado que a v0.1 nao sabe tratar corretamente —
|
|
19
|
+
* multi-item e decisao de v0.2, nao implementada aqui.
|
|
20
|
+
*/
|
|
21
|
+
function assertSingleItemCardinality(items) {
|
|
22
|
+
if (items.length > 1) {
|
|
23
|
+
throw new Error(`subscription-billing v0.1: suporta apenas 1 item por assinatura (recebeu ${items.length}). Multi-item e decisao de v0.2 (RFC §12.5).`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Normaliza data pura (`YYYY-MM-DD`) ou datetime ISO completo para um `Date` comparavel.
|
|
28
|
+
* Existe porque `currentPeriodEnd` e sempre `YYYY-MM-DD` (ver `types.ts`) mas `now` pode
|
|
29
|
+
* chegar como datetime ISO completo dependendo do chamador — comparar as duas strings
|
|
30
|
+
* diretamente (`currentPeriodEnd >= now`) e uma comparacao lexicografica INCORRETA
|
|
31
|
+
* quando os formatos divergem (achado do Design Review pos-implementacao, pre-Golden-Project).
|
|
32
|
+
*/
|
|
33
|
+
function parseIso(iso) {
|
|
34
|
+
return /^\d{4}-\d{2}-\d{2}$/.test(iso) ? new Date(`${iso}T00:00:00Z`) : new Date(iso);
|
|
35
|
+
}
|
|
36
|
+
function addOneMonth(iso) {
|
|
37
|
+
const d = parseIso(iso);
|
|
38
|
+
d.setUTCMonth(d.getUTCMonth() + 1);
|
|
39
|
+
return d.toISOString().slice(0, 10);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Aplica um evento normalizado de webhook a uma Assinatura. Espelha as regras do
|
|
43
|
+
* dental (RFC §3/§9): (a) a Assinatura interna nunca e criada `canceled`/`past_due`
|
|
44
|
+
* do nada — so atualiza uma existente; (b) `received`/`confirmed` ativa/renova;
|
|
45
|
+
* (c) `planKey` desconhecido → nenhuma reconciliacao (preserva assinaturas de
|
|
46
|
+
* plano-default), sem erro.
|
|
47
|
+
*/
|
|
48
|
+
function applySubscriptionEvent(input) {
|
|
49
|
+
const { current, tenantId, planKey, event, now } = input;
|
|
50
|
+
if (current)
|
|
51
|
+
assertSingleItemCardinality(current.items);
|
|
52
|
+
const baseSequence = current?.sequence ?? 0;
|
|
53
|
+
const domainEvents = [];
|
|
54
|
+
const causationEventId = event.externalEventId;
|
|
55
|
+
function emit(type, data, subscriptionId) {
|
|
56
|
+
const ev = (0, events_js_1.createDomainEvent)({
|
|
57
|
+
type,
|
|
58
|
+
subscriptionId,
|
|
59
|
+
tenantId,
|
|
60
|
+
previousSequence: baseSequence + domainEvents.length,
|
|
61
|
+
occurredAt: now,
|
|
62
|
+
causationEventId,
|
|
63
|
+
data,
|
|
64
|
+
});
|
|
65
|
+
domainEvents.push(ev);
|
|
66
|
+
return ev;
|
|
67
|
+
}
|
|
68
|
+
if (event.kind === 'invoice' && event.invoice) {
|
|
69
|
+
const inv = event.invoice;
|
|
70
|
+
if (inv.status === 'received' || inv.status === 'confirmed') {
|
|
71
|
+
if (!planKey) {
|
|
72
|
+
// Plano desconhecido: nao ha o que ativar com confianca — no-op (RFC §9, guarda do dental).
|
|
73
|
+
return { subscription: current ?? placeholderSubscription(tenantId, now), domainEvents: [] };
|
|
74
|
+
}
|
|
75
|
+
const subscriptionId = current?.subscriptionId ?? newSubscriptionId(tenantId);
|
|
76
|
+
const wasNewOrDormant = !current || current.status === 'canceled' || current.status === 'past_due';
|
|
77
|
+
const wasTrialing = current?.status === 'trialing';
|
|
78
|
+
const wasAlreadyActiveThisPeriod = current?.status === 'active' &&
|
|
79
|
+
current.currentPeriodEnd != null &&
|
|
80
|
+
parseIso(current.currentPeriodEnd).getTime() >= parseIso(now).getTime();
|
|
81
|
+
if (wasAlreadyActiveThisPeriod) {
|
|
82
|
+
// Idempotencia de dominio: efeito ja refletido no estado atual — no-op.
|
|
83
|
+
return { subscription: current, domainEvents: [] };
|
|
84
|
+
}
|
|
85
|
+
const next = {
|
|
86
|
+
subscriptionId,
|
|
87
|
+
tenantId,
|
|
88
|
+
items: itemsFor(planKey),
|
|
89
|
+
status: 'active',
|
|
90
|
+
currentPeriodEnd: addOneMonth(now),
|
|
91
|
+
trialEndsAt: current?.trialEndsAt ?? null,
|
|
92
|
+
sequence: baseSequence,
|
|
93
|
+
canceledAt: null,
|
|
94
|
+
};
|
|
95
|
+
if (wasNewOrDormant || wasTrialing) {
|
|
96
|
+
emit('subscription.activated', { planKey, invoiceExternalId: inv.externalId }, subscriptionId);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
emit('subscription.renewed', { planKey, invoiceExternalId: inv.externalId }, subscriptionId);
|
|
100
|
+
}
|
|
101
|
+
emit('invoice.paid', { invoiceExternalId: inv.externalId, value: inv.value }, subscriptionId);
|
|
102
|
+
return { subscription: withSequence(next, baseSequence + domainEvents.length), domainEvents };
|
|
103
|
+
}
|
|
104
|
+
if (inv.status === 'overdue') {
|
|
105
|
+
if (!current || current.status === 'canceled')
|
|
106
|
+
return { subscription: current ?? placeholderSubscription(tenantId, now), domainEvents: [] };
|
|
107
|
+
if (current.status === 'past_due')
|
|
108
|
+
return { subscription: current, domainEvents: [] }; // ja refletido — no-op
|
|
109
|
+
const next = { ...current, status: 'past_due' };
|
|
110
|
+
emit('subscription.past_due', { invoiceExternalId: inv.externalId }, current.subscriptionId);
|
|
111
|
+
return { subscription: withSequence(next, baseSequence + domainEvents.length), domainEvents };
|
|
112
|
+
}
|
|
113
|
+
if (inv.status === 'refunded' || inv.status === 'canceled') {
|
|
114
|
+
if (!current || current.status === 'canceled')
|
|
115
|
+
return { subscription: current ?? placeholderSubscription(tenantId, now), domainEvents: [] };
|
|
116
|
+
const next = { ...current, status: 'canceled', canceledAt: now };
|
|
117
|
+
if (inv.status === 'refunded')
|
|
118
|
+
emit('invoice.refunded', { invoiceExternalId: inv.externalId }, current.subscriptionId);
|
|
119
|
+
emit('subscription.canceled', { reason: inv.status }, current.subscriptionId);
|
|
120
|
+
return { subscription: withSequence(next, baseSequence + domainEvents.length), domainEvents };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// 'pending'/'failed' ou evento nao-invoice: sem reconciliacao de estado nesta v0.1
|
|
124
|
+
// (taxonomia completa de payment_failed → dunning fica para v0.2, RFC §12).
|
|
125
|
+
return { subscription: current ?? placeholderSubscription(tenantId, now), domainEvents: [] };
|
|
126
|
+
}
|
|
127
|
+
function withSequence(sub, sequence) {
|
|
128
|
+
return { ...sub, sequence };
|
|
129
|
+
}
|
|
130
|
+
function placeholderSubscription(tenantId, now) {
|
|
131
|
+
return {
|
|
132
|
+
subscriptionId: newSubscriptionId(tenantId),
|
|
133
|
+
tenantId,
|
|
134
|
+
items: [],
|
|
135
|
+
status: 'canceled',
|
|
136
|
+
currentPeriodEnd: null,
|
|
137
|
+
trialEndsAt: null,
|
|
138
|
+
sequence: 0,
|
|
139
|
+
canceledAt: now,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/** Muda de plano uma assinatura ATIVA (upgrade/downgrade) — proração fica para v0.2 (RFC §12). */
|
|
143
|
+
function changePlan(current, newPlanKey, now) {
|
|
144
|
+
assertSingleItemCardinality(current.items);
|
|
145
|
+
const domainEvents = [
|
|
146
|
+
(0, events_js_1.createDomainEvent)({
|
|
147
|
+
type: 'subscription.plan_changed',
|
|
148
|
+
subscriptionId: current.subscriptionId,
|
|
149
|
+
tenantId: current.tenantId,
|
|
150
|
+
previousSequence: current.sequence,
|
|
151
|
+
occurredAt: now,
|
|
152
|
+
data: { fromPlanKey: current.items[0]?.planKey ?? null, toPlanKey: newPlanKey },
|
|
153
|
+
}),
|
|
154
|
+
];
|
|
155
|
+
const next = { ...current, items: itemsFor(newPlanKey), sequence: current.sequence + 1 };
|
|
156
|
+
return { subscription: next, domainEvents };
|
|
157
|
+
}
|
|
158
|
+
/** Cancela uma assinatura. Politica imediato-vs-fim-de-periodo fica para v0.2 (RFC §12) — v0.1 e imediato. */
|
|
159
|
+
function cancelSubscription(current, now) {
|
|
160
|
+
const domainEvents = [
|
|
161
|
+
(0, events_js_1.createDomainEvent)({
|
|
162
|
+
type: 'subscription.canceled',
|
|
163
|
+
subscriptionId: current.subscriptionId,
|
|
164
|
+
tenantId: current.tenantId,
|
|
165
|
+
previousSequence: current.sequence,
|
|
166
|
+
occurredAt: now,
|
|
167
|
+
data: { reason: 'requested' },
|
|
168
|
+
}),
|
|
169
|
+
];
|
|
170
|
+
const next = { ...current, status: 'canceled', canceledAt: now, sequence: current.sequence + 1 };
|
|
171
|
+
return { subscription: next, domainEvents };
|
|
172
|
+
}
|
|
173
|
+
/** Inicia um trial (RFC §6/§8) — assinatura nova, sem cobranca ainda. */
|
|
174
|
+
function startTrial(tenantId, planKey, trialEndsAt, now) {
|
|
175
|
+
const subscriptionId = newSubscriptionId(tenantId);
|
|
176
|
+
const domainEvents = [
|
|
177
|
+
(0, events_js_1.createDomainEvent)({
|
|
178
|
+
type: 'subscription.trial_started',
|
|
179
|
+
subscriptionId,
|
|
180
|
+
tenantId,
|
|
181
|
+
previousSequence: 0,
|
|
182
|
+
occurredAt: now,
|
|
183
|
+
data: { planKey, trialEndsAt },
|
|
184
|
+
}),
|
|
185
|
+
];
|
|
186
|
+
const subscription = {
|
|
187
|
+
subscriptionId,
|
|
188
|
+
tenantId,
|
|
189
|
+
items: itemsFor(planKey),
|
|
190
|
+
status: 'trialing',
|
|
191
|
+
currentPeriodEnd: null,
|
|
192
|
+
trialEndsAt,
|
|
193
|
+
sequence: 1,
|
|
194
|
+
canceledAt: null,
|
|
195
|
+
};
|
|
196
|
+
return { subscription, domainEvents };
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=reconcile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../../src/subscription-billing/reconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureSaasPlanCatalog = ensureSaasPlanCatalog;
|
|
4
|
+
exports.listPublicPlans = listPublicPlans;
|
|
5
|
+
exports.getPlan = getPlan;
|
|
6
|
+
exports.withOperatorContext = withOperatorContext;
|
|
7
|
+
exports.lockTenantBilling = lockTenantBilling;
|
|
8
|
+
exports.getSubscription = getSubscription;
|
|
9
|
+
exports.getSubscriptionByTenant = getSubscriptionByTenant;
|
|
10
|
+
exports.upsertSubscription = upsertSubscription;
|
|
11
|
+
exports.setSubscriptionProviderRefs = setSubscriptionProviderRefs;
|
|
12
|
+
exports.appendDomainEvents = appendDomainEvents;
|
|
13
|
+
exports.listBillingEvents = listBillingEvents;
|
|
14
|
+
exports.upsertInvoice = upsertInvoice;
|
|
15
|
+
exports.listInvoices = listInvoices;
|
|
16
|
+
exports.insertWebhookEvent = insertWebhookEvent;
|
|
17
|
+
exports.markWebhookEvent = markWebhookEvent;
|
|
18
|
+
exports.listExecutedDunningSteps = listExecutedDunningSteps;
|
|
19
|
+
exports.recordDunningStep = recordDunningStep;
|
|
20
|
+
exports.listAllSubscriptions = listAllSubscriptions;
|
|
21
|
+
exports.backofficeSummary = backofficeSummary;
|
|
22
|
+
exports.listSubscriptionsForCron = listSubscriptionsForCron;
|
|
23
|
+
exports.listFailedWebhookEvents = listFailedWebhookEvents;
|
|
24
|
+
const shared_1 = require("@baruk/shared");
|
|
25
|
+
const plans_js_1 = require("./plans.js");
|
|
26
|
+
function parseJsonb(value, fallback) {
|
|
27
|
+
if (value == null)
|
|
28
|
+
return fallback;
|
|
29
|
+
if (typeof value === 'string') {
|
|
30
|
+
try {
|
|
31
|
+
return JSON.parse(value);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return fallback;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
function mapPlan(r) {
|
|
40
|
+
return {
|
|
41
|
+
productKey: r.product_key ?? plans_js_1.DEFAULT_PRODUCT_KEY,
|
|
42
|
+
key: r.key,
|
|
43
|
+
name: r.name,
|
|
44
|
+
description: r.description ?? null,
|
|
45
|
+
amountCents: Number(r.amount_cents),
|
|
46
|
+
currency: r.currency,
|
|
47
|
+
periodicity: r.periodicity,
|
|
48
|
+
trialDays: Number(r.trial_days),
|
|
49
|
+
modules: parseJsonb(r.modules, []),
|
|
50
|
+
limits: parseJsonb(r.limits, {}),
|
|
51
|
+
isPublic: Boolean(r.is_public),
|
|
52
|
+
isActive: Boolean(r.is_active),
|
|
53
|
+
sortOrder: Number(r.sort_order),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** Materializa o catálogo de planos (seed idempotente — atualiza os campos comerciais). */
|
|
57
|
+
async function ensureSaasPlanCatalog(db, plans) {
|
|
58
|
+
for (const p of plans) {
|
|
59
|
+
await db `
|
|
60
|
+
INSERT INTO saas_plan (id, product_key, key, name, description, amount_cents, periodicity, trial_days,
|
|
61
|
+
modules, limits, is_public, is_active, sort_order)
|
|
62
|
+
VALUES (${(0, shared_1.uuidv7)()}, ${p.productKey ?? plans_js_1.DEFAULT_PRODUCT_KEY}, ${p.key}, ${p.name}, ${p.description}, ${p.amountCents}, ${p.periodicity},
|
|
63
|
+
${p.trialDays}, ${JSON.stringify(p.modules)}::jsonb, ${JSON.stringify(p.limits)}::jsonb,
|
|
64
|
+
${p.isPublic}, ${p.isActive}, ${p.sortOrder})
|
|
65
|
+
ON CONFLICT (product_key, key) DO UPDATE SET
|
|
66
|
+
name = EXCLUDED.name, description = EXCLUDED.description,
|
|
67
|
+
amount_cents = EXCLUDED.amount_cents, periodicity = EXCLUDED.periodicity,
|
|
68
|
+
trial_days = EXCLUDED.trial_days, modules = EXCLUDED.modules, limits = EXCLUDED.limits,
|
|
69
|
+
is_public = EXCLUDED.is_public, is_active = EXCLUDED.is_active,
|
|
70
|
+
sort_order = EXCLUDED.sort_order, updated_at = now()
|
|
71
|
+
`;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Planos públicos de UM produto. O filtro é obrigatório por construção (com
|
|
76
|
+
* default) para que nenhuma superfície comercial liste, por descuido, o
|
|
77
|
+
* catálogo de outro produto do ecossistema.
|
|
78
|
+
*/
|
|
79
|
+
async function listPublicPlans(db, productKey = plans_js_1.DEFAULT_PRODUCT_KEY) {
|
|
80
|
+
const rows = await db `
|
|
81
|
+
SELECT * FROM saas_plan
|
|
82
|
+
WHERE is_public = true AND is_active = true AND product_key = ${productKey}
|
|
83
|
+
ORDER BY sort_order
|
|
84
|
+
`;
|
|
85
|
+
return rows.map(mapPlan);
|
|
86
|
+
}
|
|
87
|
+
async function getPlan(db, key, productKey = plans_js_1.DEFAULT_PRODUCT_KEY) {
|
|
88
|
+
const rows = await db `
|
|
89
|
+
SELECT * FROM saas_plan WHERE key = ${key} AND product_key = ${productKey}
|
|
90
|
+
`;
|
|
91
|
+
return rows[0] ? mapPlan(rows[0]) : null;
|
|
92
|
+
}
|
|
93
|
+
// ── Contexto de operadora (backoffice / cron) ─────────────────────────────────
|
|
94
|
+
/**
|
|
95
|
+
* Executa `fn` em transação com a GUC `app.platform_operator` setada — habilita
|
|
96
|
+
* as policies `*_operator` (0020) para leitura/escrita cross-tenant SEM abrir mão
|
|
97
|
+
* da RLS FORCE. Uso EXCLUSIVO: rotas de backoffice (após verificação de operador)
|
|
98
|
+
* e o cron de billing. Nunca exposto a request de tenant.
|
|
99
|
+
*/
|
|
100
|
+
async function withOperatorContext(db, fn) {
|
|
101
|
+
const result = await db.begin(async (tx) => {
|
|
102
|
+
await tx `select set_config('app.platform_operator', 'true', true)`;
|
|
103
|
+
return fn(tx);
|
|
104
|
+
});
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Serializa escritores de billing do MESMO tenant (webhook × webhook, webhook ×
|
|
109
|
+
* cron, gestão × webhook) via advisory lock transacional — elimina lost update
|
|
110
|
+
* de `sequence`/status sem lock global. Chamar como PRIMEIRA instrução da tx.
|
|
111
|
+
*/
|
|
112
|
+
async function lockTenantBilling(tx, tenantId) {
|
|
113
|
+
await tx `SELECT pg_advisory_xact_lock(hashtext('saas_billing:' || ${tenantId}))`;
|
|
114
|
+
}
|
|
115
|
+
/** Coluna `date` → 'YYYY-MM-DD' (o driver pode devolver Date OU string). */
|
|
116
|
+
function isoDate(value) {
|
|
117
|
+
if (value == null)
|
|
118
|
+
return null;
|
|
119
|
+
if (value instanceof Date)
|
|
120
|
+
return value.toISOString().slice(0, 10);
|
|
121
|
+
return String(value).slice(0, 10);
|
|
122
|
+
}
|
|
123
|
+
function mapSubscription(r) {
|
|
124
|
+
const tenantId = r.tenant_id;
|
|
125
|
+
return {
|
|
126
|
+
rowId: r.id,
|
|
127
|
+
subscriptionId: `sub_${tenantId}`,
|
|
128
|
+
tenantId,
|
|
129
|
+
productKey: r.product_key ?? plans_js_1.DEFAULT_PRODUCT_KEY,
|
|
130
|
+
planKey: r.plan_key,
|
|
131
|
+
items: [{ planKey: r.plan_key, quantity: 1 }],
|
|
132
|
+
status: r.status,
|
|
133
|
+
currentPeriodEnd: isoDate(r.current_period_end),
|
|
134
|
+
trialEndsAt: isoDate(r.trial_ends_at),
|
|
135
|
+
sequence: Number(r.sequence),
|
|
136
|
+
canceledAt: r.canceled_at ? new Date(r.canceled_at).toISOString() : null,
|
|
137
|
+
provider: r.provider ?? null,
|
|
138
|
+
providerCustomerId: r.provider_customer_id ?? null,
|
|
139
|
+
providerSubscriptionId: r.provider_subscription_id ?? null,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Assinatura do tenant do contexto atual PARA UM PRODUTO (RLS decide a
|
|
144
|
+
* visibilidade). Desde a migração 0022 a unicidade é `(tenant_id, product_key)`
|
|
145
|
+
* — filtrar por produto é obrigatório, senão um tenant com dois produtos leria
|
|
146
|
+
* a assinatura errada (a primeira que o Postgres devolvesse).
|
|
147
|
+
*/
|
|
148
|
+
async function getSubscription(tx, productKey = plans_js_1.DEFAULT_PRODUCT_KEY) {
|
|
149
|
+
const rows = await tx `
|
|
150
|
+
SELECT * FROM saas_subscription
|
|
151
|
+
WHERE tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid
|
|
152
|
+
AND product_key = ${productKey}
|
|
153
|
+
`;
|
|
154
|
+
return rows[0] ? mapSubscription(rows[0]) : null;
|
|
155
|
+
}
|
|
156
|
+
async function getSubscriptionByTenant(tx, tenantId, productKey = plans_js_1.DEFAULT_PRODUCT_KEY) {
|
|
157
|
+
const rows = await tx `
|
|
158
|
+
SELECT * FROM saas_subscription
|
|
159
|
+
WHERE tenant_id = ${tenantId} AND product_key = ${productKey}
|
|
160
|
+
`;
|
|
161
|
+
return rows[0] ? mapSubscription(rows[0]) : null;
|
|
162
|
+
}
|
|
163
|
+
/** Grava o `next` devolvido pelo domínio puro (upsert pela invariante 1-por-tenant-e-produto). */
|
|
164
|
+
async function upsertSubscription(tx, input) {
|
|
165
|
+
const s = input.subscription;
|
|
166
|
+
const rows = await tx `
|
|
167
|
+
INSERT INTO saas_subscription
|
|
168
|
+
(id, tenant_id, product_key, plan_key, status, current_period_end, trial_ends_at, canceled_at, sequence,
|
|
169
|
+
provider, provider_customer_id, provider_subscription_id)
|
|
170
|
+
VALUES
|
|
171
|
+
(${(0, shared_1.uuidv7)()}, ${input.tenantId}, ${input.productKey ?? plans_js_1.DEFAULT_PRODUCT_KEY}, ${input.planKey}, ${s.status}, ${s.currentPeriodEnd},
|
|
172
|
+
${s.trialEndsAt}, ${s.canceledAt}, ${s.sequence}, ${input.provider ?? null},
|
|
173
|
+
${input.providerCustomerId ?? null}, ${input.providerSubscriptionId ?? null})
|
|
174
|
+
ON CONFLICT (tenant_id, product_key) DO UPDATE SET
|
|
175
|
+
plan_key = EXCLUDED.plan_key, status = EXCLUDED.status,
|
|
176
|
+
current_period_end = EXCLUDED.current_period_end, trial_ends_at = EXCLUDED.trial_ends_at,
|
|
177
|
+
canceled_at = EXCLUDED.canceled_at, sequence = EXCLUDED.sequence,
|
|
178
|
+
provider = COALESCE(EXCLUDED.provider, saas_subscription.provider),
|
|
179
|
+
provider_customer_id = COALESCE(EXCLUDED.provider_customer_id, saas_subscription.provider_customer_id),
|
|
180
|
+
provider_subscription_id = COALESCE(EXCLUDED.provider_subscription_id, saas_subscription.provider_subscription_id),
|
|
181
|
+
updated_at = now()
|
|
182
|
+
RETURNING *
|
|
183
|
+
`;
|
|
184
|
+
return mapSubscription(rows[0]);
|
|
185
|
+
}
|
|
186
|
+
/** Atualiza SOMENTE as referências de provider (checkout) — nunca o estado da assinatura. */
|
|
187
|
+
async function setSubscriptionProviderRefs(tx, tenantId, provider, providerCustomerId) {
|
|
188
|
+
await tx `
|
|
189
|
+
UPDATE saas_subscription
|
|
190
|
+
SET provider = ${provider}, provider_customer_id = ${providerCustomerId}, updated_at = now()
|
|
191
|
+
WHERE tenant_id = ${tenantId}
|
|
192
|
+
`;
|
|
193
|
+
}
|
|
194
|
+
// ── Eventos de domínio ────────────────────────────────────────────────────────
|
|
195
|
+
async function appendDomainEvents(tx, subscriptionRowId, events) {
|
|
196
|
+
for (const ev of events) {
|
|
197
|
+
await tx `
|
|
198
|
+
INSERT INTO saas_billing_event (id, subscription_id, tenant_id, type, sequence, occurred_at, causation_event_id, data)
|
|
199
|
+
VALUES (${ev.eventId}, ${subscriptionRowId}, ${ev.tenantId}, ${ev.type}, ${ev.sequence},
|
|
200
|
+
${ev.occurredAt}, ${ev.causationEventId ?? null}, ${JSON.stringify(ev.data)}::jsonb)
|
|
201
|
+
ON CONFLICT (subscription_id, sequence) DO NOTHING
|
|
202
|
+
`;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
async function listBillingEvents(tx, limit = 50) {
|
|
206
|
+
const rows = await tx `
|
|
207
|
+
SELECT id, type, sequence, occurred_at, data FROM saas_billing_event
|
|
208
|
+
ORDER BY occurred_at DESC LIMIT ${limit}
|
|
209
|
+
`;
|
|
210
|
+
return rows.map((r) => ({
|
|
211
|
+
eventId: r.id,
|
|
212
|
+
type: r.type,
|
|
213
|
+
sequence: Number(r.sequence),
|
|
214
|
+
occurredAt: new Date(r.occurred_at).toISOString(),
|
|
215
|
+
data: r.data ?? {},
|
|
216
|
+
}));
|
|
217
|
+
}
|
|
218
|
+
/** Espelha (upsert) uma fatura do gateway — idempotente por (provider, external_id). */
|
|
219
|
+
async function upsertInvoice(tx, input) {
|
|
220
|
+
await tx `
|
|
221
|
+
INSERT INTO saas_invoice (id, tenant_id, subscription_id, provider, external_id, status,
|
|
222
|
+
amount_cents, due_date, paid_at, invoice_url, description)
|
|
223
|
+
VALUES (${(0, shared_1.uuidv7)()}, ${input.tenantId}, ${input.subscriptionRowId}, ${input.provider},
|
|
224
|
+
${input.externalId}, ${input.status}, ${input.amountCents}, ${input.dueDate ?? null},
|
|
225
|
+
${input.paidAt ?? null}, ${input.invoiceUrl ?? null}, ${input.description ?? null})
|
|
226
|
+
ON CONFLICT (provider, external_id) DO UPDATE SET
|
|
227
|
+
status = EXCLUDED.status, paid_at = EXCLUDED.paid_at,
|
|
228
|
+
invoice_url = COALESCE(EXCLUDED.invoice_url, saas_invoice.invoice_url),
|
|
229
|
+
updated_at = now()
|
|
230
|
+
`;
|
|
231
|
+
}
|
|
232
|
+
async function listInvoices(tx, limit = 50) {
|
|
233
|
+
const rows = await tx `
|
|
234
|
+
SELECT * FROM saas_invoice ORDER BY created_at DESC LIMIT ${limit}
|
|
235
|
+
`;
|
|
236
|
+
return rows.map((r) => ({
|
|
237
|
+
id: r.id,
|
|
238
|
+
provider: r.provider,
|
|
239
|
+
externalId: r.external_id,
|
|
240
|
+
status: r.status,
|
|
241
|
+
amountCents: Number(r.amount_cents),
|
|
242
|
+
dueDate: isoDate(r.due_date),
|
|
243
|
+
paidAt: r.paid_at ? new Date(r.paid_at).toISOString() : null,
|
|
244
|
+
invoiceUrl: r.invoice_url ?? null,
|
|
245
|
+
description: r.description ?? null,
|
|
246
|
+
createdAt: new Date(r.created_at).toISOString(),
|
|
247
|
+
}));
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Persiste o evento inbound com dedup por (provider, external_event_id).
|
|
251
|
+
* Retorna o id quando é a PRIMEIRA vez (deve processar) ou null quando duplicado
|
|
252
|
+
* (já recebido — responder 200 e ignorar, regra do 07-billing §6.1).
|
|
253
|
+
*/
|
|
254
|
+
async function insertWebhookEvent(db, input) {
|
|
255
|
+
// Conflito com evento anterior FAILED → reabre para reprocessar (o retry do
|
|
256
|
+
// gateway reenvia o MESMO event.id; sem isso o pagamento se perderia até o
|
|
257
|
+
// cron). processed/ignored continuam devolvendo null (dedup normal).
|
|
258
|
+
const rows = await db `
|
|
259
|
+
INSERT INTO saas_webhook_event (id, provider, external_event_id, event_type, payload)
|
|
260
|
+
VALUES (${(0, shared_1.uuidv7)()}, ${input.provider}, ${input.externalEventId}, ${input.eventType},
|
|
261
|
+
${JSON.stringify(input.payload ?? null)}::jsonb)
|
|
262
|
+
ON CONFLICT (provider, external_event_id) DO UPDATE
|
|
263
|
+
SET status = 'received', error = NULL
|
|
264
|
+
WHERE saas_webhook_event.status = 'failed'
|
|
265
|
+
RETURNING id
|
|
266
|
+
`;
|
|
267
|
+
return rows[0]?.id ?? null;
|
|
268
|
+
}
|
|
269
|
+
async function markWebhookEvent(db, id, status, tenantId, error) {
|
|
270
|
+
await db `
|
|
271
|
+
UPDATE saas_webhook_event
|
|
272
|
+
SET status = ${status}, tenant_id = ${tenantId ?? null}, error = ${error ?? null}, processed_at = now()
|
|
273
|
+
WHERE id = ${id}
|
|
274
|
+
`;
|
|
275
|
+
}
|
|
276
|
+
// ── Régua de inadimplência ───────────────────────────────────────────────────
|
|
277
|
+
async function listExecutedDunningSteps(tx, subscriptionRowId, referenceDate) {
|
|
278
|
+
const rows = await tx `
|
|
279
|
+
SELECT step_key FROM saas_dunning_event
|
|
280
|
+
WHERE subscription_id = ${subscriptionRowId} AND reference_date = ${referenceDate}
|
|
281
|
+
`;
|
|
282
|
+
return new Set(rows.map((r) => r.step_key));
|
|
283
|
+
}
|
|
284
|
+
async function recordDunningStep(tx, input) {
|
|
285
|
+
await tx `
|
|
286
|
+
INSERT INTO saas_dunning_event (id, tenant_id, subscription_id, step_key, reference_date)
|
|
287
|
+
VALUES (${(0, shared_1.uuidv7)()}, ${input.tenantId}, ${input.subscriptionRowId}, ${input.stepKey}, ${input.referenceDate})
|
|
288
|
+
ON CONFLICT (subscription_id, reference_date, step_key) DO NOTHING
|
|
289
|
+
`;
|
|
290
|
+
}
|
|
291
|
+
async function listAllSubscriptions(tx, filter = {}) {
|
|
292
|
+
const limit = filter.limit ?? 100;
|
|
293
|
+
const offset = filter.offset ?? 0;
|
|
294
|
+
const rows = filter.status
|
|
295
|
+
? await tx `
|
|
296
|
+
SELECT s.*, t.code AS tenant_code, t.display_name AS tenant_name, t.status AS tenant_status
|
|
297
|
+
FROM saas_subscription s JOIN tenant t ON t.id = s.tenant_id
|
|
298
|
+
WHERE s.status = ${filter.status}
|
|
299
|
+
ORDER BY s.updated_at DESC LIMIT ${limit} OFFSET ${offset}
|
|
300
|
+
`
|
|
301
|
+
: await tx `
|
|
302
|
+
SELECT s.*, t.code AS tenant_code, t.display_name AS tenant_name, t.status AS tenant_status
|
|
303
|
+
FROM saas_subscription s JOIN tenant t ON t.id = s.tenant_id
|
|
304
|
+
ORDER BY s.updated_at DESC LIMIT ${limit} OFFSET ${offset}
|
|
305
|
+
`;
|
|
306
|
+
return rows.map((r) => ({
|
|
307
|
+
...mapSubscription(r),
|
|
308
|
+
tenantCode: r.tenant_code,
|
|
309
|
+
tenantName: r.tenant_name,
|
|
310
|
+
tenantStatus: r.tenant_status,
|
|
311
|
+
}));
|
|
312
|
+
}
|
|
313
|
+
/** Resumo da operadora: contagem por status + MRR (planos mensais ativos; anuais /12). */
|
|
314
|
+
async function backofficeSummary(tx) {
|
|
315
|
+
const byStatusRows = await tx `
|
|
316
|
+
SELECT status, count(*)::int AS n FROM saas_subscription GROUP BY status
|
|
317
|
+
`;
|
|
318
|
+
const mrrRows = await tx `
|
|
319
|
+
SELECT COALESCE(ROUND(SUM(CASE p.periodicity
|
|
320
|
+
WHEN 'monthly' THEN p.amount_cents::numeric
|
|
321
|
+
WHEN 'quarterly' THEN p.amount_cents::numeric / 3
|
|
322
|
+
WHEN 'yearly' THEN p.amount_cents::numeric / 12
|
|
323
|
+
END)), 0)::bigint AS mrr
|
|
324
|
+
FROM saas_subscription s JOIN saas_plan p ON p.key = s.plan_key
|
|
325
|
+
WHERE s.status IN ('active', 'trialing')
|
|
326
|
+
`;
|
|
327
|
+
const byStatus = {};
|
|
328
|
+
let total = 0;
|
|
329
|
+
for (const r of byStatusRows) {
|
|
330
|
+
byStatus[r.status] = Number(r.n);
|
|
331
|
+
total += Number(r.n);
|
|
332
|
+
}
|
|
333
|
+
return { total, byStatus, mrrCents: Number(mrrRows[0]?.mrr ?? 0) };
|
|
334
|
+
}
|
|
335
|
+
/** Assinaturas que o cron precisa examinar (trial vencendo/vencido, período vencido, past_due). */
|
|
336
|
+
async function listSubscriptionsForCron(tx, today) {
|
|
337
|
+
const rows = await tx `
|
|
338
|
+
SELECT * FROM saas_subscription
|
|
339
|
+
WHERE (status = 'trialing' AND trial_ends_at IS NOT NULL AND trial_ends_at < ${today})
|
|
340
|
+
OR (status = 'active' AND current_period_end IS NOT NULL AND current_period_end < ${today})
|
|
341
|
+
OR status = 'past_due'
|
|
342
|
+
`;
|
|
343
|
+
return rows.map(mapSubscription);
|
|
344
|
+
}
|
|
345
|
+
/** Eventos `failed` recentes (7 dias) para reprocessamento pelo cron. */
|
|
346
|
+
async function listFailedWebhookEvents(db, limit = 25) {
|
|
347
|
+
const rows = await db `
|
|
348
|
+
SELECT id, provider, external_event_id, payload FROM saas_webhook_event
|
|
349
|
+
WHERE status = 'failed' AND created_at > now() - interval '7 days'
|
|
350
|
+
ORDER BY created_at ASC LIMIT ${limit}
|
|
351
|
+
`;
|
|
352
|
+
return rows.map((r) => ({
|
|
353
|
+
id: r.id,
|
|
354
|
+
provider: r.provider,
|
|
355
|
+
externalEventId: r.external_event_id,
|
|
356
|
+
payload: typeof r.payload === 'string' ? JSON.parse(r.payload) : r.payload,
|
|
357
|
+
}));
|
|
358
|
+
}
|
|
359
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/subscription-billing/repository.ts"],"names":[],"mappings":"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"}
|