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

566 lines
19 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")
// 团队和组织关联
members Member[] @relation("UserMembers")
teamMembers TeamMember[] @relation("UserTeamMembers")
invitations Invitation[] @relation("UserInvitations")
// 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[]
profiles Profile[]
// 团队和组织成员关联
members Member[] @relation("OrganizationMembers")
teams Team[] @relation("OrganizationTeams")
invitations Invitation[] @relation("OrganizationInvitations")
// 活跃会话关联
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 Profile {
// 基本信息
id String @id @default(cuid())
name String // 姓名
gender Int // 性别
idNum String // 身份证号
paperId String? // 证件号
avatar String? // 头像
command String? // 编制命令
birthday DateTime? // 生日
// 入职信息
hireDate DateTime? // 入职时间
relativeHireDate DateTime? // 相对入职时间
// 身份信息
identity String? // 身份
level String? // 等级
levelDate DateTime? // 等级时间
// 职务信息
dutyCode String // 职务代码
dutyLevel Int // 职务级别
dutyName String // 职务名称
// 关联关系
organizationId String @map("organization_id")
organization Organization @relation(fields: [organizationId], references: [id])
// 元数据 - 存储详细的、低频查询的信息
metadata Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
@@index([organizationId, deletedAt]) // 组织人员查询优化
@@index([hireDate])
@@index([level])
@@index([dutyCode, dutyLevel]) // 职务查询优化
@@map("profiles")
}
// ==== 媒体库
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")
}
// 组织成员表
model Member {
id String @id @default(cuid())
userId String @map("user_id")
organizationId String @map("organization_id")
role String // 用户在组织中的角色
createdAt DateTime @default(now())
// 关联关系
user User @relation("UserMembers", fields: [userId], references: [id], onDelete: Cascade)
organization Organization @relation("OrganizationMembers", fields: [organizationId], references: [id], onDelete: Cascade)
@@unique([userId, organizationId]) // 一个用户在一个组织中只能有一个成员记录
@@index([organizationId, role])
@@index([userId])
@@map("members")
}
// 团队表
model Team {
id String @id @default(cuid())
name String // 团队名称
organizationId String @map("organization_id")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// 关联关系
organization Organization @relation("OrganizationTeams", fields: [organizationId], references: [id], onDelete: Cascade)
teamMembers TeamMember[] @relation("TeamMembers")
invitations Invitation[] @relation("TeamInvitations")
// 活跃会话关联
activeSessions Session[] @relation("ActiveTeam")
@@index([organizationId])
@@map("teams")
}
// 团队成员表
model TeamMember {
id String @id @default(cuid())
teamId String @map("team_id")
userId String @map("user_id")
createdAt DateTime @default(now())
// 关联关系
team Team @relation("TeamMembers", fields: [teamId], references: [id], onDelete: Cascade)
user User @relation("UserTeamMembers", fields: [userId], references: [id], onDelete: Cascade)
@@unique([teamId, userId]) // 一个用户在一个团队中只能有一个成员记录
@@index([teamId])
@@index([userId])
@@map("team_members")
}
// 邀请表
model Invitation {
id String @id @default(cuid())
email String // 被邀请人的邮箱地址
inviterId String @map("inviter_id")
organizationId String @map("organization_id")
teamId String? @map("team_id") // 可选的团队ID
role String // 用户在组织中的角色
status String // 邀请状态 (pending, accepted, rejected, expired)
expiresAt DateTime // 邀请过期时间
createdAt DateTime @default(now())
// 关联关系
inviter User @relation("UserInvitations", fields: [inviterId], references: [id], onDelete: Cascade)
organization Organization @relation("OrganizationInvitations", fields: [organizationId], references: [id], onDelete: Cascade)
team Team? @relation("TeamInvitations", fields: [teamId], references: [id], onDelete: Cascade)
@@index([email, status])
@@index([organizationId, status])
@@index([teamId, status])
@@index([expiresAt])
@@map("invitations")
}
// ==== 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])
activeTeam Team? @relation("ActiveTeam", fields: [activeTeamId], 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")
}