@lastbrain/module-ai 2.0.26 → 2.0.30
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/README.md +52 -1
- package/dist/ai.build.config.d.ts.map +1 -1
- package/dist/ai.build.config.js +508 -9
- package/dist/api/admin/ai-provider-models/[id].d.ts +18 -0
- package/dist/api/admin/ai-provider-models/[id].d.ts.map +1 -0
- package/dist/api/admin/ai-provider-models/[id].js +58 -0
- package/dist/api/admin/ai-provider-models.d.ts +20 -0
- package/dist/api/admin/ai-provider-models.d.ts.map +1 -0
- package/dist/api/admin/ai-provider-models.js +26 -0
- package/dist/api/admin/ai-providers/[key].d.ts +18 -0
- package/dist/api/admin/ai-providers/[key].d.ts.map +1 -0
- package/dist/api/admin/ai-providers/[key].js +55 -0
- package/dist/api/admin/ai-providers.d.ts +20 -0
- package/dist/api/admin/ai-providers.d.ts.map +1 -0
- package/dist/api/admin/ai-providers.js +26 -0
- package/dist/api/admin/billing-analytics.d.ts +43 -0
- package/dist/api/admin/billing-analytics.d.ts.map +1 -0
- package/dist/api/admin/billing-analytics.js +144 -0
- package/dist/api/admin/global-ai-settings.d.ts +14 -0
- package/dist/api/admin/global-ai-settings.d.ts.map +1 -0
- package/dist/api/admin/global-ai-settings.js +63 -0
- package/dist/api/admin/token-packs/[id].d.ts.map +1 -1
- package/dist/api/admin/token-packs/[id].js +3 -2
- package/dist/api/admin/token-packs.d.ts.map +1 -1
- package/dist/api/admin/token-packs.js +3 -2
- package/dist/api/admin/user-monthly-details.d.ts +49 -0
- package/dist/api/admin/user-monthly-details.d.ts.map +1 -0
- package/dist/api/admin/user-monthly-details.js +140 -0
- package/dist/api/admin/user-quota.d.ts +21 -0
- package/dist/api/admin/user-quota.d.ts.map +1 -0
- package/dist/api/admin/user-quota.js +59 -0
- package/dist/api/admin/user-token/[id].d.ts.map +1 -1
- package/dist/api/admin/user-token/[id].js +2 -1
- package/dist/api/admin/user-token.d.ts +5 -2
- package/dist/api/admin/user-token.d.ts.map +1 -1
- package/dist/api/admin/user-token.js +91 -17
- package/dist/api/admin/user-usage-by-model.d.ts +22 -0
- package/dist/api/admin/user-usage-by-model.d.ts.map +1 -0
- package/dist/api/admin/user-usage-by-model.js +78 -0
- package/dist/api/admin/user-wallet-analytics.d.ts +15 -0
- package/dist/api/admin/user-wallet-analytics.d.ts.map +1 -0
- package/dist/api/admin/user-wallet-analytics.js +67 -0
- package/dist/api/admin/wallet-repair/route.d.ts +30 -0
- package/dist/api/admin/wallet-repair/route.d.ts.map +1 -0
- package/dist/api/admin/wallet-repair/route.js +63 -0
- package/dist/api/auth/ai-model-settings.d.ts +21 -0
- package/dist/api/auth/ai-model-settings.d.ts.map +1 -0
- package/dist/api/auth/ai-model-settings.js +86 -0
- package/dist/api/auth/ai-settings.d.ts +17 -0
- package/dist/api/auth/ai-settings.d.ts.map +1 -0
- package/dist/api/auth/ai-settings.js +87 -0
- package/dist/api/auth/api-keys/[id].d.ts +17 -0
- package/dist/api/auth/api-keys/[id].d.ts.map +1 -0
- package/dist/api/auth/api-keys/[id].js +66 -0
- package/dist/api/auth/api-keys.d.ts +19 -0
- package/dist/api/auth/api-keys.d.ts.map +1 -0
- package/dist/api/auth/api-keys.js +94 -0
- package/dist/api/auth/create-checkout.d.ts +1 -1
- package/dist/api/auth/create-checkout.d.ts.map +1 -1
- package/dist/api/auth/create-checkout.js +8 -6
- package/dist/api/auth/generate-image.d.ts +2 -2
- package/dist/api/auth/generate-image.d.ts.map +1 -1
- package/dist/api/auth/generate-image.js +404 -104
- package/dist/api/auth/generate-text.d.ts +3 -2
- package/dist/api/auth/generate-text.d.ts.map +1 -1
- package/dist/api/auth/generate-text.js +130 -58
- package/dist/api/auth/process-ocr.d.ts +9 -0
- package/dist/api/auth/process-ocr.d.ts.map +1 -0
- package/dist/api/auth/process-ocr.js +43 -0
- package/dist/api/auth/prompts/stats.d.ts +14 -0
- package/dist/api/auth/prompts/stats.d.ts.map +1 -0
- package/dist/api/auth/prompts/stats.js +46 -0
- package/dist/api/auth/prompts.d.ts +26 -0
- package/dist/api/auth/prompts.d.ts.map +1 -0
- package/dist/api/auth/prompts.js +175 -0
- package/dist/api/auth/token-balance.d.ts +26 -0
- package/dist/api/auth/token-balance.d.ts.map +1 -0
- package/dist/api/auth/token-balance.js +47 -0
- package/dist/api/auth/token-checkout.d.ts.map +1 -1
- package/dist/api/auth/token-checkout.js +22 -4
- package/dist/api/auth/token-packs.d.ts.map +1 -1
- package/dist/api/auth/token-packs.js +2 -1
- package/dist/api/auth/usage-by-model.d.ts +25 -0
- package/dist/api/auth/usage-by-model.d.ts.map +1 -0
- package/dist/api/auth/usage-by-model.js +95 -0
- package/dist/api/auth/usage.d.ts +26 -0
- package/dist/api/auth/usage.d.ts.map +1 -0
- package/dist/api/auth/usage.js +127 -0
- package/dist/api/auth/user-tokens.d.ts.map +1 -1
- package/dist/api/auth/user-tokens.js +36 -2
- package/dist/api/auth/wallet/route.d.ts +17 -0
- package/dist/api/auth/wallet/route.d.ts.map +1 -0
- package/dist/api/auth/wallet/route.js +68 -0
- package/dist/api/auth/wallet.d.ts +16 -0
- package/dist/api/auth/wallet.d.ts.map +1 -0
- package/dist/api/auth/wallet.js +71 -0
- package/dist/api/public/gateway-models.d.ts +25 -0
- package/dist/api/public/gateway-models.d.ts.map +1 -0
- package/dist/api/public/gateway-models.js +49 -0
- package/dist/api/public/pricing-summary.d.ts +46 -0
- package/dist/api/public/pricing-summary.d.ts.map +1 -0
- package/dist/api/public/pricing-summary.js +70 -0
- package/dist/api/public/prompts/[id]/stats.d.ts +15 -0
- package/dist/api/public/prompts/[id]/stats.d.ts.map +1 -0
- package/dist/api/public/prompts/[id]/stats.js +37 -0
- package/dist/api/public/prompts/[id]/view.d.ts +15 -0
- package/dist/api/public/prompts/[id]/view.d.ts.map +1 -0
- package/dist/api/public/prompts/[id]/view.js +41 -0
- package/dist/api/public/prompts/slug/[slug].d.ts +15 -0
- package/dist/api/public/prompts/slug/[slug].d.ts.map +1 -0
- package/dist/api/public/prompts/slug/[slug].js +40 -0
- package/dist/api/public/prompts/user/[username].d.ts +17 -0
- package/dist/api/public/prompts/user/[username].d.ts.map +1 -0
- package/dist/api/public/prompts/user/[username].js +51 -0
- package/dist/api/public/prompts.d.ts +15 -0
- package/dist/api/public/prompts.d.ts.map +1 -0
- package/dist/api/public/prompts.js +45 -0
- package/dist/api/public/token-packs.d.ts +11 -0
- package/dist/api/public/token-packs.d.ts.map +1 -0
- package/dist/api/public/token-packs.js +25 -0
- package/dist/api/public/token-pricing.d.ts +44 -0
- package/dist/api/public/token-pricing.d.ts.map +1 -0
- package/dist/api/public/token-pricing.js +168 -0
- package/dist/api/public/v1/_lib/artifacts.d.ts +52 -0
- package/dist/api/public/v1/_lib/artifacts.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/artifacts.js +217 -0
- package/dist/api/public/v1/_lib/auth.d.ts +43 -0
- package/dist/api/public/v1/_lib/auth.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/auth.js +108 -0
- package/dist/api/public/v1/_lib/errors.d.ts +17 -0
- package/dist/api/public/v1/_lib/errors.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/errors.js +16 -0
- package/dist/api/public/v1/_lib/log.d.ts +29 -0
- package/dist/api/public/v1/_lib/log.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/log.js +68 -0
- package/dist/api/public/v1/_lib/quota.d.ts +24 -0
- package/dist/api/public/v1/_lib/quota.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/quota.js +118 -0
- package/dist/api/public/v1/_lib/router.d.ts +54 -0
- package/dist/api/public/v1/_lib/router.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/router.js +119 -0
- package/dist/api/public/v1/connect.d.ts +20 -0
- package/dist/api/public/v1/connect.d.ts.map +1 -0
- package/dist/api/public/v1/connect.js +119 -0
- package/dist/api/public/v1/doc.d.ts +239 -0
- package/dist/api/public/v1/doc.d.ts.map +1 -0
- package/dist/api/public/v1/doc.js +253 -0
- package/dist/api/public/v1/history/[id].d.ts +92 -0
- package/dist/api/public/v1/history/[id].d.ts.map +1 -0
- package/dist/api/public/v1/history/[id].js +176 -0
- package/dist/api/public/v1/history.d.ts +30 -0
- package/dist/api/public/v1/history.d.ts.map +1 -0
- package/dist/api/public/v1/history.js +142 -0
- package/dist/api/public/v1/image-ai.d.ts +24 -0
- package/dist/api/public/v1/image-ai.d.ts.map +1 -0
- package/dist/api/public/v1/image-ai.js +233 -0
- package/dist/api/public/v1/prompts.d.ts +19 -0
- package/dist/api/public/v1/prompts.d.ts.map +1 -0
- package/dist/api/public/v1/prompts.js +107 -0
- package/dist/api/public/v1/provider.d.ts +16 -0
- package/dist/api/public/v1/provider.d.ts.map +1 -0
- package/dist/api/public/v1/provider.js +130 -0
- package/dist/api/public/v1/purchase.d.ts +11 -0
- package/dist/api/public/v1/purchase.d.ts.map +1 -0
- package/dist/api/public/v1/purchase.js +18 -0
- package/dist/api/public/v1/status.d.ts +35 -0
- package/dist/api/public/v1/status.d.ts.map +1 -0
- package/dist/api/public/v1/status.js +163 -0
- package/dist/api/public/v1/text-ai.d.ts +26 -0
- package/dist/api/public/v1/text-ai.d.ts.map +1 -0
- package/dist/api/public/v1/text-ai.js +239 -0
- package/dist/api/public/webhook.d.ts.map +1 -1
- package/dist/api/public/webhook.js +50 -39
- package/dist/api/track-usage.d.ts +12 -0
- package/dist/api/track-usage.d.ts.map +1 -0
- package/dist/api/track-usage.js +37 -0
- package/dist/components/Doc.d.ts.map +1 -1
- package/dist/components/Doc.js +1 -1
- package/dist/components/DocUsageCustom.js +6 -6
- package/dist/components/admin/UserTokenTab.d.ts.map +1 -1
- package/dist/components/admin/UserTokenTab.js +170 -23
- package/dist/components/auth/AuthDashboardAi.d.ts +2 -0
- package/dist/components/auth/AuthDashboardAi.d.ts.map +1 -0
- package/dist/components/auth/AuthDashboardAi.js +53 -0
- package/dist/docs/REFACTORING_BILLING_GUIDE.d.ts +277 -0
- package/dist/docs/REFACTORING_BILLING_GUIDE.d.ts.map +1 -0
- package/dist/docs/REFACTORING_BILLING_GUIDE.js +276 -0
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/scripts/migrate-tokens-to-wallet.d.ts +13 -0
- package/dist/scripts/migrate-tokens-to-wallet.d.ts.map +1 -0
- package/dist/scripts/migrate-tokens-to-wallet.js +165 -0
- package/dist/server/__tests__/billing.test.d.ts +5 -0
- package/dist/server/__tests__/billing.test.d.ts.map +1 -0
- package/dist/server/__tests__/billing.test.js +223 -0
- package/dist/server/ai-client.d.ts +59 -0
- package/dist/server/ai-client.d.ts.map +1 -0
- package/dist/server/ai-client.js +111 -0
- package/dist/server/ai-generation-service.d.ts +66 -0
- package/dist/server/ai-generation-service.d.ts.map +1 -0
- package/dist/server/ai-generation-service.js +274 -0
- package/dist/server/billing.d.ts +200 -0
- package/dist/server/billing.d.ts.map +1 -0
- package/dist/server/billing.js +488 -0
- package/dist/server/gateway-service.d.ts +13 -0
- package/dist/server/gateway-service.d.ts.map +1 -0
- package/dist/server/gateway-service.js +161 -0
- package/dist/server/global-settings.d.ts +16 -0
- package/dist/server/global-settings.d.ts.map +1 -0
- package/dist/server/global-settings.js +42 -0
- package/dist/server/model-filter.d.ts +25 -0
- package/dist/server/model-filter.d.ts.map +1 -0
- package/dist/server/model-filter.js +240 -0
- package/dist/server/ocr.d.ts +39 -0
- package/dist/server/ocr.d.ts.map +1 -0
- package/dist/server/ocr.js +280 -0
- package/dist/server/openai-client.d.ts +19 -0
- package/dist/server/openai-client.d.ts.map +1 -0
- package/dist/server/openai-client.js +26 -0
- package/dist/server/pricing-config.d.ts +18 -0
- package/dist/server/pricing-config.d.ts.map +1 -0
- package/dist/server/pricing-config.js +94 -0
- package/dist/server/pricing-validator.d.ts +41 -0
- package/dist/server/pricing-validator.d.ts.map +1 -0
- package/dist/server/pricing-validator.js +113 -0
- package/dist/server/pricing.d.ts +121 -0
- package/dist/server/pricing.d.ts.map +1 -0
- package/dist/server/pricing.js +225 -0
- package/dist/server/quota.d.ts +66 -0
- package/dist/server/quota.d.ts.map +1 -0
- package/dist/server/quota.js +538 -0
- package/dist/server/wallet-repair.d.ts +32 -0
- package/dist/server/wallet-repair.d.ts.map +1 -0
- package/dist/server/wallet-repair.js +189 -0
- package/dist/server.d.ts +13 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +87 -16
- package/dist/sitemap/handlers/prompts.d.ts +6 -0
- package/dist/sitemap/handlers/prompts.d.ts.map +1 -0
- package/dist/sitemap/handlers/prompts.js +72 -0
- package/dist/sitemap/handlers/users.d.ts +6 -0
- package/dist/sitemap/handlers/users.d.ts.map +1 -0
- package/dist/sitemap/handlers/users.js +80 -0
- package/dist/sitemap/manifest.d.ts +8 -0
- package/dist/sitemap/manifest.d.ts.map +1 -0
- package/dist/sitemap/manifest.js +27 -0
- package/dist/types/gateway.d.ts +40 -0
- package/dist/types/gateway.d.ts.map +1 -0
- package/dist/types/gateway.js +4 -0
- package/dist/types/quota.d.ts +74 -0
- package/dist/types/quota.d.ts.map +1 -0
- package/dist/types/quota.js +11 -0
- package/dist/utils/date.d.ts +7 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/date.js +17 -0
- package/dist/web/admin/AdminTokenPacksPage.js +1 -1
- package/dist/web/admin/BillingAnalyticsPage.d.ts +2 -0
- package/dist/web/admin/BillingAnalyticsPage.d.ts.map +1 -0
- package/dist/web/admin/BillingAnalyticsPage.js +141 -0
- package/dist/web/admin/GlobalAISettingsPage.d.ts +2 -0
- package/dist/web/admin/GlobalAISettingsPage.d.ts.map +1 -0
- package/dist/web/admin/GlobalAISettingsPage.js +93 -0
- package/dist/web/admin/UserTokenPage.d.ts.map +1 -1
- package/dist/web/admin/UserTokenPage.js +20 -7
- package/dist/web/auth/AISettingsPage.d.ts +2 -0
- package/dist/web/auth/AISettingsPage.d.ts.map +1 -0
- package/dist/web/auth/AISettingsPage.js +258 -0
- package/dist/web/auth/APIKeysPage.d.ts +2 -0
- package/dist/web/auth/APIKeysPage.d.ts.map +1 -0
- package/dist/web/auth/APIKeysPage.js +154 -0
- package/dist/web/auth/HistoryPage.d.ts +2 -0
- package/dist/web/auth/HistoryPage.d.ts.map +1 -0
- package/dist/web/auth/HistoryPage.js +279 -0
- package/dist/web/auth/PromptsPage.d.ts +5 -0
- package/dist/web/auth/PromptsPage.d.ts.map +1 -0
- package/dist/web/auth/PromptsPage.js +137 -0
- package/dist/web/auth/TokenPage.d.ts.map +1 -1
- package/dist/web/auth/TokenPage.js +88 -31
- package/dist/web/auth/UsageAndTokensPage.d.ts +2 -0
- package/dist/web/auth/UsageAndTokensPage.d.ts.map +1 -0
- package/dist/web/auth/UsageAndTokensPage.js +157 -0
- package/dist/web/auth/UsagePage.d.ts +2 -0
- package/dist/web/auth/UsagePage.d.ts.map +1 -0
- package/dist/web/auth/UsagePage.js +62 -0
- package/dist/web/auth/components/ApiKeyFilterSelect.d.ts +13 -0
- package/dist/web/auth/components/ApiKeyFilterSelect.d.ts.map +1 -0
- package/dist/web/auth/components/ApiKeyFilterSelect.js +16 -0
- package/dist/web/auth/components/ModelUsageTable.d.ts +19 -0
- package/dist/web/auth/components/ModelUsageTable.d.ts.map +1 -0
- package/dist/web/auth/components/ModelUsageTable.js +37 -0
- package/dist/web/auth/components/PurchaseButton.d.ts +7 -0
- package/dist/web/auth/components/PurchaseButton.d.ts.map +1 -0
- package/dist/web/auth/components/PurchaseButton.js +13 -0
- package/dist/web/auth/components/TokenHistoryCard.d.ts +20 -0
- package/dist/web/auth/components/TokenHistoryCard.d.ts.map +1 -0
- package/dist/web/auth/components/TokenHistoryCard.js +76 -0
- package/dist/web/auth/components/TokenKpiGrid.d.ts +24 -0
- package/dist/web/auth/components/TokenKpiGrid.d.ts.map +1 -0
- package/dist/web/auth/components/TokenKpiGrid.js +38 -0
- package/dist/web/auth/components/UsageByDayChart.d.ts +11 -0
- package/dist/web/auth/components/UsageByDayChart.d.ts.map +1 -0
- package/dist/web/auth/components/UsageByDayChart.js +32 -0
- package/dist/web/auth/components/UsageByModelBarChart.d.ts +12 -0
- package/dist/web/auth/components/UsageByModelBarChart.d.ts.map +1 -0
- package/dist/web/auth/components/UsageByModelBarChart.js +32 -0
- package/dist/web/auth/components/WalletStatusCard.d.ts +9 -0
- package/dist/web/auth/components/WalletStatusCard.d.ts.map +1 -0
- package/dist/web/auth/components/WalletStatusCard.js +50 -0
- package/dist/web/components/ImageGenerative.d.ts +3 -1
- package/dist/web/components/ImageGenerative.d.ts.map +1 -1
- package/dist/web/components/ImageGenerative.js +139 -52
- package/dist/web/components/TextareaGenerative.d.ts +3 -1
- package/dist/web/components/TextareaGenerative.d.ts.map +1 -1
- package/dist/web/components/TextareaGenerative.js +10 -5
- package/dist/web/public/PromptDetailPage.d.ts +25 -0
- package/dist/web/public/PromptDetailPage.d.ts.map +1 -0
- package/dist/web/public/PromptDetailPage.js +71 -0
- package/dist/web/public/PromptDetailPageServer.d.ts +15 -0
- package/dist/web/public/PromptDetailPageServer.d.ts.map +1 -0
- package/dist/web/public/PromptDetailPageServer.js +68 -0
- package/dist/web/public/PublicPromptsPage.d.ts +5 -0
- package/dist/web/public/PublicPromptsPage.d.ts.map +1 -0
- package/dist/web/public/PublicPromptsPage.js +110 -0
- package/dist/web/public/PurchaseTokensPage.d.ts +2 -0
- package/dist/web/public/PurchaseTokensPage.d.ts.map +1 -0
- package/dist/web/public/PurchaseTokensPage.js +98 -0
- package/dist/web/public/UserAvatar.d.ts +13 -0
- package/dist/web/public/UserAvatar.d.ts.map +1 -0
- package/dist/web/public/UserAvatar.js +13 -0
- package/dist/web/public/UserDetailPageServer.d.ts +15 -0
- package/dist/web/public/UserDetailPageServer.d.ts.map +1 -0
- package/dist/web/public/UserDetailPageServer.js +31 -0
- package/dist/web/public/UserPromptsPage.d.ts +9 -0
- package/dist/web/public/UserPromptsPage.d.ts.map +1 -0
- package/dist/web/public/UserPromptsPage.js +112 -0
- package/dist/web/public/UserPromptsPageServer.d.ts +15 -0
- package/dist/web/public/UserPromptsPageServer.d.ts.map +1 -0
- package/dist/web/public/UserPromptsPageServer.js +31 -0
- package/package.json +18 -9
- package/supabase/migrations/20251125000000_ai_tokens.sql +7 -0
- package/supabase/migrations/20260123100002_user_token_quota_monthly copy.sql +173 -0
- package/supabase/migrations/20260128100003_update_and_add_table.sql +368 -0
- package/supabase/migrations/20260128120000_seed_providers_models.sql +78 -0
- package/supabase/migrations/20260128131405_add_api_key_id_to_ledgers.sql +41 -0
- package/supabase/migrations/20260128140000_ai_artifacts_storage.sql +99 -0
- package/supabase/migrations/20260128140002_ai_user_settings.sql +57 -0
- package/supabase/migrations/20260128150000_drop_ai_user_settings.sql +21 -0
- package/supabase/migrations/20260128160000_wallet_billing_system.sql +192 -0
- package/supabase/migrations/20260128160001_wallet_rpc_functions.sql +165 -0
- package/supabase/migrations/20260128170000_add_pack_coef_to_token_packs.sql +30 -0
- package/supabase/migrations/20260129120000_wallet_view_rpc.sql +41 -0
- package/supabase/migrations/20260129220003_update_pack_margins.sql +31 -0
- package/supabase/migrations/20260129330004_ai_user_prompts.sql +151 -0
- package/supabase/migrations/20260129330005_ai_prompts_ip_tracking.sql +92 -0
- package/supabase/migrations/20260129330006_ai_prompts_slug.sql +64 -0
- package/supabase/migrations/20260129330007_ai_prompts_view_slug.sql +26 -0
- package/supabase/migrations/20260129440000_ai_prompts_view_username.sql +33 -0
- package/supabase/migrations/20260129450000_ai_prompts_add_lang.sql +40 -0
- package/supabase/migrations/20260131000000_extract_model_prompt_in_ledger.sql +92 -0
- package/supabase/migrations/20260131140000_fix_duplicate_purchases.sql +64 -0
- package/supabase/migrations/20260201120000_module-ai_default_models.sql +63 -0
- package/supabase/migrations/20260201130000_module-ai_remove_provider_tables.sql +17 -0
- package/supabase/migrations-down/20251217120000_user_token_quota_monthly.sql +34 -0
- package/supabase/migrations-down/20260128131405_add_api_key_id_to_ledgers.sql +25 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
-- Migration: AI Artifacts Storage System
|
|
2
|
+
-- Date: 2026-01-28
|
|
3
|
+
-- Description: Ajoute store_outputs flag + table ai_artifacts pour historique des sorties IA
|
|
4
|
+
|
|
5
|
+
-- =====================================================
|
|
6
|
+
-- 1) Ajouter flag store_outputs dans user_ai_settings
|
|
7
|
+
-- =====================================================
|
|
8
|
+
|
|
9
|
+
ALTER TABLE public.user_ai_settings
|
|
10
|
+
ADD COLUMN IF NOT EXISTS store_outputs boolean NOT NULL DEFAULT false;
|
|
11
|
+
|
|
12
|
+
COMMENT ON COLUMN public.user_ai_settings.store_outputs IS 'Active la sauvegarde automatique des sorties IA (texte, image, PDF, fichiers)';
|
|
13
|
+
|
|
14
|
+
-- =====================================================
|
|
15
|
+
-- 2) Créer table ai_artifacts
|
|
16
|
+
-- =====================================================
|
|
17
|
+
|
|
18
|
+
CREATE TABLE IF NOT EXISTS public.ai_artifacts (
|
|
19
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
20
|
+
owner_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
21
|
+
api_key_id uuid NULL REFERENCES public.api_keys(id) ON DELETE SET NULL,
|
|
22
|
+
api_key_name text NULL,
|
|
23
|
+
|
|
24
|
+
-- Type d'artefact
|
|
25
|
+
kind text NOT NULL CHECK (kind IN ('text', 'image', 'pdf', 'file')),
|
|
26
|
+
|
|
27
|
+
-- Métadonnées IA
|
|
28
|
+
provider text NULL,
|
|
29
|
+
model text NULL,
|
|
30
|
+
endpoint text NOT NULL,
|
|
31
|
+
tokens_total int NULL,
|
|
32
|
+
status_code int NOT NULL DEFAULT 200,
|
|
33
|
+
|
|
34
|
+
-- Contenu
|
|
35
|
+
text_content text NULL,
|
|
36
|
+
|
|
37
|
+
-- Storage
|
|
38
|
+
storage_bucket text NULL DEFAULT 'app',
|
|
39
|
+
storage_path text NULL,
|
|
40
|
+
mime_type text NULL,
|
|
41
|
+
size_bytes bigint NULL,
|
|
42
|
+
|
|
43
|
+
-- Métadonnées additionnelles
|
|
44
|
+
meta jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
45
|
+
|
|
46
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
-- =====================================================
|
|
50
|
+
-- 3) Indexes pour performance
|
|
51
|
+
-- =====================================================
|
|
52
|
+
|
|
53
|
+
CREATE INDEX IF NOT EXISTS idx_ai_artifacts_owner_created
|
|
54
|
+
ON public.ai_artifacts(owner_id, created_at DESC);
|
|
55
|
+
|
|
56
|
+
CREATE INDEX IF NOT EXISTS idx_ai_artifacts_api_key_created
|
|
57
|
+
ON public.ai_artifacts(api_key_id, created_at DESC)
|
|
58
|
+
WHERE api_key_id IS NOT NULL;
|
|
59
|
+
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_ai_artifacts_kind_created
|
|
61
|
+
ON public.ai_artifacts(kind, created_at DESC);
|
|
62
|
+
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_ai_artifacts_endpoint
|
|
64
|
+
ON public.ai_artifacts(endpoint, created_at DESC);
|
|
65
|
+
|
|
66
|
+
-- =====================================================
|
|
67
|
+
-- 4) RLS Policies
|
|
68
|
+
-- =====================================================
|
|
69
|
+
|
|
70
|
+
ALTER TABLE public.ai_artifacts ENABLE ROW LEVEL SECURITY;
|
|
71
|
+
|
|
72
|
+
-- Policy: Owner peut tout voir ses artifacts
|
|
73
|
+
CREATE POLICY "ai_artifacts_owner_select"
|
|
74
|
+
ON public.ai_artifacts
|
|
75
|
+
FOR SELECT
|
|
76
|
+
USING (owner_id = auth.uid());
|
|
77
|
+
|
|
78
|
+
-- Policy: Owner peut insérer ses artifacts
|
|
79
|
+
CREATE POLICY "ai_artifacts_owner_insert"
|
|
80
|
+
ON public.ai_artifacts
|
|
81
|
+
FOR INSERT
|
|
82
|
+
WITH CHECK (owner_id = auth.uid());
|
|
83
|
+
|
|
84
|
+
-- Policy: Owner peut supprimer ses artifacts
|
|
85
|
+
CREATE POLICY "ai_artifacts_owner_delete"
|
|
86
|
+
ON public.ai_artifacts
|
|
87
|
+
FOR DELETE
|
|
88
|
+
USING (owner_id = auth.uid());
|
|
89
|
+
|
|
90
|
+
-- =====================================================
|
|
91
|
+
-- 5) Comments
|
|
92
|
+
-- =====================================================
|
|
93
|
+
|
|
94
|
+
COMMENT ON TABLE public.ai_artifacts IS 'Historique des sorties IA générées (texte, images, PDFs, fichiers)';
|
|
95
|
+
COMMENT ON COLUMN public.ai_artifacts.kind IS 'Type d''artefact: text, image, pdf, file';
|
|
96
|
+
COMMENT ON COLUMN public.ai_artifacts.api_key_name IS 'Nom de la clé API au moment du call (pour construire le path storage)';
|
|
97
|
+
COMMENT ON COLUMN public.ai_artifacts.text_content IS 'Contenu textuel complet (uniquement pour kind=text)';
|
|
98
|
+
COMMENT ON COLUMN public.ai_artifacts.storage_path IS 'Chemin du fichier dans le bucket: {ownerId}/{apiKeyName}/{mm-yyyy}/{artifactId}.{ext}';
|
|
99
|
+
COMMENT ON COLUMN public.ai_artifacts.meta IS 'Métadonnées JSON: request_id, sizes, tags, image_size, etc.';
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
-- Migration: Add AI user settings table for enabled models
|
|
2
|
+
-- Stores which AI models each user has enabled/disabled
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS ai_user_settings (
|
|
5
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
6
|
+
owner_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
7
|
+
enabled_models TEXT[] DEFAULT '{}', -- Array of model IDs (e.g., "openai/gpt-4o-mini")
|
|
8
|
+
enabled_providers TEXT[] DEFAULT NULL, -- Optional: filter by provider names
|
|
9
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
10
|
+
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
11
|
+
|
|
12
|
+
UNIQUE(owner_id)
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
-- Index for faster lookups
|
|
16
|
+
CREATE INDEX IF NOT EXISTS idx_ai_user_settings_owner ON ai_user_settings(owner_id);
|
|
17
|
+
|
|
18
|
+
-- RLS policies
|
|
19
|
+
ALTER TABLE ai_user_settings ENABLE ROW LEVEL SECURITY;
|
|
20
|
+
|
|
21
|
+
-- Users can read their own settings
|
|
22
|
+
CREATE POLICY "Users can view own AI settings"
|
|
23
|
+
ON ai_user_settings
|
|
24
|
+
FOR SELECT
|
|
25
|
+
USING (auth.uid() = owner_id);
|
|
26
|
+
|
|
27
|
+
-- Users can insert their own settings
|
|
28
|
+
CREATE POLICY "Users can insert own AI settings"
|
|
29
|
+
ON ai_user_settings
|
|
30
|
+
FOR INSERT
|
|
31
|
+
WITH CHECK (auth.uid() = owner_id);
|
|
32
|
+
|
|
33
|
+
-- Users can update their own settings
|
|
34
|
+
CREATE POLICY "Users can update own AI settings"
|
|
35
|
+
ON ai_user_settings
|
|
36
|
+
FOR UPDATE
|
|
37
|
+
USING (auth.uid() = owner_id)
|
|
38
|
+
WITH CHECK (auth.uid() = owner_id);
|
|
39
|
+
|
|
40
|
+
-- Auto-update updated_at timestamp
|
|
41
|
+
CREATE OR REPLACE FUNCTION update_ai_user_settings_updated_at()
|
|
42
|
+
RETURNS TRIGGER AS $$
|
|
43
|
+
BEGIN
|
|
44
|
+
NEW.updated_at = NOW();
|
|
45
|
+
RETURN NEW;
|
|
46
|
+
END;
|
|
47
|
+
$$ LANGUAGE plpgsql;
|
|
48
|
+
|
|
49
|
+
CREATE TRIGGER trigger_update_ai_user_settings_updated_at
|
|
50
|
+
BEFORE UPDATE ON ai_user_settings
|
|
51
|
+
FOR EACH ROW
|
|
52
|
+
EXECUTE FUNCTION update_ai_user_settings_updated_at();
|
|
53
|
+
|
|
54
|
+
-- Comment
|
|
55
|
+
COMMENT ON TABLE ai_user_settings IS 'User-specific AI model enable/disable settings';
|
|
56
|
+
COMMENT ON COLUMN ai_user_settings.enabled_models IS 'Array of enabled model IDs from gateway (e.g., openai/gpt-4o-mini)';
|
|
57
|
+
COMMENT ON COLUMN ai_user_settings.enabled_providers IS 'Optional array of enabled provider names (e.g., openai, anthropic)';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
-- Migration: Drop ai_user_settings table
|
|
2
|
+
-- Use existing user_ai_settings.allowed_models instead
|
|
3
|
+
|
|
4
|
+
-- Drop trigger first
|
|
5
|
+
DROP TRIGGER IF EXISTS trigger_update_ai_user_settings_updated_at ON ai_user_settings;
|
|
6
|
+
|
|
7
|
+
-- Drop function
|
|
8
|
+
DROP FUNCTION IF EXISTS update_ai_user_settings_updated_at();
|
|
9
|
+
|
|
10
|
+
-- Drop policies
|
|
11
|
+
DROP POLICY IF EXISTS "Users can view own AI settings" ON ai_user_settings;
|
|
12
|
+
DROP POLICY IF EXISTS "Users can insert own AI settings" ON ai_user_settings;
|
|
13
|
+
DROP POLICY IF EXISTS "Users can update own AI settings" ON ai_user_settings;
|
|
14
|
+
|
|
15
|
+
-- Drop index
|
|
16
|
+
DROP INDEX IF EXISTS idx_ai_user_settings_owner;
|
|
17
|
+
|
|
18
|
+
-- Drop table
|
|
19
|
+
DROP TABLE IF EXISTS ai_user_settings;
|
|
20
|
+
|
|
21
|
+
COMMENT ON COLUMN public.user_ai_settings.allowed_models IS 'Liste des modèles activés pour l''utilisateur (format: provider/model ou [{"provider":"openai","models":["gpt-4o-mini"]}])';
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
-- Migration: Wallet-based billing system with automatic margin smoothing
|
|
2
|
+
-- Adds user_token_wallet table + extends user_token_ledger for accurate CA/marge tracking
|
|
3
|
+
|
|
4
|
+
-- ============================================================================
|
|
5
|
+
-- 1. CREATE WALLET TABLE (if not exists)
|
|
6
|
+
-- ============================================================================
|
|
7
|
+
|
|
8
|
+
CREATE TABLE IF NOT EXISTS public.user_token_wallet (
|
|
9
|
+
user_id uuid PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
10
|
+
wallet_provider_budget_usd numeric(12,6) NOT NULL DEFAULT 0 CHECK (wallet_provider_budget_usd >= 0),
|
|
11
|
+
wallet_sell_value_usd numeric(12,6) NOT NULL DEFAULT 0 CHECK (wallet_sell_value_usd >= 0),
|
|
12
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
13
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
COMMENT ON TABLE public.user_token_wallet IS
|
|
17
|
+
'Economic wallet for tokens: stores provider budget and sell value in USD for automatic margin smoothing';
|
|
18
|
+
|
|
19
|
+
COMMENT ON COLUMN public.user_token_wallet.wallet_provider_budget_usd IS
|
|
20
|
+
'Remaining provider cost budget in USD (sum of pack_price/coef from purchases minus consumed)';
|
|
21
|
+
|
|
22
|
+
COMMENT ON COLUMN public.user_token_wallet.wallet_sell_value_usd IS
|
|
23
|
+
'Remaining sell value in USD (sum of pack prices minus consumed sell value)';
|
|
24
|
+
|
|
25
|
+
-- Index for performance
|
|
26
|
+
CREATE INDEX IF NOT EXISTS idx_user_token_wallet_user_id ON public.user_token_wallet(user_id);
|
|
27
|
+
|
|
28
|
+
-- RLS policies
|
|
29
|
+
ALTER TABLE public.user_token_wallet ENABLE ROW LEVEL SECURITY;
|
|
30
|
+
|
|
31
|
+
DO $$
|
|
32
|
+
BEGIN
|
|
33
|
+
IF NOT EXISTS (
|
|
34
|
+
SELECT 1 FROM pg_policies
|
|
35
|
+
WHERE schemaname = 'public'
|
|
36
|
+
AND tablename = 'user_token_wallet'
|
|
37
|
+
AND policyname = 'Users can view their own wallet'
|
|
38
|
+
) THEN
|
|
39
|
+
CREATE POLICY "Users can view their own wallet"
|
|
40
|
+
ON public.user_token_wallet FOR SELECT
|
|
41
|
+
USING (auth.uid() = user_id);
|
|
42
|
+
END IF;
|
|
43
|
+
|
|
44
|
+
IF NOT EXISTS (
|
|
45
|
+
SELECT 1 FROM pg_policies
|
|
46
|
+
WHERE schemaname = 'public'
|
|
47
|
+
AND tablename = 'user_token_wallet'
|
|
48
|
+
AND policyname = 'Service role can manage wallets'
|
|
49
|
+
) THEN
|
|
50
|
+
CREATE POLICY "Service role can manage wallets"
|
|
51
|
+
ON public.user_token_wallet FOR ALL
|
|
52
|
+
USING (true);
|
|
53
|
+
END IF;
|
|
54
|
+
END $$;
|
|
55
|
+
|
|
56
|
+
-- ============================================================================
|
|
57
|
+
-- 2. EXTEND user_token_ledger (safe: IF NOT EXISTS)
|
|
58
|
+
-- ============================================================================
|
|
59
|
+
|
|
60
|
+
-- Provider cost for this transaction (USD)
|
|
61
|
+
ALTER TABLE public.user_token_ledger
|
|
62
|
+
ADD COLUMN IF NOT EXISTS provider_cost_usd numeric(12,8);
|
|
63
|
+
|
|
64
|
+
-- Sell value for this transaction (USD)
|
|
65
|
+
ALTER TABLE public.user_token_ledger
|
|
66
|
+
ADD COLUMN IF NOT EXISTS sell_usd numeric(12,8);
|
|
67
|
+
|
|
68
|
+
-- Margin for this transaction (USD)
|
|
69
|
+
ALTER TABLE public.user_token_ledger
|
|
70
|
+
ADD COLUMN IF NOT EXISTS margin_usd numeric(12,8);
|
|
71
|
+
|
|
72
|
+
-- Tokens debited (should match -amount for 'use' type)
|
|
73
|
+
ALTER TABLE public.user_token_ledger
|
|
74
|
+
ADD COLUMN IF NOT EXISTS debit_tokens bigint;
|
|
75
|
+
|
|
76
|
+
-- Pack coefficient (for 'purchase' type)
|
|
77
|
+
ALTER TABLE public.user_token_ledger
|
|
78
|
+
ADD COLUMN IF NOT EXISTS pack_coef numeric(4,2);
|
|
79
|
+
|
|
80
|
+
-- Pack price in USD (for 'purchase' type)
|
|
81
|
+
ALTER TABLE public.user_token_ledger
|
|
82
|
+
ADD COLUMN IF NOT EXISTS pack_price_usd numeric(10,2);
|
|
83
|
+
|
|
84
|
+
-- Provider budget added (for 'purchase' type)
|
|
85
|
+
ALTER TABLE public.user_token_ledger
|
|
86
|
+
ADD COLUMN IF NOT EXISTS provider_budget_added_usd numeric(12,6);
|
|
87
|
+
|
|
88
|
+
-- Sell value added (for 'purchase' type)
|
|
89
|
+
ALTER TABLE public.user_token_ledger
|
|
90
|
+
ADD COLUMN IF NOT EXISTS sell_value_added_usd numeric(12,6);
|
|
91
|
+
|
|
92
|
+
-- Comments
|
|
93
|
+
COMMENT ON COLUMN public.user_token_ledger.provider_cost_usd IS
|
|
94
|
+
'Real provider cost for this AI call (text/image)';
|
|
95
|
+
|
|
96
|
+
COMMENT ON COLUMN public.user_token_ledger.sell_usd IS
|
|
97
|
+
'Sell value charged for this AI call (includes margin)';
|
|
98
|
+
|
|
99
|
+
COMMENT ON COLUMN public.user_token_ledger.margin_usd IS
|
|
100
|
+
'Margin earned on this transaction (sell_usd - provider_cost_usd)';
|
|
101
|
+
|
|
102
|
+
COMMENT ON COLUMN public.user_token_ledger.debit_tokens IS
|
|
103
|
+
'Tokens debited from user balance (computed from wallet rates)';
|
|
104
|
+
|
|
105
|
+
COMMENT ON COLUMN public.user_token_ledger.pack_coef IS
|
|
106
|
+
'Margin coefficient applied to pack (e.g. 1.35 = 35% margin)';
|
|
107
|
+
|
|
108
|
+
COMMENT ON COLUMN public.user_token_ledger.pack_price_usd IS
|
|
109
|
+
'Price paid for pack in USD';
|
|
110
|
+
|
|
111
|
+
COMMENT ON COLUMN public.user_token_ledger.provider_budget_added_usd IS
|
|
112
|
+
'Provider budget added to wallet (pack_price_usd / pack_coef)';
|
|
113
|
+
|
|
114
|
+
COMMENT ON COLUMN public.user_token_ledger.sell_value_added_usd IS
|
|
115
|
+
'Sell value added to wallet (pack_price_usd)';
|
|
116
|
+
|
|
117
|
+
-- Indexes for analytics queries
|
|
118
|
+
CREATE INDEX IF NOT EXISTS idx_ledger_provider_cost ON public.user_token_ledger(provider_cost_usd)
|
|
119
|
+
WHERE provider_cost_usd IS NOT NULL;
|
|
120
|
+
|
|
121
|
+
CREATE INDEX IF NOT EXISTS idx_ledger_sell_usd ON public.user_token_ledger(sell_usd)
|
|
122
|
+
WHERE sell_usd IS NOT NULL;
|
|
123
|
+
|
|
124
|
+
-- ============================================================================
|
|
125
|
+
-- 3. FUNCTION: Initialize wallet for new users
|
|
126
|
+
-- ============================================================================
|
|
127
|
+
|
|
128
|
+
CREATE OR REPLACE FUNCTION public.initialize_user_wallet()
|
|
129
|
+
RETURNS TRIGGER AS $$
|
|
130
|
+
BEGIN
|
|
131
|
+
INSERT INTO public.user_token_wallet (user_id)
|
|
132
|
+
VALUES (NEW.id)
|
|
133
|
+
ON CONFLICT (user_id) DO NOTHING;
|
|
134
|
+
RETURN NEW;
|
|
135
|
+
END;
|
|
136
|
+
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
137
|
+
|
|
138
|
+
-- Trigger on user creation (if not already present)
|
|
139
|
+
DROP TRIGGER IF EXISTS trigger_initialize_wallet ON auth.users;
|
|
140
|
+
CREATE TRIGGER trigger_initialize_wallet
|
|
141
|
+
AFTER INSERT ON auth.users
|
|
142
|
+
FOR EACH ROW
|
|
143
|
+
EXECUTE FUNCTION public.initialize_user_wallet();
|
|
144
|
+
|
|
145
|
+
-- ============================================================================
|
|
146
|
+
-- 4. VIEW: Enhanced token balance with wallet info
|
|
147
|
+
-- ============================================================================
|
|
148
|
+
|
|
149
|
+
CREATE OR REPLACE VIEW public.user_token_balance_with_wallet AS
|
|
150
|
+
SELECT
|
|
151
|
+
u.id AS user_id,
|
|
152
|
+
COALESCE(SUM(utl.amount), 0) AS token_balance,
|
|
153
|
+
w.wallet_provider_budget_usd,
|
|
154
|
+
w.wallet_sell_value_usd,
|
|
155
|
+
w.updated_at AS wallet_updated_at,
|
|
156
|
+
-- Calculated rates (safe division)
|
|
157
|
+
CASE
|
|
158
|
+
WHEN COALESCE(SUM(utl.amount), 0) > 0
|
|
159
|
+
THEN w.wallet_provider_budget_usd / NULLIF(SUM(utl.amount), 0)
|
|
160
|
+
ELSE 0
|
|
161
|
+
END AS usd_provider_per_token,
|
|
162
|
+
CASE
|
|
163
|
+
WHEN COALESCE(SUM(utl.amount), 0) > 0
|
|
164
|
+
THEN w.wallet_sell_value_usd / NULLIF(SUM(utl.amount), 0)
|
|
165
|
+
ELSE 0
|
|
166
|
+
END AS usd_sell_per_token
|
|
167
|
+
FROM auth.users u
|
|
168
|
+
LEFT JOIN public.user_token_ledger utl ON utl.owner_id = u.id
|
|
169
|
+
LEFT JOIN public.user_token_wallet w ON w.user_id = u.id
|
|
170
|
+
GROUP BY u.id, w.wallet_provider_budget_usd, w.wallet_sell_value_usd, w.updated_at;
|
|
171
|
+
|
|
172
|
+
COMMENT ON VIEW public.user_token_balance_with_wallet IS
|
|
173
|
+
'Enhanced user token balance with wallet USD values and computed rates';
|
|
174
|
+
|
|
175
|
+
-- Grant access
|
|
176
|
+
GRANT SELECT ON public.user_token_balance_with_wallet TO authenticated, service_role;
|
|
177
|
+
|
|
178
|
+
-- ============================================================================
|
|
179
|
+
-- 5. BACKFILL: Initialize wallet for existing users
|
|
180
|
+
-- ============================================================================
|
|
181
|
+
|
|
182
|
+
-- Insert wallet entries for users who don't have one yet
|
|
183
|
+
INSERT INTO public.user_token_wallet (user_id, wallet_provider_budget_usd, wallet_sell_value_usd)
|
|
184
|
+
SELECT
|
|
185
|
+
u.id,
|
|
186
|
+
0, -- Will need manual backfill if needed
|
|
187
|
+
0
|
|
188
|
+
FROM auth.users u
|
|
189
|
+
WHERE NOT EXISTS (
|
|
190
|
+
SELECT 1 FROM public.user_token_wallet w WHERE w.user_id = u.id
|
|
191
|
+
)
|
|
192
|
+
ON CONFLICT (user_id) DO NOTHING;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
-- RPC functions for atomic wallet operations
|
|
2
|
+
|
|
3
|
+
-- ============================================================================
|
|
4
|
+
-- FUNCTION: Record token purchase
|
|
5
|
+
-- ============================================================================
|
|
6
|
+
|
|
7
|
+
CREATE OR REPLACE FUNCTION public.record_token_purchase(
|
|
8
|
+
p_user_id uuid,
|
|
9
|
+
p_amount bigint,
|
|
10
|
+
p_pack_coef numeric,
|
|
11
|
+
p_pack_price_usd numeric,
|
|
12
|
+
p_provider_budget_added_usd numeric,
|
|
13
|
+
p_sell_value_added_usd numeric,
|
|
14
|
+
p_meta jsonb DEFAULT '{}'::jsonb
|
|
15
|
+
)
|
|
16
|
+
RETURNS jsonb AS $$
|
|
17
|
+
DECLARE
|
|
18
|
+
v_new_balance bigint;
|
|
19
|
+
BEGIN
|
|
20
|
+
-- 1. Insert ledger entry
|
|
21
|
+
INSERT INTO public.user_token_ledger (
|
|
22
|
+
owner_id,
|
|
23
|
+
amount,
|
|
24
|
+
type,
|
|
25
|
+
pack_coef,
|
|
26
|
+
pack_price_usd,
|
|
27
|
+
provider_budget_added_usd,
|
|
28
|
+
sell_value_added_usd,
|
|
29
|
+
meta
|
|
30
|
+
) VALUES (
|
|
31
|
+
p_user_id,
|
|
32
|
+
p_amount,
|
|
33
|
+
'purchase',
|
|
34
|
+
p_pack_coef,
|
|
35
|
+
p_pack_price_usd,
|
|
36
|
+
p_provider_budget_added_usd,
|
|
37
|
+
p_sell_value_added_usd,
|
|
38
|
+
p_meta
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
-- 2. Update wallet (INSERT if not exists, UPDATE if exists)
|
|
42
|
+
INSERT INTO public.user_token_wallet (
|
|
43
|
+
user_id,
|
|
44
|
+
wallet_provider_budget_usd,
|
|
45
|
+
wallet_sell_value_usd,
|
|
46
|
+
updated_at
|
|
47
|
+
) VALUES (
|
|
48
|
+
p_user_id,
|
|
49
|
+
p_provider_budget_added_usd,
|
|
50
|
+
p_sell_value_added_usd,
|
|
51
|
+
now()
|
|
52
|
+
)
|
|
53
|
+
ON CONFLICT (user_id) DO UPDATE SET
|
|
54
|
+
wallet_provider_budget_usd = user_token_wallet.wallet_provider_budget_usd + p_provider_budget_added_usd,
|
|
55
|
+
wallet_sell_value_usd = user_token_wallet.wallet_sell_value_usd + p_sell_value_added_usd,
|
|
56
|
+
updated_at = now();
|
|
57
|
+
|
|
58
|
+
-- 3. Get new balance
|
|
59
|
+
SELECT COALESCE(SUM(amount), 0) INTO v_new_balance
|
|
60
|
+
FROM public.user_token_ledger
|
|
61
|
+
WHERE owner_id = p_user_id;
|
|
62
|
+
|
|
63
|
+
RETURN jsonb_build_object(
|
|
64
|
+
'success', true,
|
|
65
|
+
'new_balance', v_new_balance
|
|
66
|
+
);
|
|
67
|
+
END;
|
|
68
|
+
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
69
|
+
|
|
70
|
+
COMMENT ON FUNCTION public.record_token_purchase IS
|
|
71
|
+
'Atomically record token purchase: insert ledger + update wallet USD values';
|
|
72
|
+
|
|
73
|
+
-- ============================================================================
|
|
74
|
+
-- FUNCTION: Record token consumption
|
|
75
|
+
-- ============================================================================
|
|
76
|
+
|
|
77
|
+
CREATE OR REPLACE FUNCTION public.record_token_consumption(
|
|
78
|
+
p_user_id uuid,
|
|
79
|
+
p_debit_tokens bigint,
|
|
80
|
+
p_provider_cost_usd numeric,
|
|
81
|
+
p_sell_usd numeric,
|
|
82
|
+
p_margin_usd numeric,
|
|
83
|
+
p_meta jsonb DEFAULT '{}'::jsonb
|
|
84
|
+
)
|
|
85
|
+
RETURNS jsonb AS $$
|
|
86
|
+
DECLARE
|
|
87
|
+
v_current_balance bigint;
|
|
88
|
+
v_wallet_provider_budget numeric;
|
|
89
|
+
v_wallet_sell_value numeric;
|
|
90
|
+
v_new_balance bigint;
|
|
91
|
+
v_allow_overdraft boolean;
|
|
92
|
+
BEGIN
|
|
93
|
+
-- 1. Get current balance
|
|
94
|
+
SELECT COALESCE(SUM(amount), 0) INTO v_current_balance
|
|
95
|
+
FROM public.user_token_ledger
|
|
96
|
+
WHERE owner_id = p_user_id;
|
|
97
|
+
|
|
98
|
+
-- 2. Get wallet values
|
|
99
|
+
SELECT
|
|
100
|
+
wallet_provider_budget_usd,
|
|
101
|
+
wallet_sell_value_usd
|
|
102
|
+
INTO v_wallet_provider_budget, v_wallet_sell_value
|
|
103
|
+
FROM public.user_token_wallet
|
|
104
|
+
WHERE user_id = p_user_id;
|
|
105
|
+
|
|
106
|
+
-- 3. Check overdraft
|
|
107
|
+
v_allow_overdraft := COALESCE((p_meta->>'allowOverdraft')::boolean, false);
|
|
108
|
+
|
|
109
|
+
IF NOT v_allow_overdraft AND v_current_balance < p_debit_tokens THEN
|
|
110
|
+
RAISE EXCEPTION 'Insufficient token balance: have %, need %', v_current_balance, p_debit_tokens;
|
|
111
|
+
END IF;
|
|
112
|
+
|
|
113
|
+
IF v_wallet_provider_budget < p_provider_cost_usd THEN
|
|
114
|
+
RAISE EXCEPTION 'Insufficient provider budget: have $%, need $%', v_wallet_provider_budget, p_provider_cost_usd;
|
|
115
|
+
END IF;
|
|
116
|
+
|
|
117
|
+
IF v_wallet_sell_value < p_sell_usd THEN
|
|
118
|
+
RAISE EXCEPTION 'Insufficient sell value: have $%, need $%', v_wallet_sell_value, p_sell_usd;
|
|
119
|
+
END IF;
|
|
120
|
+
|
|
121
|
+
-- 4. Insert ledger entry (negative amount)
|
|
122
|
+
INSERT INTO public.user_token_ledger (
|
|
123
|
+
owner_id,
|
|
124
|
+
amount,
|
|
125
|
+
type,
|
|
126
|
+
debit_tokens,
|
|
127
|
+
provider_cost_usd,
|
|
128
|
+
sell_usd,
|
|
129
|
+
margin_usd,
|
|
130
|
+
meta
|
|
131
|
+
) VALUES (
|
|
132
|
+
p_user_id,
|
|
133
|
+
-p_debit_tokens,
|
|
134
|
+
'use',
|
|
135
|
+
p_debit_tokens,
|
|
136
|
+
p_provider_cost_usd,
|
|
137
|
+
p_sell_usd,
|
|
138
|
+
p_margin_usd,
|
|
139
|
+
p_meta
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
-- 5. Update wallet (subtract USD values)
|
|
143
|
+
UPDATE public.user_token_wallet
|
|
144
|
+
SET
|
|
145
|
+
wallet_provider_budget_usd = wallet_provider_budget_usd - p_provider_cost_usd,
|
|
146
|
+
wallet_sell_value_usd = wallet_sell_value_usd - p_sell_usd,
|
|
147
|
+
updated_at = now()
|
|
148
|
+
WHERE user_id = p_user_id;
|
|
149
|
+
|
|
150
|
+
-- 6. Get new balance
|
|
151
|
+
v_new_balance := v_current_balance - p_debit_tokens;
|
|
152
|
+
|
|
153
|
+
RETURN jsonb_build_object(
|
|
154
|
+
'success', true,
|
|
155
|
+
'new_balance', v_new_balance
|
|
156
|
+
);
|
|
157
|
+
END;
|
|
158
|
+
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
159
|
+
|
|
160
|
+
COMMENT ON FUNCTION public.record_token_consumption IS
|
|
161
|
+
'Atomically record AI usage: insert ledger + update wallet USD values';
|
|
162
|
+
|
|
163
|
+
-- Grant execute permissions
|
|
164
|
+
GRANT EXECUTE ON FUNCTION public.record_token_purchase TO service_role;
|
|
165
|
+
GRANT EXECUTE ON FUNCTION public.record_token_consumption TO service_role;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- Migration: Add pack_coef column to token_packs
|
|
3
|
+
-- Date: 2026-01-28 17:00:00
|
|
4
|
+
-- Description: Add coefficient column for margin calculation (replaces hardcoded 1.35)
|
|
5
|
+
-- ============================================================================
|
|
6
|
+
|
|
7
|
+
-- Add pack_coef column with default 1.35 (35% margin)
|
|
8
|
+
ALTER TABLE token_packs
|
|
9
|
+
ADD COLUMN IF NOT EXISTS pack_coef DECIMAL(5,3) DEFAULT 1.35 NOT NULL;
|
|
10
|
+
|
|
11
|
+
-- Add constraint to ensure pack_coef is reasonable (between 1.0 and 10.0)
|
|
12
|
+
ALTER TABLE token_packs
|
|
13
|
+
ADD CONSTRAINT pack_coef_range
|
|
14
|
+
CHECK (pack_coef >= 1.0 AND pack_coef <= 10.0);
|
|
15
|
+
|
|
16
|
+
-- Update existing packs with default coefficient
|
|
17
|
+
UPDATE token_packs
|
|
18
|
+
SET pack_coef = 1.35
|
|
19
|
+
WHERE pack_coef IS NULL;
|
|
20
|
+
|
|
21
|
+
-- Add comment
|
|
22
|
+
COMMENT ON COLUMN token_packs.pack_coef IS 'Coefficient de marge pour calcul wallet (1.35 = 35% de marge). Plus le coefficient est bas, plus la marge est faible pour l''utilisateur.';
|
|
23
|
+
|
|
24
|
+
-- Optionally, adjust pack_coef based on pack size (bigger packs = better rates)
|
|
25
|
+
-- Example: Small packs (< 50K tokens) = 1.50 (50% margin)
|
|
26
|
+
-- Medium packs (50K-500K tokens) = 1.35 (35% margin)
|
|
27
|
+
-- Large packs (> 500K tokens) = 1.20 (20% margin)
|
|
28
|
+
UPDATE token_packs SET pack_coef = 1.50 WHERE tokens < 50000;
|
|
29
|
+
UPDATE token_packs SET pack_coef = 1.35 WHERE tokens >= 50000 AND tokens < 500000;
|
|
30
|
+
UPDATE token_packs SET pack_coef = 1.20 WHERE tokens >= 500000;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- WALLET REPAIR - Get all balances with wallet info
|
|
3
|
+
-- Migration: 20260129120000_wallet_view_rpc.sql
|
|
4
|
+
-- Description: Add RPC function to query user_token_balance_with_wallet view
|
|
5
|
+
-- ============================================================================
|
|
6
|
+
|
|
7
|
+
-- Function to get all users with their token balance and wallet
|
|
8
|
+
CREATE OR REPLACE FUNCTION get_user_token_balances_with_wallet()
|
|
9
|
+
RETURNS TABLE (
|
|
10
|
+
user_id UUID,
|
|
11
|
+
token_balance BIGINT,
|
|
12
|
+
wallet_provider_budget_usd DECIMAL(20, 6),
|
|
13
|
+
wallet_sell_value_usd DECIMAL(20, 6),
|
|
14
|
+
wallet_updated_at TIMESTAMPTZ,
|
|
15
|
+
usd_provider_per_token DECIMAL(30, 18),
|
|
16
|
+
usd_sell_per_token DECIMAL(30, 18)
|
|
17
|
+
)
|
|
18
|
+
LANGUAGE plpgsql
|
|
19
|
+
SECURITY DEFINER
|
|
20
|
+
AS $$
|
|
21
|
+
BEGIN
|
|
22
|
+
RETURN QUERY
|
|
23
|
+
SELECT
|
|
24
|
+
v.user_id,
|
|
25
|
+
v.token_balance,
|
|
26
|
+
v.wallet_provider_budget_usd,
|
|
27
|
+
v.wallet_sell_value_usd,
|
|
28
|
+
v.wallet_updated_at,
|
|
29
|
+
v.usd_provider_per_token,
|
|
30
|
+
v.usd_sell_per_token
|
|
31
|
+
FROM user_token_balance_with_wallet v
|
|
32
|
+
ORDER BY v.token_balance DESC;
|
|
33
|
+
END;
|
|
34
|
+
$$;
|
|
35
|
+
|
|
36
|
+
-- Grant execute permission
|
|
37
|
+
GRANT EXECUTE ON FUNCTION get_user_token_balances_with_wallet() TO authenticated;
|
|
38
|
+
GRANT EXECUTE ON FUNCTION get_user_token_balances_with_wallet() TO service_role;
|
|
39
|
+
|
|
40
|
+
COMMENT ON FUNCTION get_user_token_balances_with_wallet() IS
|
|
41
|
+
'Get all users with their token balance and wallet state - for admin analytics and repair';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- UPDATE PACK MARGINS - 60% to 35% progression
|
|
3
|
+
-- Migration: 20260129020000_update_pack_margins.sql
|
|
4
|
+
-- Description: Adjust pack_coef for margin progression from 60% to 35%
|
|
5
|
+
-- ============================================================================
|
|
6
|
+
|
|
7
|
+
-- Starter (100K tokens) : 60% margin
|
|
8
|
+
UPDATE token_packs
|
|
9
|
+
SET pack_coef = 2.50
|
|
10
|
+
WHERE tokens = 100000;
|
|
11
|
+
|
|
12
|
+
-- Standard (250K tokens) : 50% margin
|
|
13
|
+
UPDATE token_packs
|
|
14
|
+
SET pack_coef = 2.00
|
|
15
|
+
WHERE tokens = 250000;
|
|
16
|
+
|
|
17
|
+
-- Premium (600K tokens) : 40% margin
|
|
18
|
+
UPDATE token_packs
|
|
19
|
+
SET pack_coef = 1.67
|
|
20
|
+
WHERE tokens = 600000;
|
|
21
|
+
|
|
22
|
+
-- Creator (2M tokens) : 35% margin
|
|
23
|
+
UPDATE token_packs
|
|
24
|
+
SET pack_coef = 1.54
|
|
25
|
+
WHERE tokens = 2000000;
|
|
26
|
+
|
|
27
|
+
-- Log the changes
|
|
28
|
+
DO $$
|
|
29
|
+
BEGIN
|
|
30
|
+
RAISE NOTICE '✅ Pack margins updated: Starter 60%%, Standard 50%%, Premium 40%%, Creator 35%%';
|
|
31
|
+
END $$;
|