// 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" output = "../src/generated/prisma" } datasource db { provider = "postgresql" } /// 统一角色枚举: /// - SYSTEM_ADMIN: 平台管理员 /// - HOSPITAL_ADMIN: 医院管理员 /// - DIRECTOR: 科室主任 /// - TEAM_LEAD: 小组组长 /// - DOCTOR: 医生 /// - ENGINEER: 工程师 enum UserRole { SYSTEM_ADMIN HOSPITAL_ADMIN DIRECTOR TEAM_LEAD DOCTOR ENGINEER } /// 医院实体:多医院租户的顶层边界。 model Hospital { /// 主键 ID。 id Int @id @default(autoincrement()) /// 医院名称。 name String /// 医院编码(唯一)。 code String @unique /// 下属科室列表。 departments Department[] /// 归属该医院的用户。 users User[] /// 归属该医院的患者。 patients Patient[] /// 该医院被分配的工程师任务关系。 engineerAssignments EngineerHospitalAssignment[] /// 创建时间。 createdAt DateTime @default(now()) /// 更新时间。 updatedAt DateTime @default(now()) @updatedAt } /// 科室实体:归属于某个医院。 model Department { /// 主键 ID。 id Int @id @default(autoincrement()) /// 科室名称。 name String /// 所属医院 ID。 hospitalId Int /// 医院外键关系。 hospital Hospital @relation(fields: [hospitalId], references: [id], onDelete: Cascade) /// 下属小组。 medicalGroups MedicalGroup[] /// 科室下用户。 users User[] /// 科室下患者。 patients Patient[] /// 创建时间。 createdAt DateTime @default(now()) /// 更新时间。 updatedAt DateTime @default(now()) @updatedAt /// 同一家医院下科室名称唯一。 @@unique([hospitalId, name]) } /// 医疗小组实体:归属于某个科室。 model MedicalGroup { /// 主键 ID。 id Int @id @default(autoincrement()) /// 小组名称。 name String /// 所属科室 ID。 departmentId Int /// 科室外键关系。 department Department @relation(fields: [departmentId], references: [id], onDelete: Cascade) /// 小组用户。 users User[] /// 小组患者。 patients Patient[] /// 创建时间。 createdAt DateTime @default(now()) /// 更新时间。 updatedAt DateTime @default(now()) @updatedAt /// 同一科室下小组名称唯一。 @@unique([departmentId, name]) } /// 用户实体:统一承载组织关系、登录凭证与上下级结构。 model User { /// 主键 ID。 id Int @id @default(autoincrement()) /// 手机号(唯一登录名)。 phone String @unique /// 密码哈希(禁止存明文)。 passwordHash String /// 用户姓名。 name String? /// 用户角色。 role UserRole @default(DOCTOR) /// 归属医院 ID(可空,支持平台角色)。 hospitalId Int? /// 归属科室 ID(可空)。 departmentId Int? /// 归属小组 ID(可空)。 medicalGroupId Int? /// 上级用户 ID(自关联层级)。 managerId Int? /// 小程序 openId(可空,唯一)。 wechatMiniOpenId String? @unique /// 服务号 openId(可空,唯一)。 wechatOfficialOpenId String? @unique /// 账号是否启用。 isActive Boolean @default(true) /// 最近登录时间。 lastLoginAt DateTime? /// 医院关系。 hospital Hospital? @relation(fields: [hospitalId], references: [id], onDelete: SetNull) /// 科室关系。 department Department? @relation(fields: [departmentId], references: [id], onDelete: SetNull) /// 小组关系。 medicalGroup MedicalGroup? @relation(fields: [medicalGroupId], references: [id], onDelete: SetNull) /// 上级关系。 manager User? @relation("UserHierarchy", fields: [managerId], references: [id], onDelete: SetNull) /// 下级关系。 subordinates User[] @relation("UserHierarchy") /// 医生持有患者关系。 patients Patient[] @relation("DoctorPatients") /// 工程师被分配医院关系。 engineerAssignments EngineerHospitalAssignment[] @relation("EngineerAssignments") /// 系统管理员分配记录关系。 assignedEngineerHospitals EngineerHospitalAssignment[] @relation("SystemAdminAssignments") /// 创建时间。 createdAt DateTime @default(now()) /// 更新时间。 updatedAt DateTime @default(now()) @updatedAt /// 角色索引,便于权限查询。 @@index([role]) /// 医院索引,便于分院查询。 @@index([hospitalId]) /// 上级索引,便于层级查询。 @@index([managerId]) /// 手机号 + 启用状态联合索引,便于登录场景查询。 @@index([phone, isActive]) } /// 患者实体:医生直接持有患者,上级通过层级可见性获取。 model Patient { /// 主键 ID。 id Int @id @default(autoincrement()) /// 患者姓名。 name String /// 所属医院 ID。 hospitalId Int /// 所属科室 ID(可空)。 departmentId Int? /// 所属小组 ID(可空)。 medicalGroupId Int? /// 负责医生 ID。 doctorId Int /// 医院关系。 hospital Hospital @relation(fields: [hospitalId], references: [id], onDelete: Restrict) /// 科室关系。 department Department? @relation(fields: [departmentId], references: [id], onDelete: SetNull) /// 小组关系。 medicalGroup MedicalGroup? @relation(fields: [medicalGroupId], references: [id], onDelete: SetNull) /// 负责医生关系。 doctor User @relation("DoctorPatients", fields: [doctorId], references: [id], onDelete: Restrict) /// 创建时间。 createdAt DateTime @default(now()) /// 更新时间。 updatedAt DateTime @default(now()) @updatedAt /// 医生索引,便于查“医生名下患者”。 @@index([doctorId]) /// 医院索引,便于查“全院患者”。 @@index([hospitalId]) } /// 工程师任务分配关系:只有系统管理员可以分配工程师到医院。 model EngineerHospitalAssignment { /// 主键 ID。 id Int @id @default(autoincrement()) /// 医院 ID。 hospitalId Int /// 工程师用户 ID。 engineerId Int /// 分配人(系统管理员)用户 ID。 assignedById Int /// 医院关系。 hospital Hospital @relation(fields: [hospitalId], references: [id], onDelete: Cascade) /// 工程师关系。 engineer User @relation("EngineerAssignments", fields: [engineerId], references: [id], onDelete: Restrict) /// 分配人关系。 assignedBy User @relation("SystemAdminAssignments", fields: [assignedById], references: [id], onDelete: Restrict) /// 创建时间。 createdAt DateTime @default(now()) /// 同一医院与工程师不能重复分配。 @@unique([hospitalId, engineerId]) /// 工程师索引。 @@index([engineerId]) /// 分配人索引。 @@index([assignedById]) }