Prmbr/prisma/schema.prisma
2025-08-26 21:44:24 +08:00

286 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id // 使用Supabase用户ID不再自动生成
email String @unique
username String? @unique // 允许为空,因为有些用户可能没有设置用户名
avatar String?
bio String?
language String @default("en")
isAdmin Boolean @default(false) // 管理员标记
versionLimit Int @default(3) // 用户自定义版本数量限制,不能超过套餐限制
// 新的订阅系统字段
subscriptionPlanId String @default("free") // 关联的订阅套餐ID
// 旧的订阅系统字段(保留用于迁移,后期会移除)
subscribePlan String @default("free") // 订阅计划: "free", "pro"
maxVersionLimit Int @default(3) // 基于订阅的最大版本限制
promptLimit Int? // 提示词数量限制(已弃用,忽略此字段)
creditBalance Float @default(0.0) // 信用余额,移除默认值
stripeCustomerId String? @unique // Stripe 客户 ID
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// 关联关系
subscriptionPlan SubscriptionPlan @relation(fields: [subscriptionPlanId], references: [id])
prompts Prompt[]
credits Credit[]
subscriptions Subscription[]
simulatorRuns SimulatorRun[]
@@map("users")
}
// 订阅套餐模型
model SubscriptionPlan {
id String @id // "free", "pro" 等
name String // 套餐名称
displayName String // 显示名称(支持国际化)
description String? // 套餐描述
price Float @default(0) // 价格(美元)
currency String @default("usd") // 货币
interval String @default("month") // 计费周期: "month", "year"
stripePriceId String? @unique // Stripe 价格 ID
isActive Boolean @default(true) // 是否激活
sortOrder Int @default(0) // 排序顺序
// 权益配置 (JSON 格式存储)
features Json // 功能特性配置
limits Json // 限制配置
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// 关联关系
users User[]
subscriptions Subscription[]
models Model[]
@@map("subscription_plans")
}
model Prompt {
id String @id @default(cuid())
name String
content String
description String?
isPublic Boolean @default(false) // 保留用于向后兼容
permissions String @default("private") // "private" | "public"
visibility String? // "under_review" | "published" | null
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
tags PromptTag[]
versions PromptVersion[]
album PromptAlbum? @relation(fields: [albumId], references: [id])
albumId String?
tests PromptTestRun[]
stats PromptStats?
simulatorRuns SimulatorRun[]
@@map("prompts")
}
model PromptVersion {
id String @id @default(cuid())
version Int
content String
changelog String?
createdAt DateTime @default(now())
promptId String
prompt Prompt @relation(fields: [promptId], references: [id], onDelete: Cascade)
simulatorRuns SimulatorRun[]
@@unique([promptId, version])
@@map("prompt_versions")
}
model PromptTag {
id String @id @default(cuid())
name String @unique
color String @default("#3B82F6")
prompts Prompt[]
@@map("prompt_tags")
}
model PromptAlbum {
id String @id @default(cuid())
name String
description String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
prompts Prompt[]
@@map("prompt_albums")
}
model PromptTestRun {
id String @id @default(cuid())
input String
output String?
success Boolean @default(false)
error String?
createdAt DateTime @default(now())
promptId String
prompt Prompt @relation(fields: [promptId], references: [id], onDelete: Cascade)
@@map("prompt_test_runs")
}
model PromptStats {
id String @id @default(cuid())
promptId String @unique
viewCount Int @default(0) // 浏览计数
likeCount Int @default(0) // 点赞计数
rating Float? // 平均评分
ratingCount Int @default(0) // 评分数量
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
prompt Prompt @relation(fields: [promptId], references: [id], onDelete: Cascade)
@@map("prompt_stats")
}
model Credit {
id String @id @default(cuid())
userId String
amount Float // 交易金额(正数为充值,负数为消费)
balance Float // 执行该交易后的余额
type String // "system_gift", "subscription_monthly", "user_purchase", "consumption"
category String? // 消费类别: "simulation", "api_call", "export" 等
note String? // 备注说明
referenceId String? // 关联的记录ID如SimulatorRun的ID
referenceType String? // 关联记录类型(如"simulator_run"
expiresAt DateTime? // 过期时间null表示永久有效
isActive Boolean @default(true) // 是否激活状态
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("credits")
}
// 订阅记录模型
model Subscription {
id String @id @default(cuid())
userId String // 用户 ID
subscriptionPlanId String // 订阅套餐 ID
stripeSubscriptionId String? @unique // Stripe 订阅 ID
stripeCustomerId String? // Stripe 客户 ID冗余存储便于查询
// 订阅状态和时间
isActive Boolean @default(false) // 是否有效
startDate DateTime? // 开始时间(订阅激活时设置)
endDate DateTime? // 结束时间(订阅激活时设置)
// 订阅状态
status String @default("pending") // "pending", "active", "canceled", "expired", "failed"
// 元数据
metadata Json? // 额外的元数据(如 Stripe 的原始数据)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// 关联关系
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
subscriptionPlan SubscriptionPlan @relation(fields: [subscriptionPlanId], references: [id])
@@map("subscriptions")
}
// AI 模型配置表 - 每个模型记录直接关联一个套餐
model Model {
id String @id @default(cuid())
subscriptionPlanId String // 关联的套餐 ID
modelId String // OpenRouter 的模型 ID如 "openai/gpt-4"
name String // 显示名称,如 "GPT-4"
provider String // 提供商,如 "OpenAI"
serviceProvider String @default("openrouter") // 服务提供者,如 "openrouter", "replicate"
outputType String @default("text") // 输出类型,如 "text", "image", "video", "audio"
description String? // 模型描述
maxTokens Int? // 最大 token 数
inputCostPer1k Float? // 输入成本每1K tokens
outputCostPer1k Float? // 输出成本每1K tokens
supportedFeatures Json? // 支持的特性(如 function_calling, vision 等)
metadata Json? // 其他元数据
customLimits Json? // 自定义限制(如每日调用次数、最大 tokens 等)
isActive Boolean @default(true) // 是否启用
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// 关联关系
subscriptionPlan SubscriptionPlan @relation(fields: [subscriptionPlanId], references: [id], onDelete: Cascade)
// 关联关系
simulatorRuns SimulatorRun[]
// 同一个套餐内不能有相同的模型ID
@@unique([subscriptionPlanId, modelId])
@@map("models")
}
// 模拟器运行记录
model SimulatorRun {
id String @id @default(cuid())
userId String
name String @default("Simulation Run") // 运行名称
promptId String
promptVersionId String? // 可选,如果选择了特定版本
modelId String
userInput String // 用户输入内容
promptContent String? // 自定义提示词内容(如果用户修改了原提示词)
output String? // AI响应输出
error String? // 错误信息
status String @default("pending") // "pending", "running", "completed", "failed"
// 运行配置
temperature Float? @default(0.7)
maxTokens Int?
topP Float?
frequencyPenalty Float?
presencePenalty Float?
// 消耗和统计
inputTokens Int? // 输入token数
outputTokens Int? // 输出token数
totalCost Float? // 总消费
duration Int? // 运行时长(毫秒)
creditId String? // 关联的信用消费记录ID
createdAt DateTime @default(now())
completedAt DateTime?
// 关联关系
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
prompt Prompt @relation(fields: [promptId], references: [id], onDelete: Cascade)
promptVersion PromptVersion? @relation(fields: [promptVersionId], references: [id], onDelete: SetNull)
model Model @relation(fields: [modelId], references: [id])
@@map("simulator_runs")
}