casualroom/apps/oa/db/generated/prisma/schema.prisma

434 lines
14 KiB
Plaintext
Executable File
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.

generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-3.0.x"]
output = "../generated/prisma"
}
datasource db {
provider = "postgres"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
name String
username String? @unique
displayUsername String? @map("display_username")
email String @unique
emailVerified Boolean @default(false)
image String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
password String?
deletedAt DateTime?
// 关联关系
organizationId String? @map("organization_id")
organization Organization? @relation(fields: [organizationId], references: [id])
posts Post[]
userActions UserAction[]
roles Role[]
resources Resource[] @relation("UserResources")
// Better Auth 关联关系
sessions Session[]
accounts Account[]
oauthAccessTokens oauthAccessToken[] @relation("UserOAuthAccessTokens")
oauthConsents oauthConsent[] @relation("UserOAuthConsents")
// SSO Provider 关联关系
ssoProviders ssoProvider[] @relation("UserSsoProviders")
metadata Json?
@@index([organizationId, deletedAt]) // 优化组织用户查询
@@map("users")
}
// 支持树形结构的组织模型
model Organization {
id String @id @default(cuid())
name String
slug String? @unique // URL友好的标识符
description String?
logo String?
// 树形结构字段
parentId String? @map("parent_id")
parent Organization? @relation("OrganizationHierarchy", fields: [parentId], references: [id])
children Organization[] @relation("OrganizationHierarchy")
// 路径字段,用于快速查询整个路径 (例如: "1.2.3")
path String?
level Int @default(0) // 层级深度
order Float @default(0) // 同级排序
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
// 关联关系
posts Post[]
users User[]
terms Term[]
// 活跃会话关联
activeSessions Session[] @relation("ActiveOrganization")
// SSO Provider 关联关系
ssoProviders ssoProvider[] @relation("OrganizationSsoProviders")
metadata Json?
@@index([parentId])
@@index([path])
@@index([level, order])
@@index([deletedAt]) // 活跃组织查询优化
@@map("organizations")
}
// 支持多媒体内容和文件管理的帖子模型(多态设计)
model Post {
id String @id @default(cuid())
// 基本信息
type String
title String
content String? // 文本内容(可选,文件类型可能只有文件信息)
excerpt String? // 摘要
// 树形结构字段(支持帖子回复、评论等层级关系,也支持文件夹结构)
parentId String? @map("parent_id")
parent Post? @relation("PostHierarchy", fields: [parentId], references: [id])
children Post[] @relation("PostHierarchy")
// 路径字段,用于快速查询整个路径
path String?
level Int @default(0) // 层级深度0为根帖子/根文件夹1为一级回复/子文件)
order Float @default(0) // 同级排序
// 状态管理
status String // draft, published, archived, deleted
publishedAt DateTime?
visibility String @default("public") // public, private
// 统计数据
viewCount Int @default(0) // 浏览量统计
likeCount Int @default(0) // 点赞数统计
startCount Int @default(0) // 收藏数统计
commentCount Int @default(0) // 评论数统计
// 关联关系
authorId String? @map("author_id")
author User? @relation(fields: [authorId], references: [id])
organizationId String? @map("organization_id")
organization Organization? @relation(fields: [organizationId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
// 关联关系
userActions UserAction[]
terms Term[] // 帖子关联的标签(多对多)
// === 元数据字段JSONB- 存储不经常查询的字段 ===
metadata Json?
// === 优化的索引设计 ===
@@index([type, status, deletedAt]) // 核心查询组合
@@index([parentId, deletedAt, order]) // 目录内容查询优化
@@index([path, deletedAt]) // 路径查询优化
@@index([authorId, type, deletedAt, updatedAt]) // 用户文件查询优化
@@index([organizationId, type, deletedAt, publishedAt]) // 组织文件查询优化
@@index([metadata(ops: JsonbPathOps)], type: Gin) // GIN 索引支持 JSONB 查询
@@map("posts")
}
// 支持树形结构的分类体系模型
model Taxonomy {
id String @id @default(cuid())
name String
slug String @unique
description String?
postTypes String[] @default([]) // 适用文章类型
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
terms Term[]
@@index([deletedAt, slug]) // 活跃分类查询优化
@@map("taxonomies")
}
// 支持树形结构的术语模型
model Term {
id String @id @default(cuid())
name String
slug String
description String?
// 树形结构字段
parentId String? @map("parent_id")
parent Term? @relation("TermHierarchy", fields: [parentId], references: [id])
children Term[] @relation("TermHierarchy")
// 路径字段,用于快速查询整个路径
path String?
level Int @default(0) // 层级深度
order Float @default(0) // 同级排序
// 关联关系
taxonomyId String @map("taxonomy_id")
taxonomy Taxonomy @relation(fields: [taxonomyId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
// 关联关系
posts Post[] // 术语关联的帖子(多对多)
organizations Organization[] // 术语关联的组织(多对多)
@@unique([taxonomyId, slug]) // 同一分类体系下的slug唯一
@@index([parentId])
@@index([path])
@@index([level, order])
@@index([taxonomyId, deletedAt]) // 分类术语查询优化
@@map("terms")
}
// 角色模型(可运行时创建)
model Role {
id String @id @default(cuid())
name String @unique // 角色名称
slug String @unique // URL友好标识符
description String? // 角色描述
permissions String[] // 权限代码数组,对应 SystemPermission 枚举值
// 角色类型
isSystem Boolean @default(false) // 是否为系统预设角色
isActive Boolean @default(true) // 是否启用
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// 关联关系
users User[]
@@index([isSystem, isActive])
@@map("roles")
}
// 统一的用户行为表
model UserAction {
id String @id @default(cuid())
userId String? @map("user_id")
postId String? @map("post_id")
type String // 行为类型: 'view', 'like', 'favorite', 'download', 'share'
description String? // 行为描述
metadata String? // 额外数据JSON格式
ipAddress String? // IP地址
userAgent String? // 用户代理
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
post Post? @relation(fields: [postId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([userId, postId, type], name: "user_post_action_unique")
@@index([type, createdAt]) // 按行为类型和时间查询优化
@@index([postId])
@@index([userId, type, createdAt]) // 用户行为查询优化
@@map("user_actions")
}
// 系统配置模型
model SystemConfig {
id String @id @default(cuid())
key String @unique // 配置键
value String // 配置值JSON字符串
type String @default("string") // 配置类型: string, number, boolean, json
description String? // 配置描述
group String? // 配置分组
isPublic Boolean @default(false) // 是否为公开配置
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([group, isPublic]) // 配置分组查询优化
@@map("system_configs")
}
// ==== 媒体库
model Resource {
id String @id @default(cuid()) @map("id")
title String? @map("title")
description String? @map("description")
type String? @map("type")
fileId String? @unique
url String?
// 元数据
meta Json? @map("meta")
// 处理状态控制
status String?
createdAt DateTime? @default(now()) @map("created_at")
updatedAt DateTime? @updatedAt @map("updated_at")
createdBy String? @map("created_by")
updatedBy String? @map("updated_by")
deletedAt DateTime? @map("deleted_at")
isPublic Boolean? @default(true) @map("is_public")
owner User? @relation("UserResources", fields: [ownerId], references: [id])
ownerId String? @map("owner_id")
// 索引
@@index([type])
@@index([createdAt])
@@map("resource")
}
// ==== Better Auth Standard Models ====
model Session {
id String @id @default(cuid())
expiresAt DateTime
token String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ipAddress String?
userAgent String?
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
// 活跃组织和团队字段
activeOrganizationId String? @map("active_organization_id")
activeTeamId String? @map("active_team_id")
// 关联关系
activeOrganization Organization? @relation("ActiveOrganization", fields: [activeOrganizationId], references: [id])
@@map("session")
}
model Account {
id String @id @default(cuid())
accountId String
providerId String
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
idToken String?
accessToken String?
refreshToken String?
accessTokenExpiresAt DateTime?
refreshTokenExpiresAt DateTime?
scope String?
password String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([providerId, accountId])
@@map("account")
}
model Verification {
id String @id @default(cuid())
identifier String @unique
value String
expiresAt DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("verification")
}
// ==== OIDC Provider Models ====
// OAuth 应用程序
model oauthApplication {
id String @id @default(cuid())
clientId String @unique @map("client_id") // OAuth 客户端的唯一标识符
clientSecret String? @map("client_secret") // 客户端密钥,对于使用 PKCE 的公共客户端为可选
name String // OAuth 客户端名称
redirectURLs String @map("redirect_urls") // 以逗号分隔的重定向 URL 列表
metadata String? // OAuth 客户端的附加元数据
type String // OAuth 客户端类型(例如 Web、移动
disabled Boolean @default(false) // 指示客户端是否被禁用
userId String? @map("user_id") // 拥有客户端的用户 ID可选
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@index([clientId])
@@index([userId])
@@index([disabled])
@@map("oauth_applications")
}
// OAuth 访问令牌
model oauthAccessToken {
id String @id @default(cuid())
accessToken String @map("access_token") // 向客户端颁发的访问令牌
refreshToken String @map("refresh_token") // 向客户端发出的刷新令牌
accessTokenExpiresAt DateTime @map("access_token_expires_at") // 访问令牌的到期日期
refreshTokenExpiresAt DateTime @map("refresh_token_expires_at") // 刷新令牌的到期日期
clientId String @map("client_id") // OAuth 客户端的 ID
userId String @map("user_id") // 与令牌关联的用户的 ID
scopes String // 授予范围的逗号分隔列表
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation("UserOAuthAccessTokens", fields: [userId], references: [id], onDelete: Cascade)
@@index([accessToken])
@@index([refreshToken])
@@index([clientId])
@@index([userId])
@@index([accessTokenExpiresAt])
@@index([refreshTokenExpiresAt])
@@map("oauth_access_tokens")
}
// OAuth 同意
model oauthConsent {
id String @id @default(cuid())
userId String @map("user_id") // 同意用户的 ID
clientId String @map("client_id") // OAuth 客户端的 ID
scopes String // 同意的范围的逗号分隔列表
consentGiven Boolean @map("consent_given") // 表明是否已获得同意
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// 关联关系
user User @relation("UserOAuthConsents", fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, clientId]) // 一个用户对一个客户端只能有一个同意记录
@@index([userId])
@@index([clientId])
@@index([consentGiven])
@@map("oauth_consents")
}
// SSO 提供程序
model ssoProvider {
id String @id @default(cuid())
issuer String // 发行者标识符
domain String // 提供商的域名
oidcConfig String? // OIDC 配置JSON 字符串)
samlConfig String? // SAML 配置JSON 字符串)
userId String? @map("user_id") // 用户 ID
providerId String @unique @map("provider_id") // 提供商 ID用于识别提供商并生成重定向 URL
organizationId String? @map("organization_id") // 组织 ID如果提供商与组织相关联
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// 关联关系
user User? @relation("UserSsoProviders", fields: [userId], references: [id], onDelete: Cascade)
organization Organization? @relation("OrganizationSsoProviders", fields: [organizationId], references: [id], onDelete: Cascade)
@@index([providerId])
@@index([userId])
@@index([organizationId])
@@index([domain])
@@index([issuer])
@@map("sso_providers")
}