schema.prisma 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // DoTouch.AI - Prisma Schema
  2. // PostgreSQL 16 datasource, client generated via `pnpm db:generate`
  3. generator client {
  4. provider = "prisma-client-js"
  5. }
  6. datasource db {
  7. provider = "postgresql"
  8. url = env("DATABASE_URL")
  9. }
  10. // ---- 用户 ----
  11. model User {
  12. id String @id @default(cuid())
  13. email String @unique
  14. passwordHash String @map("password_hash")
  15. // 社交登录:provider = local | google | facebook;providerId 为平台唯一 ID(同邮箱绑定后记录)
  16. provider String @default("local")
  17. providerId String? @unique @map("provider_id")
  18. // 邀请奖励:唯一邀请码 + 被谁邀请
  19. referralCode String? @unique @map("referral_code")
  20. referredById String? @map("referred_by_id")
  21. referredBy User? @relation("Referrals", fields: [referredById], references: [id])
  22. referrals User[] @relation("Referrals")
  23. referralRecords ReferralRecord[] @relation("RecordsAsReferrer")
  24. referredRecords ReferralRecord[]
  25. referralRewards ReferralReward[]
  26. role String @default("user") // user | admin
  27. currency String @default("USD")
  28. balanceCents BigInt @default(0) @map("balance_cents")
  29. status String @default("active") // active | suspended | banned
  30. createdAt DateTime @default(now()) @map("created_at")
  31. updatedAt DateTime @updatedAt @map("updated_at")
  32. // 用量配额(null = 不限)
  33. dailyRequestLimit Int? @map("daily_request_limit")
  34. dailyTokenLimit BigInt? @map("daily_token_limit")
  35. dailyCostCentsLimit Int? @map("daily_cost_cents_limit")
  36. totalRequestLimit Int? @map("total_request_limit")
  37. totalTokenLimit BigInt? @map("total_token_limit")
  38. totalCostCentsLimit Int? @map("total_cost_cents_limit")
  39. alertPct Int @default(80) @map("alert_pct")
  40. apiKeys ApiKey[]
  41. balanceTransactions BalanceTransaction[]
  42. usageRecords UsageRecord[]
  43. orders Order[]
  44. @@map("users")
  45. }
  46. // ---- API 密钥 ----
  47. model ApiKey {
  48. id String @id @default(cuid())
  49. userId String @map("user_id")
  50. name String
  51. keyHash String @unique @map("key_hash")
  52. prefix String // 前 12 位用于展示(dt_ + 32 hex = 36 chars)
  53. expiresAt DateTime? @map("expires_at")
  54. lastUsedAt DateTime? @map("last_used_at")
  55. status String @default("active") // active | revoked
  56. createdAt DateTime @default(now()) @map("created_at")
  57. updatedAt DateTime @updatedAt @map("updated_at")
  58. // 用量配额(null = 不限)
  59. dailyRequestLimit Int? @map("daily_request_limit")
  60. dailyTokenLimit BigInt? @map("daily_token_limit")
  61. dailyCostCentsLimit Int? @map("daily_cost_cents_limit")
  62. totalRequestLimit Int? @map("total_request_limit")
  63. totalTokenLimit BigInt? @map("total_token_limit")
  64. totalCostCentsLimit Int? @map("total_cost_cents_limit")
  65. alertPct Int @default(80) @map("alert_pct")
  66. user User @relation(fields: [userId], references: [id])
  67. usageRecords UsageRecord[]
  68. events ApiKeyEvent[]
  69. @@map("api_keys")
  70. }
  71. // ---- API Key 事件审计日志 ----
  72. model ApiKeyEvent {
  73. id String @id @default(cuid())
  74. apiKeyId String @map("api_key_id")
  75. userId String @map("user_id")
  76. action String // created | rotated | revoked | used
  77. ip String?
  78. createdAt DateTime @default(now()) @map("created_at")
  79. apiKey ApiKey @relation(fields: [apiKeyId], references: [id])
  80. @@map("api_key_events")
  81. }
  82. // ---- 模型目录(DB-backed) ----
  83. model ModelCatalog {
  84. id String @id @default(cuid())
  85. publicId String @unique @map("public_id")
  86. upstreamId String @map("upstream_id")
  87. name String
  88. provider String // Zhipu | DeepSeek | Alibaba | MiniMax | Kimi | SiliconFlow | Other
  89. category String // chat | vision | image | speech
  90. description String?
  91. contextWindow Int? @map("context_window")
  92. maxOutput Int? @map("max_output")
  93. inputPriceCents Int @default(0) @map("input_price_cents")
  94. outputPriceCents Int @default(0) @map("output_price_cents")
  95. isRecommended Boolean @default(false) @map("is_recommended")
  96. status String @default("active") // active | hidden | disabled
  97. sortOrder Int @default(0) @map("sort_order")
  98. createdAt DateTime @default(now()) @map("created_at")
  99. updatedAt DateTime @updatedAt @map("updated_at")
  100. @@map("models")
  101. }
  102. // ---- 余额变动记录 ----
  103. model BalanceTransaction {
  104. id String @id @default(cuid())
  105. userId String @map("user_id")
  106. amountCents BigInt @map("amount_cents")
  107. type String // topup | charge | refund | usage | refund
  108. refId String? @map("ref_id")
  109. createdAt DateTime @default(now()) @map("created_at")
  110. user User @relation(fields: [userId], references: [id])
  111. @@map("balance_transactions")
  112. }
  113. // ---- 用量记录 ----
  114. model UsageRecord {
  115. id String @id @default(cuid())
  116. userId String @map("user_id")
  117. apiKeyId String @map("api_key_id")
  118. model String
  119. promptTokens Int @map("prompt_tokens")
  120. completionTokens Int @map("completion_tokens")
  121. costCents Int @map("cost_cents")
  122. createdAt DateTime @default(now()) @map("created_at")
  123. user User @relation(fields: [userId], references: [id])
  124. apiKey ApiKey @relation(fields: [apiKeyId], references: [id])
  125. @@map("usage_records")
  126. }
  127. // ---- 配额事件(预警 + 超限审计) ----
  128. model QuotaEvent {
  129. id String @id @default(cuid())
  130. userId String @map("user_id")
  131. apiKeyId String? @map("api_key_id")
  132. dimension String // request | token | cost
  133. windowType String @map("window_type") // daily | total
  134. scopeType String @map("scope_type") // account | key
  135. threshold Int
  136. current BigInt
  137. action String // alert | block
  138. createdAt DateTime @default(now()) @map("created_at")
  139. @@map("quota_events")
  140. }
  141. // ---- 订单 ----
  142. model Order {
  143. id String @id @default(cuid())
  144. userId String @map("user_id")
  145. provider String // alipay | stripe | ...
  146. providerOrderId String? @map("provider_order_id")
  147. amountCents BigInt @map("amount_cents")
  148. status String @default("pending") // pending | paid | failed | refunded
  149. currency String @default("USD")
  150. paidAt DateTime? @map("paid_at")
  151. createdAt DateTime @default(now()) @map("created_at")
  152. updatedAt DateTime @updatedAt @map("updated_at")
  153. user User @relation(fields: [userId], references: [id])
  154. @@map("orders")
  155. }
  156. // 邀请记录:每对被邀请关系一条
  157. model ReferralRecord {
  158. id String @id @default(cuid())
  159. referrerId String @map("referrer_id")
  160. refereeId String @map("referee_id")
  161. refereeEmail String @map("referee_email")
  162. status String @default("registered") // registered | paid | rewarded
  163. registerAt DateTime @default(now()) @map("register_at")
  164. firstPaidAt DateTime? @map("first_paid_at")
  165. firstPaidCents BigInt? @map("first_paid_cents")
  166. createdAt DateTime @default(now()) @map("created_at")
  167. referrer User @relation("RecordsAsReferrer", fields: [referrerId], references: [id])
  168. referee User @relation(fields: [refereeId], references: [id])
  169. rewards ReferralReward[]
  170. @@map("referral_records")
  171. }
  172. // 奖励记录:注册奖励 / 被邀请人首充奖励 / 邀请人付费奖励
  173. model ReferralReward {
  174. id String @id @default(cuid())
  175. userId String @map("user_id")
  176. recordId String @map("record_id")
  177. type String // register | referee_first_pay | referrer_pay
  178. amountCents BigInt @map("amount_cents")
  179. status String @default("credited") // pending | credited
  180. createdAt DateTime @default(now()) @map("created_at")
  181. user User @relation(fields: [userId], references: [id])
  182. record ReferralRecord @relation(fields: [recordId], references: [id])
  183. @@map("referral_rewards")
  184. }
  185. // 系统配置(邀请奖励策略等,管理后台可调)
  186. model SystemConfig {
  187. id String @id @default(cuid())
  188. key String @unique
  189. value String
  190. updatedAt DateTime @updatedAt @map("updated_at")
  191. @@map("system_configs")
  192. }