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") }