@intelligo-dev/core 1.0.0-beta.1 → 1.0.0-beta.14

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 (356) hide show
  1. package/NOTICE +6 -0
  2. package/README.md +102 -0
  3. package/dist/attachments/errors.d.ts +7 -0
  4. package/dist/attachments/errors.d.ts.map +1 -0
  5. package/dist/attachments/errors.js +11 -0
  6. package/dist/attachments/errors.js.map +1 -0
  7. package/dist/attachments/index.d.ts +8 -0
  8. package/dist/attachments/index.d.ts.map +1 -0
  9. package/dist/attachments/index.js +7 -0
  10. package/dist/attachments/index.js.map +1 -0
  11. package/dist/attachments/service.d.ts +45 -0
  12. package/dist/attachments/service.d.ts.map +1 -0
  13. package/dist/attachments/service.js +100 -0
  14. package/dist/attachments/service.js.map +1 -0
  15. package/dist/attachments/types.d.ts +6 -0
  16. package/dist/attachments/types.d.ts.map +1 -0
  17. package/dist/attachments/types.js +2 -0
  18. package/dist/attachments/types.js.map +1 -0
  19. package/dist/conversations/errors.d.ts +2 -8
  20. package/dist/conversations/errors.d.ts.map +1 -1
  21. package/dist/conversations/errors.js +2 -8
  22. package/dist/conversations/errors.js.map +1 -1
  23. package/dist/conversations/index.d.ts +4 -12
  24. package/dist/conversations/index.d.ts.map +1 -1
  25. package/dist/conversations/index.js +2 -11
  26. package/dist/conversations/index.js.map +1 -1
  27. package/dist/conversations/service.d.ts +49 -61
  28. package/dist/conversations/service.d.ts.map +1 -1
  29. package/dist/conversations/service.js +110 -83
  30. package/dist/conversations/service.js.map +1 -1
  31. package/dist/conversations/types.d.ts +1 -4
  32. package/dist/conversations/types.d.ts.map +1 -1
  33. package/dist/conversations/types.js +0 -3
  34. package/dist/conversations/types.js.map +1 -1
  35. package/dist/db/client.d.ts +21 -10
  36. package/dist/db/client.d.ts.map +1 -1
  37. package/dist/db/client.js +43 -18
  38. package/dist/db/client.js.map +1 -1
  39. package/dist/db/index.d.ts +3 -3
  40. package/dist/db/index.d.ts.map +1 -1
  41. package/dist/db/index.js +3 -7
  42. package/dist/db/index.js.map +1 -1
  43. package/dist/db/schema/agents.d.ts +14 -51
  44. package/dist/db/schema/agents.d.ts.map +1 -1
  45. package/dist/db/schema/agents.js +9 -21
  46. package/dist/db/schema/agents.js.map +1 -1
  47. package/dist/db/schema/ai.d.ts +86 -1556
  48. package/dist/db/schema/ai.d.ts.map +1 -1
  49. package/dist/db/schema/ai.js +32 -236
  50. package/dist/db/schema/ai.js.map +1 -1
  51. package/dist/db/schema/auth.d.ts +5 -34
  52. package/dist/db/schema/auth.d.ts.map +1 -1
  53. package/dist/db/schema/auth.js +25 -56
  54. package/dist/db/schema/auth.js.map +1 -1
  55. package/dist/db/schema/billing.d.ts +339 -105
  56. package/dist/db/schema/billing.d.ts.map +1 -1
  57. package/dist/db/schema/billing.js +99 -58
  58. package/dist/db/schema/billing.js.map +1 -1
  59. package/dist/db/schema/feature-flags.d.ts +3 -12
  60. package/dist/db/schema/feature-flags.d.ts.map +1 -1
  61. package/dist/db/schema/feature-flags.js +3 -12
  62. package/dist/db/schema/feature-flags.js.map +1 -1
  63. package/dist/db/schema/identity.d.ts +12 -274
  64. package/dist/db/schema/identity.d.ts.map +1 -1
  65. package/dist/db/schema/identity.js +19 -104
  66. package/dist/db/schema/identity.js.map +1 -1
  67. package/dist/db/schema/index.d.ts +8 -15
  68. package/dist/db/schema/index.d.ts.map +1 -1
  69. package/dist/db/schema/index.js +12 -42
  70. package/dist/db/schema/index.js.map +1 -1
  71. package/dist/db/schema/notifications.d.ts +3 -17
  72. package/dist/db/schema/notifications.d.ts.map +1 -1
  73. package/dist/db/schema/notifications.js +3 -17
  74. package/dist/db/schema/notifications.js.map +1 -1
  75. package/dist/db/schema/usage.d.ts +94 -77
  76. package/dist/db/schema/usage.d.ts.map +1 -1
  77. package/dist/db/schema/usage.js +59 -89
  78. package/dist/db/schema/usage.js.map +1 -1
  79. package/dist/db/validate.d.ts +2 -11
  80. package/dist/db/validate.d.ts.map +1 -1
  81. package/dist/db/validate.js +6 -17
  82. package/dist/db/validate.js.map +1 -1
  83. package/dist/db/workspace-queries.d.ts +5 -29
  84. package/dist/db/workspace-queries.d.ts.map +1 -1
  85. package/dist/db/workspace-queries.js +5 -29
  86. package/dist/db/workspace-queries.js.map +1 -1
  87. package/dist/documents/classifier.d.ts +5 -12
  88. package/dist/documents/classifier.d.ts.map +1 -1
  89. package/dist/documents/classifier.js +16 -16
  90. package/dist/documents/classifier.js.map +1 -1
  91. package/dist/documents/errors.d.ts +2 -10
  92. package/dist/documents/errors.d.ts.map +1 -1
  93. package/dist/documents/errors.js +2 -10
  94. package/dist/documents/errors.js.map +1 -1
  95. package/dist/documents/index.d.ts +4 -13
  96. package/dist/documents/index.d.ts.map +1 -1
  97. package/dist/documents/index.js +3 -12
  98. package/dist/documents/index.js.map +1 -1
  99. package/dist/documents/service.d.ts +19 -26
  100. package/dist/documents/service.d.ts.map +1 -1
  101. package/dist/documents/service.js +44 -38
  102. package/dist/documents/service.js.map +1 -1
  103. package/dist/documents/types.d.ts +6 -10
  104. package/dist/documents/types.d.ts.map +1 -1
  105. package/dist/documents/types.js +0 -3
  106. package/dist/documents/types.js.map +1 -1
  107. package/dist/email/brand.d.ts +17 -0
  108. package/dist/email/brand.d.ts.map +1 -0
  109. package/dist/email/brand.js +9 -0
  110. package/dist/email/brand.js.map +1 -0
  111. package/dist/email/index.d.ts +4 -4
  112. package/dist/email/index.js +4 -4
  113. package/dist/email/provider.d.ts +1 -7
  114. package/dist/email/provider.d.ts.map +1 -1
  115. package/dist/email/provider.js +10 -19
  116. package/dist/email/provider.js.map +1 -1
  117. package/dist/email/send.d.ts +12 -12
  118. package/dist/email/send.d.ts.map +1 -1
  119. package/dist/email/send.js +5 -19
  120. package/dist/email/send.js.map +1 -1
  121. package/dist/email/senders.d.ts +17 -30
  122. package/dist/email/senders.d.ts.map +1 -1
  123. package/dist/email/senders.js +33 -47
  124. package/dist/email/senders.js.map +1 -1
  125. package/dist/email/templates/base-layout.d.ts +1 -1
  126. package/dist/email/templates/base-layout.d.ts.map +1 -1
  127. package/dist/email/templates/base-layout.js +4 -6
  128. package/dist/email/templates/base-layout.js.map +1 -1
  129. package/dist/email/templates/index.d.ts +10 -10
  130. package/dist/email/templates/index.d.ts.map +1 -1
  131. package/dist/email/templates/index.js +10 -16
  132. package/dist/email/templates/index.js.map +1 -1
  133. package/dist/email/templates/password-reset.d.ts +2 -2
  134. package/dist/email/templates/password-reset.d.ts.map +1 -1
  135. package/dist/email/templates/password-reset.js +10 -22
  136. package/dist/email/templates/password-reset.js.map +1 -1
  137. package/dist/email/templates/payment-failed.d.ts +2 -2
  138. package/dist/email/templates/payment-failed.d.ts.map +1 -1
  139. package/dist/email/templates/payment-failed.js +11 -24
  140. package/dist/email/templates/payment-failed.js.map +1 -1
  141. package/dist/email/templates/quota-warning.d.ts +4 -4
  142. package/dist/email/templates/quota-warning.d.ts.map +1 -1
  143. package/dist/email/templates/quota-warning.js +19 -39
  144. package/dist/email/templates/quota-warning.js.map +1 -1
  145. package/dist/email/templates/subscription-confirmed.d.ts +2 -2
  146. package/dist/email/templates/subscription-confirmed.d.ts.map +1 -1
  147. package/dist/email/templates/subscription-confirmed.js +13 -28
  148. package/dist/email/templates/subscription-confirmed.js.map +1 -1
  149. package/dist/email/templates/trial-expiry.d.ts +2 -2
  150. package/dist/email/templates/trial-expiry.d.ts.map +1 -1
  151. package/dist/email/templates/trial-expiry.js +12 -36
  152. package/dist/email/templates/trial-expiry.js.map +1 -1
  153. package/dist/email/templates/trial-warning.d.ts +2 -2
  154. package/dist/email/templates/trial-warning.d.ts.map +1 -1
  155. package/dist/email/templates/trial-warning.js +15 -32
  156. package/dist/email/templates/trial-warning.js.map +1 -1
  157. package/dist/email/templates/verify-email.d.ts +2 -2
  158. package/dist/email/templates/verify-email.d.ts.map +1 -1
  159. package/dist/email/templates/verify-email.js +10 -22
  160. package/dist/email/templates/verify-email.js.map +1 -1
  161. package/dist/email/templates/welcome.d.ts +2 -2
  162. package/dist/email/templates/welcome.d.ts.map +1 -1
  163. package/dist/email/templates/welcome.js +13 -20
  164. package/dist/email/templates/welcome.js.map +1 -1
  165. package/dist/email/templates/workspace-invitation.d.ts +2 -2
  166. package/dist/email/templates/workspace-invitation.d.ts.map +1 -1
  167. package/dist/email/templates/workspace-invitation.js +12 -26
  168. package/dist/email/templates/workspace-invitation.js.map +1 -1
  169. package/dist/env.d.ts +5 -10
  170. package/dist/env.d.ts.map +1 -1
  171. package/dist/env.js +41 -31
  172. package/dist/env.js.map +1 -1
  173. package/dist/identity/audit.d.ts +11 -24
  174. package/dist/identity/audit.d.ts.map +1 -1
  175. package/dist/identity/audit.js +13 -27
  176. package/dist/identity/audit.js.map +1 -1
  177. package/dist/identity/errors.d.ts +4 -12
  178. package/dist/identity/errors.d.ts.map +1 -1
  179. package/dist/identity/errors.js +2 -8
  180. package/dist/identity/errors.js.map +1 -1
  181. package/dist/identity/index.d.ts +6 -13
  182. package/dist/identity/index.d.ts.map +1 -1
  183. package/dist/identity/index.js +5 -12
  184. package/dist/identity/index.js.map +1 -1
  185. package/dist/identity/service.d.ts +29 -47
  186. package/dist/identity/service.d.ts.map +1 -1
  187. package/dist/identity/service.js +107 -79
  188. package/dist/identity/service.js.map +1 -1
  189. package/dist/identity/types.d.ts +28 -4
  190. package/dist/identity/types.d.ts.map +1 -1
  191. package/dist/identity/types.js +0 -3
  192. package/dist/identity/types.js.map +1 -1
  193. package/dist/index.d.ts +1 -2
  194. package/dist/index.d.ts.map +1 -1
  195. package/dist/index.js +3 -10
  196. package/dist/index.js.map +1 -1
  197. package/dist/logger.d.ts +7 -18
  198. package/dist/logger.d.ts.map +1 -1
  199. package/dist/logger.js +45 -49
  200. package/dist/logger.js.map +1 -1
  201. package/dist/money.d.ts +95 -0
  202. package/dist/money.d.ts.map +1 -0
  203. package/dist/money.js +208 -0
  204. package/dist/money.js.map +1 -0
  205. package/dist/notifications/index.d.ts +9 -43
  206. package/dist/notifications/index.d.ts.map +1 -1
  207. package/dist/notifications/index.js +9 -49
  208. package/dist/notifications/index.js.map +1 -1
  209. package/dist/notifications/triggers.d.ts +9 -32
  210. package/dist/notifications/triggers.d.ts.map +1 -1
  211. package/dist/notifications/triggers.js +21 -58
  212. package/dist/notifications/triggers.js.map +1 -1
  213. package/dist/notifications/types.d.ts +6 -8
  214. package/dist/notifications/types.d.ts.map +1 -1
  215. package/dist/notifications/types.js +0 -9
  216. package/dist/notifications/types.js.map +1 -1
  217. package/dist/prompt.d.ts +38 -0
  218. package/dist/prompt.d.ts.map +1 -0
  219. package/dist/prompt.js +118 -0
  220. package/dist/prompt.js.map +1 -0
  221. package/dist/registry.d.ts +32 -0
  222. package/dist/registry.d.ts.map +1 -0
  223. package/dist/registry.js +60 -0
  224. package/dist/registry.js.map +1 -0
  225. package/dist/request-context.d.ts +49 -0
  226. package/dist/request-context.d.ts.map +1 -0
  227. package/dist/request-context.js +100 -0
  228. package/dist/request-context.js.map +1 -0
  229. package/dist/storage/index.d.ts +65 -0
  230. package/dist/storage/index.d.ts.map +1 -0
  231. package/dist/storage/index.js +109 -0
  232. package/dist/storage/index.js.map +1 -0
  233. package/package.json +74 -24
  234. package/src/attachments/errors.ts +18 -0
  235. package/src/attachments/index.ts +22 -0
  236. package/src/attachments/service.ts +178 -0
  237. package/src/attachments/types.ts +6 -0
  238. package/src/conversations/errors.ts +45 -0
  239. package/src/conversations/index.ts +39 -0
  240. package/src/conversations/service.ts +594 -0
  241. package/src/conversations/types.ts +15 -0
  242. package/src/db/client.ts +91 -0
  243. package/src/db/index.ts +3 -0
  244. package/src/db/migrations/0000_baseline.sql +652 -0
  245. package/src/db/migrations/0001_reconcile_chain_built_databases.sql +53 -0
  246. package/src/db/migrations/0002_webhook_claim_lease.sql +1 -0
  247. package/src/db/migrations/0003_local_payments.sql +18 -0
  248. package/src/db/migrations/README.md +103 -36
  249. package/src/db/migrations/legacy-chain.json +206 -0
  250. package/src/db/migrations/meta/0000_snapshot.json +4182 -157
  251. package/src/db/migrations/meta/0002_snapshot.json +2478 -368
  252. package/src/db/migrations/meta/0003_snapshot.json +2567 -554
  253. package/src/db/migrations/meta/_journal.json +8 -274
  254. package/src/db/schema/agents.ts +57 -0
  255. package/src/db/schema/ai.ts +174 -0
  256. package/src/db/schema/auth.ts +183 -0
  257. package/src/db/schema/billing.ts +245 -0
  258. package/src/db/schema/feature-flags.ts +20 -0
  259. package/src/db/schema/identity.ts +250 -0
  260. package/src/db/schema/index.ts +12 -0
  261. package/src/db/schema/notifications.ts +31 -0
  262. package/src/db/schema/usage.ts +269 -0
  263. package/src/db/validate.ts +63 -0
  264. package/src/db/workspace-queries.ts +64 -0
  265. package/src/documents/classifier.ts +61 -0
  266. package/src/documents/errors.ts +44 -0
  267. package/src/documents/index.ts +24 -0
  268. package/src/documents/service.ts +256 -0
  269. package/src/documents/types.ts +24 -0
  270. package/src/email/brand.ts +24 -0
  271. package/src/email/index.ts +19 -0
  272. package/src/email/provider.ts +278 -0
  273. package/src/email/send.ts +169 -0
  274. package/src/email/senders.ts +292 -0
  275. package/src/email/templates/base-layout.tsx +145 -0
  276. package/src/email/templates/index.ts +28 -0
  277. package/src/email/templates/password-reset.tsx +72 -0
  278. package/src/email/templates/payment-failed.tsx +77 -0
  279. package/src/email/templates/quota-warning.tsx +118 -0
  280. package/src/email/templates/subscription-confirmed.tsx +91 -0
  281. package/src/email/templates/trial-expiry.tsx +124 -0
  282. package/src/email/templates/trial-warning.tsx +104 -0
  283. package/src/email/templates/verify-email.tsx +72 -0
  284. package/src/email/templates/welcome.tsx +64 -0
  285. package/src/email/templates/workspace-invitation.tsx +105 -0
  286. package/src/env.ts +180 -0
  287. package/src/identity/audit.ts +65 -0
  288. package/src/identity/errors.ts +44 -0
  289. package/src/identity/index.ts +29 -0
  290. package/src/identity/service.ts +303 -0
  291. package/src/identity/types.ts +58 -0
  292. package/src/index.ts +4 -0
  293. package/src/logger.ts +198 -0
  294. package/src/money.ts +270 -0
  295. package/src/notifications/index.ts +112 -0
  296. package/src/notifications/triggers.ts +158 -0
  297. package/src/notifications/types.ts +26 -0
  298. package/src/prompt.ts +142 -0
  299. package/src/registry.ts +75 -0
  300. package/src/request-context.ts +137 -0
  301. package/src/storage/index.ts +153 -0
  302. package/dist/db/schema/rag.d.ts +0 -171
  303. package/dist/db/schema/rag.d.ts.map +0 -1
  304. package/dist/db/schema/rag.js +0 -42
  305. package/dist/db/schema/rag.js.map +0 -1
  306. package/src/db/migrations/0000_sharp_night_nurse.sql +0 -52
  307. package/src/db/migrations/0001_hesitant_vapor.sql +0 -40
  308. package/src/db/migrations/0002_numerous_lady_vermin.sql +0 -235
  309. package/src/db/migrations/0003_mighty_jean_grey.sql +0 -37
  310. package/src/db/migrations/0004_cynical_grandmaster.sql +0 -2
  311. package/src/db/migrations/0005_careful_switch.sql +0 -8
  312. package/src/db/migrations/0006_tense_blue_marvel.sql +0 -16
  313. package/src/db/migrations/0007_next_squadron_sinister.sql +0 -1
  314. package/src/db/migrations/0008_powerful_scream.sql +0 -39
  315. package/src/db/migrations/0009_sad_ink.sql +0 -1
  316. package/src/db/migrations/0010_shocking_omega_flight.sql +0 -2
  317. package/src/db/migrations/0011_ambiguous_otto_octavius.sql +0 -151
  318. package/src/db/migrations/0011_hnsw_vector_index.sql +0 -17
  319. package/src/db/migrations/0012_user_profiles.sql +0 -30
  320. package/src/db/migrations/0013_trending_seasonal_columns.sql +0 -9
  321. package/src/db/migrations/0014_add_product_type_to_agents.sql +0 -6
  322. package/src/db/migrations/0015_new_v1_tables.sql +0 -149
  323. package/src/db/migrations/0016_document_types.sql +0 -30
  324. package/src/db/migrations/0017_document_metadata.sql +0 -2
  325. package/src/db/migrations/0018_identity_graph.sql +0 -200
  326. package/src/db/migrations/0019_db_driven_prompts.sql +0 -20
  327. package/src/db/migrations/0020_pending_extractions.sql +0 -35
  328. package/src/db/migrations/0021_rag_documents.sql +0 -39
  329. package/src/db/migrations/0022_user_quotas_usage_jsonb.sql +0 -70
  330. package/src/db/migrations/0023_user_facts_user_scoped_unique.sql +0 -17
  331. package/src/db/migrations/0024_user_memories_hnsw.sql +0 -23
  332. package/src/db/migrations/0025_audit_trigger_errcode.sql +0 -21
  333. package/src/db/migrations/0026_user_profile_snapshots_composite_pk.sql +0 -17
  334. package/src/db/migrations/0027_billing_settings_mnt_columns.sql +0 -54
  335. package/src/db/migrations/0028_trial_credits_normalized_email.sql +0 -37
  336. package/src/db/migrations/0029_usage_records_conversation_idx.sql +0 -13
  337. package/src/db/migrations/0030_pending_extractions_composite_idx.sql +0 -11
  338. package/src/db/migrations/0031_rag_documents_hnsw.sql +0 -16
  339. package/src/db/migrations/0032_rate_limit_unique_idx.sql +0 -16
  340. package/src/db/migrations/0033_pending_extractions_partial_idx.sql +0 -18
  341. package/src/db/migrations/0034_rate_limit_count.sql +0 -9
  342. package/src/db/migrations/0035_credit_reservations.sql +0 -24
  343. package/src/db/migrations/0036_executions_audit_jobs.sql +0 -96
  344. package/src/db/migrations/0037_rate_limit_minute_bucket.sql +0 -46
  345. package/src/db/migrations/0038_user_quotas_generic_usage.sql +0 -25
  346. package/src/db/migrations/0039_platform_admin_impersonation.sql +0 -27
  347. package/src/db/migrations/0040_ee_audit_chain.sql +0 -23
  348. package/src/db/migrations/meta/0001_snapshot.json +0 -631
  349. package/src/db/migrations/meta/0004_snapshot.json +0 -2500
  350. package/src/db/migrations/meta/0005_snapshot.json +0 -2548
  351. package/src/db/migrations/meta/0006_snapshot.json +0 -2650
  352. package/src/db/migrations/meta/0007_snapshot.json +0 -2657
  353. package/src/db/migrations/meta/0008_snapshot.json +0 -2719
  354. package/src/db/migrations/meta/0009_snapshot.json +0 -2726
  355. package/src/db/migrations/meta/0010_snapshot.json +0 -2739
  356. package/src/db/migrations/meta/0011_snapshot.json +0 -3886
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Better-Auth's tables. Table and column names must match what its Drizzle
3
+ * adapter expects.
4
+ */
5
+
6
+ import { sql } from "drizzle-orm";
7
+ import {
8
+ pgTable,
9
+ text,
10
+ timestamp,
11
+ boolean,
12
+ index,
13
+ uniqueIndex,
14
+ } from "drizzle-orm/pg-core";
15
+
16
+ export const users = pgTable(
17
+ "users",
18
+ {
19
+ id: text("id").primaryKey(),
20
+ name: text("name").notNull(),
21
+ email: text("email").notNull().unique(),
22
+ emailVerified: boolean("email_verified").notNull().default(false),
23
+ image: text("image"),
24
+ deletedAt: timestamp("deleted_at"), // Soft delete: null = active, timestamp = deleted
25
+ createdAt: timestamp("created_at").notNull().defaultNow(),
26
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
27
+ onboardingCompleted: boolean("onboarding_completed")
28
+ .notNull()
29
+ .default(false),
30
+ onboardingStep: text("onboarding_step"), // Current step if incomplete: "workspace" | "language" | "product"
31
+ preferredLanguage: text("preferred_language").notNull().default("en"), // a locale the app ships, e.g. "en"
32
+ /**
33
+ * Platform role, not a workspace role — "platform-admin" or null. Grants
34
+ * the operational console and impersonation. PLATFORM_ADMIN_EMAILS seeds
35
+ * it: requirePlatformAdmin promotes an allowlisted user on first use.
36
+ */
37
+ role: text("role"),
38
+ /** Required by Better-Auth's admin plugin schema; unused otherwise. */
39
+ banned: boolean("banned").notNull().default(false),
40
+ banReason: text("ban_reason"),
41
+ banExpires: timestamp("ban_expires"),
42
+ },
43
+ (table) => [
44
+ // Finding the platform admins: a handful of rows among many.
45
+ index("users_role_idx")
46
+ .on(table.role)
47
+ .where(sql`${table.role} IS NOT NULL`),
48
+ ]
49
+ );
50
+
51
+ export const sessions = pgTable(
52
+ "sessions",
53
+ {
54
+ id: text("id").primaryKey(),
55
+ userId: text("user_id")
56
+ .notNull()
57
+ .references(() => users.id, { onDelete: "cascade" }),
58
+ token: text("token").notNull().unique(),
59
+ expiresAt: timestamp("expires_at").notNull(),
60
+ ipAddress: text("ip_address"),
61
+ userAgent: text("user_agent"),
62
+ /**
63
+ * Set on a session created by an admin acting as this user, so
64
+ * impersonation stays visible on the session and in the audit trail.
65
+ */
66
+ impersonatedBy: text("impersonated_by"),
67
+ /**
68
+ * The organization plugin's active workspace. Without this column its
69
+ * set-active writes are silently dropped and workspace switching never
70
+ * persists.
71
+ */
72
+ activeOrganizationId: text("active_organization_id"),
73
+ createdAt: timestamp("created_at").notNull().defaultNow(),
74
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
75
+ },
76
+ (table) => [index("sessions_user_id_idx").on(table.userId)]
77
+ );
78
+
79
+ /** OAuth provider connections and password credentials. */
80
+ export const accounts = pgTable(
81
+ "accounts",
82
+ {
83
+ id: text("id").primaryKey(),
84
+ userId: text("user_id")
85
+ .notNull()
86
+ .references(() => users.id, { onDelete: "cascade" }),
87
+ accountId: text("account_id").notNull(),
88
+ providerId: text("provider_id").notNull(),
89
+ accessToken: text("access_token"),
90
+ refreshToken: text("refresh_token"),
91
+ accessTokenExpiresAt: timestamp("access_token_expires_at"),
92
+ refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
93
+ scope: text("scope"),
94
+ idToken: text("id_token"),
95
+ password: text("password"),
96
+ createdAt: timestamp("created_at").notNull().defaultNow(),
97
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
98
+ },
99
+ (table) => [index("accounts_user_id_idx").on(table.userId)]
100
+ );
101
+
102
+ /** Email verification and password reset tokens. */
103
+ export const verifications = pgTable("verifications", {
104
+ id: text("id").primaryKey(),
105
+ identifier: text("identifier").notNull(),
106
+ value: text("value").notNull(),
107
+ expiresAt: timestamp("expires_at").notNull(),
108
+ createdAt: timestamp("created_at").notNull().defaultNow(),
109
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
110
+ });
111
+
112
+ /** Workspaces, managed by Better-Auth's organization plugin. */
113
+ export const organization = pgTable("organization", {
114
+ id: text("id").primaryKey(),
115
+ name: text("name").notNull(),
116
+ slug: text("slug").unique(),
117
+ logo: text("logo"),
118
+ metadata: text("metadata"),
119
+ createdAt: timestamp("created_at").notNull().defaultNow(),
120
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
121
+ });
122
+
123
+ export const member = pgTable(
124
+ "member",
125
+ {
126
+ id: text("id").primaryKey(),
127
+ organizationId: text("organization_id")
128
+ .notNull()
129
+ .references(() => organization.id, { onDelete: "cascade" }),
130
+ userId: text("user_id")
131
+ .notNull()
132
+ .references(() => users.id, { onDelete: "cascade" }),
133
+ role: text("role").notNull(),
134
+ createdAt: timestamp("created_at").notNull().defaultNow(),
135
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
136
+ },
137
+ (table) => [
138
+ index("member_organization_id_idx").on(table.organizationId),
139
+ index("member_user_id_idx").on(table.userId),
140
+ uniqueIndex("member_organization_user_uniq").on(
141
+ table.organizationId,
142
+ table.userId
143
+ ),
144
+ ]
145
+ );
146
+
147
+ export const invitation = pgTable(
148
+ "invitation",
149
+ {
150
+ id: text("id").primaryKey(),
151
+ organizationId: text("organization_id")
152
+ .notNull()
153
+ .references(() => organization.id, { onDelete: "cascade" }),
154
+ email: text("email").notNull(),
155
+ role: text("role").notNull(),
156
+ status: text("status").notNull(),
157
+ expiresAt: timestamp("expires_at").notNull(),
158
+ inviterId: text("inviter_id").references(() => users.id, {
159
+ onDelete: "set null",
160
+ }),
161
+ createdAt: timestamp("created_at").notNull().defaultNow(),
162
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
163
+ },
164
+ (table) => [
165
+ index("invitation_organization_id_idx").on(table.organizationId),
166
+ index("invitation_email_idx").on(table.email),
167
+ ]
168
+ );
169
+
170
+ export type User = typeof users.$inferSelect;
171
+ export type InsertUser = typeof users.$inferInsert;
172
+ export type Session = typeof sessions.$inferSelect;
173
+ export type InsertSession = typeof sessions.$inferInsert;
174
+ export type Account = typeof accounts.$inferSelect;
175
+ export type InsertAccount = typeof accounts.$inferInsert;
176
+ export type Verification = typeof verifications.$inferSelect;
177
+ export type InsertVerification = typeof verifications.$inferInsert;
178
+ export type Organization = typeof organization.$inferSelect;
179
+ export type InsertOrganization = typeof organization.$inferInsert;
180
+ export type Member = typeof member.$inferSelect;
181
+ export type InsertMember = typeof member.$inferInsert;
182
+ export type Invitation = typeof invitation.$inferSelect;
183
+ export type InsertInvitation = typeof invitation.$inferInsert;
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Plans, subscriptions, credit ledgers, purchases, local payments and
3
+ * Stripe events. Amounts in the credit ledgers are micros of their
4
+ * currency; amounts a buyer paid are minor units of theirs.
5
+ */
6
+
7
+ import {
8
+ pgTable,
9
+ text,
10
+ timestamp,
11
+ integer,
12
+ bigint,
13
+ boolean,
14
+ index,
15
+ unique,
16
+ } from "drizzle-orm/pg-core";
17
+ import { organization, users } from "./auth";
18
+
19
+ /**
20
+ * The registered plan catalogue, copied into rows so a subscription can
21
+ * reference its plan. The catalogue is the source: the rows are written
22
+ * from it at boot, and an edit made here is overwritten by the next one.
23
+ */
24
+ export const plans = pgTable("plans", {
25
+ id: text("id").primaryKey(),
26
+ name: text("name").notNull(),
27
+ slug: text("slug").notNull().unique(),
28
+ description: text("description"),
29
+ /**
30
+ * Whole major units — 29 is twenty-nine of the currency, not cents —
31
+ * rounded from the catalogue's price. 0 for free. The row names no
32
+ * currency; readers take the deployment's billing currency.
33
+ */
34
+ priceMonthly: integer("price_monthly").notNull(),
35
+ /** Whole major units, as `priceMonthly`. 0 when the plan has no yearly price. */
36
+ priceYearly: integer("price_yearly").notNull(),
37
+ stripePriceIdMonthly: text("stripe_price_id_monthly"),
38
+ stripePriceIdYearly: text("stripe_price_id_yearly"),
39
+ features: text("features").notNull(), // JSON string array
40
+ limits: text("limits").notNull(), // JSON string: { tokens, conversations, teamMembers, workspaces, documents }
41
+ isActive: boolean("is_active").notNull().default(true),
42
+ sortOrder: integer("sort_order").notNull().default(0),
43
+ createdAt: timestamp("created_at").notNull().defaultNow(),
44
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
45
+ });
46
+
47
+ /** One subscription per workspace (unique constraint). */
48
+ export const subscriptions = pgTable(
49
+ "subscriptions",
50
+ {
51
+ id: text("id").primaryKey(),
52
+ workspaceId: text("workspace_id")
53
+ .notNull()
54
+ .references(() => organization.id, { onDelete: "cascade" }),
55
+ planId: text("plan_id")
56
+ .notNull()
57
+ .references(() => plans.id, { onDelete: "restrict" }),
58
+ stripeCustomerId: text("stripe_customer_id"),
59
+ stripeSubscriptionId: text("stripe_subscription_id").unique(),
60
+ status: text("status").notNull().default("active"), // active|past_due|canceled|trialing|incomplete
61
+ billingMode: text("billing_mode").notNull().default("subscription"), // subscription|credit
62
+ currentPeriodStart: timestamp("current_period_start"),
63
+ currentPeriodEnd: timestamp("current_period_end"),
64
+ cancelAtPeriodEnd: boolean("cancel_at_period_end").notNull().default(false),
65
+ createdAt: timestamp("created_at").notNull().defaultNow(),
66
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
67
+ },
68
+ (table) => [
69
+ index("subscriptions_workspace_id_idx").on(table.workspaceId),
70
+ unique("subscriptions_workspace_id_unique").on(table.workspaceId),
71
+ ]
72
+ );
73
+
74
+ /** One credit balance per workspace (unique constraint). */
75
+ export const creditBalances = pgTable("credit_balances", {
76
+ id: text("id").primaryKey(),
77
+ workspaceId: text("workspace_id")
78
+ .notNull()
79
+ .unique()
80
+ .references(() => organization.id, { onDelete: "cascade" }),
81
+ /** The balance, in micros of `currency`. */
82
+ balanceMicros: bigint("balance_micros", { mode: "number" })
83
+ .notNull()
84
+ .default(0),
85
+ totalPurchasedMicros: bigint("total_purchased_micros", { mode: "number" })
86
+ .notNull()
87
+ .default(0),
88
+ totalUsedMicros: bigint("total_used_micros", { mode: "number" })
89
+ .notNull()
90
+ .default(0),
91
+ /** What this ledger is denominated in; a write in another is refused. */
92
+ currency: text("currency").notNull().default("USD"),
93
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
94
+ });
95
+
96
+ /**
97
+ * Singleton (id = "default") holding the FX rate and margin, so they change
98
+ * without a deploy. Read per request, cached 60s in-process.
99
+ */
100
+ export const billingSettings = pgTable("billing_settings", {
101
+ id: text("id").primaryKey(),
102
+ /** The deployment's billing currency — every ledger row is in this. */
103
+ currency: text("currency").notNull().default("USD"),
104
+ /** What one USD costs in it, in micros: 1_000_000 is a USD deployment. */
105
+ usdRateMicros: bigint("usd_rate_micros", { mode: "number" })
106
+ .notNull()
107
+ .default(1_000_000),
108
+ /** Margin over provider cost, in basis points of a multiplier: 40_000 = 4×. */
109
+ marginBp: integer("margin_bp").notNull().default(40_000),
110
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
111
+ });
112
+
113
+ /** One-time credit purchases. */
114
+ export const creditPurchases = pgTable(
115
+ "credit_purchases",
116
+ {
117
+ id: text("id").primaryKey(),
118
+ workspaceId: text("workspace_id")
119
+ .notNull()
120
+ .references(() => organization.id, { onDelete: "cascade" }),
121
+ /** What the buyer paid, in minor units of `priceCurrency`. */
122
+ priceMinor: integer("price_minor"),
123
+ priceCurrency: text("price_currency"),
124
+ /**
125
+ * What the workspace was granted, in micros of `grantedCurrency`.
126
+ * Separate from the price on purpose: a pack sold for $5 grants an
127
+ * amount of the billing currency, which is a different unit.
128
+ */
129
+ grantedMicros: bigint("granted_micros", { mode: "number" }),
130
+ grantedCurrency: text("granted_currency"),
131
+ stripePaymentIntentId: text("stripe_payment_intent_id"),
132
+ stripeCheckoutSessionId: text("stripe_checkout_session_id"),
133
+ status: text("status").notNull().default("pending"), // pending|completed|failed
134
+ createdAt: timestamp("created_at").notNull().defaultNow(),
135
+ },
136
+ (table) => [index("credit_purchases_workspace_id_idx").on(table.workspaceId)]
137
+ );
138
+
139
+ /**
140
+ * Invoices issued through a registered payment provider (QR-and-poll
141
+ * methods such as QPay, PIX or UPI), one row per invoice. The row is
142
+ * written when the invoice is opened, so settlement knows who pays and
143
+ * what was priced without trusting the browser; `fulfilled_at` is set
144
+ * in the same transaction that grants what was bought, so a payment is
145
+ * granted once however many polls see it paid.
146
+ */
147
+ export const payments = pgTable(
148
+ "payments",
149
+ {
150
+ id: text("id").primaryKey(),
151
+ /** The PAYMENT_MODE the invoice was opened under; settlement asks the same provider. */
152
+ provider: text("provider").notNull(),
153
+ invoiceId: text("invoice_id").notNull().unique(),
154
+ workspaceId: text("workspace_id")
155
+ .notNull()
156
+ .references(() => organization.id, { onDelete: "cascade" }),
157
+ userId: text("user_id").references(() => users.id, {
158
+ onDelete: "set null",
159
+ }),
160
+ /** What was bought, in the product's words: a plan slug, a bundle id. */
161
+ reference: text("reference").notNull(),
162
+ /** The price, in minor units of `currency`. */
163
+ amountMinor: integer("amount_minor").notNull(),
164
+ currency: text("currency").notNull(),
165
+ status: text("status").notNull().default("pending"), // pending|paid|failed
166
+ fulfilledAt: timestamp("fulfilled_at"),
167
+ createdAt: timestamp("created_at").notNull().defaultNow(),
168
+ },
169
+ (table) => [index("payments_workspace_id_idx").on(table.workspaceId)]
170
+ );
171
+
172
+ /** Every Stripe event, for idempotent webhook processing and audit. */
173
+ export const financeEvents = pgTable("finance_events", {
174
+ id: text("id").primaryKey(),
175
+ workspaceId: text("workspace_id").references(() => organization.id, {
176
+ onDelete: "set null",
177
+ }),
178
+ stripeEventId: text("stripe_event_id").notNull().unique(),
179
+ type: text("type").notNull(), // e.g., "checkout.session.completed", "invoice.paid"
180
+ /** Stripe's own amount, in the minor units of `currency`. */
181
+ amountMinor: integer("amount_minor"),
182
+ currency: text("currency").default("USD"),
183
+ metadata: text("metadata"), // JSON string
184
+ /**
185
+ * When a delivery took the event for processing. A lease: a claim
186
+ * older than the webhook's lease is taken as a delivery that died.
187
+ */
188
+ claimedAt: timestamp("claimed_at"),
189
+ /** Set once the handlers finished; the event is never run again. */
190
+ processedAt: timestamp("processed_at"),
191
+ createdAt: timestamp("created_at").notNull().defaultNow(),
192
+ });
193
+
194
+ /**
195
+ * Closes the admission → settlement race. Admission inserts a reservation
196
+ * for the worst-case estimate inside the same transaction that sums the
197
+ * other active reservations, so concurrent requests cannot all be admitted
198
+ * against the same balance. Settlement closes the reservation; abandoned
199
+ * ones expire via `expires_at`, are ignored by the sum, and are deleted by
200
+ * a cleanup job.
201
+ */
202
+ export const creditReservations = pgTable(
203
+ "credit_reservations",
204
+ {
205
+ id: text("id").primaryKey(),
206
+ workspaceId: text("workspace_id")
207
+ .notNull()
208
+ .references(() => organization.id, { onDelete: "cascade" }),
209
+ /** Correlates admission with settlement. */
210
+ requestId: text("request_id").notNull().unique(),
211
+ /** The hold, in micros of `currency`. */
212
+ estimatedMicros: bigint("estimated_micros", { mode: "number" })
213
+ .notNull()
214
+ .default(0),
215
+ currency: text("currency").notNull().default("USD"),
216
+ status: text("status").notNull().default("active"), // active | settled
217
+ createdAt: timestamp("created_at").notNull().defaultNow(),
218
+ expiresAt: timestamp("expires_at").notNull(),
219
+ settledAt: timestamp("settled_at"),
220
+ },
221
+ (table) => [
222
+ index("credit_reservations_active_idx").on(
223
+ table.workspaceId,
224
+ table.status,
225
+ table.expiresAt
226
+ ),
227
+ ]
228
+ );
229
+
230
+ export type Plan = typeof plans.$inferSelect;
231
+ export type InsertPlan = typeof plans.$inferInsert;
232
+ export type Subscription = typeof subscriptions.$inferSelect;
233
+ export type InsertSubscription = typeof subscriptions.$inferInsert;
234
+ export type CreditBalance = typeof creditBalances.$inferSelect;
235
+ export type InsertCreditBalance = typeof creditBalances.$inferInsert;
236
+ export type CreditPurchase = typeof creditPurchases.$inferSelect;
237
+ export type InsertCreditPurchase = typeof creditPurchases.$inferInsert;
238
+ export type Payment = typeof payments.$inferSelect;
239
+ export type InsertPayment = typeof payments.$inferInsert;
240
+ export type FinanceEvent = typeof financeEvents.$inferSelect;
241
+ export type InsertFinanceEvent = typeof financeEvents.$inferInsert;
242
+ export type BillingSettings = typeof billingSettings.$inferSelect;
243
+ export type InsertBillingSettings = typeof billingSettings.$inferInsert;
244
+ export type CreditReservation = typeof creditReservations.$inferSelect;
245
+ export type InsertCreditReservation = typeof creditReservations.$inferInsert;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Runtime overrides for feature gates: `@intelligo-dev/billing`'s feature
3
+ * check reads a flag by name here before it falls back to the plan's
4
+ * entitlements, so a feature can be switched without a deploy.
5
+ */
6
+
7
+ import { pgTable, text, timestamp, boolean } from "drizzle-orm/pg-core";
8
+
9
+ export const featureFlags = pgTable("feature_flags", {
10
+ id: text("id").primaryKey(),
11
+ name: text("name").notNull().unique(),
12
+ description: text("description"),
13
+ enabledPlans: text("enabled_plans").notNull(), // JSON array string: e.g., '["free","pro","enterprise"]'
14
+ isActive: boolean("is_active").notNull().default(true),
15
+ createdAt: timestamp("created_at").notNull().defaultNow(),
16
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
17
+ });
18
+
19
+ export type FeatureFlag = typeof featureFlags.$inferSelect;
20
+ export type InsertFeatureFlag = typeof featureFlags.$inferInsert;