@wopr-network/platform-core 0.1.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/biome.json +61 -0
- package/dist/admin/admin-audit-log-repository.d.ts +33 -0
- package/dist/admin/admin-audit-log-repository.js +102 -0
- package/dist/admin/audit-log.d.ts +49 -0
- package/dist/admin/audit-log.js +63 -0
- package/dist/admin/index.d.ts +6 -0
- package/dist/admin/index.js +3 -0
- package/dist/admin/role-store.d.ts +37 -0
- package/dist/admin/role-store.js +106 -0
- package/dist/auth/api-key-repository.d.ts +11 -0
- package/dist/auth/api-key-repository.js +33 -0
- package/dist/auth/api-key-repository.test.d.ts +1 -0
- package/dist/auth/api-key-repository.test.js +46 -0
- package/dist/auth/auth.test.d.ts +1 -0
- package/dist/auth/auth.test.js +140 -0
- package/dist/auth/better-auth.d.ts +42 -0
- package/dist/auth/better-auth.js +196 -0
- package/dist/auth/index.d.ts +186 -0
- package/dist/auth/index.js +422 -0
- package/dist/auth/login-history-repository.d.ts +14 -0
- package/dist/auth/login-history-repository.js +15 -0
- package/dist/auth/login-history-repository.test.d.ts +1 -0
- package/dist/auth/login-history-repository.test.js +47 -0
- package/dist/auth/middleware.d.ts +55 -0
- package/dist/auth/middleware.js +101 -0
- package/dist/auth/middleware.test.d.ts +1 -0
- package/dist/auth/middleware.test.js +213 -0
- package/dist/auth/scoped-tokens.test.d.ts +1 -0
- package/dist/auth/scoped-tokens.test.js +306 -0
- package/dist/auth/tenant-access.test.d.ts +1 -0
- package/dist/auth/tenant-access.test.js +62 -0
- package/dist/auth/user-creator.d.ts +9 -0
- package/dist/auth/user-creator.js +47 -0
- package/dist/auth/user-creator.test.d.ts +1 -0
- package/dist/auth/user-creator.test.js +78 -0
- package/dist/auth/user-role-repository.d.ts +31 -0
- package/dist/auth/user-role-repository.js +53 -0
- package/dist/auth/user-role-repository.test.d.ts +1 -0
- package/dist/auth/user-role-repository.test.js +122 -0
- package/dist/billing/drizzle-webhook-seen-repository.d.ts +10 -0
- package/dist/billing/drizzle-webhook-seen-repository.js +28 -0
- package/dist/billing/index.d.ts +7 -0
- package/dist/billing/index.js +7 -0
- package/dist/billing/payment-processor.d.ts +127 -0
- package/dist/billing/payment-processor.js +8 -0
- package/dist/billing/payment-processor.test.d.ts +1 -0
- package/dist/billing/payment-processor.test.js +71 -0
- package/dist/billing/payram/cents-credits-boundary.test.d.ts +1 -0
- package/dist/billing/payram/cents-credits-boundary.test.js +75 -0
- package/dist/billing/payram/charge-store.d.ts +41 -0
- package/dist/billing/payram/charge-store.js +72 -0
- package/dist/billing/payram/charge-store.test.d.ts +1 -0
- package/dist/billing/payram/charge-store.test.js +64 -0
- package/dist/billing/payram/checkout.d.ts +15 -0
- package/dist/billing/payram/checkout.js +24 -0
- package/dist/billing/payram/checkout.test.d.ts +1 -0
- package/dist/billing/payram/checkout.test.js +74 -0
- package/dist/billing/payram/client.d.ts +7 -0
- package/dist/billing/payram/client.js +15 -0
- package/dist/billing/payram/client.test.d.ts +1 -0
- package/dist/billing/payram/client.test.js +52 -0
- package/dist/billing/payram/index.d.ts +8 -0
- package/dist/billing/payram/index.js +4 -0
- package/dist/billing/payram/types.d.ts +40 -0
- package/dist/billing/payram/types.js +1 -0
- package/dist/billing/payram/webhook.d.ts +19 -0
- package/dist/billing/payram/webhook.js +67 -0
- package/dist/billing/payram/webhook.test.d.ts +7 -0
- package/dist/billing/payram/webhook.test.js +248 -0
- package/dist/billing/stripe/cents-credits-boundary.test.d.ts +1 -0
- package/dist/billing/stripe/cents-credits-boundary.test.js +62 -0
- package/dist/billing/stripe/checkout.d.ts +20 -0
- package/dist/billing/stripe/checkout.js +63 -0
- package/dist/billing/stripe/checkout.test.d.ts +1 -0
- package/dist/billing/stripe/checkout.test.js +148 -0
- package/dist/billing/stripe/client.d.ts +14 -0
- package/dist/billing/stripe/client.js +33 -0
- package/dist/billing/stripe/client.test.d.ts +1 -0
- package/dist/billing/stripe/client.test.js +58 -0
- package/dist/billing/stripe/credit-prices.d.ts +63 -0
- package/dist/billing/stripe/credit-prices.js +81 -0
- package/dist/billing/stripe/credit-prices.test.d.ts +1 -0
- package/dist/billing/stripe/credit-prices.test.js +87 -0
- package/dist/billing/stripe/index.d.ts +14 -0
- package/dist/billing/stripe/index.js +8 -0
- package/dist/billing/stripe/payment-methods-detach-all.test.d.ts +1 -0
- package/dist/billing/stripe/payment-methods-detach-all.test.js +40 -0
- package/dist/billing/stripe/payment-methods.d.ts +25 -0
- package/dist/billing/stripe/payment-methods.js +53 -0
- package/dist/billing/stripe/payment-methods.test.d.ts +1 -0
- package/dist/billing/stripe/payment-methods.test.js +122 -0
- package/dist/billing/stripe/portal.d.ts +10 -0
- package/dist/billing/stripe/portal.js +16 -0
- package/dist/billing/stripe/portal.test.d.ts +1 -0
- package/dist/billing/stripe/portal.test.js +48 -0
- package/dist/billing/stripe/setup-intent.d.ts +16 -0
- package/dist/billing/stripe/setup-intent.js +22 -0
- package/dist/billing/stripe/setup-intent.test.d.ts +1 -0
- package/dist/billing/stripe/setup-intent.test.js +58 -0
- package/dist/billing/stripe/stripe-payment-processor.d.ts +49 -0
- package/dist/billing/stripe/stripe-payment-processor.js +166 -0
- package/dist/billing/stripe/stripe-payment-processor.test.d.ts +1 -0
- package/dist/billing/stripe/stripe-payment-processor.test.js +413 -0
- package/dist/billing/stripe/tenant-store.d.ts +56 -0
- package/dist/billing/stripe/tenant-store.js +119 -0
- package/dist/billing/stripe/tenant-store.test.d.ts +1 -0
- package/dist/billing/stripe/tenant-store.test.js +97 -0
- package/dist/billing/stripe/types.d.ts +49 -0
- package/dist/billing/stripe/types.js +1 -0
- package/dist/billing/webhook-seen-repository.d.ts +14 -0
- package/dist/billing/webhook-seen-repository.js +13 -0
- package/dist/config/billing-env.test.d.ts +1 -0
- package/dist/config/billing-env.test.js +48 -0
- package/dist/config/index.d.ts +46 -0
- package/dist/config/index.js +38 -0
- package/dist/config/logger.d.ts +2 -0
- package/dist/config/logger.js +11 -0
- package/dist/config/provider-endpoints.d.ts +6 -0
- package/dist/config/provider-endpoints.js +12 -0
- package/dist/credits/auto-topup-charge.d.ts +27 -0
- package/dist/credits/auto-topup-charge.js +139 -0
- package/dist/credits/auto-topup-charge.test.d.ts +1 -0
- package/dist/credits/auto-topup-charge.test.js +242 -0
- package/dist/credits/auto-topup-event-log-repository.d.ts +16 -0
- package/dist/credits/auto-topup-event-log-repository.js +18 -0
- package/dist/credits/auto-topup-event-log-repository.test.d.ts +1 -0
- package/dist/credits/auto-topup-event-log-repository.test.js +83 -0
- package/dist/credits/auto-topup-schedule.d.ts +27 -0
- package/dist/credits/auto-topup-schedule.js +66 -0
- package/dist/credits/auto-topup-schedule.test.d.ts +1 -0
- package/dist/credits/auto-topup-schedule.test.js +145 -0
- package/dist/credits/auto-topup-settings-repository.d.ts +54 -0
- package/dist/credits/auto-topup-settings-repository.js +184 -0
- package/dist/credits/auto-topup-settings-repository.test.d.ts +1 -0
- package/dist/credits/auto-topup-settings-repository.test.js +104 -0
- package/dist/credits/auto-topup-usage.d.ts +22 -0
- package/dist/credits/auto-topup-usage.js +56 -0
- package/dist/credits/auto-topup-usage.test.d.ts +1 -0
- package/dist/credits/auto-topup-usage.test.js +181 -0
- package/dist/credits/credit-expiry-cron.d.ts +19 -0
- package/dist/credits/credit-expiry-cron.js +50 -0
- package/dist/credits/credit-expiry-cron.test.d.ts +1 -0
- package/dist/credits/credit-expiry-cron.test.js +67 -0
- package/dist/credits/credit-ledger-extra.test.d.ts +1 -0
- package/dist/credits/credit-ledger-extra.test.js +40 -0
- package/dist/credits/credit-ledger.bench.d.ts +1 -0
- package/dist/credits/credit-ledger.bench.js +33 -0
- package/dist/credits/credit-ledger.d.ts +130 -0
- package/dist/credits/credit-ledger.js +293 -0
- package/dist/credits/credit-ledger.test.d.ts +4 -0
- package/dist/credits/credit-ledger.test.js +203 -0
- package/dist/credits/credit-transaction-repository.d.ts +17 -0
- package/dist/credits/credit-transaction-repository.js +35 -0
- package/dist/credits/credit-transaction-repository.test.d.ts +1 -0
- package/dist/credits/credit-transaction-repository.test.js +232 -0
- package/dist/credits/credit.d.ts +75 -0
- package/dist/credits/credit.js +139 -0
- package/dist/credits/credit.test.d.ts +1 -0
- package/dist/credits/credit.test.js +196 -0
- package/dist/credits/dividend-cron.d.ts +29 -0
- package/dist/credits/dividend-cron.js +88 -0
- package/dist/credits/dividend-cron.test.d.ts +1 -0
- package/dist/credits/dividend-cron.test.js +128 -0
- package/dist/credits/dividend-repository.d.ts +29 -0
- package/dist/credits/dividend-repository.js +126 -0
- package/dist/credits/dividend-repository.test.d.ts +1 -0
- package/dist/credits/dividend-repository.test.js +176 -0
- package/dist/credits/index.d.ts +9 -0
- package/dist/credits/index.js +5 -0
- package/dist/credits/repository-types.d.ts +29 -0
- package/dist/credits/repository-types.js +1 -0
- package/dist/credits/signup-grant.d.ts +12 -0
- package/dist/credits/signup-grant.js +35 -0
- package/dist/credits/signup-grant.test.d.ts +1 -0
- package/dist/credits/signup-grant.test.js +51 -0
- package/dist/credits/tenant-customer-repository.d.ts +30 -0
- package/dist/credits/tenant-customer-repository.js +5 -0
- package/dist/db/auth-user-repository.d.ts +46 -0
- package/dist/db/auth-user-repository.js +90 -0
- package/dist/db/credit-column.d.ts +27 -0
- package/dist/db/credit-column.js +13 -0
- package/dist/db/index.d.ts +14 -0
- package/dist/db/index.js +8 -0
- package/dist/db/schema/account-deletion-requests.d.ts +203 -0
- package/dist/db/schema/account-deletion-requests.js +36 -0
- package/dist/db/schema/account-export-requests.d.ts +148 -0
- package/dist/db/schema/account-export-requests.js +19 -0
- package/dist/db/schema/admin-audit.d.ts +194 -0
- package/dist/db/schema/admin-audit.js +21 -0
- package/dist/db/schema/admin-users.d.ts +177 -0
- package/dist/db/schema/admin-users.js +23 -0
- package/dist/db/schema/affiliate-fraud.d.ts +160 -0
- package/dist/db/schema/affiliate-fraud.js +18 -0
- package/dist/db/schema/affiliate.d.ts +277 -0
- package/dist/db/schema/affiliate.js +32 -0
- package/dist/db/schema/coupon-codes.d.ts +143 -0
- package/dist/db/schema/coupon-codes.js +17 -0
- package/dist/db/schema/credit-auto-topup-settings.d.ts +232 -0
- package/dist/db/schema/credit-auto-topup-settings.js +27 -0
- package/dist/db/schema/credit-auto-topup.d.ts +130 -0
- package/dist/db/schema/credit-auto-topup.js +21 -0
- package/dist/db/schema/credits.d.ts +283 -0
- package/dist/db/schema/credits.js +38 -0
- package/dist/db/schema/dividend-distributions.d.ts +130 -0
- package/dist/db/schema/dividend-distributions.js +19 -0
- package/dist/db/schema/email-notifications.d.ts +99 -0
- package/dist/db/schema/email-notifications.js +21 -0
- package/dist/db/schema/index.d.ts +33 -0
- package/dist/db/schema/index.js +33 -0
- package/dist/db/schema/meter-events.d.ts +599 -0
- package/dist/db/schema/meter-events.js +55 -0
- package/dist/db/schema/notification-preferences.d.ts +165 -0
- package/dist/db/schema/notification-preferences.js +18 -0
- package/dist/db/schema/notification-queue.d.ts +236 -0
- package/dist/db/schema/notification-queue.js +40 -0
- package/dist/db/schema/org-memberships.d.ts +63 -0
- package/dist/db/schema/org-memberships.js +15 -0
- package/dist/db/schema/organization-members.d.ts +235 -0
- package/dist/db/schema/organization-members.js +27 -0
- package/dist/db/schema/payram.d.ts +164 -0
- package/dist/db/schema/payram.js +21 -0
- package/dist/db/schema/platform-api-keys.d.ts +143 -0
- package/dist/db/schema/platform-api-keys.js +20 -0
- package/dist/db/schema/promotion-redemptions.d.ts +143 -0
- package/dist/db/schema/promotion-redemptions.js +18 -0
- package/dist/db/schema/promotions.d.ts +445 -0
- package/dist/db/schema/promotions.js +48 -0
- package/dist/db/schema/provider-credentials.d.ts +201 -0
- package/dist/db/schema/provider-credentials.js +36 -0
- package/dist/db/schema/rate-limit-entries.d.ts +75 -0
- package/dist/db/schema/rate-limit-entries.js +7 -0
- package/dist/db/schema/secret-audit-log.d.ts +109 -0
- package/dist/db/schema/secret-audit-log.js +15 -0
- package/dist/db/schema/session-usage.d.ts +194 -0
- package/dist/db/schema/session-usage.js +19 -0
- package/dist/db/schema/spending-limits.d.ts +92 -0
- package/dist/db/schema/spending-limits.js +8 -0
- package/dist/db/schema/tenant-addons.d.ts +58 -0
- package/dist/db/schema/tenant-addons.js +9 -0
- package/dist/db/schema/tenant-api-keys.d.ts +131 -0
- package/dist/db/schema/tenant-api-keys.js +21 -0
- package/dist/db/schema/tenant-capability-settings.d.ts +79 -0
- package/dist/db/schema/tenant-capability-settings.js +12 -0
- package/dist/db/schema/tenant-customers.d.ts +303 -0
- package/dist/db/schema/tenant-customers.js +25 -0
- package/dist/db/schema/tenants.d.ts +126 -0
- package/dist/db/schema/tenants.js +18 -0
- package/dist/db/schema/user-roles.d.ts +98 -0
- package/dist/db/schema/user-roles.js +18 -0
- package/dist/db/schema/webhook-seen-events.d.ts +58 -0
- package/dist/db/schema/webhook-seen-events.js +9 -0
- package/dist/email/billing-emails.d.ts +51 -0
- package/dist/email/billing-emails.js +163 -0
- package/dist/email/billing-emails.test.d.ts +1 -0
- package/dist/email/billing-emails.test.js +162 -0
- package/dist/email/client.d.ts +51 -0
- package/dist/email/client.js +102 -0
- package/dist/email/client.test.d.ts +1 -0
- package/dist/email/client.test.js +120 -0
- package/dist/email/drizzle-billing-email-repository.d.ts +21 -0
- package/dist/email/drizzle-billing-email-repository.js +36 -0
- package/dist/email/drizzle-billing-email-repository.test.d.ts +1 -0
- package/dist/email/drizzle-billing-email-repository.test.js +42 -0
- package/dist/email/index.d.ts +33 -0
- package/dist/email/index.js +22 -0
- package/dist/email/notification-preferences-store.d.ts +12 -0
- package/dist/email/notification-preferences-store.js +82 -0
- package/dist/email/notification-preferences-store.test.d.ts +1 -0
- package/dist/email/notification-preferences-store.test.js +86 -0
- package/dist/email/notification-queue-store.d.ts +25 -0
- package/dist/email/notification-queue-store.js +97 -0
- package/dist/email/notification-queue-store.test.d.ts +1 -0
- package/dist/email/notification-queue-store.test.js +177 -0
- package/dist/email/notification-repository-types.d.ts +70 -0
- package/dist/email/notification-repository-types.js +6 -0
- package/dist/email/notification-service.d.ts +41 -0
- package/dist/email/notification-service.js +196 -0
- package/dist/email/notification-service.test.d.ts +1 -0
- package/dist/email/notification-service.test.js +160 -0
- package/dist/email/notification-templates.d.ts +18 -0
- package/dist/email/notification-templates.js +574 -0
- package/dist/email/notification-templates.test.d.ts +1 -0
- package/dist/email/notification-templates.test.js +238 -0
- package/dist/email/notification-worker.d.ts +24 -0
- package/dist/email/notification-worker.js +109 -0
- package/dist/email/notification-worker.test.d.ts +1 -0
- package/dist/email/notification-worker.test.js +153 -0
- package/dist/email/require-verified.d.ts +25 -0
- package/dist/email/require-verified.js +52 -0
- package/dist/email/require-verified.test.d.ts +1 -0
- package/dist/email/require-verified.test.js +62 -0
- package/dist/email/resend-adapter.d.ts +47 -0
- package/dist/email/resend-adapter.js +137 -0
- package/dist/email/resend-adapter.test.d.ts +1 -0
- package/dist/email/resend-adapter.test.js +190 -0
- package/dist/email/templates.d.ts +22 -0
- package/dist/email/templates.js +359 -0
- package/dist/email/templates.test.d.ts +1 -0
- package/dist/email/templates.test.js +170 -0
- package/dist/email/verification.d.ts +42 -0
- package/dist/email/verification.js +83 -0
- package/dist/email/verification.test.d.ts +1 -0
- package/dist/email/verification.test.js +141 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +23 -0
- package/dist/metering/aggregator.d.ts +54 -0
- package/dist/metering/aggregator.js +123 -0
- package/dist/metering/aggregator.test.d.ts +1 -0
- package/dist/metering/aggregator.test.js +179 -0
- package/dist/metering/dlq.d.ts +31 -0
- package/dist/metering/dlq.js +82 -0
- package/dist/metering/dlq.test.d.ts +1 -0
- package/dist/metering/dlq.test.js +117 -0
- package/dist/metering/drizzle-usage-summary-repository.d.ts +67 -0
- package/dist/metering/drizzle-usage-summary-repository.js +98 -0
- package/dist/metering/emitter.d.ts +66 -0
- package/dist/metering/emitter.js +185 -0
- package/dist/metering/emitter.test.d.ts +1 -0
- package/dist/metering/emitter.test.js +171 -0
- package/dist/metering/index.d.ts +11 -0
- package/dist/metering/index.js +5 -0
- package/dist/metering/load-test.bench.d.ts +1 -0
- package/dist/metering/load-test.bench.js +103 -0
- package/dist/metering/meter-event-repository.d.ts +33 -0
- package/dist/metering/meter-event-repository.js +58 -0
- package/dist/metering/meter-repositories.test.d.ts +1 -0
- package/dist/metering/meter-repositories.test.js +419 -0
- package/dist/metering/metering.test.d.ts +1 -0
- package/dist/metering/metering.test.js +1046 -0
- package/dist/metering/reconciliation-cron.d.ts +37 -0
- package/dist/metering/reconciliation-cron.js +85 -0
- package/dist/metering/reconciliation-cron.test.d.ts +1 -0
- package/dist/metering/reconciliation-cron.test.js +162 -0
- package/dist/metering/reconciliation-repository.d.ts +27 -0
- package/dist/metering/reconciliation-repository.js +43 -0
- package/dist/metering/reconciliation-repository.test.d.ts +1 -0
- package/dist/metering/reconciliation-repository.test.js +160 -0
- package/dist/metering/types.d.ts +88 -0
- package/dist/metering/types.js +1 -0
- package/dist/metering/wal.d.ts +49 -0
- package/dist/metering/wal.js +124 -0
- package/dist/metering/wal.test.d.ts +1 -0
- package/dist/metering/wal.test.js +175 -0
- package/dist/middleware/csrf.d.ts +24 -0
- package/dist/middleware/csrf.js +80 -0
- package/dist/middleware/csrf.test.d.ts +1 -0
- package/dist/middleware/csrf.test.js +152 -0
- package/dist/middleware/drizzle-rate-limit-repository.d.ts +9 -0
- package/dist/middleware/drizzle-rate-limit-repository.js +52 -0
- package/dist/middleware/drizzle-rate-limit-repository.test.d.ts +1 -0
- package/dist/middleware/drizzle-rate-limit-repository.test.js +74 -0
- package/dist/middleware/get-client-ip.d.ts +22 -0
- package/dist/middleware/get-client-ip.js +51 -0
- package/dist/middleware/get-client-ip.test.d.ts +1 -0
- package/dist/middleware/get-client-ip.test.js +40 -0
- package/dist/middleware/index.d.ts +5 -0
- package/dist/middleware/index.js +4 -0
- package/dist/middleware/rate-limit-repository.d.ts +19 -0
- package/dist/middleware/rate-limit-repository.js +1 -0
- package/dist/middleware/rate-limit.d.ts +57 -0
- package/dist/middleware/rate-limit.js +109 -0
- package/dist/middleware/rate-limit.test.d.ts +1 -0
- package/dist/middleware/rate-limit.test.js +247 -0
- package/dist/security/credential-vault/audit-repository.d.ts +27 -0
- package/dist/security/credential-vault/audit-repository.js +42 -0
- package/dist/security/credential-vault/audit-repository.test.d.ts +1 -0
- package/dist/security/credential-vault/audit-repository.test.js +78 -0
- package/dist/security/credential-vault/credential-repository.d.ts +94 -0
- package/dist/security/credential-vault/credential-repository.js +145 -0
- package/dist/security/credential-vault/credential-repository.test.d.ts +1 -0
- package/dist/security/credential-vault/credential-repository.test.js +206 -0
- package/dist/security/credential-vault/index.d.ts +12 -0
- package/dist/security/credential-vault/index.js +6 -0
- package/dist/security/credential-vault/key-rotation.d.ts +18 -0
- package/dist/security/credential-vault/key-rotation.js +52 -0
- package/dist/security/credential-vault/key-rotation.test.d.ts +1 -0
- package/dist/security/credential-vault/key-rotation.test.js +95 -0
- package/dist/security/credential-vault/migrate-plaintext.d.ts +15 -0
- package/dist/security/credential-vault/migrate-plaintext.js +80 -0
- package/dist/security/credential-vault/migrate-plaintext.test.d.ts +1 -0
- package/dist/security/credential-vault/migrate-plaintext.test.js +111 -0
- package/dist/security/credential-vault/migration-check.d.ts +15 -0
- package/dist/security/credential-vault/migration-check.js +71 -0
- package/dist/security/credential-vault/migration-check.test.d.ts +1 -0
- package/dist/security/credential-vault/migration-check.test.js +457 -0
- package/dist/security/credential-vault/store.d.ts +106 -0
- package/dist/security/credential-vault/store.js +181 -0
- package/dist/security/credential-vault/store.test.d.ts +1 -0
- package/dist/security/credential-vault/store.test.js +482 -0
- package/dist/security/encryption.d.ts +22 -0
- package/dist/security/encryption.js +53 -0
- package/dist/security/encryption.test.d.ts +1 -0
- package/dist/security/encryption.test.js +95 -0
- package/dist/security/host-validation.d.ts +11 -0
- package/dist/security/host-validation.js +108 -0
- package/dist/security/host-validation.test.d.ts +1 -0
- package/dist/security/host-validation.test.js +106 -0
- package/dist/security/index.d.ts +11 -0
- package/dist/security/index.js +11 -0
- package/dist/security/key-audit.d.ts +16 -0
- package/dist/security/key-audit.js +35 -0
- package/dist/security/key-audit.test.d.ts +1 -0
- package/dist/security/key-audit.test.js +50 -0
- package/dist/security/key-injection.d.ts +28 -0
- package/dist/security/key-injection.js +57 -0
- package/dist/security/key-injection.test.d.ts +1 -0
- package/dist/security/key-injection.test.js +97 -0
- package/dist/security/key-validation.d.ts +16 -0
- package/dist/security/key-validation.js +78 -0
- package/dist/security/key-validation.test.d.ts +1 -0
- package/dist/security/key-validation.test.js +87 -0
- package/dist/security/redirect-allowlist.d.ts +6 -0
- package/dist/security/redirect-allowlist.js +36 -0
- package/dist/security/redirect-allowlist.test.d.ts +1 -0
- package/dist/security/redirect-allowlist.test.js +55 -0
- package/dist/security/tenant-keys/capability-settings-store.d.ts +22 -0
- package/dist/security/tenant-keys/capability-settings-store.js +33 -0
- package/dist/security/tenant-keys/capability-settings-store.test.d.ts +1 -0
- package/dist/security/tenant-keys/capability-settings-store.test.js +77 -0
- package/dist/security/tenant-keys/index.d.ts +10 -0
- package/dist/security/tenant-keys/index.js +5 -0
- package/dist/security/tenant-keys/key-resolution-repository.d.ts +15 -0
- package/dist/security/tenant-keys/key-resolution-repository.js +18 -0
- package/dist/security/tenant-keys/key-resolution-repository.test.d.ts +1 -0
- package/dist/security/tenant-keys/key-resolution-repository.test.js +72 -0
- package/dist/security/tenant-keys/key-resolution.d.ts +39 -0
- package/dist/security/tenant-keys/key-resolution.js +59 -0
- package/dist/security/tenant-keys/key-resolution.test.d.ts +1 -0
- package/dist/security/tenant-keys/key-resolution.test.js +97 -0
- package/dist/security/tenant-keys/org-key-resolution.d.ts +30 -0
- package/dist/security/tenant-keys/org-key-resolution.js +50 -0
- package/dist/security/tenant-keys/org-key-resolution.test.d.ts +1 -0
- package/dist/security/tenant-keys/org-key-resolution.test.js +103 -0
- package/dist/security/tenant-keys/tenant-key-repository.d.ts +36 -0
- package/dist/security/tenant-keys/tenant-key-repository.js +96 -0
- package/dist/security/tenant-keys/tenant-key-repository.test.d.ts +1 -0
- package/dist/security/tenant-keys/tenant-key-repository.test.js +114 -0
- package/dist/security/types.d.ts +35 -0
- package/dist/security/types.js +15 -0
- package/dist/tenancy/drizzle-org-repository.d.ts +40 -0
- package/dist/tenancy/drizzle-org-repository.js +126 -0
- package/dist/tenancy/index.d.ts +6 -0
- package/dist/tenancy/index.js +3 -0
- package/dist/tenancy/org-member-repository.d.ts +57 -0
- package/dist/tenancy/org-member-repository.js +99 -0
- package/dist/tenancy/org-repository.test.d.ts +1 -0
- package/dist/tenancy/org-repository.test.js +143 -0
- package/dist/tenancy/org-service.d.ts +70 -0
- package/dist/tenancy/org-service.js +223 -0
- package/dist/tenancy/org-service.test.d.ts +1 -0
- package/dist/tenancy/org-service.test.js +550 -0
- package/dist/test/db.d.ts +33 -0
- package/dist/test/db.js +65 -0
- package/dist/trpc/index.d.ts +1 -0
- package/dist/trpc/index.js +1 -0
- package/dist/trpc/init.d.ts +49 -0
- package/dist/trpc/init.js +108 -0
- package/dist/trpc/init.test.d.ts +1 -0
- package/dist/trpc/init.test.js +154 -0
- package/drizzle/migrations/0000_slippery_mandrill.sql +559 -0
- package/drizzle/migrations/meta/0000_snapshot.json +4374 -0
- package/drizzle/migrations/meta/_journal.json +13 -0
- package/drizzle.config.ts +41 -0
- package/package.json +64 -0
- package/src/admin/admin-audit-log-repository.ts +135 -0
- package/src/admin/audit-log.ts +111 -0
- package/src/admin/index.ts +6 -0
- package/src/admin/role-store.ts +134 -0
- package/src/auth/api-key-repository.test.ts +63 -0
- package/src/auth/api-key-repository.ts +46 -0
- package/src/auth/auth.test.ts +166 -0
- package/src/auth/better-auth.ts +216 -0
- package/src/auth/index.ts +520 -0
- package/src/auth/login-history-repository.test.ts +54 -0
- package/src/auth/login-history-repository.ts +28 -0
- package/src/auth/middleware.test.ts +264 -0
- package/src/auth/middleware.ts +117 -0
- package/src/auth/scoped-tokens.test.ts +362 -0
- package/src/auth/tenant-access.test.ts +69 -0
- package/src/auth/user-creator.test.ts +98 -0
- package/src/auth/user-creator.ts +54 -0
- package/src/auth/user-role-repository.test.ts +149 -0
- package/src/auth/user-role-repository.ts +67 -0
- package/src/billing/drizzle-webhook-seen-repository.ts +34 -0
- package/src/billing/index.ts +22 -0
- package/src/billing/payment-processor.test.ts +93 -0
- package/src/billing/payment-processor.ts +150 -0
- package/src/billing/payram/cents-credits-boundary.test.ts +84 -0
- package/src/billing/payram/charge-store.test.ts +84 -0
- package/src/billing/payram/charge-store.ts +109 -0
- package/src/billing/payram/checkout.test.ts +99 -0
- package/src/billing/payram/checkout.ts +40 -0
- package/src/billing/payram/client.test.ts +62 -0
- package/src/billing/payram/client.ts +21 -0
- package/src/billing/payram/index.ts +14 -0
- package/src/billing/payram/types.ts +44 -0
- package/src/billing/payram/webhook.test.ts +318 -0
- package/src/billing/payram/webhook.ts +97 -0
- package/src/billing/stripe/cents-credits-boundary.test.ts +70 -0
- package/src/billing/stripe/checkout.test.ts +186 -0
- package/src/billing/stripe/checkout.ts +82 -0
- package/src/billing/stripe/client.test.ts +64 -0
- package/src/billing/stripe/client.ts +39 -0
- package/src/billing/stripe/credit-prices.test.ts +114 -0
- package/src/billing/stripe/credit-prices.ts +113 -0
- package/src/billing/stripe/index.ts +14 -0
- package/src/billing/stripe/payment-methods-detach-all.test.ts +53 -0
- package/src/billing/stripe/payment-methods.test.ts +157 -0
- package/src/billing/stripe/payment-methods.ts +76 -0
- package/src/billing/stripe/portal.test.ts +63 -0
- package/src/billing/stripe/portal.ts +25 -0
- package/src/billing/stripe/setup-intent.test.ts +78 -0
- package/src/billing/stripe/setup-intent.ts +34 -0
- package/src/billing/stripe/stripe-payment-processor.test.ts +517 -0
- package/src/billing/stripe/stripe-payment-processor.ts +255 -0
- package/src/billing/stripe/tenant-store.test.ts +124 -0
- package/src/billing/stripe/tenant-store.ts +151 -0
- package/src/billing/stripe/types.ts +53 -0
- package/src/billing/webhook-seen-repository.ts +24 -0
- package/src/config/billing-env.test.ts +54 -0
- package/src/config/index.ts +44 -0
- package/src/config/logger.ts +12 -0
- package/src/config/provider-endpoints.ts +14 -0
- package/src/credits/auto-topup-charge.test.ts +292 -0
- package/src/credits/auto-topup-charge.ts +171 -0
- package/src/credits/auto-topup-event-log-repository.test.ts +99 -0
- package/src/credits/auto-topup-event-log-repository.ts +30 -0
- package/src/credits/auto-topup-schedule.test.ts +179 -0
- package/src/credits/auto-topup-schedule.ts +93 -0
- package/src/credits/auto-topup-settings-repository.test.ts +123 -0
- package/src/credits/auto-topup-settings-repository.ts +245 -0
- package/src/credits/auto-topup-usage.test.ts +220 -0
- package/src/credits/auto-topup-usage.ts +68 -0
- package/src/credits/credit-expiry-cron.test.ts +125 -0
- package/src/credits/credit-expiry-cron.ts +76 -0
- package/src/credits/credit-ledger-extra.test.ts +57 -0
- package/src/credits/credit-ledger.bench.ts +56 -0
- package/src/credits/credit-ledger.test.ts +276 -0
- package/src/credits/credit-ledger.ts +450 -0
- package/src/credits/credit-transaction-repository.test.ts +274 -0
- package/src/credits/credit-transaction-repository.ts +62 -0
- package/src/credits/credit.test.ts +234 -0
- package/src/credits/credit.ts +160 -0
- package/src/credits/dividend-cron.test.ts +158 -0
- package/src/credits/dividend-cron.ts +127 -0
- package/src/credits/dividend-repository.test.ts +223 -0
- package/src/credits/dividend-repository.ts +182 -0
- package/src/credits/index.ts +25 -0
- package/src/credits/repository-types.ts +33 -0
- package/src/credits/signup-grant.test.ts +63 -0
- package/src/credits/signup-grant.ts +44 -0
- package/src/credits/tenant-customer-repository.ts +28 -0
- package/src/db/auth-user-repository.ts +124 -0
- package/src/db/credit-column.ts +17 -0
- package/src/db/index.ts +21 -0
- package/src/db/schema/account-deletion-requests.ts +41 -0
- package/src/db/schema/account-export-requests.ts +24 -0
- package/src/db/schema/admin-audit.ts +26 -0
- package/src/db/schema/admin-users.ts +31 -0
- package/src/db/schema/affiliate-fraud.ts +23 -0
- package/src/db/schema/affiliate.ts +38 -0
- package/src/db/schema/coupon-codes.ts +22 -0
- package/src/db/schema/credit-auto-topup-settings.ts +32 -0
- package/src/db/schema/credit-auto-topup.ts +26 -0
- package/src/db/schema/credits.ts +44 -0
- package/src/db/schema/dividend-distributions.ts +24 -0
- package/src/db/schema/email-notifications.ts +26 -0
- package/src/db/schema/index.ts +33 -0
- package/src/db/schema/meter-events.ts +70 -0
- package/src/db/schema/notification-preferences.ts +19 -0
- package/src/db/schema/notification-queue.ts +45 -0
- package/src/db/schema/org-memberships.ts +20 -0
- package/src/db/schema/organization-members.ts +37 -0
- package/src/db/schema/payram.ts +26 -0
- package/src/db/schema/platform-api-keys.ts +25 -0
- package/src/db/schema/promotion-redemptions.ts +23 -0
- package/src/db/schema/promotions.ts +57 -0
- package/src/db/schema/provider-credentials.ts +41 -0
- package/src/db/schema/rate-limit-entries.ts +12 -0
- package/src/db/schema/secret-audit-log.ts +20 -0
- package/src/db/schema/session-usage.ts +24 -0
- package/src/db/schema/spending-limits.ts +9 -0
- package/src/db/schema/tenant-addons.ts +14 -0
- package/src/db/schema/tenant-api-keys.ts +26 -0
- package/src/db/schema/tenant-capability-settings.ts +17 -0
- package/src/db/schema/tenant-customers.ts +35 -0
- package/src/db/schema/tenants.ts +23 -0
- package/src/db/schema/user-roles.ts +23 -0
- package/src/db/schema/webhook-seen-events.ts +14 -0
- package/src/email/billing-emails.test.ts +198 -0
- package/src/email/billing-emails.ts +211 -0
- package/src/email/client.test.ts +149 -0
- package/src/email/client.ts +137 -0
- package/src/email/drizzle-billing-email-repository.test.ts +52 -0
- package/src/email/drizzle-billing-email-repository.ts +59 -0
- package/src/email/index.ts +57 -0
- package/src/email/notification-preferences-store.test.ts +102 -0
- package/src/email/notification-preferences-store.ts +90 -0
- package/src/email/notification-queue-store.test.ts +215 -0
- package/src/email/notification-queue-store.ts +127 -0
- package/src/email/notification-repository-types.ts +101 -0
- package/src/email/notification-service.test.ts +178 -0
- package/src/email/notification-service.ts +265 -0
- package/src/email/notification-templates.test.ts +261 -0
- package/src/email/notification-templates.ts +727 -0
- package/src/email/notification-worker.test.ts +189 -0
- package/src/email/notification-worker.ts +133 -0
- package/src/email/require-verified.ts +65 -0
- package/src/email/resend-adapter.test.ts +253 -0
- package/src/email/resend-adapter.ts +157 -0
- package/src/email/templates.test.ts +217 -0
- package/src/email/templates.ts +469 -0
- package/src/email/verification.test.ts +185 -0
- package/src/email/verification.ts +110 -0
- package/src/index.ts +51 -0
- package/src/metering/aggregator.test.ts +239 -0
- package/src/metering/aggregator.ts +160 -0
- package/src/metering/dlq.test.ts +134 -0
- package/src/metering/dlq.ts +102 -0
- package/src/metering/drizzle-usage-summary-repository.ts +167 -0
- package/src/metering/emitter.test.ts +202 -0
- package/src/metering/emitter.ts +227 -0
- package/src/metering/index.ts +21 -0
- package/src/metering/load-test.bench.ts +130 -0
- package/src/metering/meter-event-repository.ts +87 -0
- package/src/metering/meter-repositories.test.ts +491 -0
- package/src/metering/metering.test.ts +1317 -0
- package/src/metering/reconciliation-cron.test.ts +202 -0
- package/src/metering/reconciliation-cron.ts +134 -0
- package/src/metering/reconciliation-repository.test.ts +196 -0
- package/src/metering/reconciliation-repository.ts +83 -0
- package/src/metering/types.ts +93 -0
- package/src/metering/wal.test.ts +222 -0
- package/src/metering/wal.ts +139 -0
- package/src/middleware/csrf.test.ts +178 -0
- package/src/middleware/csrf.ts +101 -0
- package/src/middleware/drizzle-rate-limit-repository.test.ts +97 -0
- package/src/middleware/drizzle-rate-limit-repository.ts +57 -0
- package/src/middleware/get-client-ip.test.ts +49 -0
- package/src/middleware/get-client-ip.ts +62 -0
- package/src/middleware/index.ts +12 -0
- package/src/middleware/rate-limit-repository.ts +22 -0
- package/src/middleware/rate-limit.test.ts +338 -0
- package/src/middleware/rate-limit.ts +169 -0
- package/src/security/credential-vault/audit-repository.test.ts +91 -0
- package/src/security/credential-vault/audit-repository.ts +64 -0
- package/src/security/credential-vault/credential-repository.test.ts +264 -0
- package/src/security/credential-vault/credential-repository.ts +233 -0
- package/src/security/credential-vault/index.ts +26 -0
- package/src/security/credential-vault/key-rotation.test.ts +139 -0
- package/src/security/credential-vault/key-rotation.ts +70 -0
- package/src/security/credential-vault/migrate-plaintext.test.ts +138 -0
- package/src/security/credential-vault/migrate-plaintext.ts +101 -0
- package/src/security/credential-vault/migration-check.test.ts +533 -0
- package/src/security/credential-vault/migration-check.ts +88 -0
- package/src/security/credential-vault/store.test.ts +569 -0
- package/src/security/credential-vault/store.ts +284 -0
- package/src/security/encryption.test.ts +114 -0
- package/src/security/encryption.ts +65 -0
- package/src/security/host-validation.test.ts +136 -0
- package/src/security/host-validation.ts +116 -0
- package/src/security/index.ts +59 -0
- package/src/security/key-audit.test.ts +57 -0
- package/src/security/key-audit.ts +45 -0
- package/src/security/key-injection.test.ts +131 -0
- package/src/security/key-injection.ts +71 -0
- package/src/security/key-validation.test.ts +111 -0
- package/src/security/key-validation.ts +84 -0
- package/src/security/redirect-allowlist.test.ts +70 -0
- package/src/security/redirect-allowlist.ts +35 -0
- package/src/security/tenant-keys/capability-settings-store.test.ts +98 -0
- package/src/security/tenant-keys/capability-settings-store.ts +53 -0
- package/src/security/tenant-keys/index.ts +10 -0
- package/src/security/tenant-keys/key-resolution-repository.test.ts +95 -0
- package/src/security/tenant-keys/key-resolution-repository.ts +31 -0
- package/src/security/tenant-keys/key-resolution.test.ts +173 -0
- package/src/security/tenant-keys/key-resolution.ts +87 -0
- package/src/security/tenant-keys/org-key-resolution.test.ts +217 -0
- package/src/security/tenant-keys/org-key-resolution.ts +76 -0
- package/src/security/tenant-keys/tenant-key-repository.test.ts +143 -0
- package/src/security/tenant-keys/tenant-key-repository.ts +130 -0
- package/src/security/types.ts +43 -0
- package/src/tenancy/drizzle-org-repository.ts +169 -0
- package/src/tenancy/index.ts +6 -0
- package/src/tenancy/org-member-repository.ts +159 -0
- package/src/tenancy/org-repository.test.ts +172 -0
- package/src/tenancy/org-service.test.ts +634 -0
- package/src/tenancy/org-service.ts +290 -0
- package/src/test/db.ts +97 -0
- package/src/trpc/index.ts +11 -0
- package/src/trpc/init.test.ts +196 -0
- package/src/trpc/init.ts +138 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { index, pgTable, text, uniqueIndex } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
export const affiliateFraudEvents = pgTable(
|
|
5
|
+
"affiliate_fraud_events",
|
|
6
|
+
{
|
|
7
|
+
id: text("id").primaryKey(),
|
|
8
|
+
referralId: text("referral_id").notNull(),
|
|
9
|
+
referrerTenantId: text("referrer_tenant_id").notNull(),
|
|
10
|
+
referredTenantId: text("referred_tenant_id").notNull(),
|
|
11
|
+
verdict: text("verdict").notNull(),
|
|
12
|
+
signals: text("signals").notNull(),
|
|
13
|
+
signalDetails: text("signal_details").notNull(),
|
|
14
|
+
phase: text("phase").notNull(),
|
|
15
|
+
createdAt: text("created_at").notNull().default(sql`(now())`),
|
|
16
|
+
},
|
|
17
|
+
(table) => [
|
|
18
|
+
index("idx_fraud_referrer").on(table.referrerTenantId),
|
|
19
|
+
index("idx_fraud_referred").on(table.referredTenantId),
|
|
20
|
+
index("idx_fraud_verdict").on(table.verdict),
|
|
21
|
+
uniqueIndex("uq_fraud_referral_phase").on(table.referralId, table.phase),
|
|
22
|
+
],
|
|
23
|
+
);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { boolean, index, integer, pgTable, text } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Affiliate codes — one per tenant, generated lazily on first request.
|
|
6
|
+
* Code is a short 6-char alphanumeric string used in referral links.
|
|
7
|
+
*/
|
|
8
|
+
export const affiliateCodes = pgTable("affiliate_codes", {
|
|
9
|
+
tenantId: text("tenant_id").primaryKey(),
|
|
10
|
+
code: text("code").notNull().unique(),
|
|
11
|
+
createdAt: text("created_at").notNull().default(sql`(now())`),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Affiliate referrals — tracks who referred whom and conversion status.
|
|
16
|
+
* referred_tenant_id is UNIQUE to enforce first-referrer-wins.
|
|
17
|
+
*/
|
|
18
|
+
export const affiliateReferrals = pgTable(
|
|
19
|
+
"affiliate_referrals",
|
|
20
|
+
{
|
|
21
|
+
id: text("id").primaryKey(),
|
|
22
|
+
referrerTenantId: text("referrer_tenant_id").notNull(),
|
|
23
|
+
referredTenantId: text("referred_tenant_id").notNull().unique(),
|
|
24
|
+
code: text("code").notNull(),
|
|
25
|
+
signedUpAt: text("signed_up_at").notNull().default(sql`(now())`),
|
|
26
|
+
firstPurchaseAt: text("first_purchase_at"),
|
|
27
|
+
matchAmountCents: integer("match_amount_cents"),
|
|
28
|
+
matchedAt: text("matched_at"),
|
|
29
|
+
payoutSuppressed: boolean("payout_suppressed").notNull().default(false),
|
|
30
|
+
suppressionReason: text("suppression_reason"),
|
|
31
|
+
signupIp: text("signup_ip"),
|
|
32
|
+
signupEmail: text("signup_email"),
|
|
33
|
+
},
|
|
34
|
+
(table) => [
|
|
35
|
+
index("idx_affiliate_ref_referrer").on(table.referrerTenantId),
|
|
36
|
+
index("idx_affiliate_ref_code").on(table.code),
|
|
37
|
+
],
|
|
38
|
+
);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { index, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
|
2
|
+
import { promotions } from "./promotions.js";
|
|
3
|
+
|
|
4
|
+
export const couponCodes = pgTable(
|
|
5
|
+
"coupon_codes",
|
|
6
|
+
{
|
|
7
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
8
|
+
promotionId: uuid("promotion_id")
|
|
9
|
+
.notNull()
|
|
10
|
+
.references(() => promotions.id),
|
|
11
|
+
code: text("code").notNull().unique(),
|
|
12
|
+
assignedTenantId: text("assigned_tenant_id"),
|
|
13
|
+
assignedEmail: text("assigned_email"),
|
|
14
|
+
redeemedAt: timestamp("redeemed_at", { withTimezone: true }),
|
|
15
|
+
redeemedByTenantId: text("redeemed_by_tenant_id"),
|
|
16
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
17
|
+
},
|
|
18
|
+
(t) => [
|
|
19
|
+
index("coupon_codes_promotion_idx").on(t.promotionId),
|
|
20
|
+
index("coupon_codes_assigned_tenant_idx").on(t.assignedTenantId),
|
|
21
|
+
],
|
|
22
|
+
);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { boolean, index, integer, pgTable, text } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Per-tenant auto-topup configuration.
|
|
6
|
+
* Two independent modes: usage-based (after spend) and schedule-based (cron).
|
|
7
|
+
*/
|
|
8
|
+
export const creditAutoTopupSettings = pgTable(
|
|
9
|
+
"credit_auto_topup_settings",
|
|
10
|
+
{
|
|
11
|
+
tenantId: text("tenant_id").primaryKey(),
|
|
12
|
+
// Usage-based trigger
|
|
13
|
+
usageEnabled: boolean("usage_enabled").notNull().default(false),
|
|
14
|
+
usageThresholdCents: integer("usage_threshold_cents").notNull().default(100),
|
|
15
|
+
usageTopupCents: integer("usage_topup_cents").notNull().default(500),
|
|
16
|
+
usageConsecutiveFailures: integer("usage_consecutive_failures").notNull().default(0),
|
|
17
|
+
usageChargeInFlight: boolean("usage_charge_in_flight").notNull().default(false),
|
|
18
|
+
// Schedule-based trigger
|
|
19
|
+
scheduleEnabled: boolean("schedule_enabled").notNull().default(false),
|
|
20
|
+
scheduleAmountCents: integer("schedule_amount_cents").notNull().default(500),
|
|
21
|
+
scheduleIntervalHours: integer("schedule_interval_hours").notNull().default(168),
|
|
22
|
+
scheduleNextAt: text("schedule_next_at"),
|
|
23
|
+
scheduleConsecutiveFailures: integer("schedule_consecutive_failures").notNull().default(0),
|
|
24
|
+
// Metadata
|
|
25
|
+
createdAt: text("created_at").notNull().default(sql`(now())`),
|
|
26
|
+
updatedAt: text("updated_at").notNull().default(sql`(now())`),
|
|
27
|
+
},
|
|
28
|
+
(table) => [
|
|
29
|
+
index("idx_auto_topup_settings_usage").on(table.usageEnabled),
|
|
30
|
+
index("idx_auto_topup_settings_schedule").on(table.scheduleEnabled, table.scheduleNextAt),
|
|
31
|
+
],
|
|
32
|
+
);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { index, integer, pgTable, text } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Records every auto-topup attempt — both successes and failures.
|
|
6
|
+
* Used by admin analytics to track auto-topup revenue and failure rates.
|
|
7
|
+
*/
|
|
8
|
+
export const creditAutoTopup = pgTable(
|
|
9
|
+
"credit_auto_topup",
|
|
10
|
+
{
|
|
11
|
+
id: text("id").primaryKey(),
|
|
12
|
+
tenantId: text("tenant_id").notNull(),
|
|
13
|
+
amountCents: integer("amount_cents").notNull(),
|
|
14
|
+
status: text("status").notNull(), // "success" | "failed"
|
|
15
|
+
failureReason: text("failure_reason"),
|
|
16
|
+
/** Stripe payment intent or charge ID, if applicable */
|
|
17
|
+
paymentReference: text("payment_reference"),
|
|
18
|
+
createdAt: text("created_at").notNull().default(sql`(now())`),
|
|
19
|
+
},
|
|
20
|
+
(table) => [
|
|
21
|
+
index("idx_auto_topup_tenant").on(table.tenantId),
|
|
22
|
+
index("idx_auto_topup_status").on(table.status),
|
|
23
|
+
index("idx_auto_topup_created").on(table.createdAt),
|
|
24
|
+
index("idx_auto_topup_tenant_created").on(table.tenantId, table.createdAt),
|
|
25
|
+
],
|
|
26
|
+
);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { index, pgTable, text } from "drizzle-orm/pg-core";
|
|
3
|
+
import { creditColumn } from "../credit-column.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Credit transaction ledger — every credit/debit is an immutable row.
|
|
7
|
+
* Positive amount = credit (money in), negative = debit (money out).
|
|
8
|
+
*/
|
|
9
|
+
export const creditTransactions = pgTable(
|
|
10
|
+
"credit_transactions",
|
|
11
|
+
{
|
|
12
|
+
id: text("id").primaryKey(),
|
|
13
|
+
tenantId: text("tenant_id").notNull(),
|
|
14
|
+
amount: creditColumn("amount_credits").notNull(),
|
|
15
|
+
balanceAfter: creditColumn("balance_after_credits").notNull(),
|
|
16
|
+
type: text("type").notNull(), // signup_grant | purchase | bounty | referral | promo | community_dividend | bot_runtime | adapter_usage | addon | refund | correction
|
|
17
|
+
description: text("description"),
|
|
18
|
+
referenceId: text("reference_id").unique(),
|
|
19
|
+
fundingSource: text("funding_source"), // "stripe" | "payram" | null (null = legacy/signup)
|
|
20
|
+
attributedUserId: text("attributed_user_id"), // nullable — null for system/bot charges
|
|
21
|
+
createdAt: text("created_at").notNull().default(sql`(now())`),
|
|
22
|
+
expiresAt: text("expires_at"), // nullable — null means never expires
|
|
23
|
+
stripeFingerprint: text("stripe_fingerprint"),
|
|
24
|
+
},
|
|
25
|
+
(table) => [
|
|
26
|
+
index("idx_credit_tx_tenant").on(table.tenantId),
|
|
27
|
+
index("idx_credit_tx_type").on(table.type),
|
|
28
|
+
index("idx_credit_tx_ref").on(table.referenceId),
|
|
29
|
+
index("idx_credit_tx_created").on(table.createdAt),
|
|
30
|
+
index("idx_credit_tx_tenant_created").on(table.tenantId, table.createdAt),
|
|
31
|
+
index("idx_credit_tx_expires").on(table.expiresAt),
|
|
32
|
+
index("idx_credit_tx_fingerprint").on(table.stripeFingerprint).where(sql`${table.stripeFingerprint} IS NOT NULL`),
|
|
33
|
+
],
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Denormalized credit balance per tenant — updated atomically alongside
|
|
38
|
+
* every credit_transactions insert via a Drizzle transaction.
|
|
39
|
+
*/
|
|
40
|
+
export const creditBalances = pgTable("credit_balances", {
|
|
41
|
+
tenantId: text("tenant_id").primaryKey(),
|
|
42
|
+
balance: creditColumn("balance_credits").notNull().default(sql`0`),
|
|
43
|
+
lastUpdated: text("last_updated").notNull().default(sql`(now())`),
|
|
44
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { index, integer, pgTable, text } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Dividend distribution ledger — one row per tenant per day when a dividend is paid.
|
|
6
|
+
* Written by the nightly dividend cron; read by the dividend API endpoints.
|
|
7
|
+
*/
|
|
8
|
+
export const dividendDistributions = pgTable(
|
|
9
|
+
"dividend_distributions",
|
|
10
|
+
{
|
|
11
|
+
id: text("id").primaryKey(),
|
|
12
|
+
tenantId: text("tenant_id").notNull(),
|
|
13
|
+
date: text("date").notNull(),
|
|
14
|
+
amountCents: integer("amount_cents").notNull(),
|
|
15
|
+
poolCents: integer("pool_cents").notNull(),
|
|
16
|
+
activeUsers: integer("active_users").notNull(),
|
|
17
|
+
createdAt: text("created_at").notNull().default(sql`(now())`),
|
|
18
|
+
},
|
|
19
|
+
(table) => [
|
|
20
|
+
index("idx_dividend_dist_tenant").on(table.tenantId),
|
|
21
|
+
index("idx_dividend_dist_date").on(table.date),
|
|
22
|
+
index("idx_dividend_dist_tenant_date").on(table.tenantId, table.date),
|
|
23
|
+
],
|
|
24
|
+
);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { index, pgTable, text, unique } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Email notification deduplication table.
|
|
6
|
+
*
|
|
7
|
+
* Tracks which billing emails have been sent to prevent duplicates.
|
|
8
|
+
* Unique constraint on (tenantId, emailType, sentDate) ensures max 1
|
|
9
|
+
* email per type per day per tenant.
|
|
10
|
+
*/
|
|
11
|
+
export const emailNotifications = pgTable(
|
|
12
|
+
"email_notifications",
|
|
13
|
+
{
|
|
14
|
+
id: text("id").primaryKey(),
|
|
15
|
+
tenantId: text("tenant_id").notNull(),
|
|
16
|
+
emailType: text("email_type").notNull(),
|
|
17
|
+
sentAt: text("sent_at").notNull().default(sql`(now())`),
|
|
18
|
+
/** Date string (YYYY-MM-DD) extracted from sentAt for dedup constraint. */
|
|
19
|
+
sentDate: text("sent_date").notNull(),
|
|
20
|
+
},
|
|
21
|
+
(table) => [
|
|
22
|
+
unique("uniq_email_per_day").on(table.tenantId, table.emailType, table.sentDate),
|
|
23
|
+
index("idx_email_notif_tenant").on(table.tenantId),
|
|
24
|
+
index("idx_email_notif_type").on(table.emailType),
|
|
25
|
+
],
|
|
26
|
+
);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export * from "./account-deletion-requests.js";
|
|
2
|
+
export * from "./account-export-requests.js";
|
|
3
|
+
export * from "./admin-audit.js";
|
|
4
|
+
export * from "./admin-users.js";
|
|
5
|
+
export * from "./affiliate.js";
|
|
6
|
+
export * from "./affiliate-fraud.js";
|
|
7
|
+
export * from "./coupon-codes.js";
|
|
8
|
+
export * from "./credits.js";
|
|
9
|
+
export * from "./credit-auto-topup.js";
|
|
10
|
+
export * from "./credit-auto-topup-settings.js";
|
|
11
|
+
export * from "./dividend-distributions.js";
|
|
12
|
+
export * from "./email-notifications.js";
|
|
13
|
+
export * from "./meter-events.js";
|
|
14
|
+
export * from "./notification-preferences.js";
|
|
15
|
+
export * from "./notification-queue.js";
|
|
16
|
+
export * from "./org-memberships.js";
|
|
17
|
+
export * from "./organization-members.js";
|
|
18
|
+
export * from "./payram.js";
|
|
19
|
+
export * from "./platform-api-keys.js";
|
|
20
|
+
export * from "./promotion-redemptions.js";
|
|
21
|
+
export * from "./promotions.js";
|
|
22
|
+
export * from "./provider-credentials.js";
|
|
23
|
+
export * from "./rate-limit-entries.js";
|
|
24
|
+
export * from "./secret-audit-log.js";
|
|
25
|
+
export * from "./session-usage.js";
|
|
26
|
+
export * from "./spending-limits.js";
|
|
27
|
+
export * from "./tenant-addons.js";
|
|
28
|
+
export * from "./tenant-api-keys.js";
|
|
29
|
+
export * from "./tenant-capability-settings.js";
|
|
30
|
+
export * from "./tenant-customers.js";
|
|
31
|
+
export * from "./tenants.js";
|
|
32
|
+
export * from "./user-roles.js";
|
|
33
|
+
export * from "./webhook-seen-events.js";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { bigint, index, integer, pgTable, real, text, uniqueIndex } from "drizzle-orm/pg-core";
|
|
2
|
+
|
|
3
|
+
export const meterEvents = pgTable(
|
|
4
|
+
"meter_events",
|
|
5
|
+
{
|
|
6
|
+
id: text("id").primaryKey(),
|
|
7
|
+
tenant: text("tenant").notNull(),
|
|
8
|
+
cost: bigint("cost", { mode: "number" }).notNull(),
|
|
9
|
+
charge: bigint("charge", { mode: "number" }).notNull(),
|
|
10
|
+
capability: text("capability").notNull(),
|
|
11
|
+
provider: text("provider").notNull(),
|
|
12
|
+
timestamp: bigint("timestamp", { mode: "number" }).notNull(),
|
|
13
|
+
sessionId: text("session_id"),
|
|
14
|
+
duration: integer("duration"),
|
|
15
|
+
usageUnits: real("usage_units"),
|
|
16
|
+
usageUnitType: text("usage_unit_type"),
|
|
17
|
+
tier: text("tier"),
|
|
18
|
+
metadata: text("metadata"),
|
|
19
|
+
},
|
|
20
|
+
(table) => [
|
|
21
|
+
index("idx_meter_tenant").on(table.tenant),
|
|
22
|
+
index("idx_meter_timestamp").on(table.timestamp),
|
|
23
|
+
index("idx_meter_capability").on(table.capability),
|
|
24
|
+
index("idx_meter_session").on(table.sessionId),
|
|
25
|
+
index("idx_meter_tenant_timestamp").on(table.tenant, table.timestamp),
|
|
26
|
+
index("idx_meter_tier").on(table.tier),
|
|
27
|
+
],
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export const usageSummaries = pgTable(
|
|
31
|
+
"usage_summaries",
|
|
32
|
+
{
|
|
33
|
+
id: text("id").primaryKey(),
|
|
34
|
+
tenant: text("tenant").notNull(),
|
|
35
|
+
capability: text("capability").notNull(),
|
|
36
|
+
provider: text("provider").notNull(),
|
|
37
|
+
eventCount: integer("event_count").notNull(),
|
|
38
|
+
totalCost: bigint("total_cost", { mode: "number" }).notNull(),
|
|
39
|
+
totalCharge: bigint("total_charge", { mode: "number" }).notNull(),
|
|
40
|
+
totalDuration: integer("total_duration").notNull().default(0),
|
|
41
|
+
windowStart: bigint("window_start", { mode: "number" }).notNull(),
|
|
42
|
+
windowEnd: bigint("window_end", { mode: "number" }).notNull(),
|
|
43
|
+
},
|
|
44
|
+
(table) => [
|
|
45
|
+
index("idx_summary_tenant").on(table.tenant, table.windowStart),
|
|
46
|
+
index("idx_summary_window").on(table.windowStart, table.windowEnd),
|
|
47
|
+
],
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
export const billingPeriodSummaries = pgTable(
|
|
51
|
+
"billing_period_summaries",
|
|
52
|
+
{
|
|
53
|
+
id: text("id").primaryKey(),
|
|
54
|
+
tenant: text("tenant").notNull(),
|
|
55
|
+
capability: text("capability").notNull(),
|
|
56
|
+
provider: text("provider").notNull(),
|
|
57
|
+
eventCount: integer("event_count").notNull(),
|
|
58
|
+
totalCost: bigint("total_cost", { mode: "number" }).notNull(),
|
|
59
|
+
totalCharge: bigint("total_charge", { mode: "number" }).notNull(),
|
|
60
|
+
totalDuration: integer("total_duration").notNull().default(0),
|
|
61
|
+
periodStart: bigint("period_start", { mode: "number" }).notNull(),
|
|
62
|
+
periodEnd: bigint("period_end", { mode: "number" }).notNull(),
|
|
63
|
+
updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
|
|
64
|
+
},
|
|
65
|
+
(table) => [
|
|
66
|
+
uniqueIndex("idx_billing_period_unique").on(table.tenant, table.capability, table.provider, table.periodStart),
|
|
67
|
+
index("idx_billing_period_tenant").on(table.tenant, table.periodStart),
|
|
68
|
+
index("idx_billing_period_window").on(table.periodStart, table.periodEnd),
|
|
69
|
+
],
|
|
70
|
+
);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { bigint, boolean, pgTable, text } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Per-tenant notification preferences.
|
|
6
|
+
* Each row is a tenant with boolean flags for each notification category.
|
|
7
|
+
* Absent row = all defaults (everything enabled except agentStatusChanges).
|
|
8
|
+
*/
|
|
9
|
+
export const notificationPreferences = pgTable("notification_preferences", {
|
|
10
|
+
tenantId: text("tenant_id").primaryKey(),
|
|
11
|
+
billingLowBalance: boolean("billing_low_balance").notNull().default(true),
|
|
12
|
+
billingReceipts: boolean("billing_receipts").notNull().default(true),
|
|
13
|
+
billingAutoTopup: boolean("billing_auto_topup").notNull().default(true),
|
|
14
|
+
agentChannelDisconnect: boolean("agent_channel_disconnect").notNull().default(true),
|
|
15
|
+
agentStatusChanges: boolean("agent_status_changes").notNull().default(false),
|
|
16
|
+
accountRoleChanges: boolean("account_role_changes").notNull().default(true),
|
|
17
|
+
accountTeamInvites: boolean("account_team_invites").notNull().default(true),
|
|
18
|
+
updatedAt: bigint("updated_at", { mode: "number" }).notNull().default(sql`(extract(epoch from now()))::bigint`),
|
|
19
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { bigint, index, integer, pgTable, text } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Notification queue — queues system emails with retry support.
|
|
6
|
+
*
|
|
7
|
+
* Types: low_balance, grace_entered, suspended, receipt, welcome, reactivated
|
|
8
|
+
* States: pending -> sent | failed | dead_letter
|
|
9
|
+
*
|
|
10
|
+
* All timestamps are unix epoch milliseconds (integer) to match admin_notes.
|
|
11
|
+
*/
|
|
12
|
+
export const notificationQueue = pgTable(
|
|
13
|
+
"notification_queue",
|
|
14
|
+
{
|
|
15
|
+
id: text("id").primaryKey(),
|
|
16
|
+
tenantId: text("tenant_id").notNull(),
|
|
17
|
+
emailType: text("email_type").notNull(),
|
|
18
|
+
/** Recipient email address */
|
|
19
|
+
recipientEmail: text("recipient_email").notNull(),
|
|
20
|
+
/** JSON payload for the email template */
|
|
21
|
+
payload: text("payload").notNull().default("{}"),
|
|
22
|
+
/** pending | sent | failed | dead_letter */
|
|
23
|
+
status: text("status").notNull().default("pending"),
|
|
24
|
+
/** Number of send attempts */
|
|
25
|
+
attempts: integer("attempts").notNull().default(0),
|
|
26
|
+
/** Max retry attempts before dead-lettering */
|
|
27
|
+
maxAttempts: integer("max_attempts").notNull().default(3),
|
|
28
|
+
/** Unix epoch ms of last attempt */
|
|
29
|
+
lastAttemptAt: bigint("last_attempt_at", { mode: "number" }),
|
|
30
|
+
/** Error message from last failed attempt */
|
|
31
|
+
lastError: text("last_error"),
|
|
32
|
+
/** When to next retry (unix epoch ms). Null = immediately eligible. */
|
|
33
|
+
retryAfter: bigint("retry_after", { mode: "number" }),
|
|
34
|
+
createdAt: bigint("created_at", { mode: "number" })
|
|
35
|
+
.notNull()
|
|
36
|
+
.default(sql`(extract(epoch from now()) * 1000)::bigint`),
|
|
37
|
+
sentAt: bigint("sent_at", { mode: "number" }),
|
|
38
|
+
},
|
|
39
|
+
(table) => [
|
|
40
|
+
index("idx_notif_queue_tenant").on(table.tenantId),
|
|
41
|
+
index("idx_notif_queue_status").on(table.status),
|
|
42
|
+
index("idx_notif_queue_type").on(table.emailType),
|
|
43
|
+
index("idx_notif_queue_retry").on(table.status, table.retryAfter),
|
|
44
|
+
],
|
|
45
|
+
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { bigint, index, pgTable, primaryKey, text, uniqueIndex } from "drizzle-orm/pg-core";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Org membership — maps member tenants to their parent org tenant.
|
|
5
|
+
* A member tenant can belong to at most one org (unique on member_tenant_id).
|
|
6
|
+
* Created by org management flows (WOP-1006). Read-only for this feature.
|
|
7
|
+
*/
|
|
8
|
+
export const orgMemberships = pgTable(
|
|
9
|
+
"org_memberships",
|
|
10
|
+
{
|
|
11
|
+
orgTenantId: text("org_tenant_id").notNull(),
|
|
12
|
+
memberTenantId: text("member_tenant_id").notNull(),
|
|
13
|
+
createdAt: bigint("created_at", { mode: "number" }).notNull(),
|
|
14
|
+
},
|
|
15
|
+
(table) => [
|
|
16
|
+
primaryKey({ columns: [table.orgTenantId, table.memberTenantId] }),
|
|
17
|
+
uniqueIndex("idx_org_memberships_member_unique").on(table.memberTenantId),
|
|
18
|
+
index("idx_org_memberships_org").on(table.orgTenantId),
|
|
19
|
+
],
|
|
20
|
+
);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { bigint, index, pgTable, text, uniqueIndex } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
export const organizationMembers = pgTable(
|
|
5
|
+
"organization_members",
|
|
6
|
+
{
|
|
7
|
+
id: text("id").primaryKey(),
|
|
8
|
+
orgId: text("org_id").notNull(),
|
|
9
|
+
userId: text("user_id").notNull(),
|
|
10
|
+
role: text("role").notNull().default("member"), // "owner" | "admin" | "member"
|
|
11
|
+
joinedAt: bigint("joined_at", { mode: "number" })
|
|
12
|
+
.notNull()
|
|
13
|
+
.default(sql`(extract(epoch from now()) * 1000)::bigint`),
|
|
14
|
+
},
|
|
15
|
+
(table) => [
|
|
16
|
+
index("idx_org_members_org_id").on(table.orgId),
|
|
17
|
+
index("idx_org_members_user_id").on(table.userId),
|
|
18
|
+
uniqueIndex("org_members_org_user_unique").on(table.orgId, table.userId),
|
|
19
|
+
],
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export const organizationInvites = pgTable(
|
|
23
|
+
"organization_invites",
|
|
24
|
+
{
|
|
25
|
+
id: text("id").primaryKey(),
|
|
26
|
+
orgId: text("org_id").notNull(),
|
|
27
|
+
email: text("email").notNull(),
|
|
28
|
+
role: text("role").notNull().default("member"), // "admin" | "member"
|
|
29
|
+
invitedBy: text("invited_by").notNull(),
|
|
30
|
+
token: text("token").notNull().unique(),
|
|
31
|
+
expiresAt: bigint("expires_at", { mode: "number" }).notNull(),
|
|
32
|
+
createdAt: bigint("created_at", { mode: "number" })
|
|
33
|
+
.notNull()
|
|
34
|
+
.default(sql`(extract(epoch from now()) * 1000)::bigint`),
|
|
35
|
+
},
|
|
36
|
+
(table) => [index("idx_org_invites_org_id").on(table.orgId), index("idx_org_invites_token").on(table.token)],
|
|
37
|
+
);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { index, integer, pgTable, text } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* PayRam payment sessions — tracks the lifecycle of each crypto payment.
|
|
6
|
+
* reference_id is the PayRam-assigned unique identifier.
|
|
7
|
+
*/
|
|
8
|
+
export const payramCharges = pgTable(
|
|
9
|
+
"payram_charges",
|
|
10
|
+
{
|
|
11
|
+
referenceId: text("reference_id").primaryKey(),
|
|
12
|
+
tenantId: text("tenant_id").notNull(),
|
|
13
|
+
amountUsdCents: integer("amount_usd_cents").notNull(),
|
|
14
|
+
status: text("status").notNull().default("OPEN"),
|
|
15
|
+
currency: text("currency"),
|
|
16
|
+
filledAmount: text("filled_amount"),
|
|
17
|
+
createdAt: text("created_at").notNull().default(sql`(now())`),
|
|
18
|
+
updatedAt: text("updated_at").notNull().default(sql`(now())`),
|
|
19
|
+
creditedAt: text("credited_at"),
|
|
20
|
+
},
|
|
21
|
+
(table) => [
|
|
22
|
+
index("idx_payram_charges_tenant").on(table.tenantId),
|
|
23
|
+
index("idx_payram_charges_status").on(table.status),
|
|
24
|
+
index("idx_payram_charges_created").on(table.createdAt),
|
|
25
|
+
],
|
|
26
|
+
);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { bigint, index, pgTable, text, uniqueIndex } from "drizzle-orm/pg-core";
|
|
2
|
+
|
|
3
|
+
export const platformApiKeys = pgTable(
|
|
4
|
+
"platform_api_keys",
|
|
5
|
+
{
|
|
6
|
+
id: text("id").primaryKey(),
|
|
7
|
+
/** SHA-256 hex digest of the raw API key. Raw key is NEVER stored. */
|
|
8
|
+
keyHash: text("key_hash").notNull(),
|
|
9
|
+
/** The user this key authenticates as. */
|
|
10
|
+
userId: text("user_id").notNull(),
|
|
11
|
+
/** JSON-serialized string[] of roles (e.g. '["admin","user"]'). */
|
|
12
|
+
roles: text("roles").notNull(),
|
|
13
|
+
/** Optional human-readable label. */
|
|
14
|
+
label: text("label").notNull().default(""),
|
|
15
|
+
/** Unix epoch ms. Null = never expires. */
|
|
16
|
+
expiresAt: bigint("expires_at", { mode: "number" }),
|
|
17
|
+
/** Unix epoch ms. Null = not revoked. */
|
|
18
|
+
revokedAt: bigint("revoked_at", { mode: "number" }),
|
|
19
|
+
createdAt: bigint("created_at", { mode: "number" }).notNull(),
|
|
20
|
+
},
|
|
21
|
+
(table) => [
|
|
22
|
+
uniqueIndex("idx_platform_api_keys_hash").on(table.keyHash),
|
|
23
|
+
index("idx_platform_api_keys_user").on(table.userId),
|
|
24
|
+
],
|
|
25
|
+
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { index, integer, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
|
2
|
+
import { couponCodes } from "./coupon-codes.js";
|
|
3
|
+
import { promotions } from "./promotions.js";
|
|
4
|
+
|
|
5
|
+
export const promotionRedemptions = pgTable(
|
|
6
|
+
"promotion_redemptions",
|
|
7
|
+
{
|
|
8
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
9
|
+
promotionId: uuid("promotion_id")
|
|
10
|
+
.notNull()
|
|
11
|
+
.references(() => promotions.id),
|
|
12
|
+
tenantId: text("tenant_id").notNull(),
|
|
13
|
+
couponCodeId: uuid("coupon_code_id").references(() => couponCodes.id),
|
|
14
|
+
creditsGranted: integer("credits_granted").notNull(),
|
|
15
|
+
creditTransactionId: text("credit_transaction_id").notNull(),
|
|
16
|
+
purchaseAmountCredits: integer("purchase_amount_credits"),
|
|
17
|
+
redeemedAt: timestamp("redeemed_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18
|
+
},
|
|
19
|
+
(t) => [
|
|
20
|
+
index("promotion_redemptions_promotion_idx").on(t.promotionId),
|
|
21
|
+
index("promotion_redemptions_tenant_idx").on(t.tenantId),
|
|
22
|
+
],
|
|
23
|
+
);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { boolean, index, integer, pgEnum, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
|
2
|
+
|
|
3
|
+
export const promotionTypeEnum = pgEnum("promotion_type", [
|
|
4
|
+
"bonus_on_purchase",
|
|
5
|
+
"coupon_fixed",
|
|
6
|
+
"coupon_unique",
|
|
7
|
+
"batch_grant",
|
|
8
|
+
]);
|
|
9
|
+
|
|
10
|
+
export const promotionStatusEnum = pgEnum("promotion_status", [
|
|
11
|
+
"draft",
|
|
12
|
+
"scheduled",
|
|
13
|
+
"active",
|
|
14
|
+
"paused",
|
|
15
|
+
"expired",
|
|
16
|
+
"cancelled",
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
export const promotionValueTypeEnum = pgEnum("promotion_value_type", ["flat_credits", "percent_of_purchase"]);
|
|
20
|
+
|
|
21
|
+
export const promotionUserSegmentEnum = pgEnum("promotion_user_segment", [
|
|
22
|
+
"all",
|
|
23
|
+
"new_users",
|
|
24
|
+
"existing_users",
|
|
25
|
+
"tenant_list",
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
export const promotions = pgTable(
|
|
29
|
+
"promotions",
|
|
30
|
+
{
|
|
31
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
32
|
+
name: text("name").notNull(),
|
|
33
|
+
type: promotionTypeEnum("type").notNull(),
|
|
34
|
+
status: promotionStatusEnum("status").notNull().default("draft"),
|
|
35
|
+
startsAt: timestamp("starts_at", { withTimezone: true }),
|
|
36
|
+
endsAt: timestamp("ends_at", { withTimezone: true }),
|
|
37
|
+
valueType: promotionValueTypeEnum("value_type").notNull(),
|
|
38
|
+
valueAmount: integer("value_amount").notNull(),
|
|
39
|
+
maxValueCredits: integer("max_value_credits"),
|
|
40
|
+
firstPurchaseOnly: boolean("first_purchase_only").notNull().default(false),
|
|
41
|
+
minPurchaseCredits: integer("min_purchase_credits"),
|
|
42
|
+
userSegment: promotionUserSegmentEnum("user_segment").notNull().default("all"),
|
|
43
|
+
eligibleTenantIds: text("eligible_tenant_ids").array(),
|
|
44
|
+
totalUseLimit: integer("total_use_limit"),
|
|
45
|
+
perUserLimit: integer("per_user_limit").notNull().default(1),
|
|
46
|
+
budgetCredits: integer("budget_credits"),
|
|
47
|
+
totalUses: integer("total_uses").notNull().default(0),
|
|
48
|
+
totalCreditsGranted: integer("total_credits_granted").notNull().default(0),
|
|
49
|
+
couponCode: text("coupon_code").unique(),
|
|
50
|
+
couponBatchId: uuid("coupon_batch_id"),
|
|
51
|
+
createdBy: text("created_by").notNull(),
|
|
52
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
53
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
54
|
+
notes: text("notes"),
|
|
55
|
+
},
|
|
56
|
+
(t) => [index("promotions_status_idx").on(t.status), index("promotions_coupon_code_idx").on(t.couponCode)],
|
|
57
|
+
);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { boolean, index, pgTable, text } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Provider credentials table — stores encrypted platform-level API keys
|
|
6
|
+
* for upstream AI providers used in hosted/gateway mode.
|
|
7
|
+
*
|
|
8
|
+
* Keys are encrypted at rest with AES-256-GCM. Multiple keys per provider
|
|
9
|
+
* are supported for rotation and load distribution.
|
|
10
|
+
*/
|
|
11
|
+
export const providerCredentials = pgTable(
|
|
12
|
+
"provider_credentials",
|
|
13
|
+
{
|
|
14
|
+
id: text("id").primaryKey(),
|
|
15
|
+
/** Provider identifier (e.g. "anthropic", "openai", "openrouter") */
|
|
16
|
+
provider: text("provider").notNull(),
|
|
17
|
+
/** Human-readable label (e.g. "Anthropic Production") */
|
|
18
|
+
keyName: text("key_name").notNull(),
|
|
19
|
+
/** AES-256-GCM encrypted API key (JSON-serialized EncryptedPayload) */
|
|
20
|
+
encryptedValue: text("encrypted_value").notNull(),
|
|
21
|
+
/** Auth mechanism: "header", "bearer", "basic" */
|
|
22
|
+
authType: text("auth_type").notNull(),
|
|
23
|
+
/** HTTP header name for injection (e.g. "x-api-key", "Authorization") */
|
|
24
|
+
authHeader: text("auth_header"),
|
|
25
|
+
/** Whether this credential is active and eligible for use */
|
|
26
|
+
isActive: boolean("is_active").notNull().default(true),
|
|
27
|
+
/** ISO timestamp of last successful validation */
|
|
28
|
+
lastValidated: text("last_validated"),
|
|
29
|
+
/** ISO timestamp of record creation */
|
|
30
|
+
createdAt: text("created_at").notNull().default(sql`(now())`),
|
|
31
|
+
/** ISO timestamp of last key rotation */
|
|
32
|
+
rotatedAt: text("rotated_at"),
|
|
33
|
+
/** Admin user ID who created/last modified this credential */
|
|
34
|
+
createdBy: text("created_by").notNull(),
|
|
35
|
+
},
|
|
36
|
+
(table) => [
|
|
37
|
+
index("idx_provider_creds_provider").on(table.provider),
|
|
38
|
+
index("idx_provider_creds_active").on(table.provider, table.isActive),
|
|
39
|
+
index("idx_provider_creds_created_by").on(table.createdBy),
|
|
40
|
+
],
|
|
41
|
+
);
|