@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.
Files changed (365) hide show
  1. package/README.md +52 -1
  2. package/dist/ai.build.config.d.ts.map +1 -1
  3. package/dist/ai.build.config.js +508 -9
  4. package/dist/api/admin/ai-provider-models/[id].d.ts +18 -0
  5. package/dist/api/admin/ai-provider-models/[id].d.ts.map +1 -0
  6. package/dist/api/admin/ai-provider-models/[id].js +58 -0
  7. package/dist/api/admin/ai-provider-models.d.ts +20 -0
  8. package/dist/api/admin/ai-provider-models.d.ts.map +1 -0
  9. package/dist/api/admin/ai-provider-models.js +26 -0
  10. package/dist/api/admin/ai-providers/[key].d.ts +18 -0
  11. package/dist/api/admin/ai-providers/[key].d.ts.map +1 -0
  12. package/dist/api/admin/ai-providers/[key].js +55 -0
  13. package/dist/api/admin/ai-providers.d.ts +20 -0
  14. package/dist/api/admin/ai-providers.d.ts.map +1 -0
  15. package/dist/api/admin/ai-providers.js +26 -0
  16. package/dist/api/admin/billing-analytics.d.ts +43 -0
  17. package/dist/api/admin/billing-analytics.d.ts.map +1 -0
  18. package/dist/api/admin/billing-analytics.js +144 -0
  19. package/dist/api/admin/global-ai-settings.d.ts +14 -0
  20. package/dist/api/admin/global-ai-settings.d.ts.map +1 -0
  21. package/dist/api/admin/global-ai-settings.js +63 -0
  22. package/dist/api/admin/token-packs/[id].d.ts.map +1 -1
  23. package/dist/api/admin/token-packs/[id].js +3 -2
  24. package/dist/api/admin/token-packs.d.ts.map +1 -1
  25. package/dist/api/admin/token-packs.js +3 -2
  26. package/dist/api/admin/user-monthly-details.d.ts +49 -0
  27. package/dist/api/admin/user-monthly-details.d.ts.map +1 -0
  28. package/dist/api/admin/user-monthly-details.js +140 -0
  29. package/dist/api/admin/user-quota.d.ts +21 -0
  30. package/dist/api/admin/user-quota.d.ts.map +1 -0
  31. package/dist/api/admin/user-quota.js +59 -0
  32. package/dist/api/admin/user-token/[id].d.ts.map +1 -1
  33. package/dist/api/admin/user-token/[id].js +2 -1
  34. package/dist/api/admin/user-token.d.ts +5 -2
  35. package/dist/api/admin/user-token.d.ts.map +1 -1
  36. package/dist/api/admin/user-token.js +91 -17
  37. package/dist/api/admin/user-usage-by-model.d.ts +22 -0
  38. package/dist/api/admin/user-usage-by-model.d.ts.map +1 -0
  39. package/dist/api/admin/user-usage-by-model.js +78 -0
  40. package/dist/api/admin/user-wallet-analytics.d.ts +15 -0
  41. package/dist/api/admin/user-wallet-analytics.d.ts.map +1 -0
  42. package/dist/api/admin/user-wallet-analytics.js +67 -0
  43. package/dist/api/admin/wallet-repair/route.d.ts +30 -0
  44. package/dist/api/admin/wallet-repair/route.d.ts.map +1 -0
  45. package/dist/api/admin/wallet-repair/route.js +63 -0
  46. package/dist/api/auth/ai-model-settings.d.ts +21 -0
  47. package/dist/api/auth/ai-model-settings.d.ts.map +1 -0
  48. package/dist/api/auth/ai-model-settings.js +86 -0
  49. package/dist/api/auth/ai-settings.d.ts +17 -0
  50. package/dist/api/auth/ai-settings.d.ts.map +1 -0
  51. package/dist/api/auth/ai-settings.js +87 -0
  52. package/dist/api/auth/api-keys/[id].d.ts +17 -0
  53. package/dist/api/auth/api-keys/[id].d.ts.map +1 -0
  54. package/dist/api/auth/api-keys/[id].js +66 -0
  55. package/dist/api/auth/api-keys.d.ts +19 -0
  56. package/dist/api/auth/api-keys.d.ts.map +1 -0
  57. package/dist/api/auth/api-keys.js +94 -0
  58. package/dist/api/auth/create-checkout.d.ts +1 -1
  59. package/dist/api/auth/create-checkout.d.ts.map +1 -1
  60. package/dist/api/auth/create-checkout.js +8 -6
  61. package/dist/api/auth/generate-image.d.ts +2 -2
  62. package/dist/api/auth/generate-image.d.ts.map +1 -1
  63. package/dist/api/auth/generate-image.js +404 -104
  64. package/dist/api/auth/generate-text.d.ts +3 -2
  65. package/dist/api/auth/generate-text.d.ts.map +1 -1
  66. package/dist/api/auth/generate-text.js +130 -58
  67. package/dist/api/auth/process-ocr.d.ts +9 -0
  68. package/dist/api/auth/process-ocr.d.ts.map +1 -0
  69. package/dist/api/auth/process-ocr.js +43 -0
  70. package/dist/api/auth/prompts/stats.d.ts +14 -0
  71. package/dist/api/auth/prompts/stats.d.ts.map +1 -0
  72. package/dist/api/auth/prompts/stats.js +46 -0
  73. package/dist/api/auth/prompts.d.ts +26 -0
  74. package/dist/api/auth/prompts.d.ts.map +1 -0
  75. package/dist/api/auth/prompts.js +175 -0
  76. package/dist/api/auth/token-balance.d.ts +26 -0
  77. package/dist/api/auth/token-balance.d.ts.map +1 -0
  78. package/dist/api/auth/token-balance.js +47 -0
  79. package/dist/api/auth/token-checkout.d.ts.map +1 -1
  80. package/dist/api/auth/token-checkout.js +22 -4
  81. package/dist/api/auth/token-packs.d.ts.map +1 -1
  82. package/dist/api/auth/token-packs.js +2 -1
  83. package/dist/api/auth/usage-by-model.d.ts +25 -0
  84. package/dist/api/auth/usage-by-model.d.ts.map +1 -0
  85. package/dist/api/auth/usage-by-model.js +95 -0
  86. package/dist/api/auth/usage.d.ts +26 -0
  87. package/dist/api/auth/usage.d.ts.map +1 -0
  88. package/dist/api/auth/usage.js +127 -0
  89. package/dist/api/auth/user-tokens.d.ts.map +1 -1
  90. package/dist/api/auth/user-tokens.js +36 -2
  91. package/dist/api/auth/wallet/route.d.ts +17 -0
  92. package/dist/api/auth/wallet/route.d.ts.map +1 -0
  93. package/dist/api/auth/wallet/route.js +68 -0
  94. package/dist/api/auth/wallet.d.ts +16 -0
  95. package/dist/api/auth/wallet.d.ts.map +1 -0
  96. package/dist/api/auth/wallet.js +71 -0
  97. package/dist/api/public/gateway-models.d.ts +25 -0
  98. package/dist/api/public/gateway-models.d.ts.map +1 -0
  99. package/dist/api/public/gateway-models.js +49 -0
  100. package/dist/api/public/pricing-summary.d.ts +46 -0
  101. package/dist/api/public/pricing-summary.d.ts.map +1 -0
  102. package/dist/api/public/pricing-summary.js +70 -0
  103. package/dist/api/public/prompts/[id]/stats.d.ts +15 -0
  104. package/dist/api/public/prompts/[id]/stats.d.ts.map +1 -0
  105. package/dist/api/public/prompts/[id]/stats.js +37 -0
  106. package/dist/api/public/prompts/[id]/view.d.ts +15 -0
  107. package/dist/api/public/prompts/[id]/view.d.ts.map +1 -0
  108. package/dist/api/public/prompts/[id]/view.js +41 -0
  109. package/dist/api/public/prompts/slug/[slug].d.ts +15 -0
  110. package/dist/api/public/prompts/slug/[slug].d.ts.map +1 -0
  111. package/dist/api/public/prompts/slug/[slug].js +40 -0
  112. package/dist/api/public/prompts/user/[username].d.ts +17 -0
  113. package/dist/api/public/prompts/user/[username].d.ts.map +1 -0
  114. package/dist/api/public/prompts/user/[username].js +51 -0
  115. package/dist/api/public/prompts.d.ts +15 -0
  116. package/dist/api/public/prompts.d.ts.map +1 -0
  117. package/dist/api/public/prompts.js +45 -0
  118. package/dist/api/public/token-packs.d.ts +11 -0
  119. package/dist/api/public/token-packs.d.ts.map +1 -0
  120. package/dist/api/public/token-packs.js +25 -0
  121. package/dist/api/public/token-pricing.d.ts +44 -0
  122. package/dist/api/public/token-pricing.d.ts.map +1 -0
  123. package/dist/api/public/token-pricing.js +168 -0
  124. package/dist/api/public/v1/_lib/artifacts.d.ts +52 -0
  125. package/dist/api/public/v1/_lib/artifacts.d.ts.map +1 -0
  126. package/dist/api/public/v1/_lib/artifacts.js +217 -0
  127. package/dist/api/public/v1/_lib/auth.d.ts +43 -0
  128. package/dist/api/public/v1/_lib/auth.d.ts.map +1 -0
  129. package/dist/api/public/v1/_lib/auth.js +108 -0
  130. package/dist/api/public/v1/_lib/errors.d.ts +17 -0
  131. package/dist/api/public/v1/_lib/errors.d.ts.map +1 -0
  132. package/dist/api/public/v1/_lib/errors.js +16 -0
  133. package/dist/api/public/v1/_lib/log.d.ts +29 -0
  134. package/dist/api/public/v1/_lib/log.d.ts.map +1 -0
  135. package/dist/api/public/v1/_lib/log.js +68 -0
  136. package/dist/api/public/v1/_lib/quota.d.ts +24 -0
  137. package/dist/api/public/v1/_lib/quota.d.ts.map +1 -0
  138. package/dist/api/public/v1/_lib/quota.js +118 -0
  139. package/dist/api/public/v1/_lib/router.d.ts +54 -0
  140. package/dist/api/public/v1/_lib/router.d.ts.map +1 -0
  141. package/dist/api/public/v1/_lib/router.js +119 -0
  142. package/dist/api/public/v1/connect.d.ts +20 -0
  143. package/dist/api/public/v1/connect.d.ts.map +1 -0
  144. package/dist/api/public/v1/connect.js +119 -0
  145. package/dist/api/public/v1/doc.d.ts +239 -0
  146. package/dist/api/public/v1/doc.d.ts.map +1 -0
  147. package/dist/api/public/v1/doc.js +253 -0
  148. package/dist/api/public/v1/history/[id].d.ts +92 -0
  149. package/dist/api/public/v1/history/[id].d.ts.map +1 -0
  150. package/dist/api/public/v1/history/[id].js +176 -0
  151. package/dist/api/public/v1/history.d.ts +30 -0
  152. package/dist/api/public/v1/history.d.ts.map +1 -0
  153. package/dist/api/public/v1/history.js +142 -0
  154. package/dist/api/public/v1/image-ai.d.ts +24 -0
  155. package/dist/api/public/v1/image-ai.d.ts.map +1 -0
  156. package/dist/api/public/v1/image-ai.js +233 -0
  157. package/dist/api/public/v1/prompts.d.ts +19 -0
  158. package/dist/api/public/v1/prompts.d.ts.map +1 -0
  159. package/dist/api/public/v1/prompts.js +107 -0
  160. package/dist/api/public/v1/provider.d.ts +16 -0
  161. package/dist/api/public/v1/provider.d.ts.map +1 -0
  162. package/dist/api/public/v1/provider.js +130 -0
  163. package/dist/api/public/v1/purchase.d.ts +11 -0
  164. package/dist/api/public/v1/purchase.d.ts.map +1 -0
  165. package/dist/api/public/v1/purchase.js +18 -0
  166. package/dist/api/public/v1/status.d.ts +35 -0
  167. package/dist/api/public/v1/status.d.ts.map +1 -0
  168. package/dist/api/public/v1/status.js +163 -0
  169. package/dist/api/public/v1/text-ai.d.ts +26 -0
  170. package/dist/api/public/v1/text-ai.d.ts.map +1 -0
  171. package/dist/api/public/v1/text-ai.js +239 -0
  172. package/dist/api/public/webhook.d.ts.map +1 -1
  173. package/dist/api/public/webhook.js +50 -39
  174. package/dist/api/track-usage.d.ts +12 -0
  175. package/dist/api/track-usage.d.ts.map +1 -0
  176. package/dist/api/track-usage.js +37 -0
  177. package/dist/components/Doc.d.ts.map +1 -1
  178. package/dist/components/Doc.js +1 -1
  179. package/dist/components/DocUsageCustom.js +6 -6
  180. package/dist/components/admin/UserTokenTab.d.ts.map +1 -1
  181. package/dist/components/admin/UserTokenTab.js +170 -23
  182. package/dist/components/auth/AuthDashboardAi.d.ts +2 -0
  183. package/dist/components/auth/AuthDashboardAi.d.ts.map +1 -0
  184. package/dist/components/auth/AuthDashboardAi.js +53 -0
  185. package/dist/docs/REFACTORING_BILLING_GUIDE.d.ts +277 -0
  186. package/dist/docs/REFACTORING_BILLING_GUIDE.d.ts.map +1 -0
  187. package/dist/docs/REFACTORING_BILLING_GUIDE.js +276 -0
  188. package/dist/index.d.ts +15 -1
  189. package/dist/index.d.ts.map +1 -1
  190. package/dist/index.js +18 -1
  191. package/dist/scripts/migrate-tokens-to-wallet.d.ts +13 -0
  192. package/dist/scripts/migrate-tokens-to-wallet.d.ts.map +1 -0
  193. package/dist/scripts/migrate-tokens-to-wallet.js +165 -0
  194. package/dist/server/__tests__/billing.test.d.ts +5 -0
  195. package/dist/server/__tests__/billing.test.d.ts.map +1 -0
  196. package/dist/server/__tests__/billing.test.js +223 -0
  197. package/dist/server/ai-client.d.ts +59 -0
  198. package/dist/server/ai-client.d.ts.map +1 -0
  199. package/dist/server/ai-client.js +111 -0
  200. package/dist/server/ai-generation-service.d.ts +66 -0
  201. package/dist/server/ai-generation-service.d.ts.map +1 -0
  202. package/dist/server/ai-generation-service.js +274 -0
  203. package/dist/server/billing.d.ts +200 -0
  204. package/dist/server/billing.d.ts.map +1 -0
  205. package/dist/server/billing.js +488 -0
  206. package/dist/server/gateway-service.d.ts +13 -0
  207. package/dist/server/gateway-service.d.ts.map +1 -0
  208. package/dist/server/gateway-service.js +161 -0
  209. package/dist/server/global-settings.d.ts +16 -0
  210. package/dist/server/global-settings.d.ts.map +1 -0
  211. package/dist/server/global-settings.js +42 -0
  212. package/dist/server/model-filter.d.ts +25 -0
  213. package/dist/server/model-filter.d.ts.map +1 -0
  214. package/dist/server/model-filter.js +240 -0
  215. package/dist/server/ocr.d.ts +39 -0
  216. package/dist/server/ocr.d.ts.map +1 -0
  217. package/dist/server/ocr.js +280 -0
  218. package/dist/server/openai-client.d.ts +19 -0
  219. package/dist/server/openai-client.d.ts.map +1 -0
  220. package/dist/server/openai-client.js +26 -0
  221. package/dist/server/pricing-config.d.ts +18 -0
  222. package/dist/server/pricing-config.d.ts.map +1 -0
  223. package/dist/server/pricing-config.js +94 -0
  224. package/dist/server/pricing-validator.d.ts +41 -0
  225. package/dist/server/pricing-validator.d.ts.map +1 -0
  226. package/dist/server/pricing-validator.js +113 -0
  227. package/dist/server/pricing.d.ts +121 -0
  228. package/dist/server/pricing.d.ts.map +1 -0
  229. package/dist/server/pricing.js +225 -0
  230. package/dist/server/quota.d.ts +66 -0
  231. package/dist/server/quota.d.ts.map +1 -0
  232. package/dist/server/quota.js +538 -0
  233. package/dist/server/wallet-repair.d.ts +32 -0
  234. package/dist/server/wallet-repair.d.ts.map +1 -0
  235. package/dist/server/wallet-repair.js +189 -0
  236. package/dist/server.d.ts +13 -1
  237. package/dist/server.d.ts.map +1 -1
  238. package/dist/server.js +87 -16
  239. package/dist/sitemap/handlers/prompts.d.ts +6 -0
  240. package/dist/sitemap/handlers/prompts.d.ts.map +1 -0
  241. package/dist/sitemap/handlers/prompts.js +72 -0
  242. package/dist/sitemap/handlers/users.d.ts +6 -0
  243. package/dist/sitemap/handlers/users.d.ts.map +1 -0
  244. package/dist/sitemap/handlers/users.js +80 -0
  245. package/dist/sitemap/manifest.d.ts +8 -0
  246. package/dist/sitemap/manifest.d.ts.map +1 -0
  247. package/dist/sitemap/manifest.js +27 -0
  248. package/dist/types/gateway.d.ts +40 -0
  249. package/dist/types/gateway.d.ts.map +1 -0
  250. package/dist/types/gateway.js +4 -0
  251. package/dist/types/quota.d.ts +74 -0
  252. package/dist/types/quota.d.ts.map +1 -0
  253. package/dist/types/quota.js +11 -0
  254. package/dist/utils/date.d.ts +7 -0
  255. package/dist/utils/date.d.ts.map +1 -0
  256. package/dist/utils/date.js +17 -0
  257. package/dist/web/admin/AdminTokenPacksPage.js +1 -1
  258. package/dist/web/admin/BillingAnalyticsPage.d.ts +2 -0
  259. package/dist/web/admin/BillingAnalyticsPage.d.ts.map +1 -0
  260. package/dist/web/admin/BillingAnalyticsPage.js +141 -0
  261. package/dist/web/admin/GlobalAISettingsPage.d.ts +2 -0
  262. package/dist/web/admin/GlobalAISettingsPage.d.ts.map +1 -0
  263. package/dist/web/admin/GlobalAISettingsPage.js +93 -0
  264. package/dist/web/admin/UserTokenPage.d.ts.map +1 -1
  265. package/dist/web/admin/UserTokenPage.js +20 -7
  266. package/dist/web/auth/AISettingsPage.d.ts +2 -0
  267. package/dist/web/auth/AISettingsPage.d.ts.map +1 -0
  268. package/dist/web/auth/AISettingsPage.js +258 -0
  269. package/dist/web/auth/APIKeysPage.d.ts +2 -0
  270. package/dist/web/auth/APIKeysPage.d.ts.map +1 -0
  271. package/dist/web/auth/APIKeysPage.js +154 -0
  272. package/dist/web/auth/HistoryPage.d.ts +2 -0
  273. package/dist/web/auth/HistoryPage.d.ts.map +1 -0
  274. package/dist/web/auth/HistoryPage.js +279 -0
  275. package/dist/web/auth/PromptsPage.d.ts +5 -0
  276. package/dist/web/auth/PromptsPage.d.ts.map +1 -0
  277. package/dist/web/auth/PromptsPage.js +137 -0
  278. package/dist/web/auth/TokenPage.d.ts.map +1 -1
  279. package/dist/web/auth/TokenPage.js +88 -31
  280. package/dist/web/auth/UsageAndTokensPage.d.ts +2 -0
  281. package/dist/web/auth/UsageAndTokensPage.d.ts.map +1 -0
  282. package/dist/web/auth/UsageAndTokensPage.js +157 -0
  283. package/dist/web/auth/UsagePage.d.ts +2 -0
  284. package/dist/web/auth/UsagePage.d.ts.map +1 -0
  285. package/dist/web/auth/UsagePage.js +62 -0
  286. package/dist/web/auth/components/ApiKeyFilterSelect.d.ts +13 -0
  287. package/dist/web/auth/components/ApiKeyFilterSelect.d.ts.map +1 -0
  288. package/dist/web/auth/components/ApiKeyFilterSelect.js +16 -0
  289. package/dist/web/auth/components/ModelUsageTable.d.ts +19 -0
  290. package/dist/web/auth/components/ModelUsageTable.d.ts.map +1 -0
  291. package/dist/web/auth/components/ModelUsageTable.js +37 -0
  292. package/dist/web/auth/components/PurchaseButton.d.ts +7 -0
  293. package/dist/web/auth/components/PurchaseButton.d.ts.map +1 -0
  294. package/dist/web/auth/components/PurchaseButton.js +13 -0
  295. package/dist/web/auth/components/TokenHistoryCard.d.ts +20 -0
  296. package/dist/web/auth/components/TokenHistoryCard.d.ts.map +1 -0
  297. package/dist/web/auth/components/TokenHistoryCard.js +76 -0
  298. package/dist/web/auth/components/TokenKpiGrid.d.ts +24 -0
  299. package/dist/web/auth/components/TokenKpiGrid.d.ts.map +1 -0
  300. package/dist/web/auth/components/TokenKpiGrid.js +38 -0
  301. package/dist/web/auth/components/UsageByDayChart.d.ts +11 -0
  302. package/dist/web/auth/components/UsageByDayChart.d.ts.map +1 -0
  303. package/dist/web/auth/components/UsageByDayChart.js +32 -0
  304. package/dist/web/auth/components/UsageByModelBarChart.d.ts +12 -0
  305. package/dist/web/auth/components/UsageByModelBarChart.d.ts.map +1 -0
  306. package/dist/web/auth/components/UsageByModelBarChart.js +32 -0
  307. package/dist/web/auth/components/WalletStatusCard.d.ts +9 -0
  308. package/dist/web/auth/components/WalletStatusCard.d.ts.map +1 -0
  309. package/dist/web/auth/components/WalletStatusCard.js +50 -0
  310. package/dist/web/components/ImageGenerative.d.ts +3 -1
  311. package/dist/web/components/ImageGenerative.d.ts.map +1 -1
  312. package/dist/web/components/ImageGenerative.js +139 -52
  313. package/dist/web/components/TextareaGenerative.d.ts +3 -1
  314. package/dist/web/components/TextareaGenerative.d.ts.map +1 -1
  315. package/dist/web/components/TextareaGenerative.js +10 -5
  316. package/dist/web/public/PromptDetailPage.d.ts +25 -0
  317. package/dist/web/public/PromptDetailPage.d.ts.map +1 -0
  318. package/dist/web/public/PromptDetailPage.js +71 -0
  319. package/dist/web/public/PromptDetailPageServer.d.ts +15 -0
  320. package/dist/web/public/PromptDetailPageServer.d.ts.map +1 -0
  321. package/dist/web/public/PromptDetailPageServer.js +68 -0
  322. package/dist/web/public/PublicPromptsPage.d.ts +5 -0
  323. package/dist/web/public/PublicPromptsPage.d.ts.map +1 -0
  324. package/dist/web/public/PublicPromptsPage.js +110 -0
  325. package/dist/web/public/PurchaseTokensPage.d.ts +2 -0
  326. package/dist/web/public/PurchaseTokensPage.d.ts.map +1 -0
  327. package/dist/web/public/PurchaseTokensPage.js +98 -0
  328. package/dist/web/public/UserAvatar.d.ts +13 -0
  329. package/dist/web/public/UserAvatar.d.ts.map +1 -0
  330. package/dist/web/public/UserAvatar.js +13 -0
  331. package/dist/web/public/UserDetailPageServer.d.ts +15 -0
  332. package/dist/web/public/UserDetailPageServer.d.ts.map +1 -0
  333. package/dist/web/public/UserDetailPageServer.js +31 -0
  334. package/dist/web/public/UserPromptsPage.d.ts +9 -0
  335. package/dist/web/public/UserPromptsPage.d.ts.map +1 -0
  336. package/dist/web/public/UserPromptsPage.js +112 -0
  337. package/dist/web/public/UserPromptsPageServer.d.ts +15 -0
  338. package/dist/web/public/UserPromptsPageServer.d.ts.map +1 -0
  339. package/dist/web/public/UserPromptsPageServer.js +31 -0
  340. package/package.json +18 -9
  341. package/supabase/migrations/20251125000000_ai_tokens.sql +7 -0
  342. package/supabase/migrations/20260123100002_user_token_quota_monthly copy.sql +173 -0
  343. package/supabase/migrations/20260128100003_update_and_add_table.sql +368 -0
  344. package/supabase/migrations/20260128120000_seed_providers_models.sql +78 -0
  345. package/supabase/migrations/20260128131405_add_api_key_id_to_ledgers.sql +41 -0
  346. package/supabase/migrations/20260128140000_ai_artifacts_storage.sql +99 -0
  347. package/supabase/migrations/20260128140002_ai_user_settings.sql +57 -0
  348. package/supabase/migrations/20260128150000_drop_ai_user_settings.sql +21 -0
  349. package/supabase/migrations/20260128160000_wallet_billing_system.sql +192 -0
  350. package/supabase/migrations/20260128160001_wallet_rpc_functions.sql +165 -0
  351. package/supabase/migrations/20260128170000_add_pack_coef_to_token_packs.sql +30 -0
  352. package/supabase/migrations/20260129120000_wallet_view_rpc.sql +41 -0
  353. package/supabase/migrations/20260129220003_update_pack_margins.sql +31 -0
  354. package/supabase/migrations/20260129330004_ai_user_prompts.sql +151 -0
  355. package/supabase/migrations/20260129330005_ai_prompts_ip_tracking.sql +92 -0
  356. package/supabase/migrations/20260129330006_ai_prompts_slug.sql +64 -0
  357. package/supabase/migrations/20260129330007_ai_prompts_view_slug.sql +26 -0
  358. package/supabase/migrations/20260129440000_ai_prompts_view_username.sql +33 -0
  359. package/supabase/migrations/20260129450000_ai_prompts_add_lang.sql +40 -0
  360. package/supabase/migrations/20260131000000_extract_model_prompt_in_ledger.sql +92 -0
  361. package/supabase/migrations/20260131140000_fix_duplicate_purchases.sql +64 -0
  362. package/supabase/migrations/20260201120000_module-ai_default_models.sql +63 -0
  363. package/supabase/migrations/20260201130000_module-ai_remove_provider_tables.sql +17 -0
  364. package/supabase/migrations-down/20251217120000_user_token_quota_monthly.sql +34 -0
  365. 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 $$;