training_data/packages/common/prisma/schema.prisma

482 lines
19 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
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Taxonomy {
id String @id @default(cuid())
name String @unique
slug String @unique @map("slug")
deletedAt DateTime? @map("deleted_at")
createdAt DateTime @default(now()) @map("created_at")
terms Term[]
objectType String[] @map("object_type")
order Float? @map("order")
@@index([order, deletedAt])
@@map("taxonomy")
}
model Term {
id String @id @default(cuid())
name String
taxonomy Taxonomy? @relation(fields: [taxonomyId], references: [id])
taxonomyId String? @map("taxonomy_id")
order Float? @map("order")
description String?
parentId String? @map("parent_id")
parent Term? @relation("ChildParent", fields: [parentId], references: [id], onDelete: Cascade)
children Term[] @relation("ChildParent")
ancestors TermAncestry[] @relation("DescendantToAncestor")
descendants TermAncestry[] @relation("AncestorToDescendant")
domainId String? @map("domain_id")
domain Department? @relation("TermDom", fields: [domainId], references: [id])
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
createdBy String? @map("created_by")
depts Department[] @relation("department_term")
hasChildren Boolean? @default(false) @map("has_children")
courses Course[] @relation("course_term")
@@index([name]) // 对name字段建立索引以加快基于name的查找速度
@@index([parentId]) // 对parentId字段建立索引以加快基于parentId的查找速度
@@map("term")
}
model TermAncestry {
id String @id @default(cuid())
ancestorId String? @map("ancestor_id")
descendantId String @map("descendant_id")
relDepth Int @map("rel_depth")
ancestor Term? @relation("AncestorToDescendant", fields: [ancestorId], references: [id])
descendant Term @relation("DescendantToAncestor", fields: [descendantId], references: [id])
// 索引建议
@@index([ancestorId]) // 针对祖先的查询
@@index([descendantId]) // 针对后代的查询
@@index([ancestorId, descendantId]) // 组合索引,用于查询特定的祖先-后代关系
@@index([relDepth]) // 根据关系深度的查询
@@map("term_ancestry")
}
model Staff {
id String @id @default(cuid())
showname String? @map("showname")
username String @unique @map("username")
avatar String? @map("avatar")
password String? @map("password")
phoneNumber String? @unique @map("phone_number")
domainId String? @map("domain_id")
deptId String? @map("dept_id")
domain Department? @relation("DomainStaff", fields: [domainId], references: [id])
department Department? @relation("DeptStaff", fields: [deptId], references: [id])
order Float?
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
enabled Boolean? @default(true)
deletedAt DateTime? @map("deleted_at")
officerId String? @map("officer_id")
watchedPost Post[] @relation("post_watch_staff")
visits Visit[]
posts Post[]
sentMsgs Message[] @relation("message_sender")
receivedMsgs Message[] @relation("message_receiver")
registerToken String?
enrollments Enrollment[]
teachedCourses CourseInstructor[]
ownedResources Resource[]
@@index([officerId])
@@index([deptId])
@@index([domainId])
@@index([username])
@@index([order])
@@map("staff")
}
model Department {
id String @id @default(cuid())
name String
order Float?
ancestors DeptAncestry[] @relation("DescendantToAncestor")
descendants DeptAncestry[] @relation("AncestorToDescendant")
parentId String? @map("parent_id")
parent Department? @relation("ChildParent", fields: [parentId], references: [id])
children Department[] @relation("ChildParent")
domainId String? @map("domain_id")
domainTerms Term[] @relation("TermDom")
deletedAt DateTime? @map("deleted_at")
isDomain Boolean? @default(false) @map("is_domain")
domainStaffs Staff[] @relation("DomainStaff")
deptStaffs Staff[] @relation("DeptStaff")
terms Term[] @relation("department_term")
watchedPost Post[] @relation("post_watch_dept")
hasChildren Boolean? @default(false) @map("has_children")
@@index([parentId])
@@index([isDomain])
@@index([name])
@@index([order])
@@map("department")
}
model DeptAncestry {
id String @id @default(cuid())
ancestorId String? @map("ancestor_id")
descendantId String @map("descendant_id")
relDepth Int @map("rel_depth")
ancestor Department? @relation("AncestorToDescendant", fields: [ancestorId], references: [id])
descendant Department @relation("DescendantToAncestor", fields: [descendantId], references: [id])
// 索引建议
@@index([ancestorId]) // 针对祖先的查询
@@index([descendantId]) // 针对后代的查询
@@index([ancestorId, descendantId]) // 组合索引,用于查询特定的祖先-后代关系
@@index([relDepth]) // 根据关系深度的查询
@@map("dept_ancestry")
}
model RoleMap {
id String @id @default(cuid())
objectId String @map("object_id")
roleId String @map("role_id")
domainId String? @map("domain_id")
objectType String @map("object_type")
role Role @relation(fields: [roleId], references: [id])
@@index([domainId])
@@index([objectId])
@@map("rolemap")
}
model Role {
id String @id @default(cuid())
name String @unique @map("name")
permissions String[] @default([]) @map("permissions")
roleMaps RoleMap[]
system Boolean? @default(false) @map("system")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@map("role")
}
model AppConfig {
id String @id @default(cuid())
slug String @unique
title String?
description String?
meta Json?
@@map("app_config")
}
model Post {
// 字符串类型字段
id String @id @default(cuid()) // 帖子唯一标识,使用 cuid() 生成默认值
type String? // 帖子类型,可为空
title String? // 帖子标题,可为空
content String? // 帖子内容,可为空
domainId String? @map("domain_id")
// 日期时间类型字段
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at") // 删除时间,可为空
// 整数类型字段
rating Int // 评分(1-5星)
// 关系类型字段
authorId String? @map("author_id")
author Staff? @relation(fields: [authorId], references: [id]) // 帖子作者,关联 Staff 模型
visits Visit[] // 访问记录,关联 Visit 模型
courseId String @map("course_id")
course Course @relation(fields: [courseId], references: [id]) // 关联课程,关联 Course 模型
parentId String? @map("parent_id")
parent Post? @relation("PostChildren", fields: [parentId], references: [id]) // 父级帖子,关联 Post 模型
children Post[] @relation("PostChildren") // 子级帖子列表,关联 Post 模型
lectureId String? @map("lecture_id")
lecture Lecture? @relation(fields: [lectureId], references: [id]) // 关联讲座,关联 Lecture 模型
resources Resource[] // 附件列表
watchableStaffs Staff[] @relation("post_watch_staff") // 可观看的员工列表,关联 Staff 模型
watchableDepts Department[] @relation("post_watch_dept") // 可观看的部门列表,关联 Department 模型
// 复合索引
@@index([type, domainId]) // 类型和域组合查询
@@index([authorId, type]) // 作者和类型组合查询
@@index([parentId, type]) // 父级帖子和创建时间索引
// 时间相关索引
@@index([createdAt]) // 按创建时间倒序索引
@@index([updatedAt]) // 按更新时间倒序索引
}
model Message {
id String @id @default(cuid())
url String?
intent String?
option Json?
senderId String? @map("sender_id")
type String?
sender Staff? @relation(name: "message_sender", fields: [senderId], references: [id])
title String?
content String?
receivers Staff[] @relation("message_receiver")
visits Visit[]
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime? @updatedAt @map("updated_at")
@@index([type, createdAt])
@@map("message")
}
model Visit {
id String @id @default(cuid()) @map("id")
type String?
views Int @default(1) @map("views")
sourceIP String? @map("source_ip")
// 关联关系
visitorId String @map("visitor_id")
visitor Staff @relation(fields: [visitorId], references: [id])
postId String? @map("post_id")
post Post? @relation(fields: [postId], references: [id])
message Message? @relation(fields: [messageId], references: [id])
messageId String? @map("message_id")
enrollment Enrollment? @relation(fields: [enrollmentId], references: [id], onDelete: Cascade)
enrollmentId String? @map("enrollment_id") // 报名记录ID
lecture Lecture? @relation(fields: [lectureId], references: [id], onDelete: Cascade)
lectureId String? @map("lecture_id") // 课时ID
// 学习数据
progress Float? @default(0) @map("progress") // 完成进度(0-100%)
isCompleted Boolean? @default(false) @map("is_completed") // 是否完成
lastPosition Int? @default(0) @map("last_position") // 视频播放位置(秒)
totalWatchTime Int? @default(0) @map("total_watch_time") // 总观看时长(秒)
// 时间记录
lastWatchedAt DateTime? @map("last_watched_at") // 最后观看时间
createdAt DateTime @default(now()) @map("created_at") // 创建时间
updatedAt DateTime @updatedAt @map("updated_at") // 更新时间
@@unique([enrollmentId, lectureId]) // 确保每个报名只有一条课时进度
@@index([isCompleted]) // 完成状态索引
@@index([lastWatchedAt]) // 最后观看时间索引
@@index([postId, type, visitorId])
@@index([messageId, type, visitorId])
@@map("visit")
}
model Course {
id String @id @default(cuid()) @map("id") // 课程唯一标识符
title String? @map("title") // 课程标题
subTitle String? @map("sub_title") // 课程副标题(可选)
description String? @map("description") // 课程详细描述
thumbnail String? @map("thumbnail") // 课程封面图片URL(可选)
level String? @map("level") // 课程难度等级
// 课程内容组织结构
terms Term[] @relation("course_term") // 课程学期
instructors CourseInstructor[] // 课程讲师团队
sections Section[] // 课程章节结构
lectures Lecture[]
enrollments Enrollment[] // 学生报名记录
reviews Post[] // 学员课程评价
// 课程规划与目标设定
requirements String[] @map("requirements") // 课程学习前置要求
objectives String[] @map("objectives") // 具体的学习目标
// 课程统计指标
totalDuration Int? @default(0) @map("total_duration") // 课程总时长(分钟)
totalLectures Int? @default(0) @map("total_lectures") // 总课时数
averageRating Float? @default(0) @map("average_rating") // 平均评分(1-5分)
numberOfReviews Int? @default(0) @map("number_of_reviews") // 评价总数
numberOfStudents Int? @default(0) @map("number_of_students") // 学习人数
completionRate Float? @default(0) @map("completion_rate") // 完课率(0-100%)
// 课程状态管理
status String? @map("status") // 课程状态(如:草稿/已发布/已归档)
isFeatured Boolean? @default(false) @map("is_featured") // 是否为精选推荐课程
// 生命周期时间戳
createdAt DateTime? @default(now()) @map("created_at") // 创建时间
updatedAt DateTime? @updatedAt @map("updated_at") // 最后更新时间
publishedAt DateTime? @map("published_at") // 发布时间
archivedAt DateTime? @map("archived_at") // 归档时间
deletedAt DateTime? @map("deleted_at") // 软删除时间
// 数据库索引优化
@@index([status]) // 课程状态索引,用于快速筛选
@@index([level]) // 难度等级索引,用于分类查询
@@index([isFeatured]) // 精选标记索引,用于首页推荐
@@map("course")
}
model Section {
id String @id @default(cuid()) @map("id")
title String @map("title")
description String? @map("description")
objectives String[] @map("objectives")
order Float? @default(0) @map("order")
totalDuration Int @default(0) @map("total_duration")
totalLectures Int @default(0) @map("total_lectures")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
// 关联关系
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
courseId String @map("course_id")
lectures Lecture[]
@@index([courseId, order])
@@map("section")
}
model Lecture {
id String @id @default(cuid()) @map("id")
title String @map("title")
description String? @map("description")
order Float? @default(0) @map("order")
duration Int @map("duration")
type String @map("type")
content String? @map("content")
videoUrl String? @map("video_url")
videoThumbnail String? @map("video_thumbnail")
publishedAt DateTime? @map("published_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
// 关联关系
resources Resource[]
section Section? @relation(fields: [sectionId], references: [id], onDelete: Cascade)
sectionId String? @map("section_id")
course Course? @relation(fields: [courseId], references: [id], onDelete: Cascade)
courseId String? @map("course_id")
comments Post[]
visits Visit[]
@@index([sectionId, order])
@@index([type, publishedAt])
@@map("lecture")
}
model Enrollment {
id String @id @default(cuid()) @map("id")
status String @map("status")
completionRate Float @default(0) @map("completion_rate")
lastAccessedAt DateTime? @map("last_accessed_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
completedAt DateTime? @map("completed_at")
// 关联关系
student Staff @relation(fields: [studentId], references: [id])
studentId String @map("student_id")
course Course @relation(fields: [courseId], references: [id])
courseId String @map("course_id")
visits Visit[]
@@unique([studentId, courseId])
@@index([status])
@@index([completedAt])
@@map("enrollment")
}
model CourseInstructor {
courseId String @map("course_id")
instructorId String @map("instructor_id")
role String @map("role")
createdAt DateTime @default(now()) @map("created_at")
order Float? @default(0) @map("order")
course Course @relation(fields: [courseId], references: [id])
instructor Staff @relation(fields: [instructorId], references: [id])
@@id([courseId, instructorId])
@@map("course_instructor")
}
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?
// 元数据
metadata Json? @map("metadata")
// 处理状态控制
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 Staff? @relation(fields: [ownerId], references: [id])
ownerId String? @map("owner_id")
post Post? @relation(fields: [postId], references: [id])
postId String? @map("post_id")
lecture Lecture? @relation(fields: [lectureId], references: [id])
lectureId String? @map("lecture_id")
// 索引
@@index([type])
@@index([createdAt])
@@map("resource")
}
model Node {
id String @id @default(cuid()) @map("id")
title String @map("title")
description String? @map("description")
type String @map("type")
style Json? @map("style")
position Json? @map("position")
data Json? @map("data")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// 关联关系
sourceEdges NodeEdge[] @relation("source_node")
targetEdges NodeEdge[] @relation("target_node")
@@map("node")
}
model NodeEdge {
id String @id @default(cuid()) @map("id")
type String? @map("type")
label String? @map("label")
description String? @map("description")
style Json? @map("style")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
source Node @relation("source_node", fields: [sourceId], references: [id], onDelete: Cascade)
sourceId String @map("source_id")
target Node @relation("target_node", fields: [targetId], references: [id], onDelete: Cascade)
targetId String @map("target_id")
@@unique([sourceId, targetId, type])
@@index([sourceId])
@@index([targetId])
@@map("node_edge")
}